diff --git a/README.md b/README.md
index 51e333c..0569e9b 100644
--- a/README.md
+++ b/README.md
@@ -8,8 +8,6 @@ This repo was created to support [a workshop](https://www.meetup.com/Coffee-Code
## TODO
-* Firefox support
-* Extension component
* Testing component
* Shadow DOM
* Stencil ?
diff --git a/bower_components/custom-elements/.bower.json b/bower_components/custom-elements/.bower.json
new file mode 100644
index 0000000..9c51378
--- /dev/null
+++ b/bower_components/custom-elements/.bower.json
@@ -0,0 +1,36 @@
+{
+ "name": "custom-elements",
+ "main": "custom-elements.min.js",
+ "homepage": "http://webcomponents.org",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/webcomponents/custom-elements.git"
+ },
+ "keywords": [
+ "webcomponents"
+ ],
+ "license": "BSD-3-Clause",
+ "ignore": [],
+ "devDependencies": {
+ "web-component-tester": "^6.0.0",
+ "webcomponents-platform": "webcomponents/webcomponents-platform#^1.0.0",
+ "es6-promise": "stefanpenner/es6-promise#^4.0.0",
+ "html-imports": "webcomponents/html-imports#^1.0.0",
+ "template": "webcomponents/template#^1.2.0",
+ "shadydom": "webcomponents/shadydom#^1.0.6"
+ },
+ "version": "1.0.6",
+ "_release": "1.0.6",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.6",
+ "commit": "21967541c1a0b2e3b20d2666ad5c6f25ee4a296e"
+ },
+ "_source": "https://github.com/webcomponents/custom-elements.git",
+ "_target": "^1.0.6",
+ "_originalSource": "webcomponents/custom-elements",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/bower_components/custom-elements/.gitignore b/bower_components/custom-elements/.gitignore
new file mode 100644
index 0000000..616d6b5
--- /dev/null
+++ b/bower_components/custom-elements/.gitignore
@@ -0,0 +1,4 @@
+node_modules
+bower_components
+
+npm-debug.log*
diff --git a/bower_components/custom-elements/.travis.yml b/bower_components/custom-elements/.travis.yml
new file mode 100644
index 0000000..ba29123
--- /dev/null
+++ b/bower_components/custom-elements/.travis.yml
@@ -0,0 +1,23 @@
+language: node_js
+node_js: 6
+dist: trusty
+addons:
+ firefox: latest
+ apt:
+ sources:
+ - google-chrome
+ packages:
+ - google-chrome-stable
+before_script:
+- export PATH=$PWD/node_modules/.bin:$PATH
+- npm run bower-install
+script:
+- npm run build
+- xvfb-run wct
+- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then wct -s 'windows 10/microsoftedge@14'
+ -s 'windows 8.1/internet explorer@11' -s 'os x 10.11/safari@10' -s 'os x 10.11/safari@9';
+ fi
+env:
+ global:
+ - secure: NDKE0TviiIuKwDJd+eOmd+T42K2en8HbuBvLpfMQb+7564dqRgy+a539IhY9z0CTdMZ7Z0cGcSVwXCQz4SmtA36ARNy4EWlldNSMYU8dYbNyAK0JF4KH6kTrzljB4SPIxb5psN8QY/mD4MjN3LhwzWVF7giumeAUnPkuv+lGHOVVZ+budPIEDemQXc22IZUCYbzzaBpFLf/vdkeyA3ieLcyMnCGbP29zgB1swa1vniTqdcgzuNWwZ46lW5ZQEMj4NPHYUXjiq9rUa/zcaAQoC75YNSVqAxduXLfKvuqZTEWO1mosOV2xpWLBvT981i+UP0t2dAIX2dFgLKKUzlcOwq2Yi5SXcrG+5TJFvuF/+uhfg5Sdu9uBjeql0Vx0NlCydeNBYltRKAWDDj2ePzs2/69Ori54QXQLu3fcC2RBe6te6QMVg91F4PiZJPhkHzw5qgAa4k5X8kpC4JzT6aigPyUUkBd3oYe8TnAsjfp6Z/GbSfJI7fdgqtDnO8lLvE4aF9f6l1rDGsyWL0lwEbAZvWdzqY/Bzhq46BcjrEBSZCh98up15+d6w6IuFgFqPPwXRloOQUiW8IokCExgv3RDilP0CxPWZdf4yHc2nTn7HhvVrzI54UG7eVkh7wywseRFVmIL/Cr5kciWjc200zKwDT2kTZ6EuRMAnTXYbbDZQOU=
+ - secure: OEht4eHm8qMKz+5Q9d7tKDOKH1YOCMyYbxdHzudtbWlNX5NHOCpHOfMOKYTM4WGBWU+GPCqgjNAnf4AfBKUWuLyxM0QB08d9k+ggHLMN+2Fh2h6KqInatrxlIetgGbRqgPFpACTRoEovdH+IVo8vaHn9SW6CyT3L84eRgvbIqlfgZrSpgaxrS3ChO0AYCS4yhN1ui3SeqThUtq/kFYiwB2QYvw5DvFbyQ7YAbXyt/+9tcEOyNt3WGKyFZWhYBQ8gmo5S+CnZnny/DXle6Wx3h53pMhkDjeeRWuNufdvxOumy1WZhYQ46zc3eu6JWTI/3aqKxeABdPIqfPQ19mhWHDgAdXiyLkTQIiOxnnEZklSEkgeqbWfZDJ7ta6Vbl0PhOsqH/0H/7jC3XzgDAaHxqkeRL1f0QSUG0/8jfZzwHMN+AhfoVw8DOAIpQSnVVRTRWN2Y/g1ygdaaJ1Z+8/WMyheFc3/XZASA6S4h2+Jrlde6By9/j1d9kUES2qiUVUwdko5/Kxxq0rkfvo7jrx6ojNOEIuBWxyYcNOciYZKhA5VtLZ3YiD8C7DXGR5un73ktWxw0r5wX0GJgfMsdkjCYR7GEBLLGsiPDah7TVqCGWHzzBFaXq6HAKY6jce+TDp2ReFUh0h0siOKKCX1RFBMzDyK/HUZ9F7JUcPJ8Hwtze3j8=
diff --git a/bower_components/custom-elements/CONTRIBUTING.md b/bower_components/custom-elements/CONTRIBUTING.md
new file mode 100644
index 0000000..00381ed
--- /dev/null
+++ b/bower_components/custom-elements/CONTRIBUTING.md
@@ -0,0 +1,64 @@
+# Contributing
+
+Want to contribute to webcomponents.js? Great!
+
+We are more than happy to accept external contributions to the project in the form of [bug reports](../../issues) and pull requests.
+
+## Contributor License Agreement
+
+Before we can accept patches, there's a quick web form you need to fill out.
+
+- If you're contributing as an individual (e.g. you own the intellectual property), fill out [this form](http://code.google.com/legal/individual-cla-v1.0.html).
+- If you're contributing under a company, fill out [this form](http://code.google.com/legal/corporate-cla-v1.0.html) instead.
+
+This CLA asserts that contributions are owned by you and that we can license all work under our [license](LICENSE).
+
+Other projects require a similar agreement: jQuery, Firefox, Apache, Node, and many more.
+
+[More about CLAs](https://www.google.com/search?q=Contributor%20License%20Agreement)
+
+## Initial setup
+
+1. Setup Gulp: `sudo npm install -g gulp`
+1. Fork the project on github and pull down your copy.
+ > replace the {{ username }} with your username and {{ repository }} with the repository name
+
+ git clone git@github.com:{{ username }}/{{ repository }}.git
+
+1. Test your change results in a working build.
+ > in the repo you've made changes to, try generating a build:
+
+ cd $REPO
+ npm install
+ gulp build
+
+The builds will be placed into the `dist/` directory if all goes well.
+
+1. Commit your code and make a pull request.
+
+That's it for the one time setup. Now you're ready to make a change.
+
+## Submitting a pull request
+
+We iterate fast! To avoid potential merge conflicts, it's a good idea to pull from the main project before making a change and submitting a pull request. The easiest way to do this is setup a remote called `upstream` and do a pull before working on a change:
+
+ git remote add upstream git://github.com/polymer/webcomponentsjs.git
+
+Then before making a change, do a pull from the upstream `master` branch:
+
+ git pull upstream master
+
+To make life easier, add a "pull upstream" alias in your `.gitconfig`:
+
+ [alias]
+ pu = !"git fetch origin -v; git fetch upstream -v; git merge upstream/master"
+
+That will pull in changes from your forked repo, the main (upstream) repo, and merge the two. Then it's just a matter of running `git pu` before a change and pushing to your repo:
+
+ git checkout master
+ git pu
+ # make change
+ git commit -a -m 'Awesome things.'
+ git push
+
+Lastly, don't forget to submit the pull request.
diff --git a/bower_components/custom-elements/DEVELOPING.md b/bower_components/custom-elements/DEVELOPING.md
new file mode 100644
index 0000000..9b5f4f8
--- /dev/null
+++ b/bower_components/custom-elements/DEVELOPING.md
@@ -0,0 +1,167 @@
+# Custom Elements v1
+
+## Status
+
+The polyfill should be mostly feature complete now. It supports defining
+custom elements, the custom element reactions, and upgrading existing elements. It integrates with native Shadow DOM v1, and native and polyfilled HTML Imports.
+
+The implementation could use more tests, especially around ordering of
+reactions. The source references old versions of the spec.
+
+### To do
+
+ 1. Implement Node#isConnected
+ 2. Implement built-in element extension (is=)
+ 3. Add reaction callback ordering tests
+ 4. Reorganize tests to be closer to spec structure
+ 5. Performance tests
+
+## Building & Running Tests
+
+ 1. Install web-component-tester
+
+ ```bash
+ $ npm i -g web-component-tester
+ ```
+
+ 2. Checkout the webcomponentsjs v1 branch
+
+ ```bash
+ $ git clone https://github.com/webcomponents/webcomponentsjs.git
+ $ cd webcomponentsjs
+ $ npm i
+ $ gulp build
+ ```
+
+ 3. Run tests
+
+ ```bash
+ $ wct tests/CustomElements/v1/index.html -l chrome
+ ```
+
+ 4. Bower link to use in another project
+
+ ```bash
+ $ bower link
+ $ cd {your project directory}
+ $ bower link webcomponentsjs
+ ```
+
+## Implementation approach and browser support
+
+The polyfill leans heavily on MutationObservers to drive custom element creation and reactions. This means that the polyfill requires native or polyfilled MutationObservers. The polyfill also uses Map and Set, though those would be easy to polyfill or remove.
+
+The implementation should work without additional polyfills in IE 11, Edge, Safari >6, Firefox, Chrome, Android Browser >4.4, and Opera (not Mini).
+
+IE 10 should be supported with the Mutation Observer polyfill.
+
+This branch does not pass the CI tests yet, but it passes locally in Chrome 52, Safari 9.1, Safari Technical Preview, and Firefox 47.
+
+Because MutationObservers are used to create custom element instances and react to document structure and attribute changes, all reactions are asynchronous while in the specs, some are synchronous. This is by design, since some of the synchronous reactions are impossible to polyfill. We consider it more important that reactions have the same relative timing to each other as the spec, for example attributeChangedCallback happens after connectedCallback.
+
+### Implementing the "Constructor-call Trick"
+
+The HTMLElement constructor is now specified to return a different object than `this`, so that the parser and upgrades can call the constructor on elements that have already been allocated. JavaScript allows this, but some compilers, such as TypeScript and Closure currently don't.
+
+The HTMLElement constructor is also specified to look up the tag name associated with a constructor by using `new.target`. `new.target` isn't available in ES5, is not polyfillable, but `this.constructor` behaves similarly for most ES5 class patterns, including the output of Babel, TypeScript and Closure, so the polyfill uses that to look up tag names.
+
+`new.target` isn't even feature detectable, since it's a syntax error in ES5. Because of this, the polyfill can't check `new.target` first and fallback to `this.constructor`. This also means that ES5-style constructors can't conditionally make a "super" call to the HTMLElement constructor (with `Reflect.construct`) in non-ES6 environments to be compatible with native Custom Elements.
+
+To allow for elements that work in both ES5 and ES6 environments, we provide a shim to be used in browsers that have native Custom Elements v1 support, that overrides the HTMLElement constructor and calls `Reflect.construct` with either the value of `new.target` or `this.constructor`. This shim can only be executed in ES6 environments that support `new.target`, and so should be conditionally loaded. The shim and the polyfill should not be loaded at the same time.
+
+## Building
+
+The Custom Elements V1 polyfill does not use the same module or build system as
+the other webcomponentsjs polyfills, and its build is not integrated into the default build tasks yet.
+
+To build run:
+
+ gulp CustomElementsV1
+
+This creates a CustomElementsV1.min.js file in dist/
+
+## Custom Elements in the DOM Spec
+
+### 4.2.3 Mutation Algorithms
+
+https://dom.spec.whatwg.org/#mutation-algorithms
+
+ * insert 6.5.2.1: call connectedCallback
+ * insert 6.5.2.2: upgrade
+ * remove 14: call disconnectedCallback
+ * remove 15.2: call disconnectedCallback
+
+### 4.4 Node
+
+https://dom.spec.whatwg.org/#concept-node-clone
+
+ * clone 2.1: performs create-element
+ * clone 2.2: append attributes
+
+isConnected looks like it's Custom Elements related, but it's actually part of Shadow DOM. We might want to implement it for on non-native Shadow DOM environments, since we already watch for all connections and disconnections.
+
+### 4.5 Document
+
+https://dom.spec.whatwg.org/#interface-document
+
+ * createElement and createElementNS take ElementCreationOptions
+
+https://dom.spec.whatwg.org/#dom-document-createelement
+
+ * createElement 3, 4, 5, 7
+ * createElementNS 2, 3, 4, 5
+
+### 4.9 Element
+
+https://dom.spec.whatwg.org/#concept-element-custom-element-state
+
+https://dom.spec.whatwg.org/#concept-create-element
+
+ * create an element 2, 3, 4, 5, 6
+
+https://dom.spec.whatwg.org/#concept-element-attributes-change
+
+ * change an attribute 2
+
+https://dom.spec.whatwg.org/#concept-element-attributes-append
+
+ * append an attribute 2
+
+https://dom.spec.whatwg.org/#concept-element-attributes-remove
+
+ * remove an attribute 2
+
+https://dom.spec.whatwg.org/#concept-element-attributes-replace
+
+ * replace an attribute 2
+
+https://dom.spec.whatwg.org/#dom-element-attachshadow
+
+ * attachShadow 2 (nothing to implement)
+
+## Custom Elements in the HTML Spec
+
+
+### 3.2.3 HTML element constructors
+
+https://html.spec.whatwg.org/multipage/dom.html#html-element-constructors
+
+ * HTML element constructors 1-9
+
+### 4.13 Custom Elements
+
+https://html.spec.whatwg.org/multipage/scripting.html#custom-elements
+
+https://html.spec.whatwg.org/multipage/scripting.html#valid-custom-element-name
+
+https://html.spec.whatwg.org/multipage/scripting.html#customelementsregistry
+
+### 7.3 Window
+
+https://html.spec.whatwg.org/multipage/browsers.html#window
+
+ * Window#customElements
+
+https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token
+
+ * create an element for a token 3, 4, 5, 6, 7, 8, 9
diff --git a/bower_components/custom-elements/LICENSE.md b/bower_components/custom-elements/LICENSE.md
new file mode 100644
index 0000000..bb3f440
--- /dev/null
+++ b/bower_components/custom-elements/LICENSE.md
@@ -0,0 +1,19 @@
+# License
+
+Everything in this repo is BSD style license unless otherwise specified.
+
+Copyright (c) 2015 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.
\ No newline at end of file
diff --git a/bower_components/custom-elements/README.md b/bower_components/custom-elements/README.md
new file mode 100644
index 0000000..415504f
--- /dev/null
+++ b/bower_components/custom-elements/README.md
@@ -0,0 +1,211 @@
+# Custom Elements (v1) Polyfill [](https://travis-ci.org/webcomponents/custom-elements)
+
+A polyfill for the [custom elements](https://html.spec.whatwg.org/multipage/scripting.html#custom-elements)
+v1 spec.
+
+## Using
+
+Include `custom-elements.min.js` at the beginning of your page, *before* any code that
+manipulates the DOM:
+```html
+
+```
+
+## Developing
+
+1. Install and build
+
+ ```
+ npm install
+ npm run build
+ ```
+ (Or, `npm i && gulp`, if [gulp](https://github.com/gulpjs/gulp) is installed globally.)
+
+1. Test
+
+ ```
+ npm run test
+ ```
+ (Or, [`wct`](https://github.com/Polymer/web-component-tester), if installed
+ globally.)
+
+## Custom element reactions in the DOM and HTML specs
+
+API which might trigger custom element reactions in the [DOM](https://dom.spec.whatwg.org/)
+and [HTML](https://html.spec.whatwg.org/) specifications are marked with the
+[`CEReactions` extended attribute](https://html.spec.whatwg.org/multipage/scripting.html#cereactions).
+
+## Known Bugs and Limitations
+
+- `adoptedCallback` is not supported.
+- Changing an attribute of a customizable (but uncustomized) element will not
+ cause that element to upgrade.
+- Only DOM API is patched. Notably, this excludes API from the HTML spec marked
+ with the `CEReactions` extended attribute.
+ - Unpatched API from the DOM spec:
+ - Setters on `Element` for `id`, `className`, and `slot`.
+ - `DOMTokenList` (`element.classList`)
+ - `NamedNodeMap` (`element.attributes`)
+ - `Attr` (`element.attributes.getNamedItem('attr-name')`)
+- The [custom element reactions stack](https://html.spec.whatwg.org/multipage/scripting.html#custom-element-reactions-stack)
+ is not implemented.
+ - Typically, DOM operations patched in this polyfill gather the list of
+ elements to which a given callback would apply and then iterate that list,
+ calling the callback on each element. This mechanism breaks down if an
+ element's callback performs another DOM operation that manipulates an area
+ of the tree that was captured in the outer operation's list of elements.
+ When this happens, the callbacks from the inner DOM operation will be called
+ *before* those of the outer DOM operation (typically, depending on the patch
+ implementation), as opposed to a spec-compliant implementation where the
+ callbacks are always run in the order they were inserted into each
+ particular element's reaction queue.
+- Custom elements created by the UA's parser are customized as if they were
+ upgraded, rather than constructed.
+ - These elements are only learned about *after* they have been constructed,
+ and typically after their descendants have been constructed. When these
+ elements are constructed, their children are visible and editable *even
+ though they would not yet exist and manipulating them would throw in a
+ spec-compliant implementation of custom elements!*
+- The [requirements for custom element constructors](https://html.spec.whatwg.org/multipage/scripting.html#custom-element-conformance)
+ are not enforced.
+ - These requirements are not generally enforcable in user script because of
+ the ability to use the `new` operator on a custom element constructor. This
+ means there is no way to know when a call to a constructor has begun or
+ finished.
+- Methods of the `ParentNode` and `ChildNode` interfaces do not support
+ `DocumentFragment`s as arguments.
+- Your custom element constructor's prototype *must* have a property named
+ `constructor` which is that constructor.
+ - By default, for every constructable function `F`, `F.prototype.constructor === F`.
+ If you replace the prototype of your constructor `F`, you must make sure
+ that `F.prototype.constructor === F` remains true. Otherwise, the polyfill
+ will not be able to create or upgrade your custom elements.
+- The [`:defined` CSS pseudo-class](https://html.spec.whatwg.org/multipage/semantics-other.html#pseudo-classes)
+ is not supported.
+
+### ES5 vs ES2015
+
+The custom elements v1 spec is not compatible with ES5 style classes. This means
+ES2015 code compiled to ES5 will not work with a native implementation of Custom
+Elements.[0] While it's possible to force the custom elements polyfill to be
+used to workaround this issue (by setting (`customElements.forcePolyfill = true;`
+before loading the polyfill), you will not be using the UA's native
+implementation in that case.
+
+Since this is not ideal, we've provided an alternative:
+[native-shim.js](https://github.com/webcomponents/custom-elements/blob/master/src/native-shim.js).
+Loading this shim minimally augments the native implementation to be compatible
+with ES5 code. We are also working on some future refinements to this approach
+that will improve the implementation and automatically detect if it's needed.
+
+[0] The spec requires that an element call the `HTMLElement` constructor.
+Typically an ES5 style class would do something like `HTMLElement.call(this)` to
+emulate `super()`. However, `HTMLElement` *must* be called as a constructor and
+not as a plain function, i.e. with `Reflect.construct(HTMLElement, [], MyCEConstructor)`,
+or it will throw.
+
+### Parser-created elements in the main document
+
+By default, the polyfill uses a `MutationObserver` to learn about and upgrade
+elements in the main document as they are parsed. This `MutationObserver` is
+attached to `document` synchronously when the script is run.
+- If you attach a `MutationObserver` earlier before loading the polyfill, that
+ mutation observer will not see upgraded custom elements.
+- If you move a node with descendants that have not yet been inserted by the
+ parser out of the main document, those nodes will not be noticed or upgraded
+ (until another action would trigger an upgrade).
+
+Note: Using `polyfillWrapFlushCallback` disconnects this `MutationObserver`.
+
+### `customElements.polyfillWrapFlushCallback`
+
+tl;dr: The polyfill gets slower as the size of your page and number of custom
+element definitons increases. You can use `polyfillWrapFlushCallback` to prevent
+redundant work.
+
+To avoid a potential memory leak, the polyfill does not maintain a list of upgrade
+candidates. This means that calling `customElements.define` causes a synchronous,
+full-document walk to search for elements with `localName`s matching the new
+definition. Given that this operation is potentially expensive and, if your page
+loads many custom element definitions before using any of them, highly redundant,
+an extra method is added to the `CustomElementRegistry` prototype -
+`polyfillWrapFlushCallback`.
+
+`polyfillWrapFlushCallback` allows you to block the synchronous, full-document
+upgrade attempts made when calling `define` and perform them later. Call
+`polyfillWrapFlushCallback` with a function; the next time `customElements.define`
+is called and a full-document upgrade would happen, your function will be called
+instead. The only argument to your function is *another* function which, when
+called, will run the full-document upgrade attempt.
+
+For example, if you wanted to delay upgrades until the document's ready state
+was `'complete'`, you could use the following:
+
+```javascript
+customElements.polyfillWrapFlushCallback(function(flush) {
+ if (document.readyState === 'complete') {
+ // If the document is already complete, flush synchronously.
+ flush();
+ } else {
+ // Otherwise, wait until it is complete.
+ document.addEventListener('readystatechange', function() {
+ if (document.readyState === 'complete') {
+ flush();
+ }
+ });
+ }
+});
+```
+
+Once your wrapper function is called (because the polyfill wants to upgrade the
+document), it will not be called again until you have triggered the
+full-document upgrade attempt. If multiple definitions are registered before you
+trigger upgrades, all of those definitions will apply when you trigger upgrades -
+don't call the provided function multiple times.
+
+Promises returned by `customElements.whenDefined` will not resolve until a
+full-document upgrade attempt has been performed *after* the given local name
+has been defined.
+
+```javascript
+let flush;
+customElements.polyfillWrapFlushCallback(f => flush = f);
+
+const p = customElements.whenDefined('c-e', () => console.log('c-e defined'));
+
+customElements.define('c-e', class extends HTMLElement {});
+// `p` is not yet resolved; `flush` is now a function.
+
+flush(); // Resolves `p`.
+```
+
+You can't remove a callback given to `polyfillWrapFlushCallback`. If the
+condition your callback was intended to wait on is no longer important, your
+callback should call the given function synchronously. (See the
+`document.readyState` example above.)
+
+**Calling `polyfillWrapFlushCallback` disconnects the `MutationObserver` watching
+the main document.** This means that you must delay until at least
+`document.readyState !== 'loading'` to be sure that all elements in the main
+document are found (subject to exceptions mentioned in the section above).
+
+You can call `polyfillWrapFlushCallback` multiple times, each function given
+will automatically wrap and delay any previous wrappers:
+
+```javascript
+customElements.polyfillWrapFlushCallback(function(flush) {
+ console.log('added first');
+ flush();
+});
+
+customElements.polyfillWrapFlushCallback(function(flush) {
+ console.log('added second');
+ setTimeout(() => flush(), 1000);
+});
+
+customElements.define('c-e', class extends HTMLElement {});
+// 'added second'
+// ~1s delay
+// 'added first'
+// The document is walked to attempt upgrades.
+```
diff --git a/bower_components/custom-elements/bower.json b/bower_components/custom-elements/bower.json
new file mode 100644
index 0000000..4a50073
--- /dev/null
+++ b/bower_components/custom-elements/bower.json
@@ -0,0 +1,25 @@
+{
+ "name": "custom-elements",
+ "main": "custom-elements.min.js",
+ "homepage": "http://webcomponents.org",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/webcomponents/custom-elements.git"
+ },
+ "keywords": [
+ "webcomponents"
+ ],
+ "license": "BSD-3-Clause",
+ "ignore": [],
+ "devDependencies": {
+ "web-component-tester": "^6.0.0",
+ "webcomponents-platform": "webcomponents/webcomponents-platform#^1.0.0",
+ "es6-promise": "stefanpenner/es6-promise#^4.0.0",
+ "html-imports": "webcomponents/html-imports#^1.0.0",
+ "template": "webcomponents/template#^1.2.0",
+ "shadydom": "webcomponents/shadydom#^1.0.6"
+ }
+}
diff --git a/bower_components/custom-elements/custom-elements.min.js b/bower_components/custom-elements/custom-elements.min.js
new file mode 100644
index 0000000..81bd847
--- /dev/null
+++ b/bower_components/custom-elements/custom-elements.min.js
@@ -0,0 +1,38 @@
+(function(){
+'use strict';var h=new function(){};var aa=new Set("annotation-xml color-profile font-face font-face-src font-face-uri font-face-format font-face-name missing-glyph".split(" "));function n(b){var a=aa.has(b);b=/^[a-z][.0-9_a-z]*-[\-.0-9_a-z]*$/.test(b);return!a&&b}function p(b){var a=b.isConnected;if(void 0!==a)return a;for(;b&&!(b.__CE_isImportDocument||b instanceof Document);)b=b.parentNode||(window.ShadowRoot&&b instanceof ShadowRoot?b.host:void 0);return!(!b||!(b.__CE_isImportDocument||b instanceof Document))}
+function q(b,a){for(;a&&a!==b&&!a.nextSibling;)a=a.parentNode;return a&&a!==b?a.nextSibling:null}
+function t(b,a,c){c=c?c:new Set;for(var d=b;d;){if(d.nodeType===Node.ELEMENT_NODE){var e=d;a(e);var f=e.localName;if("link"===f&&"import"===e.getAttribute("rel")){d=e.import;if(d instanceof Node&&!c.has(d))for(c.add(d),d=d.firstChild;d;d=d.nextSibling)t(d,a,c);d=q(b,e);continue}else if("template"===f){d=q(b,e);continue}if(e=e.__CE_shadowRoot)for(e=e.firstChild;e;e=e.nextSibling)t(e,a,c)}d=d.firstChild?d.firstChild:q(b,d)}}function u(b,a,c){b[a]=c};function v(){this.a=new Map;this.o=new Map;this.f=[];this.b=!1}function ba(b,a,c){b.a.set(a,c);b.o.set(c.constructor,c)}function w(b,a){b.b=!0;b.f.push(a)}function x(b,a){b.b&&t(a,function(a){return y(b,a)})}function y(b,a){if(b.b&&!a.__CE_patched){a.__CE_patched=!0;for(var c=0;c=} visitedImports\n */\nexport function walkDeepDescendantElements(root, callback, visitedImports = new Set()) {\n let node = root;\n while (node) {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = /** @type {!Element} */(node);\n\n callback(element);\n\n const localName = element.localName;\n if (localName === 'link' && element.getAttribute('rel') === 'import') {\n // If this import (polyfilled or not) has it's root node available,\n // walk it.\n const importNode = /** @type {!Node} */ (element.import);\n if (importNode instanceof Node && !visitedImports.has(importNode)) {\n // Prevent multiple walks of the same import root.\n visitedImports.add(importNode);\n\n for (let child = importNode.firstChild; child; child = child.nextSibling) {\n walkDeepDescendantElements(child, callback, visitedImports);\n }\n }\n\n // Ignore descendants of import links to prevent attempting to walk the\n // elements created by the HTML Imports polyfill that we just walked\n // above.\n node = nextSiblingOrAncestorSibling(root, element);\n continue;\n } else if (localName === 'template') {\n // Ignore descendants of templates. There shouldn't be any descendants\n // because they will be moved into `.content` during construction in\n // browsers that support template but, in case they exist and are still\n // waiting to be moved by a polyfill, they will be ignored.\n node = nextSiblingOrAncestorSibling(root, element);\n continue;\n }\n\n // Walk shadow roots.\n const shadowRoot = element.__CE_shadowRoot;\n if (shadowRoot) {\n for (let child = shadowRoot.firstChild; child; child = child.nextSibling) {\n walkDeepDescendantElements(child, callback, visitedImports);\n }\n }\n }\n\n node = nextNode(root, node);\n }\n}\n\n/**\n * Used to suppress Closure's \"Modifying the prototype is only allowed if the\n * constructor is in the same scope\" warning without using\n * `@suppress {newCheckTypes, duplicate}` because `newCheckTypes` is too broad.\n *\n * @param {!Object} destination\n * @param {string} name\n * @param {*} value\n */\nexport function setPropertyUnchecked(destination, name, value) {\n destination[name] = value;\n}\n","import * as Utilities from './Utilities.js';\nimport CEState from './CustomElementState.js';\n\nexport default class CustomElementInternals {\n constructor() {\n /** @type {!Map} */\n this._localNameToDefinition = new Map();\n\n /** @type {!Map} */\n this._constructorToDefinition = new Map();\n\n /** @type {!Array} */\n this._patches = [];\n\n /** @type {boolean} */\n this._hasPatches = false;\n }\n\n /**\n * @param {string} localName\n * @param {!CustomElementDefinition} definition\n */\n setDefinition(localName, definition) {\n this._localNameToDefinition.set(localName, definition);\n this._constructorToDefinition.set(definition.constructor, definition);\n }\n\n /**\n * @param {string} localName\n * @return {!CustomElementDefinition|undefined}\n */\n localNameToDefinition(localName) {\n return this._localNameToDefinition.get(localName);\n }\n\n /**\n * @param {!Function} constructor\n * @return {!CustomElementDefinition|undefined}\n */\n constructorToDefinition(constructor) {\n return this._constructorToDefinition.get(constructor);\n }\n\n /**\n * @param {!function(!Node)} listener\n */\n addPatch(listener) {\n this._hasPatches = true;\n this._patches.push(listener);\n }\n\n /**\n * @param {!Node} node\n */\n patchTree(node) {\n if (!this._hasPatches) return;\n\n Utilities.walkDeepDescendantElements(node, element => this.patch(element));\n }\n\n /**\n * @param {!Node} node\n */\n patch(node) {\n if (!this._hasPatches) return;\n\n if (node.__CE_patched) return;\n node.__CE_patched = true;\n\n for (let i = 0; i < this._patches.length; i++) {\n this._patches[i](node);\n }\n }\n\n /**\n * @param {!Node} root\n */\n connectTree(root) {\n const elements = [];\n\n Utilities.walkDeepDescendantElements(root, element => elements.push(element));\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n if (element.__CE_state === CEState.custom) {\n this.connectedCallback(element);\n } else {\n this.upgradeElement(element);\n }\n }\n }\n\n /**\n * @param {!Node} root\n */\n disconnectTree(root) {\n const elements = [];\n\n Utilities.walkDeepDescendantElements(root, element => elements.push(element));\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n if (element.__CE_state === CEState.custom) {\n this.disconnectedCallback(element);\n }\n }\n }\n\n /**\n * Upgrades all uncustomized custom elements at and below a root node for\n * which there is a definition. When custom element reaction callbacks are\n * assumed to be called synchronously (which, by the current DOM / HTML spec\n * definitions, they are *not*), callbacks for both elements customized\n * synchronously by the parser and elements being upgraded occur in the same\n * relative order.\n *\n * NOTE: This function, when used to simulate the construction of a tree that\n * is already created but not customized (i.e. by the parser), does *not*\n * prevent the element from reading the 'final' (true) state of the tree. For\n * example, the element, during truly synchronous parsing / construction would\n * see that it contains no children as they have not yet been inserted.\n * However, this function does not modify the tree, the element will\n * (incorrectly) have children. Additionally, self-modification restrictions\n * for custom element constructors imposed by the DOM spec are *not* enforced.\n *\n *\n * The following nested list shows the steps extending down from the HTML\n * spec's parsing section that cause elements to be synchronously created and\n * upgraded:\n *\n * The \"in body\" insertion mode:\n * https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody\n * - Switch on token:\n * .. other cases ..\n * -> Any other start tag\n * - [Insert an HTML element](below) for the token.\n *\n * Insert an HTML element:\n * https://html.spec.whatwg.org/multipage/syntax.html#insert-an-html-element\n * - Insert a foreign element for the token in the HTML namespace:\n * https://html.spec.whatwg.org/multipage/syntax.html#insert-a-foreign-element\n * - Create an element for a token:\n * https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token\n * - Will execute script flag is true?\n * - (Element queue pushed to the custom element reactions stack.)\n * - Create an element:\n * https://dom.spec.whatwg.org/#concept-create-element\n * - Sync CE flag is true?\n * - Constructor called.\n * - Self-modification restrictions enforced.\n * - Sync CE flag is false?\n * - (Upgrade reaction enqueued.)\n * - Attributes appended to element.\n * (`attributeChangedCallback` reactions enqueued.)\n * - Will execute script flag is true?\n * - (Element queue popped from the custom element reactions stack.\n * Reactions in the popped stack are invoked.)\n * - (Element queue pushed to the custom element reactions stack.)\n * - Insert the element:\n * https://dom.spec.whatwg.org/#concept-node-insert\n * - Shadow-including descendants are connected. During parsing\n * construction, there are no shadow-*excluding* descendants.\n * However, the constructor may have validly attached a shadow\n * tree to itself and added descendants to that shadow tree.\n * (`connectedCallback` reactions enqueued.)\n * - (Element queue popped from the custom element reactions stack.\n * Reactions in the popped stack are invoked.)\n *\n * @param {!Node} root\n * @param {{\n * visitedImports: (!Set|undefined),\n * upgrade: (!function(!Element)|undefined),\n * }=} options\n */\n patchAndUpgradeTree(root, options = {}) {\n const visitedImports = options.visitedImports || new Set();\n const upgrade = options.upgrade || (element => this.upgradeElement(element));\n\n const elements = [];\n\n const gatherElements = element => {\n if (element.localName === 'link' && element.getAttribute('rel') === 'import') {\n // The HTML Imports polyfill sets a descendant element of the link to\n // the `import` property, specifically this is *not* a Document.\n const importNode = /** @type {?Node} */ (element.import);\n\n if (importNode instanceof Node) {\n importNode.__CE_isImportDocument = true;\n // Connected links are associated with the registry.\n importNode.__CE_hasRegistry = true;\n }\n\n if (importNode && importNode.readyState === 'complete') {\n importNode.__CE_documentLoadHandled = true;\n } else {\n // If this link's import root is not available, its contents can't be\n // walked. Wait for 'load' and walk it when it's ready.\n element.addEventListener('load', () => {\n const importNode = /** @type {!Node} */ (element.import);\n\n if (importNode.__CE_documentLoadHandled) return;\n importNode.__CE_documentLoadHandled = true;\n\n // Clone the `visitedImports` set that was populated sync during\n // the `patchAndUpgradeTree` call that caused this 'load' handler to\n // be added. Then, remove *this* link's import node so that we can\n // walk that import again, even if it was partially walked later\n // during the same `patchAndUpgradeTree` call.\n const clonedVisitedImports = new Set(visitedImports);\n clonedVisitedImports.delete(importNode);\n\n this.patchAndUpgradeTree(importNode, {visitedImports: clonedVisitedImports, upgrade});\n });\n }\n } else {\n elements.push(element);\n }\n };\n\n // `walkDeepDescendantElements` populates (and internally checks against)\n // `visitedImports` when traversing a loaded import.\n Utilities.walkDeepDescendantElements(root, gatherElements, visitedImports);\n\n if (this._hasPatches) {\n for (let i = 0; i < elements.length; i++) {\n this.patch(elements[i]);\n }\n }\n\n for (let i = 0; i < elements.length; i++) {\n upgrade(elements[i]);\n }\n }\n\n /**\n * @param {!Element} element\n */\n upgradeElement(element) {\n const currentState = element.__CE_state;\n if (currentState !== undefined) return;\n\n // Prevent elements created in documents without a browsing context from\n // upgrading.\n //\n // https://html.spec.whatwg.org/multipage/custom-elements.html#look-up-a-custom-element-definition\n // \"If document does not have a browsing context, return null.\"\n //\n // https://html.spec.whatwg.org/multipage/window-object.html#dom-document-defaultview\n // \"The defaultView IDL attribute of the Document interface, on getting,\n // must return this Document's browsing context's WindowProxy object, if\n // this Document has an associated browsing context, or null otherwise.\"\n const ownerDocument = element.ownerDocument;\n if (\n !ownerDocument.defaultView &&\n !(ownerDocument.__CE_isImportDocument && ownerDocument.__CE_hasRegistry)\n ) return;\n\n const definition = this.localNameToDefinition(element.localName);\n if (!definition) return;\n\n definition.constructionStack.push(element);\n\n const constructor = definition.constructor;\n try {\n try {\n let result = new (constructor)();\n if (result !== element) {\n throw new Error('The custom element constructor did not produce the element being upgraded.');\n }\n } finally {\n definition.constructionStack.pop();\n }\n } catch (e) {\n element.__CE_state = CEState.failed;\n throw e;\n }\n\n element.__CE_state = CEState.custom;\n element.__CE_definition = definition;\n\n if (definition.attributeChangedCallback) {\n const observedAttributes = definition.observedAttributes;\n for (let i = 0; i < observedAttributes.length; i++) {\n const name = observedAttributes[i];\n const value = element.getAttribute(name);\n if (value !== null) {\n this.attributeChangedCallback(element, name, null, value, null);\n }\n }\n }\n\n if (Utilities.isConnected(element)) {\n this.connectedCallback(element);\n }\n }\n\n /**\n * @param {!Element} element\n */\n connectedCallback(element) {\n const definition = element.__CE_definition;\n if (definition.connectedCallback) {\n definition.connectedCallback.call(element);\n }\n }\n\n /**\n * @param {!Element} element\n */\n disconnectedCallback(element) {\n const definition = element.__CE_definition;\n if (definition.disconnectedCallback) {\n definition.disconnectedCallback.call(element);\n }\n }\n\n /**\n * @param {!Element} element\n * @param {string} name\n * @param {?string} oldValue\n * @param {?string} newValue\n * @param {?string} namespace\n */\n attributeChangedCallback(element, name, oldValue, newValue, namespace) {\n const definition = element.__CE_definition;\n if (\n definition.attributeChangedCallback &&\n definition.observedAttributes.indexOf(name) > -1\n ) {\n definition.attributeChangedCallback.call(element, name, oldValue, newValue, namespace);\n }\n }\n}\n","/**\n * @enum {number}\n */\nconst CustomElementState = {\n custom: 1,\n failed: 2,\n};\n\nexport default CustomElementState;\n","import CustomElementInternals from './CustomElementInternals.js';\n\nexport default class DocumentConstructionObserver {\n constructor(internals, doc) {\n /**\n * @type {!CustomElementInternals}\n */\n this._internals = internals;\n\n /**\n * @type {!Document}\n */\n this._document = doc;\n\n /**\n * @type {MutationObserver|undefined}\n */\n this._observer = undefined;\n\n\n // Simulate tree construction for all currently accessible nodes in the\n // document.\n this._internals.patchAndUpgradeTree(this._document);\n\n if (this._document.readyState === 'loading') {\n this._observer = new MutationObserver(this._handleMutations.bind(this));\n\n // Nodes created by the parser are given to the observer *before* the next\n // task runs. Inline scripts are run in a new task. This means that the\n // observer will be able to handle the newly parsed nodes before the inline\n // script is run.\n this._observer.observe(this._document, {\n childList: true,\n subtree: true,\n });\n }\n }\n\n disconnect() {\n if (this._observer) {\n this._observer.disconnect();\n }\n }\n\n /**\n * @param {!Array} mutations\n */\n _handleMutations(mutations) {\n // Once the document's `readyState` is 'interactive' or 'complete', all new\n // nodes created within that document will be the result of script and\n // should be handled by patching.\n const readyState = this._document.readyState;\n if (readyState === 'interactive' || readyState === 'complete') {\n this.disconnect();\n }\n\n for (let i = 0; i < mutations.length; i++) {\n const addedNodes = mutations[i].addedNodes;\n for (let j = 0; j < addedNodes.length; j++) {\n const node = addedNodes[j];\n this._internals.patchAndUpgradeTree(node);\n }\n }\n }\n}\n","/**\n * @template T\n */\nexport default class Deferred {\n constructor() {\n /**\n * @private\n * @type {T|undefined}\n */\n this._value = undefined;\n\n /**\n * @private\n * @type {Function|undefined}\n */\n this._resolve = undefined;\n\n /**\n * @private\n * @type {!Promise}\n */\n this._promise = new Promise(resolve => {\n this._resolve = resolve;\n\n if (this._value) {\n resolve(this._value);\n }\n });\n }\n\n /**\n * @param {T} value\n */\n resolve(value) {\n if (this._value) {\n throw new Error('Already resolved.');\n }\n\n this._value = value;\n\n if (this._resolve) {\n this._resolve(value);\n }\n }\n\n /**\n * @return {!Promise}\n */\n toPromise() {\n return this._promise;\n }\n}\n","import CustomElementInternals from './CustomElementInternals.js';\nimport DocumentConstructionObserver from './DocumentConstructionObserver.js';\nimport Deferred from './Deferred.js';\nimport * as Utilities from './Utilities.js';\n\n/**\n * @unrestricted\n */\nexport default class CustomElementRegistry {\n\n /**\n * @param {!CustomElementInternals} internals\n */\n constructor(internals) {\n /**\n * @private\n * @type {boolean}\n */\n this._elementDefinitionIsRunning = false;\n\n /**\n * @private\n * @type {!CustomElementInternals}\n */\n this._internals = internals;\n\n /**\n * @private\n * @type {!Map>}\n */\n this._whenDefinedDeferred = new Map();\n\n /**\n * The default flush callback triggers the document walk synchronously.\n * @private\n * @type {!Function}\n */\n this._flushCallback = fn => fn();\n\n /**\n * @private\n * @type {boolean}\n */\n this._flushPending = false;\n\n /**\n * @private\n * @type {!Array}\n */\n this._pendingDefinitions = [];\n\n /**\n * @private\n * @type {!DocumentConstructionObserver}\n */\n this._documentConstructionObserver = new DocumentConstructionObserver(internals, document);\n }\n\n /**\n * @param {string} localName\n * @param {!Function} constructor\n */\n define(localName, constructor) {\n if (!(constructor instanceof Function)) {\n throw new TypeError('Custom element constructors must be functions.');\n }\n\n if (!Utilities.isValidCustomElementName(localName)) {\n throw new SyntaxError(`The element name '${localName}' is not valid.`);\n }\n\n if (this._internals.localNameToDefinition(localName)) {\n throw new Error(`A custom element with name '${localName}' has already been defined.`);\n }\n\n if (this._elementDefinitionIsRunning) {\n throw new Error('A custom element is already being defined.');\n }\n this._elementDefinitionIsRunning = true;\n\n let connectedCallback;\n let disconnectedCallback;\n let adoptedCallback;\n let attributeChangedCallback;\n let observedAttributes;\n try {\n /** @type {!Object} */\n const prototype = constructor.prototype;\n if (!(prototype instanceof Object)) {\n throw new TypeError('The custom element constructor\\'s prototype is not an object.');\n }\n\n function getCallback(name) {\n const callbackValue = prototype[name];\n if (callbackValue !== undefined && !(callbackValue instanceof Function)) {\n throw new Error(`The '${name}' callback must be a function.`);\n }\n return callbackValue;\n }\n\n connectedCallback = getCallback('connectedCallback');\n disconnectedCallback = getCallback('disconnectedCallback');\n adoptedCallback = getCallback('adoptedCallback');\n attributeChangedCallback = getCallback('attributeChangedCallback');\n observedAttributes = constructor['observedAttributes'] || [];\n } catch (e) {\n return;\n } finally {\n this._elementDefinitionIsRunning = false;\n }\n\n const definition = {\n localName,\n constructor,\n connectedCallback,\n disconnectedCallback,\n adoptedCallback,\n attributeChangedCallback,\n observedAttributes,\n constructionStack: [],\n };\n\n this._internals.setDefinition(localName, definition);\n this._pendingDefinitions.push(definition);\n\n // If we've already called the flush callback and it hasn't called back yet,\n // don't call it again.\n if (!this._flushPending) {\n this._flushPending = true;\n this._flushCallback(() => this._flush());\n }\n }\n\n _flush() {\n // If no new definitions were defined, don't attempt to flush. This could\n // happen if a flush callback keeps the function it is given and calls it\n // multiple times.\n if (this._flushPending === false) return;\n this._flushPending = false;\n\n const pendingDefinitions = this._pendingDefinitions;\n\n /**\n * Unupgraded elements with definitions that were defined *before* the last\n * flush, in document order.\n * @type {!Array}\n */\n const elementsWithStableDefinitions = [];\n\n /**\n * A map from `localName`s of definitions that were defined *after* the last\n * flush to unupgraded elements matching that definition, in document order.\n * @type {!Map>}\n */\n const elementsWithPendingDefinitions = new Map();\n for (let i = 0; i < pendingDefinitions.length; i++) {\n elementsWithPendingDefinitions.set(pendingDefinitions[i].localName, []);\n }\n\n this._internals.patchAndUpgradeTree(document, {\n upgrade: element => {\n // Ignore the element if it has already upgraded or failed to upgrade.\n if (element.__CE_state !== undefined) return;\n\n const localName = element.localName;\n\n // If there is an applicable pending definition for the element, add the\n // element to the list of elements to be upgraded with that definition.\n const pendingElements = elementsWithPendingDefinitions.get(localName);\n if (pendingElements) {\n pendingElements.push(element);\n // If there is *any other* applicable definition for the element, add it\n // to the list of elements with stable definitions that need to be upgraded.\n } else if (this._internals.localNameToDefinition(localName)) {\n elementsWithStableDefinitions.push(element);\n }\n },\n });\n\n // Upgrade elements with 'stable' definitions first.\n for (let i = 0; i < elementsWithStableDefinitions.length; i++) {\n this._internals.upgradeElement(elementsWithStableDefinitions[i]);\n }\n\n // Upgrade elements with 'pending' definitions in the order they were defined.\n while (pendingDefinitions.length > 0) {\n const definition = pendingDefinitions.shift();\n const localName = definition.localName;\n\n // Attempt to upgrade all applicable elements.\n const pendingUpgradableElements = elementsWithPendingDefinitions.get(definition.localName);\n for (let i = 0; i < pendingUpgradableElements.length; i++) {\n this._internals.upgradeElement(pendingUpgradableElements[i]);\n }\n\n // Resolve any promises created by `whenDefined` for the definition.\n const deferred = this._whenDefinedDeferred.get(localName);\n if (deferred) {\n deferred.resolve(undefined);\n }\n }\n }\n\n /**\n * @param {string} localName\n * @return {Function|undefined}\n */\n get(localName) {\n const definition = this._internals.localNameToDefinition(localName);\n if (definition) {\n return definition.constructor;\n }\n\n return undefined;\n }\n\n /**\n * @param {string} localName\n * @return {!Promise}\n */\n whenDefined(localName) {\n if (!Utilities.isValidCustomElementName(localName)) {\n return Promise.reject(new SyntaxError(`'${localName}' is not a valid custom element name.`));\n }\n\n const prior = this._whenDefinedDeferred.get(localName);\n if (prior) {\n return prior.toPromise();\n }\n\n const deferred = new Deferred();\n this._whenDefinedDeferred.set(localName, deferred);\n\n const definition = this._internals.localNameToDefinition(localName);\n // Resolve immediately only if the given local name has a definition *and*\n // the full document walk to upgrade elements with that local name has\n // already happened.\n if (definition && !this._pendingDefinitions.some(d => d.localName === localName)) {\n deferred.resolve(undefined);\n }\n\n return deferred.toPromise();\n }\n\n polyfillWrapFlushCallback(outer) {\n this._documentConstructionObserver.disconnect();\n const inner = this._flushCallback;\n this._flushCallback = flush => outer(() => inner(flush));\n }\n}\n\n// Closure compiler exports.\nwindow['CustomElementRegistry'] = CustomElementRegistry;\nCustomElementRegistry.prototype['define'] = CustomElementRegistry.prototype.define;\nCustomElementRegistry.prototype['get'] = CustomElementRegistry.prototype.get;\nCustomElementRegistry.prototype['whenDefined'] = CustomElementRegistry.prototype.whenDefined;\nCustomElementRegistry.prototype['polyfillWrapFlushCallback'] = CustomElementRegistry.prototype.polyfillWrapFlushCallback;\n","export default {\n Document_createElement: window.Document.prototype.createElement,\n Document_createElementNS: window.Document.prototype.createElementNS,\n Document_importNode: window.Document.prototype.importNode,\n Document_prepend: window.Document.prototype['prepend'],\n Document_append: window.Document.prototype['append'],\n DocumentFragment_prepend: window.DocumentFragment.prototype['prepend'],\n DocumentFragment_append: window.DocumentFragment.prototype['append'],\n Node_cloneNode: window.Node.prototype.cloneNode,\n Node_appendChild: window.Node.prototype.appendChild,\n Node_insertBefore: window.Node.prototype.insertBefore,\n Node_removeChild: window.Node.prototype.removeChild,\n Node_replaceChild: window.Node.prototype.replaceChild,\n Node_textContent: Object.getOwnPropertyDescriptor(window.Node.prototype, 'textContent'),\n Element_attachShadow: window.Element.prototype['attachShadow'],\n Element_innerHTML: Object.getOwnPropertyDescriptor(window.Element.prototype, 'innerHTML'),\n Element_getAttribute: window.Element.prototype.getAttribute,\n Element_setAttribute: window.Element.prototype.setAttribute,\n Element_removeAttribute: window.Element.prototype.removeAttribute,\n Element_getAttributeNS: window.Element.prototype.getAttributeNS,\n Element_setAttributeNS: window.Element.prototype.setAttributeNS,\n Element_removeAttributeNS: window.Element.prototype.removeAttributeNS,\n Element_insertAdjacentElement: window.Element.prototype['insertAdjacentElement'],\n Element_prepend: window.Element.prototype['prepend'],\n Element_append: window.Element.prototype['append'],\n Element_before: window.Element.prototype['before'],\n Element_after: window.Element.prototype['after'],\n Element_replaceWith: window.Element.prototype['replaceWith'],\n Element_remove: window.Element.prototype['remove'],\n HTMLElement: window.HTMLElement,\n HTMLElement_innerHTML: Object.getOwnPropertyDescriptor(window.HTMLElement.prototype, 'innerHTML'),\n HTMLElement_insertAdjacentElement: window.HTMLElement.prototype['insertAdjacentElement'],\n};\n","import Native from './Native.js';\nimport CustomElementInternals from '../CustomElementInternals.js';\nimport CEState from '../CustomElementState.js';\nimport AlreadyConstructedMarker from '../AlreadyConstructedMarker.js';\n\n/**\n * @param {!CustomElementInternals} internals\n */\nexport default function(internals) {\n window['HTMLElement'] = (function() {\n /**\n * @type {function(new: HTMLElement): !HTMLElement}\n */\n function HTMLElement() {\n // This should really be `new.target` but `new.target` can't be emulated\n // in ES5. Assuming the user keeps the default value of the constructor's\n // prototype's `constructor` property, this is equivalent.\n /** @type {!Function} */\n const constructor = this.constructor;\n\n const definition = internals.constructorToDefinition(constructor);\n if (!definition) {\n throw new Error('The custom element being constructed was not registered with `customElements`.');\n }\n\n const constructionStack = definition.constructionStack;\n\n if (constructionStack.length === 0) {\n const element = Native.Document_createElement.call(document, definition.localName);\n Object.setPrototypeOf(element, constructor.prototype);\n element.__CE_state = CEState.custom;\n element.__CE_definition = definition;\n internals.patch(element);\n return element;\n }\n\n const lastIndex = constructionStack.length - 1;\n const element = constructionStack[lastIndex];\n if (element === AlreadyConstructedMarker) {\n throw new Error('The HTMLElement constructor was either called reentrantly for this constructor or called multiple times.');\n }\n constructionStack[lastIndex] = AlreadyConstructedMarker;\n\n Object.setPrototypeOf(element, constructor.prototype);\n internals.patch(/** @type {!HTMLElement} */ (element));\n\n return element;\n }\n\n HTMLElement.prototype = Native.HTMLElement.prototype;\n\n return HTMLElement;\n })();\n};\n","/**\n * @license\n * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n */\n\nimport CustomElementInternals from './CustomElementInternals.js';\nimport CustomElementRegistry from './CustomElementRegistry.js';\n\nimport PatchHTMLElement from './Patch/HTMLElement.js';\nimport PatchDocument from './Patch/Document.js';\nimport PatchDocumentFragment from './Patch/DocumentFragment.js';\nimport PatchNode from './Patch/Node.js';\nimport PatchElement from './Patch/Element.js';\n\nconst priorCustomElements = window['customElements'];\n\nif (!priorCustomElements ||\n priorCustomElements['forcePolyfill'] ||\n (typeof priorCustomElements['define'] != 'function') ||\n (typeof priorCustomElements['get'] != 'function')) {\n /** @type {!CustomElementInternals} */\n const internals = new CustomElementInternals();\n\n PatchHTMLElement(internals);\n PatchDocument(internals);\n PatchDocumentFragment(internals);\n PatchNode(internals);\n PatchElement(internals);\n\n // The main document is always associated with the registry.\n document.__CE_hasRegistry = true;\n\n /** @type {!CustomElementRegistry} */\n const customElements = new CustomElementRegistry(internals);\n\n Object.defineProperty(window, 'customElements', {\n configurable: true,\n enumerable: true,\n value: customElements,\n });\n}\n","import CustomElementInternals from '../../CustomElementInternals.js';\nimport * as Utilities from '../../Utilities.js';\n\n/**\n * @typedef {{\n * prepend: !function(...(!Node|string)),\n * append: !function(...(!Node|string)),\n * }}\n */\nlet ParentNodeNativeMethods;\n\n/**\n * @param {!CustomElementInternals} internals\n * @param {!Object} destination\n * @param {!ParentNodeNativeMethods} builtIn\n */\nexport default function(internals, destination, builtIn) {\n /**\n * @param {!function(...(!Node|string))} builtInMethod\n * @return {!function(...(!Node|string))}\n */\n function appendPrependPatch(builtInMethod) {\n return function(...nodes) {\n /**\n * A copy of `nodes`, with any DocumentFragment replaced by its children.\n * @type {!Array}\n */\n const flattenedNodes = [];\n\n /**\n * Elements in `nodes` that were connected before this call.\n * @type {!Array}\n */\n const connectedElements = [];\n\n for (var i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n if (node instanceof Element && Utilities.isConnected(node)) {\n connectedElements.push(node);\n }\n\n if (node instanceof DocumentFragment) {\n for (let child = node.firstChild; child; child = child.nextSibling) {\n flattenedNodes.push(child);\n }\n } else {\n flattenedNodes.push(node);\n }\n }\n\n builtInMethod.apply(this, nodes);\n\n for (let i = 0; i < connectedElements.length; i++) {\n internals.disconnectTree(connectedElements[i]);\n }\n\n if (Utilities.isConnected(this)) {\n for (let i = 0; i < flattenedNodes.length; i++) {\n const node = flattenedNodes[i];\n if (node instanceof Element) {\n internals.connectTree(node);\n }\n }\n }\n };\n }\n\n if (builtIn.prepend !== undefined) {\n Utilities.setPropertyUnchecked(destination, 'prepend', appendPrependPatch(builtIn.prepend));\n }\n\n if (builtIn.append !== undefined) {\n Utilities.setPropertyUnchecked(destination, 'append', appendPrependPatch(builtIn.append));\n }\n};\n","import Native from './Native.js';\nimport CustomElementInternals from '../CustomElementInternals.js';\nimport * as Utilities from '../Utilities.js';\n\nimport PatchParentNode from './Interface/ParentNode.js';\n\n/**\n * @param {!CustomElementInternals} internals\n */\nexport default function(internals) {\n Utilities.setPropertyUnchecked(Document.prototype, 'createElement',\n /**\n * @this {Document}\n * @param {string} localName\n * @return {!Element}\n */\n function(localName) {\n // Only create custom elements if this document is associated with the registry.\n if (this.__CE_hasRegistry) {\n const definition = internals.localNameToDefinition(localName);\n if (definition) {\n return new (definition.constructor)();\n }\n }\n\n const result = /** @type {!Element} */\n (Native.Document_createElement.call(this, localName));\n internals.patch(result);\n return result;\n });\n\n Utilities.setPropertyUnchecked(Document.prototype, 'importNode',\n /**\n * @this {Document}\n * @param {!Node} node\n * @param {boolean=} deep\n * @return {!Node}\n */\n function(node, deep) {\n const clone = Native.Document_importNode.call(this, node, deep);\n // Only create custom elements if this document is associated with the registry.\n if (!this.__CE_hasRegistry) {\n internals.patchTree(clone);\n } else {\n internals.patchAndUpgradeTree(clone);\n }\n return clone;\n });\n\n const NS_HTML = \"http://www.w3.org/1999/xhtml\";\n\n Utilities.setPropertyUnchecked(Document.prototype, 'createElementNS',\n /**\n * @this {Document}\n * @param {?string} namespace\n * @param {string} localName\n * @return {!Element}\n */\n function(namespace, localName) {\n // Only create custom elements if this document is associated with the registry.\n if (this.__CE_hasRegistry && (namespace === null || namespace === NS_HTML)) {\n const definition = internals.localNameToDefinition(localName);\n if (definition) {\n return new (definition.constructor)();\n }\n }\n\n const result = /** @type {!Element} */\n (Native.Document_createElementNS.call(this, namespace, localName));\n internals.patch(result);\n return result;\n });\n\n PatchParentNode(internals, Document.prototype, {\n prepend: Native.Document_prepend,\n append: Native.Document_append,\n });\n};\n","import Native from './Native.js';\nimport CustomElementInternals from '../CustomElementInternals.js';\nimport * as Utilities from '../Utilities.js';\n\n/**\n * @param {!CustomElementInternals} internals\n */\nexport default function(internals) {\n // `Node#nodeValue` is implemented on `Attr`.\n // `Node#textContent` is implemented on `Attr`, `Element`.\n\n Utilities.setPropertyUnchecked(Node.prototype, 'insertBefore',\n /**\n * @this {Node}\n * @param {!Node} node\n * @param {?Node} refNode\n * @return {!Node}\n */\n function(node, refNode) {\n if (node instanceof DocumentFragment) {\n const insertedNodes = Array.prototype.slice.apply(node.childNodes);\n const nativeResult = Native.Node_insertBefore.call(this, node, refNode);\n\n // DocumentFragments can't be connected, so `disconnectTree` will never\n // need to be called on a DocumentFragment's children after inserting it.\n\n if (Utilities.isConnected(this)) {\n for (let i = 0; i < insertedNodes.length; i++) {\n internals.connectTree(insertedNodes[i]);\n }\n }\n\n return nativeResult;\n }\n\n const nodeWasConnected = Utilities.isConnected(node);\n const nativeResult = Native.Node_insertBefore.call(this, node, refNode);\n\n if (nodeWasConnected) {\n internals.disconnectTree(node);\n }\n\n if (Utilities.isConnected(this)) {\n internals.connectTree(node);\n }\n\n return nativeResult;\n });\n\n Utilities.setPropertyUnchecked(Node.prototype, 'appendChild',\n /**\n * @this {Node}\n * @param {!Node} node\n * @return {!Node}\n */\n function(node) {\n if (node instanceof DocumentFragment) {\n const insertedNodes = Array.prototype.slice.apply(node.childNodes);\n const nativeResult = Native.Node_appendChild.call(this, node);\n\n // DocumentFragments can't be connected, so `disconnectTree` will never\n // need to be called on a DocumentFragment's children after inserting it.\n\n if (Utilities.isConnected(this)) {\n for (let i = 0; i < insertedNodes.length; i++) {\n internals.connectTree(insertedNodes[i]);\n }\n }\n\n return nativeResult;\n }\n\n const nodeWasConnected = Utilities.isConnected(node);\n const nativeResult = Native.Node_appendChild.call(this, node);\n\n if (nodeWasConnected) {\n internals.disconnectTree(node);\n }\n\n if (Utilities.isConnected(this)) {\n internals.connectTree(node);\n }\n\n return nativeResult;\n });\n\n Utilities.setPropertyUnchecked(Node.prototype, 'cloneNode',\n /**\n * @this {Node}\n * @param {boolean=} deep\n * @return {!Node}\n */\n function(deep) {\n const clone = Native.Node_cloneNode.call(this, deep);\n // Only create custom elements if this element's owner document is\n // associated with the registry.\n if (!this.ownerDocument.__CE_hasRegistry) {\n internals.patchTree(clone);\n } else {\n internals.patchAndUpgradeTree(clone);\n }\n return clone;\n });\n\n Utilities.setPropertyUnchecked(Node.prototype, 'removeChild',\n /**\n * @this {Node}\n * @param {!Node} node\n * @return {!Node}\n */\n function(node) {\n const nodeWasConnected = Utilities.isConnected(node);\n const nativeResult = Native.Node_removeChild.call(this, node);\n\n if (nodeWasConnected) {\n internals.disconnectTree(node);\n }\n\n return nativeResult;\n });\n\n Utilities.setPropertyUnchecked(Node.prototype, 'replaceChild',\n /**\n * @this {Node}\n * @param {!Node} nodeToInsert\n * @param {!Node} nodeToRemove\n * @return {!Node}\n */\n function(nodeToInsert, nodeToRemove) {\n if (nodeToInsert instanceof DocumentFragment) {\n const insertedNodes = Array.prototype.slice.apply(nodeToInsert.childNodes);\n const nativeResult = Native.Node_replaceChild.call(this, nodeToInsert, nodeToRemove);\n\n // DocumentFragments can't be connected, so `disconnectTree` will never\n // need to be called on a DocumentFragment's children after inserting it.\n\n if (Utilities.isConnected(this)) {\n internals.disconnectTree(nodeToRemove);\n for (let i = 0; i < insertedNodes.length; i++) {\n internals.connectTree(insertedNodes[i]);\n }\n }\n\n return nativeResult;\n }\n\n const nodeToInsertWasConnected = Utilities.isConnected(nodeToInsert);\n const nativeResult = Native.Node_replaceChild.call(this, nodeToInsert, nodeToRemove);\n const thisIsConnected = Utilities.isConnected(this);\n\n if (thisIsConnected) {\n internals.disconnectTree(nodeToRemove);\n }\n\n if (nodeToInsertWasConnected) {\n internals.disconnectTree(nodeToInsert);\n }\n\n if (thisIsConnected) {\n internals.connectTree(nodeToInsert);\n }\n\n return nativeResult;\n });\n\n\n function patch_textContent(destination, baseDescriptor) {\n Object.defineProperty(destination, 'textContent', {\n enumerable: baseDescriptor.enumerable,\n configurable: true,\n get: baseDescriptor.get,\n set: /** @this {Node} */ function(assignedValue) {\n // If this is a text node then there are no nodes to disconnect.\n if (this.nodeType === Node.TEXT_NODE) {\n baseDescriptor.set.call(this, assignedValue);\n return;\n }\n\n let removedNodes = undefined;\n // Checking for `firstChild` is faster than reading `childNodes.length`\n // to compare with 0.\n if (this.firstChild) {\n // Using `childNodes` is faster than `children`, even though we only\n // care about elements.\n const childNodes = this.childNodes;\n const childNodesLength = childNodes.length;\n if (childNodesLength > 0 && Utilities.isConnected(this)) {\n // Copying an array by iterating is faster than using slice.\n removedNodes = new Array(childNodesLength);\n for (let i = 0; i < childNodesLength; i++) {\n removedNodes[i] = childNodes[i];\n }\n }\n }\n\n baseDescriptor.set.call(this, assignedValue);\n\n if (removedNodes) {\n for (let i = 0; i < removedNodes.length; i++) {\n internals.disconnectTree(removedNodes[i]);\n }\n }\n },\n });\n }\n\n if (Native.Node_textContent && Native.Node_textContent.get) {\n patch_textContent(Node.prototype, Native.Node_textContent);\n } else {\n internals.addPatch(function(element) {\n patch_textContent(element, {\n enumerable: true,\n configurable: true,\n // NOTE: This implementation of the `textContent` getter assumes that\n // text nodes' `textContent` getter will not be patched.\n get: /** @this {Node} */ function() {\n /** @type {!Array} */\n const parts = [];\n\n for (let i = 0; i < this.childNodes.length; i++) {\n parts.push(this.childNodes[i].textContent);\n }\n\n return parts.join('');\n },\n set: /** @this {Node} */ function(assignedValue) {\n while (this.firstChild) {\n Native.Node_removeChild.call(this, this.firstChild);\n }\n Native.Node_appendChild.call(this, document.createTextNode(assignedValue));\n },\n });\n });\n }\n};\n","import CustomElementInternals from '../../CustomElementInternals.js';\nimport * as Utilities from '../../Utilities.js';\n\n/**\n * @typedef {{\n * before: !function(...(!Node|string)),\n * after: !function(...(!Node|string)),\n * replaceWith: !function(...(!Node|string)),\n * remove: !function(),\n * }}\n */\nlet ChildNodeNativeMethods;\n\n/**\n * @param {!CustomElementInternals} internals\n * @param {!Object} destination\n * @param {!ChildNodeNativeMethods} builtIn\n */\nexport default function(internals, destination, builtIn) {\n /**\n * @param {!function(...(!Node|string))} builtInMethod\n * @return {!function(...(!Node|string))}\n */\n function beforeAfterPatch(builtInMethod) {\n return function(...nodes) {\n /**\n * A copy of `nodes`, with any DocumentFragment replaced by its children.\n * @type {!Array}\n */\n const flattenedNodes = [];\n\n /**\n * Elements in `nodes` that were connected before this call.\n * @type {!Array}\n */\n const connectedElements = [];\n\n for (var i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n if (node instanceof Element && Utilities.isConnected(node)) {\n connectedElements.push(node);\n }\n\n if (node instanceof DocumentFragment) {\n for (let child = node.firstChild; child; child = child.nextSibling) {\n flattenedNodes.push(child);\n }\n } else {\n flattenedNodes.push(node);\n }\n }\n\n builtInMethod.apply(this, nodes);\n\n for (let i = 0; i < connectedElements.length; i++) {\n internals.disconnectTree(connectedElements[i]);\n }\n\n if (Utilities.isConnected(this)) {\n for (let i = 0; i < flattenedNodes.length; i++) {\n const node = flattenedNodes[i];\n if (node instanceof Element) {\n internals.connectTree(node);\n }\n }\n }\n };\n }\n\n if (builtIn.before !== undefined) {\n Utilities.setPropertyUnchecked(destination, 'before', beforeAfterPatch(builtIn.before));\n }\n\n if (builtIn.before !== undefined) {\n Utilities.setPropertyUnchecked(destination, 'after', beforeAfterPatch(builtIn.after));\n }\n\n if (builtIn.replaceWith !== undefined) {\n Utilities.setPropertyUnchecked(destination, 'replaceWith',\n /**\n * @param {...(!Node|string)} nodes\n */\n function(...nodes) {\n /**\n * A copy of `nodes`, with any DocumentFragment replaced by its children.\n * @type {!Array}\n */\n const flattenedNodes = [];\n\n /**\n * Elements in `nodes` that were connected before this call.\n * @type {!Array}\n */\n const connectedElements = [];\n\n for (var i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n if (node instanceof Element && Utilities.isConnected(node)) {\n connectedElements.push(node);\n }\n\n if (node instanceof DocumentFragment) {\n for (let child = node.firstChild; child; child = child.nextSibling) {\n flattenedNodes.push(child);\n }\n } else {\n flattenedNodes.push(node);\n }\n }\n\n const wasConnected = Utilities.isConnected(this);\n\n builtIn.replaceWith.apply(this, nodes);\n\n for (let i = 0; i < connectedElements.length; i++) {\n internals.disconnectTree(connectedElements[i]);\n }\n\n if (wasConnected) {\n internals.disconnectTree(this);\n for (let i = 0; i < flattenedNodes.length; i++) {\n const node = flattenedNodes[i];\n if (node instanceof Element) {\n internals.connectTree(node);\n }\n }\n }\n });\n }\n\n if (builtIn.remove !== undefined) {\n Utilities.setPropertyUnchecked(destination, 'remove',\n function() {\n const wasConnected = Utilities.isConnected(this);\n\n builtIn.remove.call(this);\n\n if (wasConnected) {\n internals.disconnectTree(this);\n }\n });\n }\n};\n","import Native from './Native.js';\nimport CustomElementInternals from '../CustomElementInternals.js';\nimport CEState from '../CustomElementState.js';\nimport * as Utilities from '../Utilities.js';\n\nimport PatchParentNode from './Interface/ParentNode.js';\nimport PatchChildNode from './Interface/ChildNode.js';\n\n/**\n * @param {!CustomElementInternals} internals\n */\nexport default function(internals) {\n if (Native.Element_attachShadow) {\n Utilities.setPropertyUnchecked(Element.prototype, 'attachShadow',\n /**\n * @this {Element}\n * @param {!{mode: string}} init\n * @return {ShadowRoot}\n */\n function(init) {\n const shadowRoot = Native.Element_attachShadow.call(this, init);\n this.__CE_shadowRoot = shadowRoot;\n return shadowRoot;\n });\n }\n\n\n function patch_innerHTML(destination, baseDescriptor) {\n Object.defineProperty(destination, 'innerHTML', {\n enumerable: baseDescriptor.enumerable,\n configurable: true,\n get: baseDescriptor.get,\n set: /** @this {Element} */ function(htmlString) {\n const isConnected = Utilities.isConnected(this);\n\n // NOTE: In IE11, when using the native `innerHTML` setter, all nodes\n // that were previously descendants of the context element have all of\n // their children removed as part of the set - the entire subtree is\n // 'disassembled'. This work around walks the subtree *before* using the\n // native setter.\n /** @type {!Array|undefined} */\n let removedElements = undefined;\n if (isConnected) {\n removedElements = [];\n Utilities.walkDeepDescendantElements(this, element => {\n if (element !== this) {\n removedElements.push(element);\n }\n });\n }\n\n baseDescriptor.set.call(this, htmlString);\n\n if (removedElements) {\n for (let i = 0; i < removedElements.length; i++) {\n const element = removedElements[i];\n if (element.__CE_state === CEState.custom) {\n internals.disconnectedCallback(element);\n }\n }\n }\n\n // Only create custom elements if this element's owner document is\n // associated with the registry.\n if (!this.ownerDocument.__CE_hasRegistry) {\n internals.patchTree(this);\n } else {\n internals.patchAndUpgradeTree(this);\n }\n return htmlString;\n },\n });\n }\n\n if (Native.Element_innerHTML && Native.Element_innerHTML.get) {\n patch_innerHTML(Element.prototype, Native.Element_innerHTML);\n } else if (Native.HTMLElement_innerHTML && Native.HTMLElement_innerHTML.get) {\n patch_innerHTML(HTMLElement.prototype, Native.HTMLElement_innerHTML);\n } else {\n\n internals.addPatch(function(element) {\n patch_innerHTML(element, {\n enumerable: true,\n configurable: true,\n // Implements getting `innerHTML` by performing an unpatched `cloneNode`\n // of the element and returning the resulting element's `innerHTML`.\n // TODO: Is this too expensive?\n get: /** @this {Element} */ function() {\n return Native.Node_cloneNode.call(this, true).innerHTML;\n },\n // Implements setting `innerHTML` by creating an unpatched element,\n // setting `innerHTML` of that element and replacing the target\n // element's children with those of the unpatched element.\n set: /** @this {Element} */ function(assignedValue) {\n // NOTE: re-route to `content` for `template` elements.\n // We need to do this because `template.appendChild` does not\n // route into `template.content`.\n const isTemplate = (this.localName === 'template');\n /** @type {!Node} */\n const content = isTemplate ? (/** @type {!HTMLTemplateElement} */\n (this)).content : this;\n /** @type {!Node} */\n const rawElement = Native.Document_createElement.call(document,\n this.localName);\n rawElement.innerHTML = assignedValue;\n\n while (content.childNodes.length > 0) {\n Native.Node_removeChild.call(content, content.childNodes[0]);\n }\n const container = isTemplate ? rawElement.content : rawElement;\n while (container.childNodes.length > 0) {\n Native.Node_appendChild.call(content, container.childNodes[0]);\n }\n },\n });\n });\n }\n\n\n Utilities.setPropertyUnchecked(Element.prototype, 'setAttribute',\n /**\n * @this {Element}\n * @param {string} name\n * @param {string} newValue\n */\n function(name, newValue) {\n // Fast path for non-custom elements.\n if (this.__CE_state !== CEState.custom) {\n return Native.Element_setAttribute.call(this, name, newValue);\n }\n\n const oldValue = Native.Element_getAttribute.call(this, name);\n Native.Element_setAttribute.call(this, name, newValue);\n newValue = Native.Element_getAttribute.call(this, name);\n internals.attributeChangedCallback(this, name, oldValue, newValue, null);\n });\n\n Utilities.setPropertyUnchecked(Element.prototype, 'setAttributeNS',\n /**\n * @this {Element}\n * @param {?string} namespace\n * @param {string} name\n * @param {string} newValue\n */\n function(namespace, name, newValue) {\n // Fast path for non-custom elements.\n if (this.__CE_state !== CEState.custom) {\n return Native.Element_setAttributeNS.call(this, namespace, name, newValue);\n }\n\n const oldValue = Native.Element_getAttributeNS.call(this, namespace, name);\n Native.Element_setAttributeNS.call(this, namespace, name, newValue);\n newValue = Native.Element_getAttributeNS.call(this, namespace, name);\n internals.attributeChangedCallback(this, name, oldValue, newValue, namespace);\n });\n\n Utilities.setPropertyUnchecked(Element.prototype, 'removeAttribute',\n /**\n * @this {Element}\n * @param {string} name\n */\n function(name) {\n // Fast path for non-custom elements.\n if (this.__CE_state !== CEState.custom) {\n return Native.Element_removeAttribute.call(this, name);\n }\n\n const oldValue = Native.Element_getAttribute.call(this, name);\n Native.Element_removeAttribute.call(this, name);\n if (oldValue !== null) {\n internals.attributeChangedCallback(this, name, oldValue, null, null);\n }\n });\n\n Utilities.setPropertyUnchecked(Element.prototype, 'removeAttributeNS',\n /**\n * @this {Element}\n * @param {?string} namespace\n * @param {string} name\n */\n function(namespace, name) {\n // Fast path for non-custom elements.\n if (this.__CE_state !== CEState.custom) {\n return Native.Element_removeAttributeNS.call(this, namespace, name);\n }\n\n const oldValue = Native.Element_getAttributeNS.call(this, namespace, name);\n Native.Element_removeAttributeNS.call(this, namespace, name);\n // In older browsers, `Element#getAttributeNS` may return the empty string\n // instead of null if the attribute does not exist. For details, see;\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttributeNS#Notes\n const newValue = Native.Element_getAttributeNS.call(this, namespace, name);\n if (oldValue !== newValue) {\n internals.attributeChangedCallback(this, name, oldValue, newValue, namespace);\n }\n });\n\n\n function patch_insertAdjacentElement(destination, baseMethod) {\n Utilities.setPropertyUnchecked(destination, 'insertAdjacentElement',\n /**\n * @this {Element}\n * @param {string} where\n * @param {!Element} element\n * @return {?Element}\n */\n function(where, element) {\n const wasConnected = Utilities.isConnected(element);\n const insertedElement = /** @type {!Element} */\n (baseMethod.call(this, where, element));\n\n if (wasConnected) {\n internals.disconnectTree(element);\n }\n\n if (Utilities.isConnected(insertedElement)) {\n internals.connectTree(element);\n }\n return insertedElement;\n });\n }\n\n if (Native.HTMLElement_insertAdjacentElement) {\n patch_insertAdjacentElement(HTMLElement.prototype, Native.HTMLElement_insertAdjacentElement);\n } else if (Native.Element_insertAdjacentElement) {\n patch_insertAdjacentElement(Element.prototype, Native.Element_insertAdjacentElement);\n } else {\n console.warn('Custom Elements: `Element#insertAdjacentElement` was not patched.');\n }\n\n\n PatchParentNode(internals, Element.prototype, {\n prepend: Native.Element_prepend,\n append: Native.Element_append,\n });\n\n PatchChildNode(internals, Element.prototype, {\n before: Native.Element_before,\n after: Native.Element_after,\n replaceWith: Native.Element_replaceWith,\n remove: Native.Element_remove,\n });\n};\n","import CustomElementInternals from '../CustomElementInternals.js';\nimport Native from './Native.js';\nimport PatchParentNode from './Interface/ParentNode.js';\n\n/**\n * @param {!CustomElementInternals} internals\n */\nexport default function(internals) {\n PatchParentNode(internals, DocumentFragment.prototype, {\n prepend: Native.DocumentFragment_prepend,\n append: Native.DocumentFragment_append,\n });\n};\n"]}
\ No newline at end of file
diff --git a/bower_components/custom-elements/externs/custom-elements.js b/bower_components/custom-elements/externs/custom-elements.js
new file mode 100644
index 0000000..93378d0
--- /dev/null
+++ b/bower_components/custom-elements/externs/custom-elements.js
@@ -0,0 +1,58 @@
+/** @type {boolean|undefined} */
+CustomElementRegistry.prototype.forcePolyfill;
+
+class AlreadyConstructedMarker {}
+
+/**
+ * @enum {number}
+ */
+const CustomElementState = {
+ custom: 1,
+ failed: 2,
+};
+
+/**
+ * @typedef {{
+ * localName: string,
+ * constructor: !Function,
+ * connectedCallback: Function,
+ * disconnectedCallback: Function,
+ * adoptedCallback: Function,
+ * attributeChangedCallback: Function,
+ * observedAttributes: !Array,
+ * constructionStack: !Array,
+ * }}
+ */
+let CustomElementDefinition;
+
+
+// These properties are defined in the closure externs so that they will not be
+// renamed during minification.
+
+// Used for both Documents and Nodes which represent documents in the HTML
+// Imports polyfill.
+
+/** @type {boolean|undefined} */
+Node.prototype.__CE_hasRegistry;
+
+/** @type {boolean|undefined} */
+Node.prototype.__CE_isImportDocument;
+
+/** @type {boolean|undefined} */
+Node.prototype.__CE_documentLoadHandled;
+
+// Apply generally to Node.
+
+/** @type {boolean|undefined} */
+Node.prototype.__CE_patched;
+
+// Apply generally to Element.
+
+/** @type {!CustomElementState|undefined} */
+Element.prototype.__CE_state;
+
+/** @type {!CustomElementDefinition|undefined} */
+Element.prototype.__CE_definition;
+
+/** @type {!DocumentFragment|undefined} */
+Element.prototype.__CE_shadowRoot;
diff --git a/bower_components/custom-elements/gulpfile.js b/bower_components/custom-elements/gulpfile.js
new file mode 100644
index 0000000..9b11443
--- /dev/null
+++ b/bower_components/custom-elements/gulpfile.js
@@ -0,0 +1,51 @@
+/**
+ * @license
+ * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by 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';
+
+const compilerPackage = require('google-closure-compiler');
+const gulp = require('gulp');
+const sourcemaps = require('gulp-sourcemaps');
+const rollup = require('rollup-stream');
+const source = require('vinyl-source-stream');
+
+const closureCompiler = compilerPackage.gulp();
+
+gulp.task('default', () => {
+ return gulp.src('./src/**/*.js', {base: './'})
+ .pipe(sourcemaps.init())
+ .pipe(closureCompiler({
+ compilation_level: 'ADVANCED',
+ warning_level: 'VERBOSE',
+ language_in: 'ECMASCRIPT6_STRICT',
+ language_out: 'ECMASCRIPT5_STRICT',
+ externs: ['externs/custom-elements.js'],
+ dependency_mode: 'STRICT',
+ entry_point: ['/src/custom-elements'],
+ js_output_file: 'custom-elements.min.js',
+ output_wrapper: '(function(){\n%output%\n}).call(self);',
+ assume_function_wrapper: true,
+ new_type_inf: true,
+ rewrite_polyfills: false,
+ }))
+ .pipe(sourcemaps.write('/'))
+ .pipe(gulp.dest('./'));
+});
+
+gulp.task('debug', () => {
+ return rollup({
+ entry: './src/custom-elements.js',
+ format: 'iife',
+ sourceMap: false,
+ indent: true,
+ })
+ .pipe(source('custom-elements.min.js'))
+ .pipe(gulp.dest('./'));
+});
diff --git a/bower_components/custom-elements/package.json b/bower_components/custom-elements/package.json
new file mode 100644
index 0000000..132eeae
--- /dev/null
+++ b/bower_components/custom-elements/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "@webcomponents/custom-elements",
+ "version": "1.0.6",
+ "description": "HTML Custom Elements Polyfill",
+ "main": "custom-elements.min.js",
+ "directories": {
+ "test": "tests"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/webcomponents/custom-elements.git"
+ },
+ "author": "The Polymer Authors",
+ "license": "BSD-3-Clause",
+ "bugs": {
+ "url": "https://github.com/webcomponents/custom-elements/issues"
+ },
+ "scripts": {
+ "bower-install": "$(npm bin)/bower install",
+ "build": "gulp",
+ "test": "wct"
+ },
+ "homepage": "http://webcomponents.org",
+ "devDependencies": {
+ "@webcomponents/html-imports": "^1.0.0",
+ "@webcomponents/template": "^1.0.0",
+ "@webcomponents/webcomponents-platform": "^1.0.0",
+ "bower": "^1.8.0",
+ "es6-promise": "^4.1.0",
+ "google-closure-compiler": "^20170409.0.0",
+ "gulp": "^3.8.8",
+ "gulp-sourcemaps": "^1.6.0",
+ "rollup-stream": "^1.14.0",
+ "vinyl-source-stream": "^1.1.0",
+ "web-component-tester": "^6.0.0"
+ },
+ "publishConfig": {
+ "access": "public"
+ }
+}
diff --git a/bower_components/custom-elements/src/AlreadyConstructedMarker.js b/bower_components/custom-elements/src/AlreadyConstructedMarker.js
new file mode 100644
index 0000000..2f72d4c
--- /dev/null
+++ b/bower_components/custom-elements/src/AlreadyConstructedMarker.js
@@ -0,0 +1,10 @@
+/**
+ * This class exists only to work around Closure's lack of a way to describe
+ * singletons. It represents the 'already constructed marker' used in custom
+ * element construction stacks.
+ *
+ * https://html.spec.whatwg.org/#concept-already-constructed-marker
+ */
+class AlreadyConstructedMarker {}
+
+export default new AlreadyConstructedMarker();
diff --git a/bower_components/custom-elements/src/CustomElementInternals.js b/bower_components/custom-elements/src/CustomElementInternals.js
new file mode 100644
index 0000000..8eb46d7
--- /dev/null
+++ b/bower_components/custom-elements/src/CustomElementInternals.js
@@ -0,0 +1,333 @@
+import * as Utilities from './Utilities.js';
+import CEState from './CustomElementState.js';
+
+export default class CustomElementInternals {
+ constructor() {
+ /** @type {!Map} */
+ this._localNameToDefinition = new Map();
+
+ /** @type {!Map} */
+ this._constructorToDefinition = new Map();
+
+ /** @type {!Array} */
+ this._patches = [];
+
+ /** @type {boolean} */
+ this._hasPatches = false;
+ }
+
+ /**
+ * @param {string} localName
+ * @param {!CustomElementDefinition} definition
+ */
+ setDefinition(localName, definition) {
+ this._localNameToDefinition.set(localName, definition);
+ this._constructorToDefinition.set(definition.constructor, definition);
+ }
+
+ /**
+ * @param {string} localName
+ * @return {!CustomElementDefinition|undefined}
+ */
+ localNameToDefinition(localName) {
+ return this._localNameToDefinition.get(localName);
+ }
+
+ /**
+ * @param {!Function} constructor
+ * @return {!CustomElementDefinition|undefined}
+ */
+ constructorToDefinition(constructor) {
+ return this._constructorToDefinition.get(constructor);
+ }
+
+ /**
+ * @param {!function(!Node)} listener
+ */
+ addPatch(listener) {
+ this._hasPatches = true;
+ this._patches.push(listener);
+ }
+
+ /**
+ * @param {!Node} node
+ */
+ patchTree(node) {
+ if (!this._hasPatches) return;
+
+ Utilities.walkDeepDescendantElements(node, element => this.patch(element));
+ }
+
+ /**
+ * @param {!Node} node
+ */
+ patch(node) {
+ if (!this._hasPatches) return;
+
+ if (node.__CE_patched) return;
+ node.__CE_patched = true;
+
+ for (let i = 0; i < this._patches.length; i++) {
+ this._patches[i](node);
+ }
+ }
+
+ /**
+ * @param {!Node} root
+ */
+ connectTree(root) {
+ const elements = [];
+
+ Utilities.walkDeepDescendantElements(root, element => elements.push(element));
+
+ for (let i = 0; i < elements.length; i++) {
+ const element = elements[i];
+ if (element.__CE_state === CEState.custom) {
+ this.connectedCallback(element);
+ } else {
+ this.upgradeElement(element);
+ }
+ }
+ }
+
+ /**
+ * @param {!Node} root
+ */
+ disconnectTree(root) {
+ const elements = [];
+
+ Utilities.walkDeepDescendantElements(root, element => elements.push(element));
+
+ for (let i = 0; i < elements.length; i++) {
+ const element = elements[i];
+ if (element.__CE_state === CEState.custom) {
+ this.disconnectedCallback(element);
+ }
+ }
+ }
+
+ /**
+ * Upgrades all uncustomized custom elements at and below a root node for
+ * which there is a definition. When custom element reaction callbacks are
+ * assumed to be called synchronously (which, by the current DOM / HTML spec
+ * definitions, they are *not*), callbacks for both elements customized
+ * synchronously by the parser and elements being upgraded occur in the same
+ * relative order.
+ *
+ * NOTE: This function, when used to simulate the construction of a tree that
+ * is already created but not customized (i.e. by the parser), does *not*
+ * prevent the element from reading the 'final' (true) state of the tree. For
+ * example, the element, during truly synchronous parsing / construction would
+ * see that it contains no children as they have not yet been inserted.
+ * However, this function does not modify the tree, the element will
+ * (incorrectly) have children. Additionally, self-modification restrictions
+ * for custom element constructors imposed by the DOM spec are *not* enforced.
+ *
+ *
+ * The following nested list shows the steps extending down from the HTML
+ * spec's parsing section that cause elements to be synchronously created and
+ * upgraded:
+ *
+ * The "in body" insertion mode:
+ * https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
+ * - Switch on token:
+ * .. other cases ..
+ * -> Any other start tag
+ * - [Insert an HTML element](below) for the token.
+ *
+ * Insert an HTML element:
+ * https://html.spec.whatwg.org/multipage/syntax.html#insert-an-html-element
+ * - Insert a foreign element for the token in the HTML namespace:
+ * https://html.spec.whatwg.org/multipage/syntax.html#insert-a-foreign-element
+ * - Create an element for a token:
+ * https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token
+ * - Will execute script flag is true?
+ * - (Element queue pushed to the custom element reactions stack.)
+ * - Create an element:
+ * https://dom.spec.whatwg.org/#concept-create-element
+ * - Sync CE flag is true?
+ * - Constructor called.
+ * - Self-modification restrictions enforced.
+ * - Sync CE flag is false?
+ * - (Upgrade reaction enqueued.)
+ * - Attributes appended to element.
+ * (`attributeChangedCallback` reactions enqueued.)
+ * - Will execute script flag is true?
+ * - (Element queue popped from the custom element reactions stack.
+ * Reactions in the popped stack are invoked.)
+ * - (Element queue pushed to the custom element reactions stack.)
+ * - Insert the element:
+ * https://dom.spec.whatwg.org/#concept-node-insert
+ * - Shadow-including descendants are connected. During parsing
+ * construction, there are no shadow-*excluding* descendants.
+ * However, the constructor may have validly attached a shadow
+ * tree to itself and added descendants to that shadow tree.
+ * (`connectedCallback` reactions enqueued.)
+ * - (Element queue popped from the custom element reactions stack.
+ * Reactions in the popped stack are invoked.)
+ *
+ * @param {!Node} root
+ * @param {{
+ * visitedImports: (!Set|undefined),
+ * upgrade: (!function(!Element)|undefined),
+ * }=} options
+ */
+ patchAndUpgradeTree(root, options = {}) {
+ const visitedImports = options.visitedImports || new Set();
+ const upgrade = options.upgrade || (element => this.upgradeElement(element));
+
+ const elements = [];
+
+ const gatherElements = element => {
+ if (element.localName === 'link' && element.getAttribute('rel') === 'import') {
+ // The HTML Imports polyfill sets a descendant element of the link to
+ // the `import` property, specifically this is *not* a Document.
+ const importNode = /** @type {?Node} */ (element.import);
+
+ if (importNode instanceof Node) {
+ importNode.__CE_isImportDocument = true;
+ // Connected links are associated with the registry.
+ importNode.__CE_hasRegistry = true;
+ }
+
+ if (importNode && importNode.readyState === 'complete') {
+ importNode.__CE_documentLoadHandled = true;
+ } else {
+ // If this link's import root is not available, its contents can't be
+ // walked. Wait for 'load' and walk it when it's ready.
+ element.addEventListener('load', () => {
+ const importNode = /** @type {!Node} */ (element.import);
+
+ if (importNode.__CE_documentLoadHandled) return;
+ importNode.__CE_documentLoadHandled = true;
+
+ // Clone the `visitedImports` set that was populated sync during
+ // the `patchAndUpgradeTree` call that caused this 'load' handler to
+ // be added. Then, remove *this* link's import node so that we can
+ // walk that import again, even if it was partially walked later
+ // during the same `patchAndUpgradeTree` call.
+ const clonedVisitedImports = new Set(visitedImports);
+ clonedVisitedImports.delete(importNode);
+
+ this.patchAndUpgradeTree(importNode, {visitedImports: clonedVisitedImports, upgrade});
+ });
+ }
+ } else {
+ elements.push(element);
+ }
+ };
+
+ // `walkDeepDescendantElements` populates (and internally checks against)
+ // `visitedImports` when traversing a loaded import.
+ Utilities.walkDeepDescendantElements(root, gatherElements, visitedImports);
+
+ if (this._hasPatches) {
+ for (let i = 0; i < elements.length; i++) {
+ this.patch(elements[i]);
+ }
+ }
+
+ for (let i = 0; i < elements.length; i++) {
+ upgrade(elements[i]);
+ }
+ }
+
+ /**
+ * @param {!Element} element
+ */
+ upgradeElement(element) {
+ const currentState = element.__CE_state;
+ if (currentState !== undefined) return;
+
+ // Prevent elements created in documents without a browsing context from
+ // upgrading.
+ //
+ // https://html.spec.whatwg.org/multipage/custom-elements.html#look-up-a-custom-element-definition
+ // "If document does not have a browsing context, return null."
+ //
+ // https://html.spec.whatwg.org/multipage/window-object.html#dom-document-defaultview
+ // "The defaultView IDL attribute of the Document interface, on getting,
+ // must return this Document's browsing context's WindowProxy object, if
+ // this Document has an associated browsing context, or null otherwise."
+ const ownerDocument = element.ownerDocument;
+ if (
+ !ownerDocument.defaultView &&
+ !(ownerDocument.__CE_isImportDocument && ownerDocument.__CE_hasRegistry)
+ ) return;
+
+ const definition = this.localNameToDefinition(element.localName);
+ if (!definition) return;
+
+ definition.constructionStack.push(element);
+
+ const constructor = definition.constructor;
+ try {
+ try {
+ let result = new (constructor)();
+ if (result !== element) {
+ throw new Error('The custom element constructor did not produce the element being upgraded.');
+ }
+ } finally {
+ definition.constructionStack.pop();
+ }
+ } catch (e) {
+ element.__CE_state = CEState.failed;
+ throw e;
+ }
+
+ element.__CE_state = CEState.custom;
+ element.__CE_definition = definition;
+
+ if (definition.attributeChangedCallback) {
+ const observedAttributes = definition.observedAttributes;
+ for (let i = 0; i < observedAttributes.length; i++) {
+ const name = observedAttributes[i];
+ const value = element.getAttribute(name);
+ if (value !== null) {
+ this.attributeChangedCallback(element, name, null, value, null);
+ }
+ }
+ }
+
+ if (Utilities.isConnected(element)) {
+ this.connectedCallback(element);
+ }
+ }
+
+ /**
+ * @param {!Element} element
+ */
+ connectedCallback(element) {
+ const definition = element.__CE_definition;
+ if (definition.connectedCallback) {
+ definition.connectedCallback.call(element);
+ }
+ }
+
+ /**
+ * @param {!Element} element
+ */
+ disconnectedCallback(element) {
+ const definition = element.__CE_definition;
+ if (definition.disconnectedCallback) {
+ definition.disconnectedCallback.call(element);
+ }
+ }
+
+ /**
+ * @param {!Element} element
+ * @param {string} name
+ * @param {?string} oldValue
+ * @param {?string} newValue
+ * @param {?string} namespace
+ */
+ attributeChangedCallback(element, name, oldValue, newValue, namespace) {
+ const definition = element.__CE_definition;
+ if (
+ definition.attributeChangedCallback &&
+ definition.observedAttributes.indexOf(name) > -1
+ ) {
+ definition.attributeChangedCallback.call(element, name, oldValue, newValue, namespace);
+ }
+ }
+}
diff --git a/bower_components/custom-elements/src/CustomElementRegistry.js b/bower_components/custom-elements/src/CustomElementRegistry.js
new file mode 100644
index 0000000..87b94c9
--- /dev/null
+++ b/bower_components/custom-elements/src/CustomElementRegistry.js
@@ -0,0 +1,257 @@
+import CustomElementInternals from './CustomElementInternals.js';
+import DocumentConstructionObserver from './DocumentConstructionObserver.js';
+import Deferred from './Deferred.js';
+import * as Utilities from './Utilities.js';
+
+/**
+ * @unrestricted
+ */
+export default class CustomElementRegistry {
+
+ /**
+ * @param {!CustomElementInternals} internals
+ */
+ constructor(internals) {
+ /**
+ * @private
+ * @type {boolean}
+ */
+ this._elementDefinitionIsRunning = false;
+
+ /**
+ * @private
+ * @type {!CustomElementInternals}
+ */
+ this._internals = internals;
+
+ /**
+ * @private
+ * @type {!Map>}
+ */
+ this._whenDefinedDeferred = new Map();
+
+ /**
+ * The default flush callback triggers the document walk synchronously.
+ * @private
+ * @type {!Function}
+ */
+ this._flushCallback = fn => fn();
+
+ /**
+ * @private
+ * @type {boolean}
+ */
+ this._flushPending = false;
+
+ /**
+ * @private
+ * @type {!Array}
+ */
+ this._pendingDefinitions = [];
+
+ /**
+ * @private
+ * @type {!DocumentConstructionObserver}
+ */
+ this._documentConstructionObserver = new DocumentConstructionObserver(internals, document);
+ }
+
+ /**
+ * @param {string} localName
+ * @param {!Function} constructor
+ */
+ define(localName, constructor) {
+ if (!(constructor instanceof Function)) {
+ throw new TypeError('Custom element constructors must be functions.');
+ }
+
+ if (!Utilities.isValidCustomElementName(localName)) {
+ throw new SyntaxError(`The element name '${localName}' is not valid.`);
+ }
+
+ if (this._internals.localNameToDefinition(localName)) {
+ throw new Error(`A custom element with name '${localName}' has already been defined.`);
+ }
+
+ if (this._elementDefinitionIsRunning) {
+ throw new Error('A custom element is already being defined.');
+ }
+ this._elementDefinitionIsRunning = true;
+
+ let connectedCallback;
+ let disconnectedCallback;
+ let adoptedCallback;
+ let attributeChangedCallback;
+ let observedAttributes;
+ try {
+ /** @type {!Object} */
+ const prototype = constructor.prototype;
+ if (!(prototype instanceof Object)) {
+ throw new TypeError('The custom element constructor\'s prototype is not an object.');
+ }
+
+ function getCallback(name) {
+ const callbackValue = prototype[name];
+ if (callbackValue !== undefined && !(callbackValue instanceof Function)) {
+ throw new Error(`The '${name}' callback must be a function.`);
+ }
+ return callbackValue;
+ }
+
+ connectedCallback = getCallback('connectedCallback');
+ disconnectedCallback = getCallback('disconnectedCallback');
+ adoptedCallback = getCallback('adoptedCallback');
+ attributeChangedCallback = getCallback('attributeChangedCallback');
+ observedAttributes = constructor['observedAttributes'] || [];
+ } catch (e) {
+ return;
+ } finally {
+ this._elementDefinitionIsRunning = false;
+ }
+
+ const definition = {
+ localName,
+ constructor,
+ connectedCallback,
+ disconnectedCallback,
+ adoptedCallback,
+ attributeChangedCallback,
+ observedAttributes,
+ constructionStack: [],
+ };
+
+ this._internals.setDefinition(localName, definition);
+ this._pendingDefinitions.push(definition);
+
+ // If we've already called the flush callback and it hasn't called back yet,
+ // don't call it again.
+ if (!this._flushPending) {
+ this._flushPending = true;
+ this._flushCallback(() => this._flush());
+ }
+ }
+
+ _flush() {
+ // If no new definitions were defined, don't attempt to flush. This could
+ // happen if a flush callback keeps the function it is given and calls it
+ // multiple times.
+ if (this._flushPending === false) return;
+ this._flushPending = false;
+
+ const pendingDefinitions = this._pendingDefinitions;
+
+ /**
+ * Unupgraded elements with definitions that were defined *before* the last
+ * flush, in document order.
+ * @type {!Array}
+ */
+ const elementsWithStableDefinitions = [];
+
+ /**
+ * A map from `localName`s of definitions that were defined *after* the last
+ * flush to unupgraded elements matching that definition, in document order.
+ * @type {!Map>}
+ */
+ const elementsWithPendingDefinitions = new Map();
+ for (let i = 0; i < pendingDefinitions.length; i++) {
+ elementsWithPendingDefinitions.set(pendingDefinitions[i].localName, []);
+ }
+
+ this._internals.patchAndUpgradeTree(document, {
+ upgrade: element => {
+ // Ignore the element if it has already upgraded or failed to upgrade.
+ if (element.__CE_state !== undefined) return;
+
+ const localName = element.localName;
+
+ // If there is an applicable pending definition for the element, add the
+ // element to the list of elements to be upgraded with that definition.
+ const pendingElements = elementsWithPendingDefinitions.get(localName);
+ if (pendingElements) {
+ pendingElements.push(element);
+ // If there is *any other* applicable definition for the element, add it
+ // to the list of elements with stable definitions that need to be upgraded.
+ } else if (this._internals.localNameToDefinition(localName)) {
+ elementsWithStableDefinitions.push(element);
+ }
+ },
+ });
+
+ // Upgrade elements with 'stable' definitions first.
+ for (let i = 0; i < elementsWithStableDefinitions.length; i++) {
+ this._internals.upgradeElement(elementsWithStableDefinitions[i]);
+ }
+
+ // Upgrade elements with 'pending' definitions in the order they were defined.
+ while (pendingDefinitions.length > 0) {
+ const definition = pendingDefinitions.shift();
+ const localName = definition.localName;
+
+ // Attempt to upgrade all applicable elements.
+ const pendingUpgradableElements = elementsWithPendingDefinitions.get(definition.localName);
+ for (let i = 0; i < pendingUpgradableElements.length; i++) {
+ this._internals.upgradeElement(pendingUpgradableElements[i]);
+ }
+
+ // Resolve any promises created by `whenDefined` for the definition.
+ const deferred = this._whenDefinedDeferred.get(localName);
+ if (deferred) {
+ deferred.resolve(undefined);
+ }
+ }
+ }
+
+ /**
+ * @param {string} localName
+ * @return {Function|undefined}
+ */
+ get(localName) {
+ const definition = this._internals.localNameToDefinition(localName);
+ if (definition) {
+ return definition.constructor;
+ }
+
+ return undefined;
+ }
+
+ /**
+ * @param {string} localName
+ * @return {!Promise}
+ */
+ whenDefined(localName) {
+ if (!Utilities.isValidCustomElementName(localName)) {
+ return Promise.reject(new SyntaxError(`'${localName}' is not a valid custom element name.`));
+ }
+
+ const prior = this._whenDefinedDeferred.get(localName);
+ if (prior) {
+ return prior.toPromise();
+ }
+
+ const deferred = new Deferred();
+ this._whenDefinedDeferred.set(localName, deferred);
+
+ const definition = this._internals.localNameToDefinition(localName);
+ // Resolve immediately only if the given local name has a definition *and*
+ // the full document walk to upgrade elements with that local name has
+ // already happened.
+ if (definition && !this._pendingDefinitions.some(d => d.localName === localName)) {
+ deferred.resolve(undefined);
+ }
+
+ return deferred.toPromise();
+ }
+
+ polyfillWrapFlushCallback(outer) {
+ this._documentConstructionObserver.disconnect();
+ const inner = this._flushCallback;
+ this._flushCallback = flush => outer(() => inner(flush));
+ }
+}
+
+// Closure compiler exports.
+window['CustomElementRegistry'] = CustomElementRegistry;
+CustomElementRegistry.prototype['define'] = CustomElementRegistry.prototype.define;
+CustomElementRegistry.prototype['get'] = CustomElementRegistry.prototype.get;
+CustomElementRegistry.prototype['whenDefined'] = CustomElementRegistry.prototype.whenDefined;
+CustomElementRegistry.prototype['polyfillWrapFlushCallback'] = CustomElementRegistry.prototype.polyfillWrapFlushCallback;
diff --git a/bower_components/custom-elements/src/CustomElementState.js b/bower_components/custom-elements/src/CustomElementState.js
new file mode 100644
index 0000000..47c3d5e
--- /dev/null
+++ b/bower_components/custom-elements/src/CustomElementState.js
@@ -0,0 +1,9 @@
+/**
+ * @enum {number}
+ */
+const CustomElementState = {
+ custom: 1,
+ failed: 2,
+};
+
+export default CustomElementState;
diff --git a/bower_components/custom-elements/src/Deferred.js b/bower_components/custom-elements/src/Deferred.js
new file mode 100644
index 0000000..2551e34
--- /dev/null
+++ b/bower_components/custom-elements/src/Deferred.js
@@ -0,0 +1,52 @@
+/**
+ * @template T
+ */
+export default class Deferred {
+ constructor() {
+ /**
+ * @private
+ * @type {T|undefined}
+ */
+ this._value = undefined;
+
+ /**
+ * @private
+ * @type {Function|undefined}
+ */
+ this._resolve = undefined;
+
+ /**
+ * @private
+ * @type {!Promise}
+ */
+ this._promise = new Promise(resolve => {
+ this._resolve = resolve;
+
+ if (this._value) {
+ resolve(this._value);
+ }
+ });
+ }
+
+ /**
+ * @param {T} value
+ */
+ resolve(value) {
+ if (this._value) {
+ throw new Error('Already resolved.');
+ }
+
+ this._value = value;
+
+ if (this._resolve) {
+ this._resolve(value);
+ }
+ }
+
+ /**
+ * @return {!Promise}
+ */
+ toPromise() {
+ return this._promise;
+ }
+}
diff --git a/bower_components/custom-elements/src/DocumentConstructionObserver.js b/bower_components/custom-elements/src/DocumentConstructionObserver.js
new file mode 100644
index 0000000..b150d36
--- /dev/null
+++ b/bower_components/custom-elements/src/DocumentConstructionObserver.js
@@ -0,0 +1,65 @@
+import CustomElementInternals from './CustomElementInternals.js';
+
+export default class DocumentConstructionObserver {
+ constructor(internals, doc) {
+ /**
+ * @type {!CustomElementInternals}
+ */
+ this._internals = internals;
+
+ /**
+ * @type {!Document}
+ */
+ this._document = doc;
+
+ /**
+ * @type {MutationObserver|undefined}
+ */
+ this._observer = undefined;
+
+
+ // Simulate tree construction for all currently accessible nodes in the
+ // document.
+ this._internals.patchAndUpgradeTree(this._document);
+
+ if (this._document.readyState === 'loading') {
+ this._observer = new MutationObserver(this._handleMutations.bind(this));
+
+ // Nodes created by the parser are given to the observer *before* the next
+ // task runs. Inline scripts are run in a new task. This means that the
+ // observer will be able to handle the newly parsed nodes before the inline
+ // script is run.
+ this._observer.observe(this._document, {
+ childList: true,
+ subtree: true,
+ });
+ }
+ }
+
+ disconnect() {
+ if (this._observer) {
+ this._observer.disconnect();
+ }
+ }
+
+ /**
+ * @param {!Array} mutations
+ */
+ _handleMutations(mutations) {
+ // Once the document's `readyState` is 'interactive' or 'complete', all new
+ // nodes created within that document will be the result of script and
+ // should be handled by patching.
+ const readyState = this._document.readyState;
+ if (readyState === 'interactive' || readyState === 'complete') {
+ this.disconnect();
+ }
+
+ for (let i = 0; i < mutations.length; i++) {
+ const addedNodes = mutations[i].addedNodes;
+ for (let j = 0; j < addedNodes.length; j++) {
+ const node = addedNodes[j];
+ this._internals.patchAndUpgradeTree(node);
+ }
+ }
+ }
+}
diff --git a/bower_components/custom-elements/src/Patch/Document.js b/bower_components/custom-elements/src/Patch/Document.js
new file mode 100644
index 0000000..f764362
--- /dev/null
+++ b/bower_components/custom-elements/src/Patch/Document.js
@@ -0,0 +1,78 @@
+import Native from './Native.js';
+import CustomElementInternals from '../CustomElementInternals.js';
+import * as Utilities from '../Utilities.js';
+
+import PatchParentNode from './Interface/ParentNode.js';
+
+/**
+ * @param {!CustomElementInternals} internals
+ */
+export default function(internals) {
+ Utilities.setPropertyUnchecked(Document.prototype, 'createElement',
+ /**
+ * @this {Document}
+ * @param {string} localName
+ * @return {!Element}
+ */
+ function(localName) {
+ // Only create custom elements if this document is associated with the registry.
+ if (this.__CE_hasRegistry) {
+ const definition = internals.localNameToDefinition(localName);
+ if (definition) {
+ return new (definition.constructor)();
+ }
+ }
+
+ const result = /** @type {!Element} */
+ (Native.Document_createElement.call(this, localName));
+ internals.patch(result);
+ return result;
+ });
+
+ Utilities.setPropertyUnchecked(Document.prototype, 'importNode',
+ /**
+ * @this {Document}
+ * @param {!Node} node
+ * @param {boolean=} deep
+ * @return {!Node}
+ */
+ function(node, deep) {
+ const clone = Native.Document_importNode.call(this, node, deep);
+ // Only create custom elements if this document is associated with the registry.
+ if (!this.__CE_hasRegistry) {
+ internals.patchTree(clone);
+ } else {
+ internals.patchAndUpgradeTree(clone);
+ }
+ return clone;
+ });
+
+ const NS_HTML = "http://www.w3.org/1999/xhtml";
+
+ Utilities.setPropertyUnchecked(Document.prototype, 'createElementNS',
+ /**
+ * @this {Document}
+ * @param {?string} namespace
+ * @param {string} localName
+ * @return {!Element}
+ */
+ function(namespace, localName) {
+ // Only create custom elements if this document is associated with the registry.
+ if (this.__CE_hasRegistry && (namespace === null || namespace === NS_HTML)) {
+ const definition = internals.localNameToDefinition(localName);
+ if (definition) {
+ return new (definition.constructor)();
+ }
+ }
+
+ const result = /** @type {!Element} */
+ (Native.Document_createElementNS.call(this, namespace, localName));
+ internals.patch(result);
+ return result;
+ });
+
+ PatchParentNode(internals, Document.prototype, {
+ prepend: Native.Document_prepend,
+ append: Native.Document_append,
+ });
+};
diff --git a/bower_components/custom-elements/src/Patch/DocumentFragment.js b/bower_components/custom-elements/src/Patch/DocumentFragment.js
new file mode 100644
index 0000000..987bee6
--- /dev/null
+++ b/bower_components/custom-elements/src/Patch/DocumentFragment.js
@@ -0,0 +1,13 @@
+import CustomElementInternals from '../CustomElementInternals.js';
+import Native from './Native.js';
+import PatchParentNode from './Interface/ParentNode.js';
+
+/**
+ * @param {!CustomElementInternals} internals
+ */
+export default function(internals) {
+ PatchParentNode(internals, DocumentFragment.prototype, {
+ prepend: Native.DocumentFragment_prepend,
+ append: Native.DocumentFragment_append,
+ });
+};
diff --git a/bower_components/custom-elements/src/Patch/Element.js b/bower_components/custom-elements/src/Patch/Element.js
new file mode 100644
index 0000000..9f80b12
--- /dev/null
+++ b/bower_components/custom-elements/src/Patch/Element.js
@@ -0,0 +1,243 @@
+import Native from './Native.js';
+import CustomElementInternals from '../CustomElementInternals.js';
+import CEState from '../CustomElementState.js';
+import * as Utilities from '../Utilities.js';
+
+import PatchParentNode from './Interface/ParentNode.js';
+import PatchChildNode from './Interface/ChildNode.js';
+
+/**
+ * @param {!CustomElementInternals} internals
+ */
+export default function(internals) {
+ if (Native.Element_attachShadow) {
+ Utilities.setPropertyUnchecked(Element.prototype, 'attachShadow',
+ /**
+ * @this {Element}
+ * @param {!{mode: string}} init
+ * @return {ShadowRoot}
+ */
+ function(init) {
+ const shadowRoot = Native.Element_attachShadow.call(this, init);
+ this.__CE_shadowRoot = shadowRoot;
+ return shadowRoot;
+ });
+ }
+
+
+ function patch_innerHTML(destination, baseDescriptor) {
+ Object.defineProperty(destination, 'innerHTML', {
+ enumerable: baseDescriptor.enumerable,
+ configurable: true,
+ get: baseDescriptor.get,
+ set: /** @this {Element} */ function(htmlString) {
+ const isConnected = Utilities.isConnected(this);
+
+ // NOTE: In IE11, when using the native `innerHTML` setter, all nodes
+ // that were previously descendants of the context element have all of
+ // their children removed as part of the set - the entire subtree is
+ // 'disassembled'. This work around walks the subtree *before* using the
+ // native setter.
+ /** @type {!Array|undefined} */
+ let removedElements = undefined;
+ if (isConnected) {
+ removedElements = [];
+ Utilities.walkDeepDescendantElements(this, element => {
+ if (element !== this) {
+ removedElements.push(element);
+ }
+ });
+ }
+
+ baseDescriptor.set.call(this, htmlString);
+
+ if (removedElements) {
+ for (let i = 0; i < removedElements.length; i++) {
+ const element = removedElements[i];
+ if (element.__CE_state === CEState.custom) {
+ internals.disconnectedCallback(element);
+ }
+ }
+ }
+
+ // Only create custom elements if this element's owner document is
+ // associated with the registry.
+ if (!this.ownerDocument.__CE_hasRegistry) {
+ internals.patchTree(this);
+ } else {
+ internals.patchAndUpgradeTree(this);
+ }
+ return htmlString;
+ },
+ });
+ }
+
+ if (Native.Element_innerHTML && Native.Element_innerHTML.get) {
+ patch_innerHTML(Element.prototype, Native.Element_innerHTML);
+ } else if (Native.HTMLElement_innerHTML && Native.HTMLElement_innerHTML.get) {
+ patch_innerHTML(HTMLElement.prototype, Native.HTMLElement_innerHTML);
+ } else {
+
+ internals.addPatch(function(element) {
+ patch_innerHTML(element, {
+ enumerable: true,
+ configurable: true,
+ // Implements getting `innerHTML` by performing an unpatched `cloneNode`
+ // of the element and returning the resulting element's `innerHTML`.
+ // TODO: Is this too expensive?
+ get: /** @this {Element} */ function() {
+ return Native.Node_cloneNode.call(this, true).innerHTML;
+ },
+ // Implements setting `innerHTML` by creating an unpatched element,
+ // setting `innerHTML` of that element and replacing the target
+ // element's children with those of the unpatched element.
+ set: /** @this {Element} */ function(assignedValue) {
+ // NOTE: re-route to `content` for `template` elements.
+ // We need to do this because `template.appendChild` does not
+ // route into `template.content`.
+ const isTemplate = (this.localName === 'template');
+ /** @type {!Node} */
+ const content = isTemplate ? (/** @type {!HTMLTemplateElement} */
+ (this)).content : this;
+ /** @type {!Node} */
+ const rawElement = Native.Document_createElement.call(document,
+ this.localName);
+ rawElement.innerHTML = assignedValue;
+
+ while (content.childNodes.length > 0) {
+ Native.Node_removeChild.call(content, content.childNodes[0]);
+ }
+ const container = isTemplate ? rawElement.content : rawElement;
+ while (container.childNodes.length > 0) {
+ Native.Node_appendChild.call(content, container.childNodes[0]);
+ }
+ },
+ });
+ });
+ }
+
+
+ Utilities.setPropertyUnchecked(Element.prototype, 'setAttribute',
+ /**
+ * @this {Element}
+ * @param {string} name
+ * @param {string} newValue
+ */
+ function(name, newValue) {
+ // Fast path for non-custom elements.
+ if (this.__CE_state !== CEState.custom) {
+ return Native.Element_setAttribute.call(this, name, newValue);
+ }
+
+ const oldValue = Native.Element_getAttribute.call(this, name);
+ Native.Element_setAttribute.call(this, name, newValue);
+ newValue = Native.Element_getAttribute.call(this, name);
+ internals.attributeChangedCallback(this, name, oldValue, newValue, null);
+ });
+
+ Utilities.setPropertyUnchecked(Element.prototype, 'setAttributeNS',
+ /**
+ * @this {Element}
+ * @param {?string} namespace
+ * @param {string} name
+ * @param {string} newValue
+ */
+ function(namespace, name, newValue) {
+ // Fast path for non-custom elements.
+ if (this.__CE_state !== CEState.custom) {
+ return Native.Element_setAttributeNS.call(this, namespace, name, newValue);
+ }
+
+ const oldValue = Native.Element_getAttributeNS.call(this, namespace, name);
+ Native.Element_setAttributeNS.call(this, namespace, name, newValue);
+ newValue = Native.Element_getAttributeNS.call(this, namespace, name);
+ internals.attributeChangedCallback(this, name, oldValue, newValue, namespace);
+ });
+
+ Utilities.setPropertyUnchecked(Element.prototype, 'removeAttribute',
+ /**
+ * @this {Element}
+ * @param {string} name
+ */
+ function(name) {
+ // Fast path for non-custom elements.
+ if (this.__CE_state !== CEState.custom) {
+ return Native.Element_removeAttribute.call(this, name);
+ }
+
+ const oldValue = Native.Element_getAttribute.call(this, name);
+ Native.Element_removeAttribute.call(this, name);
+ if (oldValue !== null) {
+ internals.attributeChangedCallback(this, name, oldValue, null, null);
+ }
+ });
+
+ Utilities.setPropertyUnchecked(Element.prototype, 'removeAttributeNS',
+ /**
+ * @this {Element}
+ * @param {?string} namespace
+ * @param {string} name
+ */
+ function(namespace, name) {
+ // Fast path for non-custom elements.
+ if (this.__CE_state !== CEState.custom) {
+ return Native.Element_removeAttributeNS.call(this, namespace, name);
+ }
+
+ const oldValue = Native.Element_getAttributeNS.call(this, namespace, name);
+ Native.Element_removeAttributeNS.call(this, namespace, name);
+ // In older browsers, `Element#getAttributeNS` may return the empty string
+ // instead of null if the attribute does not exist. For details, see;
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttributeNS#Notes
+ const newValue = Native.Element_getAttributeNS.call(this, namespace, name);
+ if (oldValue !== newValue) {
+ internals.attributeChangedCallback(this, name, oldValue, newValue, namespace);
+ }
+ });
+
+
+ function patch_insertAdjacentElement(destination, baseMethod) {
+ Utilities.setPropertyUnchecked(destination, 'insertAdjacentElement',
+ /**
+ * @this {Element}
+ * @param {string} where
+ * @param {!Element} element
+ * @return {?Element}
+ */
+ function(where, element) {
+ const wasConnected = Utilities.isConnected(element);
+ const insertedElement = /** @type {!Element} */
+ (baseMethod.call(this, where, element));
+
+ if (wasConnected) {
+ internals.disconnectTree(element);
+ }
+
+ if (Utilities.isConnected(insertedElement)) {
+ internals.connectTree(element);
+ }
+ return insertedElement;
+ });
+ }
+
+ if (Native.HTMLElement_insertAdjacentElement) {
+ patch_insertAdjacentElement(HTMLElement.prototype, Native.HTMLElement_insertAdjacentElement);
+ } else if (Native.Element_insertAdjacentElement) {
+ patch_insertAdjacentElement(Element.prototype, Native.Element_insertAdjacentElement);
+ } else {
+ console.warn('Custom Elements: `Element#insertAdjacentElement` was not patched.');
+ }
+
+
+ PatchParentNode(internals, Element.prototype, {
+ prepend: Native.Element_prepend,
+ append: Native.Element_append,
+ });
+
+ PatchChildNode(internals, Element.prototype, {
+ before: Native.Element_before,
+ after: Native.Element_after,
+ replaceWith: Native.Element_replaceWith,
+ remove: Native.Element_remove,
+ });
+};
diff --git a/bower_components/custom-elements/src/Patch/HTMLElement.js b/bower_components/custom-elements/src/Patch/HTMLElement.js
new file mode 100644
index 0000000..f69c01a
--- /dev/null
+++ b/bower_components/custom-elements/src/Patch/HTMLElement.js
@@ -0,0 +1,54 @@
+import Native from './Native.js';
+import CustomElementInternals from '../CustomElementInternals.js';
+import CEState from '../CustomElementState.js';
+import AlreadyConstructedMarker from '../AlreadyConstructedMarker.js';
+
+/**
+ * @param {!CustomElementInternals} internals
+ */
+export default function(internals) {
+ window['HTMLElement'] = (function() {
+ /**
+ * @type {function(new: HTMLElement): !HTMLElement}
+ */
+ function HTMLElement() {
+ // This should really be `new.target` but `new.target` can't be emulated
+ // in ES5. Assuming the user keeps the default value of the constructor's
+ // prototype's `constructor` property, this is equivalent.
+ /** @type {!Function} */
+ const constructor = this.constructor;
+
+ const definition = internals.constructorToDefinition(constructor);
+ if (!definition) {
+ throw new Error('The custom element being constructed was not registered with `customElements`.');
+ }
+
+ const constructionStack = definition.constructionStack;
+
+ if (constructionStack.length === 0) {
+ const element = Native.Document_createElement.call(document, definition.localName);
+ Object.setPrototypeOf(element, constructor.prototype);
+ element.__CE_state = CEState.custom;
+ element.__CE_definition = definition;
+ internals.patch(element);
+ return element;
+ }
+
+ const lastIndex = constructionStack.length - 1;
+ const element = constructionStack[lastIndex];
+ if (element === AlreadyConstructedMarker) {
+ throw new Error('The HTMLElement constructor was either called reentrantly for this constructor or called multiple times.');
+ }
+ constructionStack[lastIndex] = AlreadyConstructedMarker;
+
+ Object.setPrototypeOf(element, constructor.prototype);
+ internals.patch(/** @type {!HTMLElement} */ (element));
+
+ return element;
+ }
+
+ HTMLElement.prototype = Native.HTMLElement.prototype;
+
+ return HTMLElement;
+ })();
+};
diff --git a/bower_components/custom-elements/src/Patch/Interface/ChildNode.js b/bower_components/custom-elements/src/Patch/Interface/ChildNode.js
new file mode 100644
index 0000000..8560c99
--- /dev/null
+++ b/bower_components/custom-elements/src/Patch/Interface/ChildNode.js
@@ -0,0 +1,145 @@
+import CustomElementInternals from '../../CustomElementInternals.js';
+import * as Utilities from '../../Utilities.js';
+
+/**
+ * @typedef {{
+ * before: !function(...(!Node|string)),
+ * after: !function(...(!Node|string)),
+ * replaceWith: !function(...(!Node|string)),
+ * remove: !function(),
+ * }}
+ */
+let ChildNodeNativeMethods;
+
+/**
+ * @param {!CustomElementInternals} internals
+ * @param {!Object} destination
+ * @param {!ChildNodeNativeMethods} builtIn
+ */
+export default function(internals, destination, builtIn) {
+ /**
+ * @param {!function(...(!Node|string))} builtInMethod
+ * @return {!function(...(!Node|string))}
+ */
+ function beforeAfterPatch(builtInMethod) {
+ return function(...nodes) {
+ /**
+ * A copy of `nodes`, with any DocumentFragment replaced by its children.
+ * @type {!Array}
+ */
+ const flattenedNodes = [];
+
+ /**
+ * Elements in `nodes` that were connected before this call.
+ * @type {!Array}
+ */
+ const connectedElements = [];
+
+ for (var i = 0; i < nodes.length; i++) {
+ const node = nodes[i];
+
+ if (node instanceof Element && Utilities.isConnected(node)) {
+ connectedElements.push(node);
+ }
+
+ if (node instanceof DocumentFragment) {
+ for (let child = node.firstChild; child; child = child.nextSibling) {
+ flattenedNodes.push(child);
+ }
+ } else {
+ flattenedNodes.push(node);
+ }
+ }
+
+ builtInMethod.apply(this, nodes);
+
+ for (let i = 0; i < connectedElements.length; i++) {
+ internals.disconnectTree(connectedElements[i]);
+ }
+
+ if (Utilities.isConnected(this)) {
+ for (let i = 0; i < flattenedNodes.length; i++) {
+ const node = flattenedNodes[i];
+ if (node instanceof Element) {
+ internals.connectTree(node);
+ }
+ }
+ }
+ };
+ }
+
+ if (builtIn.before !== undefined) {
+ Utilities.setPropertyUnchecked(destination, 'before', beforeAfterPatch(builtIn.before));
+ }
+
+ if (builtIn.before !== undefined) {
+ Utilities.setPropertyUnchecked(destination, 'after', beforeAfterPatch(builtIn.after));
+ }
+
+ if (builtIn.replaceWith !== undefined) {
+ Utilities.setPropertyUnchecked(destination, 'replaceWith',
+ /**
+ * @param {...(!Node|string)} nodes
+ */
+ function(...nodes) {
+ /**
+ * A copy of `nodes`, with any DocumentFragment replaced by its children.
+ * @type {!Array}
+ */
+ const flattenedNodes = [];
+
+ /**
+ * Elements in `nodes` that were connected before this call.
+ * @type {!Array}
+ */
+ const connectedElements = [];
+
+ for (var i = 0; i < nodes.length; i++) {
+ const node = nodes[i];
+
+ if (node instanceof Element && Utilities.isConnected(node)) {
+ connectedElements.push(node);
+ }
+
+ if (node instanceof DocumentFragment) {
+ for (let child = node.firstChild; child; child = child.nextSibling) {
+ flattenedNodes.push(child);
+ }
+ } else {
+ flattenedNodes.push(node);
+ }
+ }
+
+ const wasConnected = Utilities.isConnected(this);
+
+ builtIn.replaceWith.apply(this, nodes);
+
+ for (let i = 0; i < connectedElements.length; i++) {
+ internals.disconnectTree(connectedElements[i]);
+ }
+
+ if (wasConnected) {
+ internals.disconnectTree(this);
+ for (let i = 0; i < flattenedNodes.length; i++) {
+ const node = flattenedNodes[i];
+ if (node instanceof Element) {
+ internals.connectTree(node);
+ }
+ }
+ }
+ });
+ }
+
+ if (builtIn.remove !== undefined) {
+ Utilities.setPropertyUnchecked(destination, 'remove',
+ function() {
+ const wasConnected = Utilities.isConnected(this);
+
+ builtIn.remove.call(this);
+
+ if (wasConnected) {
+ internals.disconnectTree(this);
+ }
+ });
+ }
+};
diff --git a/bower_components/custom-elements/src/Patch/Interface/ParentNode.js b/bower_components/custom-elements/src/Patch/Interface/ParentNode.js
new file mode 100644
index 0000000..0edeca0
--- /dev/null
+++ b/bower_components/custom-elements/src/Patch/Interface/ParentNode.js
@@ -0,0 +1,76 @@
+import CustomElementInternals from '../../CustomElementInternals.js';
+import * as Utilities from '../../Utilities.js';
+
+/**
+ * @typedef {{
+ * prepend: !function(...(!Node|string)),
+ * append: !function(...(!Node|string)),
+ * }}
+ */
+let ParentNodeNativeMethods;
+
+/**
+ * @param {!CustomElementInternals} internals
+ * @param {!Object} destination
+ * @param {!ParentNodeNativeMethods} builtIn
+ */
+export default function(internals, destination, builtIn) {
+ /**
+ * @param {!function(...(!Node|string))} builtInMethod
+ * @return {!function(...(!Node|string))}
+ */
+ function appendPrependPatch(builtInMethod) {
+ return function(...nodes) {
+ /**
+ * A copy of `nodes`, with any DocumentFragment replaced by its children.
+ * @type {!Array}
+ */
+ const flattenedNodes = [];
+
+ /**
+ * Elements in `nodes` that were connected before this call.
+ * @type {!Array}
+ */
+ const connectedElements = [];
+
+ for (var i = 0; i < nodes.length; i++) {
+ const node = nodes[i];
+
+ if (node instanceof Element && Utilities.isConnected(node)) {
+ connectedElements.push(node);
+ }
+
+ if (node instanceof DocumentFragment) {
+ for (let child = node.firstChild; child; child = child.nextSibling) {
+ flattenedNodes.push(child);
+ }
+ } else {
+ flattenedNodes.push(node);
+ }
+ }
+
+ builtInMethod.apply(this, nodes);
+
+ for (let i = 0; i < connectedElements.length; i++) {
+ internals.disconnectTree(connectedElements[i]);
+ }
+
+ if (Utilities.isConnected(this)) {
+ for (let i = 0; i < flattenedNodes.length; i++) {
+ const node = flattenedNodes[i];
+ if (node instanceof Element) {
+ internals.connectTree(node);
+ }
+ }
+ }
+ };
+ }
+
+ if (builtIn.prepend !== undefined) {
+ Utilities.setPropertyUnchecked(destination, 'prepend', appendPrependPatch(builtIn.prepend));
+ }
+
+ if (builtIn.append !== undefined) {
+ Utilities.setPropertyUnchecked(destination, 'append', appendPrependPatch(builtIn.append));
+ }
+};
diff --git a/bower_components/custom-elements/src/Patch/Native.js b/bower_components/custom-elements/src/Patch/Native.js
new file mode 100644
index 0000000..aea0496
--- /dev/null
+++ b/bower_components/custom-elements/src/Patch/Native.js
@@ -0,0 +1,33 @@
+export default {
+ Document_createElement: window.Document.prototype.createElement,
+ Document_createElementNS: window.Document.prototype.createElementNS,
+ Document_importNode: window.Document.prototype.importNode,
+ Document_prepend: window.Document.prototype['prepend'],
+ Document_append: window.Document.prototype['append'],
+ DocumentFragment_prepend: window.DocumentFragment.prototype['prepend'],
+ DocumentFragment_append: window.DocumentFragment.prototype['append'],
+ Node_cloneNode: window.Node.prototype.cloneNode,
+ Node_appendChild: window.Node.prototype.appendChild,
+ Node_insertBefore: window.Node.prototype.insertBefore,
+ Node_removeChild: window.Node.prototype.removeChild,
+ Node_replaceChild: window.Node.prototype.replaceChild,
+ Node_textContent: Object.getOwnPropertyDescriptor(window.Node.prototype, 'textContent'),
+ Element_attachShadow: window.Element.prototype['attachShadow'],
+ Element_innerHTML: Object.getOwnPropertyDescriptor(window.Element.prototype, 'innerHTML'),
+ Element_getAttribute: window.Element.prototype.getAttribute,
+ Element_setAttribute: window.Element.prototype.setAttribute,
+ Element_removeAttribute: window.Element.prototype.removeAttribute,
+ Element_getAttributeNS: window.Element.prototype.getAttributeNS,
+ Element_setAttributeNS: window.Element.prototype.setAttributeNS,
+ Element_removeAttributeNS: window.Element.prototype.removeAttributeNS,
+ Element_insertAdjacentElement: window.Element.prototype['insertAdjacentElement'],
+ Element_prepend: window.Element.prototype['prepend'],
+ Element_append: window.Element.prototype['append'],
+ Element_before: window.Element.prototype['before'],
+ Element_after: window.Element.prototype['after'],
+ Element_replaceWith: window.Element.prototype['replaceWith'],
+ Element_remove: window.Element.prototype['remove'],
+ HTMLElement: window.HTMLElement,
+ HTMLElement_innerHTML: Object.getOwnPropertyDescriptor(window.HTMLElement.prototype, 'innerHTML'),
+ HTMLElement_insertAdjacentElement: window.HTMLElement.prototype['insertAdjacentElement'],
+};
diff --git a/bower_components/custom-elements/src/Patch/Node.js b/bower_components/custom-elements/src/Patch/Node.js
new file mode 100644
index 0000000..98c3c2d
--- /dev/null
+++ b/bower_components/custom-elements/src/Patch/Node.js
@@ -0,0 +1,235 @@
+import Native from './Native.js';
+import CustomElementInternals from '../CustomElementInternals.js';
+import * as Utilities from '../Utilities.js';
+
+/**
+ * @param {!CustomElementInternals} internals
+ */
+export default function(internals) {
+ // `Node#nodeValue` is implemented on `Attr`.
+ // `Node#textContent` is implemented on `Attr`, `Element`.
+
+ Utilities.setPropertyUnchecked(Node.prototype, 'insertBefore',
+ /**
+ * @this {Node}
+ * @param {!Node} node
+ * @param {?Node} refNode
+ * @return {!Node}
+ */
+ function(node, refNode) {
+ if (node instanceof DocumentFragment) {
+ const insertedNodes = Array.prototype.slice.apply(node.childNodes);
+ const nativeResult = Native.Node_insertBefore.call(this, node, refNode);
+
+ // DocumentFragments can't be connected, so `disconnectTree` will never
+ // need to be called on a DocumentFragment's children after inserting it.
+
+ if (Utilities.isConnected(this)) {
+ for (let i = 0; i < insertedNodes.length; i++) {
+ internals.connectTree(insertedNodes[i]);
+ }
+ }
+
+ return nativeResult;
+ }
+
+ const nodeWasConnected = Utilities.isConnected(node);
+ const nativeResult = Native.Node_insertBefore.call(this, node, refNode);
+
+ if (nodeWasConnected) {
+ internals.disconnectTree(node);
+ }
+
+ if (Utilities.isConnected(this)) {
+ internals.connectTree(node);
+ }
+
+ return nativeResult;
+ });
+
+ Utilities.setPropertyUnchecked(Node.prototype, 'appendChild',
+ /**
+ * @this {Node}
+ * @param {!Node} node
+ * @return {!Node}
+ */
+ function(node) {
+ if (node instanceof DocumentFragment) {
+ const insertedNodes = Array.prototype.slice.apply(node.childNodes);
+ const nativeResult = Native.Node_appendChild.call(this, node);
+
+ // DocumentFragments can't be connected, so `disconnectTree` will never
+ // need to be called on a DocumentFragment's children after inserting it.
+
+ if (Utilities.isConnected(this)) {
+ for (let i = 0; i < insertedNodes.length; i++) {
+ internals.connectTree(insertedNodes[i]);
+ }
+ }
+
+ return nativeResult;
+ }
+
+ const nodeWasConnected = Utilities.isConnected(node);
+ const nativeResult = Native.Node_appendChild.call(this, node);
+
+ if (nodeWasConnected) {
+ internals.disconnectTree(node);
+ }
+
+ if (Utilities.isConnected(this)) {
+ internals.connectTree(node);
+ }
+
+ return nativeResult;
+ });
+
+ Utilities.setPropertyUnchecked(Node.prototype, 'cloneNode',
+ /**
+ * @this {Node}
+ * @param {boolean=} deep
+ * @return {!Node}
+ */
+ function(deep) {
+ const clone = Native.Node_cloneNode.call(this, deep);
+ // Only create custom elements if this element's owner document is
+ // associated with the registry.
+ if (!this.ownerDocument.__CE_hasRegistry) {
+ internals.patchTree(clone);
+ } else {
+ internals.patchAndUpgradeTree(clone);
+ }
+ return clone;
+ });
+
+ Utilities.setPropertyUnchecked(Node.prototype, 'removeChild',
+ /**
+ * @this {Node}
+ * @param {!Node} node
+ * @return {!Node}
+ */
+ function(node) {
+ const nodeWasConnected = Utilities.isConnected(node);
+ const nativeResult = Native.Node_removeChild.call(this, node);
+
+ if (nodeWasConnected) {
+ internals.disconnectTree(node);
+ }
+
+ return nativeResult;
+ });
+
+ Utilities.setPropertyUnchecked(Node.prototype, 'replaceChild',
+ /**
+ * @this {Node}
+ * @param {!Node} nodeToInsert
+ * @param {!Node} nodeToRemove
+ * @return {!Node}
+ */
+ function(nodeToInsert, nodeToRemove) {
+ if (nodeToInsert instanceof DocumentFragment) {
+ const insertedNodes = Array.prototype.slice.apply(nodeToInsert.childNodes);
+ const nativeResult = Native.Node_replaceChild.call(this, nodeToInsert, nodeToRemove);
+
+ // DocumentFragments can't be connected, so `disconnectTree` will never
+ // need to be called on a DocumentFragment's children after inserting it.
+
+ if (Utilities.isConnected(this)) {
+ internals.disconnectTree(nodeToRemove);
+ for (let i = 0; i < insertedNodes.length; i++) {
+ internals.connectTree(insertedNodes[i]);
+ }
+ }
+
+ return nativeResult;
+ }
+
+ const nodeToInsertWasConnected = Utilities.isConnected(nodeToInsert);
+ const nativeResult = Native.Node_replaceChild.call(this, nodeToInsert, nodeToRemove);
+ const thisIsConnected = Utilities.isConnected(this);
+
+ if (thisIsConnected) {
+ internals.disconnectTree(nodeToRemove);
+ }
+
+ if (nodeToInsertWasConnected) {
+ internals.disconnectTree(nodeToInsert);
+ }
+
+ if (thisIsConnected) {
+ internals.connectTree(nodeToInsert);
+ }
+
+ return nativeResult;
+ });
+
+
+ function patch_textContent(destination, baseDescriptor) {
+ Object.defineProperty(destination, 'textContent', {
+ enumerable: baseDescriptor.enumerable,
+ configurable: true,
+ get: baseDescriptor.get,
+ set: /** @this {Node} */ function(assignedValue) {
+ // If this is a text node then there are no nodes to disconnect.
+ if (this.nodeType === Node.TEXT_NODE) {
+ baseDescriptor.set.call(this, assignedValue);
+ return;
+ }
+
+ let removedNodes = undefined;
+ // Checking for `firstChild` is faster than reading `childNodes.length`
+ // to compare with 0.
+ if (this.firstChild) {
+ // Using `childNodes` is faster than `children`, even though we only
+ // care about elements.
+ const childNodes = this.childNodes;
+ const childNodesLength = childNodes.length;
+ if (childNodesLength > 0 && Utilities.isConnected(this)) {
+ // Copying an array by iterating is faster than using slice.
+ removedNodes = new Array(childNodesLength);
+ for (let i = 0; i < childNodesLength; i++) {
+ removedNodes[i] = childNodes[i];
+ }
+ }
+ }
+
+ baseDescriptor.set.call(this, assignedValue);
+
+ if (removedNodes) {
+ for (let i = 0; i < removedNodes.length; i++) {
+ internals.disconnectTree(removedNodes[i]);
+ }
+ }
+ },
+ });
+ }
+
+ if (Native.Node_textContent && Native.Node_textContent.get) {
+ patch_textContent(Node.prototype, Native.Node_textContent);
+ } else {
+ internals.addPatch(function(element) {
+ patch_textContent(element, {
+ enumerable: true,
+ configurable: true,
+ // NOTE: This implementation of the `textContent` getter assumes that
+ // text nodes' `textContent` getter will not be patched.
+ get: /** @this {Node} */ function() {
+ /** @type {!Array} */
+ const parts = [];
+
+ for (let i = 0; i < this.childNodes.length; i++) {
+ parts.push(this.childNodes[i].textContent);
+ }
+
+ return parts.join('');
+ },
+ set: /** @this {Node} */ function(assignedValue) {
+ while (this.firstChild) {
+ Native.Node_removeChild.call(this, this.firstChild);
+ }
+ Native.Node_appendChild.call(this, document.createTextNode(assignedValue));
+ },
+ });
+ });
+ }
+};
diff --git a/bower_components/custom-elements/src/Utilities.js b/bower_components/custom-elements/src/Utilities.js
new file mode 100644
index 0000000..6be1b72
--- /dev/null
+++ b/bower_components/custom-elements/src/Utilities.js
@@ -0,0 +1,129 @@
+const reservedTagList = new Set([
+ 'annotation-xml',
+ 'color-profile',
+ 'font-face',
+ 'font-face-src',
+ 'font-face-uri',
+ 'font-face-format',
+ 'font-face-name',
+ 'missing-glyph',
+]);
+
+/**
+ * @param {string} localName
+ * @returns {boolean}
+ */
+export function isValidCustomElementName(localName) {
+ const reserved = reservedTagList.has(localName);
+ const validForm = /^[a-z][.0-9_a-z]*-[\-.0-9_a-z]*$/.test(localName);
+ return !reserved && validForm;
+}
+
+/**
+ * @private
+ * @param {!Node} node
+ * @return {boolean}
+ */
+export function isConnected(node) {
+ // Use `Node#isConnected`, if defined.
+ const nativeValue = node.isConnected;
+ if (nativeValue !== undefined) {
+ return nativeValue;
+ }
+
+ /** @type {?Node|undefined} */
+ let current = node;
+ while (current && !(current.__CE_isImportDocument || current instanceof Document)) {
+ current = current.parentNode || (window.ShadowRoot && current instanceof ShadowRoot ? current.host : undefined);
+ }
+ return !!(current && (current.__CE_isImportDocument || current instanceof Document));
+}
+
+/**
+ * @param {!Node} root
+ * @param {!Node} start
+ * @return {?Node}
+ */
+function nextSiblingOrAncestorSibling(root, start) {
+ let node = start;
+ while (node && node !== root && !node.nextSibling) {
+ node = node.parentNode;
+ }
+ return (!node || node === root) ? null : node.nextSibling;
+}
+
+/**
+ * @param {!Node} root
+ * @param {!Node} start
+ * @return {?Node}
+ */
+function nextNode(root, start) {
+ return start.firstChild ? start.firstChild : nextSiblingOrAncestorSibling(root, start);
+}
+
+/**
+ * @param {!Node} root
+ * @param {!function(!Element)} callback
+ * @param {!Set=} visitedImports
+ */
+export function walkDeepDescendantElements(root, callback, visitedImports = new Set()) {
+ let node = root;
+ while (node) {
+ if (node.nodeType === Node.ELEMENT_NODE) {
+ const element = /** @type {!Element} */(node);
+
+ callback(element);
+
+ const localName = element.localName;
+ if (localName === 'link' && element.getAttribute('rel') === 'import') {
+ // If this import (polyfilled or not) has it's root node available,
+ // walk it.
+ const importNode = /** @type {!Node} */ (element.import);
+ if (importNode instanceof Node && !visitedImports.has(importNode)) {
+ // Prevent multiple walks of the same import root.
+ visitedImports.add(importNode);
+
+ for (let child = importNode.firstChild; child; child = child.nextSibling) {
+ walkDeepDescendantElements(child, callback, visitedImports);
+ }
+ }
+
+ // Ignore descendants of import links to prevent attempting to walk the
+ // elements created by the HTML Imports polyfill that we just walked
+ // above.
+ node = nextSiblingOrAncestorSibling(root, element);
+ continue;
+ } else if (localName === 'template') {
+ // Ignore descendants of templates. There shouldn't be any descendants
+ // because they will be moved into `.content` during construction in
+ // browsers that support template but, in case they exist and are still
+ // waiting to be moved by a polyfill, they will be ignored.
+ node = nextSiblingOrAncestorSibling(root, element);
+ continue;
+ }
+
+ // Walk shadow roots.
+ const shadowRoot = element.__CE_shadowRoot;
+ if (shadowRoot) {
+ for (let child = shadowRoot.firstChild; child; child = child.nextSibling) {
+ walkDeepDescendantElements(child, callback, visitedImports);
+ }
+ }
+ }
+
+ node = nextNode(root, node);
+ }
+}
+
+/**
+ * Used to suppress Closure's "Modifying the prototype is only allowed if the
+ * constructor is in the same scope" warning without using
+ * `@suppress {newCheckTypes, duplicate}` because `newCheckTypes` is too broad.
+ *
+ * @param {!Object} destination
+ * @param {string} name
+ * @param {*} value
+ */
+export function setPropertyUnchecked(destination, name, value) {
+ destination[name] = value;
+}
diff --git a/bower_components/custom-elements/src/custom-elements.js b/bower_components/custom-elements/src/custom-elements.js
new file mode 100644
index 0000000..229fa98
--- /dev/null
+++ b/bower_components/custom-elements/src/custom-elements.js
@@ -0,0 +1,46 @@
+/**
+ * @license
+ * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+import CustomElementInternals from './CustomElementInternals.js';
+import CustomElementRegistry from './CustomElementRegistry.js';
+
+import PatchHTMLElement from './Patch/HTMLElement.js';
+import PatchDocument from './Patch/Document.js';
+import PatchDocumentFragment from './Patch/DocumentFragment.js';
+import PatchNode from './Patch/Node.js';
+import PatchElement from './Patch/Element.js';
+
+const priorCustomElements = window['customElements'];
+
+if (!priorCustomElements ||
+ priorCustomElements['forcePolyfill'] ||
+ (typeof priorCustomElements['define'] != 'function') ||
+ (typeof priorCustomElements['get'] != 'function')) {
+ /** @type {!CustomElementInternals} */
+ const internals = new CustomElementInternals();
+
+ PatchHTMLElement(internals);
+ PatchDocument(internals);
+ PatchDocumentFragment(internals);
+ PatchNode(internals);
+ PatchElement(internals);
+
+ // The main document is always associated with the registry.
+ document.__CE_hasRegistry = true;
+
+ /** @type {!CustomElementRegistry} */
+ const customElements = new CustomElementRegistry(internals);
+
+ Object.defineProperty(window, 'customElements', {
+ configurable: true,
+ enumerable: true,
+ value: customElements,
+ });
+}
diff --git a/bower_components/custom-elements/src/native-shim.js b/bower_components/custom-elements/src/native-shim.js
new file mode 100644
index 0000000..2011d29
--- /dev/null
+++ b/bower_components/custom-elements/src/native-shim.js
@@ -0,0 +1,164 @@
+/**
+ * @license
+ * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+/**
+ * This shim allows elements written in, or compiled to, ES5 to work on native
+ * implementations of Custom Elements.
+ *
+ * ES5-style classes don't work with native Custom Elements because the
+ * HTMLElement constructor uses the value of `new.target` to look up the custom
+ * element definition for the currently called constructor. `new.target` is only
+ * set when `new` is called and is only propagated via super() calls. super()
+ * is not emulatable in ES5. The pattern of `SuperClass.call(this)`` only works
+ * when extending other ES5-style classes, and does not propagate `new.target`.
+ *
+ * This shim allows the native HTMLElement constructor to work by generating and
+ * registering a stand-in class instead of the users custom element class. This
+ * stand-in class's constructor has an actual call to super().
+ * `customElements.define()` and `customElements.get()` are both overridden to
+ * hide this stand-in class from users.
+ *
+ * In order to create instance of the user-defined class, rather than the stand
+ * in, the stand-in's constructor swizzles its instances prototype and invokes
+ * the user-defined constructor. When the user-defined constructor is called
+ * directly it creates an instance of the stand-in class to get a real extension
+ * of HTMLElement and returns that.
+ *
+ * There are two important constructors: A patched HTMLElement constructor, and
+ * the StandInElement constructor. They both will be called to create an element
+ * but which is called first depends on whether the browser creates the element
+ * or the user-defined constructor is called directly. The variables
+ * `browserConstruction` and `userConstruction` control the flow between the
+ * two constructors.
+ *
+ * This shim should be better than forcing the polyfill because:
+ * 1. It's smaller
+ * 2. All reaction timings are the same as native (mostly synchronous)
+ * 3. All reaction triggering DOM operations are automatically supported
+ *
+ * There are some restrictions and requirements on ES5 constructors:
+ * 1. All constructors in a inheritance hierarchy must be ES5-style, so that
+ * they can be called with Function.call(). This effectively means that the
+ * whole application must be compiled to ES5.
+ * 2. Constructors must return the value of the emulated super() call. Like
+ * `return SuperClass.call(this)`
+ * 3. The `this` reference should not be used before the emulated super() call
+ * just like `this` is illegal to use before super() in ES6.
+ * 4. Constructors should not create other custom elements before the emulated
+ * super() call. This is the same restriction as with native custom
+ * elements.
+ *
+ * Compiling valid class-based custom elements to ES5 will satisfy these
+ * requirements with the latest version of popular transpilers.
+ */
+(() => {
+ 'use strict';
+
+ // Do nothing if `customElements` does not exist.
+ if (!window.customElements) return;
+
+ const NativeHTMLElement = window.HTMLElement;
+ const nativeDefine = window.customElements.define;
+ const nativeGet = window.customElements.get;
+
+ /**
+ * Map of user-provided constructors to tag names.
+ *
+ * @type {Map}
+ */
+ const tagnameByConstructor = new Map();
+
+ /**
+ * Map of tag names to user-provided constructors.
+ *
+ * @type {Map}
+ */
+ const constructorByTagname = new Map();
+
+
+ /**
+ * Whether the constructors are being called by a browser process, ie parsing
+ * or createElement.
+ */
+ let browserConstruction = false;
+
+ /**
+ * Whether the constructors are being called by a user-space process, ie
+ * calling an element constructor.
+ */
+ let userConstruction = false;
+
+ window.HTMLElement = function() {
+ if (!browserConstruction) {
+ const tagname = tagnameByConstructor.get(this.constructor);
+ const fakeClass = nativeGet.call(window.customElements, tagname);
+
+ // Make sure that the fake constructor doesn't call back to this constructor
+ userConstruction = true;
+ const instance = new (fakeClass)();
+ return instance;
+ }
+ // Else do nothing. This will be reached by ES5-style classes doing
+ // HTMLElement.call() during initialization
+ browserConstruction = false;
+ };
+ // By setting the patched HTMLElement's prototype property to the native
+ // HTMLElement's prototype we make sure that:
+ // document.createElement('a') instanceof HTMLElement
+ // works because instanceof uses HTMLElement.prototype, which is on the
+ // ptototype chain of built-in elements.
+ window.HTMLElement.prototype = NativeHTMLElement.prototype;
+
+ const define = (tagname, elementClass) => {
+ const elementProto = elementClass.prototype;
+ const StandInElement = class extends NativeHTMLElement {
+ constructor() {
+ // Call the native HTMLElement constructor, this gives us the
+ // under-construction instance as `this`:
+ super();
+
+ // The prototype will be wrong up because the browser used our fake
+ // class, so fix it:
+ Object.setPrototypeOf(this, elementProto);
+
+ if (!userConstruction) {
+ // Make sure that user-defined constructor bottom's out to a do-nothing
+ // HTMLElement() call
+ browserConstruction = true;
+ // Call the user-defined constructor on our instance:
+ elementClass.call(this);
+ }
+ userConstruction = false;
+ }
+ };
+ const standInProto = StandInElement.prototype;
+ StandInElement.observedAttributes = elementClass.observedAttributes;
+ standInProto.connectedCallback = elementProto.connectedCallback;
+ standInProto.disconnectedCallback = elementProto.disconnectedCallback;
+ standInProto.attributeChangedCallback = elementProto.attributeChangedCallback;
+ standInProto.adoptedCallback = elementProto.adoptedCallback;
+
+ tagnameByConstructor.set(elementClass, tagname);
+ constructorByTagname.set(tagname, elementClass);
+ nativeDefine.call(window.customElements, tagname, StandInElement);
+ };
+
+ const get = (tagname) => constructorByTagname.get(tagname);
+
+ // Workaround for Safari bug where patching customElements can be lost, likely
+ // due to native wrapper garbage collection issue
+ Object.defineProperty(window, 'customElements',
+ {value: window.customElements, configurable: true, writable: true});
+ Object.defineProperty(window.customElements, 'define',
+ {value: define, configurable: true, writable: true});
+ Object.defineProperty(window.customElements, 'get',
+ {value: get, configurable: true, writable: true});
+
+})();
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/clone-contenteditable.html b/bower_components/custom-elements/tests/chromium/custom-elements/clone-contenteditable.html
new file mode 100644
index 0000000..02522ed
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/clone-contenteditable.html
@@ -0,0 +1,34 @@
+
+
+
+
aa
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/constructor-context-dies-before-super.html b/bower_components/custom-elements/tests/chromium/custom-elements/constructor-context-dies-before-super.html
new file mode 100644
index 0000000..7b23222
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/constructor-context-dies-before-super.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/constructor-context-dies-cross-context-call.html b/bower_components/custom-elements/tests/chromium/custom-elements/constructor-context-dies-cross-context-call.html
new file mode 100644
index 0000000..bdf6faf
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/constructor-context-dies-cross-context-call.html
@@ -0,0 +1,39 @@
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/constructor-may-poach-upgrading-element.html b/bower_components/custom-elements/tests/chromium/custom-elements/constructor-may-poach-upgrading-element.html
new file mode 100644
index 0000000..feac93d
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/constructor-may-poach-upgrading-element.html
@@ -0,0 +1,65 @@
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/define-context-dies-retrieving-prototype.html b/bower_components/custom-elements/tests/chromium/custom-elements/define-context-dies-retrieving-prototype.html
new file mode 100644
index 0000000..f8435ca
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/define-context-dies-retrieving-prototype.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/gc.html b/bower_components/custom-elements/tests/chromium/custom-elements/gc.html
new file mode 100644
index 0000000..a8957d6
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/gc.html
@@ -0,0 +1,65 @@
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/adopted-callback.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/adopted-callback.html
new file mode 100644
index 0000000..febf725
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/adopted-callback.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/async-imports.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/async-imports.html
new file mode 100644
index 0000000..6a3e5fa
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/async-imports.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/async-nested-imports.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/async-nested-imports.html
new file mode 100644
index 0000000..c2643d9
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/async-nested-imports.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/attribute-changed-callback.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/attribute-changed-callback.html
new file mode 100644
index 0000000..cf854ed
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/attribute-changed-callback.html
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/circular-imports.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/circular-imports.html
new file mode 100644
index 0000000..66dc282
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/circular-imports.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/create-element-in-import.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/create-element-in-import.html
new file mode 100644
index 0000000..97b22f9
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/create-element-in-import.html
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/detached-import.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/detached-import.html
new file mode 100644
index 0000000..1886b4b
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/detached-import.html
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/inner-html-in-import.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/inner-html-in-import.html
new file mode 100644
index 0000000..a7162e8
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/inner-html-in-import.html
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/nested-imports.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/nested-imports.html
new file mode 100644
index 0000000..812aed8
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/nested-imports.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/adopted-nodes.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/adopted-nodes.html
new file mode 100644
index 0000000..0da4b69
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/adopted-nodes.html
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/async-component.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/async-component.html
new file mode 100644
index 0000000..4b7d7d8
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/async-component.html
@@ -0,0 +1,8 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/async-nested-component.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/async-nested-component.html
new file mode 100644
index 0000000..7702fe4
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/async-nested-component.html
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/attribute-parsercreate.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/attribute-parsercreate.html
new file mode 100644
index 0000000..c97af20
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/attribute-parsercreate.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/attribute-upgrade.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/attribute-upgrade.html
new file mode 100644
index 0000000..2a26d6a
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/attribute-upgrade.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/circular-level1.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/circular-level1.html
new file mode 100644
index 0000000..2cf6604
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/circular-level1.html
@@ -0,0 +1,12 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/circular-level2.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/circular-level2.html
new file mode 100644
index 0000000..d450ca8
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/circular-level2.html
@@ -0,0 +1,12 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/create-element.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/create-element.html
new file mode 100644
index 0000000..a98bd07
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/create-element.html
@@ -0,0 +1,38 @@
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/import-custom.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/import-custom.html
new file mode 100644
index 0000000..010bcd1
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/import-custom.html
@@ -0,0 +1,2 @@
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/inner-html.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/inner-html.html
new file mode 100644
index 0000000..b227e75
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/inner-html.html
@@ -0,0 +1,28 @@
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/nested-level1.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/nested-level1.html
new file mode 100644
index 0000000..b7388cf
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/nested-level1.html
@@ -0,0 +1,14 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/nested-level2.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/nested-level2.html
new file mode 100644
index 0000000..4af6cf4
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/nested-level2.html
@@ -0,0 +1,13 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/nested-level3.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/nested-level3.html
new file mode 100644
index 0000000..3f69b5e
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/nested-level3.html
@@ -0,0 +1,12 @@
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/upgrade.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/upgrade.html
new file mode 100644
index 0000000..ad5e0e5
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/resources/upgrade.html
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/sync-create-element-order.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/sync-create-element-order.html
new file mode 100644
index 0000000..182df2b
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/sync-create-element-order.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/imports/upgrade-order.html b/bower_components/custom-elements/tests/chromium/custom-elements/imports/upgrade-order.html
new file mode 100644
index 0000000..eb9728e
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/imports/upgrade-order.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/isolated-worlds.html b/bower_components/custom-elements/tests/chromium/custom-elements/isolated-worlds.html
new file mode 100644
index 0000000..a41e4d3
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/isolated-worlds.html
@@ -0,0 +1,80 @@
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/adopt-node.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/adopt-node.html
new file mode 100644
index 0000000..039c6b7
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/adopt-node.html
@@ -0,0 +1,57 @@
+
+Custom Elements: adopt node
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/callback.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/callback.html
new file mode 100644
index 0000000..4012e67
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/callback.html
@@ -0,0 +1,212 @@
+
+Custom Elements: Create an element when definition is non-null and synchronous flag not set
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/construct.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/construct.html
new file mode 100644
index 0000000..18a7f79
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/construct.html
@@ -0,0 +1,77 @@
+
+Custom Elements: Constructor Tests
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/create-element-defined-asynchronous.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/create-element-defined-asynchronous.html
new file mode 100644
index 0000000..c38b1a0
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/create-element-defined-asynchronous.html
@@ -0,0 +1,79 @@
+
+Custom Elements: Create an element when definition is non-null and synchronous flag not set
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/create-element-defined-synchronous.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/create-element-defined-synchronous.html
new file mode 100644
index 0000000..8d4b952
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/create-element-defined-synchronous.html
@@ -0,0 +1,120 @@
+
+Custom Elements: Create an element when definition is non-null and synchronous flag set
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/create-element-inside-template.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/create-element-inside-template.html
new file mode 100644
index 0000000..967763d
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/create-element-inside-template.html
@@ -0,0 +1,25 @@
+
+Custom Elements: create an element inside a template
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/custom-elements-registry/get.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/custom-elements-registry/get.html
new file mode 100644
index 0000000..9d1b60d
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/custom-elements-registry/get.html
@@ -0,0 +1,44 @@
+
+
+Custom Elements: CustomElementRegistry.get
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/custom-elements-registry/when_defined.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/custom-elements-registry/when_defined.html
new file mode 100644
index 0000000..fa6a4ba
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/custom-elements-registry/when_defined.html
@@ -0,0 +1,101 @@
+
+Custom Elements: CustomElementRegistry.whenDefined
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/define-element.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/define-element.html
new file mode 100644
index 0000000..ca3c310
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/define-element.html
@@ -0,0 +1,412 @@
+
+Custom Elements: defineElement
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/doc-without-browsing-context.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/doc-without-browsing-context.html
new file mode 100644
index 0000000..fbaf1dc
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/doc-without-browsing-context.html
@@ -0,0 +1,53 @@
+
+Custom Elements: create an element inside a template
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/insert-a-node-try-to-upgrade.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/insert-a-node-try-to-upgrade.html
new file mode 100644
index 0000000..9070ad2
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/insert-a-node-try-to-upgrade.html
@@ -0,0 +1,52 @@
+
+Custom Elements: Insert a node should try to upgrade
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/parsing.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/parsing.html
new file mode 100644
index 0000000..e6b3842
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/parsing.html
@@ -0,0 +1,285 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/remove-element.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/remove-element.html
new file mode 100644
index 0000000..58d3761
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/remove-element.html
@@ -0,0 +1,34 @@
+
+Custom Elements: Remove an element
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/report-the-exception.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/report-the-exception.html
new file mode 100644
index 0000000..c3f293e
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/report-the-exception.html
@@ -0,0 +1,156 @@
+
+Custom Elements: report the exception
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/resources/custom-elements-helpers.js b/bower_components/custom-elements/tests/chromium/custom-elements/spec/resources/custom-elements-helpers.js
new file mode 100644
index 0000000..659be1e
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/resources/custom-elements-helpers.js
@@ -0,0 +1,54 @@
+function create_window_in_test(t, srcdoc) {
+ let p = new Promise((resolve) => {
+ let f = document.createElement('iframe');
+ srcdoc = srcdoc || '';
+ // srcdoc = `\n` +
+ srcdoc = `\n` +
+ `\n` + srcdoc;
+ f.srcdoc = srcdoc;
+ f.onload = (event) => {
+ let w = f.contentWindow;
+ t.add_cleanup(() => f.parentNode && f.remove());
+ resolve(w);
+ };
+ document.body.appendChild(f);
+ });
+ return p;
+}
+
+function test_with_window(f, name, srcdoc) {
+ promise_test((t) => {
+ return create_window_in_test(t, srcdoc)
+ .then((w) => {
+ f(w);
+ });
+ }, name);
+}
+
+function assert_throws_dom_exception(global_context, code, func, description) {
+ let exception;
+ assert_throws(code, () => {
+ try {
+ func.call(this);
+ } catch(e) {
+ exception = e;
+ throw e;
+ }
+ }, description);
+ assert_true(exception instanceof global_context.DOMException, 'DOMException on the appropriate window');
+}
+
+function assert_array_equals_callback_invocations(actual, expected, description) {
+ assert_equals(actual.length, expected.length);
+ for (let len=actual.length, i=0; i
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/state-failed-create.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/state-failed-create.html
new file mode 100644
index 0000000..9eee83c
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/state-failed-create.html
@@ -0,0 +1,48 @@
+
+Custom Elements: Custom Element State "Failed" in document parser
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/state-failed-upgrade-expected.txt b/bower_components/custom-elements/tests/chromium/custom-elements/spec/state-failed-upgrade-expected.txt
new file mode 100644
index 0000000..ceca9b5
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/state-failed-upgrade-expected.txt
@@ -0,0 +1,6 @@
+CONSOLE ERROR: line 21: Uncaught Error
+CONSOLE ERROR: line 2445: Uncaught Error: assert_unreached: connectedCallback should not be invoked if constructor threw Reached unreachable code
+This is a testharness.js-based test.
+PASS Custom Elements: Custom Element State "Failed" in Upgrades
+Harness: the test ran to completion.
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/state-failed-upgrade.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/state-failed-upgrade.html
new file mode 100644
index 0000000..fff117f
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/state-failed-upgrade.html
@@ -0,0 +1,52 @@
+
+Custom Elements: Custom Element State "Failed" in Upgrades
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/spec/upgrade-element.html b/bower_components/custom-elements/tests/chromium/custom-elements/spec/upgrade-element.html
new file mode 100644
index 0000000..2feaf1f
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/spec/upgrade-element.html
@@ -0,0 +1,117 @@
+
+Custom Elements: upgrade element
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/custom-elements/v0-v1-interop.html b/bower_components/custom-elements/tests/chromium/custom-elements/v0-v1-interop.html
new file mode 100644
index 0000000..ce7e824
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/custom-elements/v0-v1-interop.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/resources/Ahem.otf b/bower_components/custom-elements/tests/chromium/resources/Ahem.otf
new file mode 100644
index 0000000..6dd4ba2
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/Ahem.otf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/Ahem.ttf b/bower_components/custom-elements/tests/chromium/resources/Ahem.ttf
new file mode 100644
index 0000000..ac81cb0
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/Ahem.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/Ahem.woff b/bower_components/custom-elements/tests/chromium/resources/Ahem.woff
new file mode 100644
index 0000000..0bc8093
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/Ahem.woff differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/Ahem.woff2 b/bower_components/custom-elements/tests/chromium/resources/Ahem.woff2
new file mode 100644
index 0000000..bf3cc77
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/Ahem.woff2 differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/AhemNoXHeight.ttf b/bower_components/custom-elements/tests/chromium/resources/AhemNoXHeight.ttf
new file mode 100644
index 0000000..d58e81e
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/AhemNoXHeight.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/README.txt b/bower_components/custom-elements/tests/chromium/resources/README.txt
new file mode 100644
index 0000000..ea2813d
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/README.txt
@@ -0,0 +1,26 @@
+The following files are used to run W3C testharness.js-style tests,
+either authored for Blink or imported from W3C's web-platform-tests.
+These files should not be modified locally, as they are imported.
+
+* testharness.js from testharness.js
+* testharness.css from testharness.js
+* idlharness.js from testharness.js
+* WebIDLParser.js from webidl2.js
+* vendor-prefix.js from web-platform-tests
+
+NOTE: The 'WebIDLParser.js' file is developed as 'webidl2.js' but
+web-platform-tests's wpt-tools server is configured to serve the
+resource under a different name, which is matched here.
+
+The following files are native to Blink and can be modified:
+
+* testharnessreport.js integration with Blink's test runner
+
+See also:
+* https://www.chromium.org/blink/importing-the-w3c-tests
+* LayoutTests/imported/README
+
+References:
+* web-platform-tests https://github.com/w3c/web-platform-tests
+* testharness.js https://github.com/w3c/testharness.js
+* webidl2.js https://github.com/darobin/webidl2.js
diff --git a/bower_components/custom-elements/tests/chromium/resources/SpaceOnly.otf b/bower_components/custom-elements/tests/chromium/resources/SpaceOnly.otf
new file mode 100644
index 0000000..5b1343c
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/SpaceOnly.otf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/WebIDLParser.js b/bower_components/custom-elements/tests/chromium/resources/WebIDLParser.js
new file mode 100644
index 0000000..71030cf
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/WebIDLParser.js
@@ -0,0 +1,1012 @@
+
+
+(function () {
+ var tokenise = function (str) {
+ var tokens = []
+ , re = {
+ "float": /^-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][-+]?[0-9]+)?|[0-9]+[Ee][-+]?[0-9]+)/
+ , "integer": /^-?(0([Xx][0-9A-Fa-f]+|[0-7]*)|[1-9][0-9]*)/
+ , "identifier": /^[A-Z_a-z][0-9A-Z_a-z]*/
+ , "string": /^"[^"]*"/
+ , "whitespace": /^(?:[\t\n\r ]+|[\t\n\r ]*((\/\/.*|\/\*(.|\n|\r)*?\*\/)[\t\n\r ]*))+/
+ , "other": /^[^\t\n\r 0-9A-Z_a-z]/
+ }
+ , types = []
+ ;
+ for (var k in re) types.push(k);
+ while (str.length > 0) {
+ var matched = false;
+ for (var i = 0, n = types.length; i < n; i++) {
+ var type = types[i];
+ str = str.replace(re[type], function (tok) {
+ tokens.push({ type: type, value: tok });
+ matched = true;
+ return "";
+ });
+ if (matched) break;
+ }
+ if (matched) continue;
+ throw new Error("Token stream not progressing");
+ }
+ return tokens;
+ };
+
+ var parse = function (tokens, opt) {
+ var line = 1;
+ tokens = tokens.slice();
+
+ var FLOAT = "float"
+ , INT = "integer"
+ , ID = "identifier"
+ , STR = "string"
+ , OTHER = "other"
+ ;
+
+ var WebIDLParseError = function (str, line, input, tokens) {
+ this.message = str;
+ this.line = line;
+ this.input = input;
+ this.tokens = tokens;
+ };
+ WebIDLParseError.prototype.toString = function () {
+ return this.message + ", line " + this.line + " (tokens: '" + this.input + "')\n" +
+ JSON.stringify(this.tokens, null, 4);
+ };
+
+ var error = function (str) {
+ var tok = "", numTokens = 0, maxTokens = 5;
+ while (numTokens < maxTokens && tokens.length > numTokens) {
+ tok += tokens[numTokens].value;
+ numTokens++;
+ }
+ throw new WebIDLParseError(str, line, tok, tokens.slice(0, 5));
+ };
+
+ var last_token = null;
+
+ var consume = function (type, value) {
+ if (!tokens.length || tokens[0].type !== type) return;
+ if (typeof value === "undefined" || tokens[0].value === value) {
+ last_token = tokens.shift();
+ if (type === ID) last_token.value = last_token.value.replace(/^_/, "");
+ return last_token;
+ }
+ };
+
+ var ws = function () {
+ if (!tokens.length) return;
+ if (tokens[0].type === "whitespace") {
+ var t = tokens.shift();
+ t.value.replace(/\n/g, function (m) { line++; return m; });
+ return t;
+ }
+ };
+
+ var all_ws = function (store, pea) { // pea == post extended attribute, tpea = same for types
+ var t = { type: "whitespace", value: "" };
+ while (true) {
+ var w = ws();
+ if (!w) break;
+ t.value += w.value;
+ }
+ if (t.value.length > 0) {
+ if (store) {
+ var w = t.value
+ , re = {
+ "ws": /^([\t\n\r ]+)/
+ , "line-comment": /^\/\/(.*)\n?/m
+ , "multiline-comment": /^\/\*((?:.|\n|\r)*?)\*\//
+ }
+ , wsTypes = []
+ ;
+ for (var k in re) wsTypes.push(k);
+ while (w.length) {
+ var matched = false;
+ for (var i = 0, n = wsTypes.length; i < n; i++) {
+ var type = wsTypes[i];
+ w = w.replace(re[type], function (tok, m1) {
+ store.push({ type: type + (pea ? ("-" + pea) : ""), value: m1 });
+ matched = true;
+ return "";
+ });
+ if (matched) break;
+ }
+ if (matched) continue;
+ throw new Error("Surprising white space construct."); // this shouldn't happen
+ }
+ }
+ return t;
+ }
+ };
+
+ var integer_type = function () {
+ var ret = "";
+ all_ws();
+ if (consume(ID, "unsigned")) ret = "unsigned ";
+ all_ws();
+ if (consume(ID, "short")) return ret + "short";
+ if (consume(ID, "long")) {
+ ret += "long";
+ all_ws();
+ if (consume(ID, "long")) return ret + " long";
+ return ret;
+ }
+ if (ret) error("Failed to parse integer type");
+ };
+
+ var float_type = function () {
+ var ret = "";
+ all_ws();
+ if (consume(ID, "unrestricted")) ret = "unrestricted ";
+ all_ws();
+ if (consume(ID, "float")) return ret + "float";
+ if (consume(ID, "double")) return ret + "double";
+ if (ret) error("Failed to parse float type");
+ };
+
+ var primitive_type = function () {
+ var num_type = integer_type() || float_type();
+ if (num_type) return num_type;
+ all_ws();
+ if (consume(ID, "boolean")) return "boolean";
+ if (consume(ID, "byte")) return "byte";
+ if (consume(ID, "octet")) return "octet";
+ };
+
+ var const_value = function () {
+ if (consume(ID, "true")) return { type: "boolean", value: true };
+ if (consume(ID, "false")) return { type: "boolean", value: false };
+ if (consume(ID, "null")) return { type: "null" };
+ if (consume(ID, "Infinity")) return { type: "Infinity", negative: false };
+ if (consume(ID, "NaN")) return { type: "NaN" };
+ var ret = consume(FLOAT) || consume(INT);
+ if (ret) return { type: "number", value: 1 * ret.value };
+ var tok = consume(OTHER, "-");
+ if (tok) {
+ if (consume(ID, "Infinity")) return { type: "Infinity", negative: true };
+ else tokens.unshift(tok);
+ }
+ };
+
+ var type_suffix = function (obj) {
+ while (true) {
+ all_ws();
+ if (consume(OTHER, "?")) {
+ if (obj.nullable) error("Can't nullable more than once");
+ obj.nullable = true;
+ }
+ else if (consume(OTHER, "[")) {
+ all_ws();
+ consume(OTHER, "]") || error("Unterminated array type");
+ if (!obj.array) {
+ obj.array = 1;
+ obj.nullableArray = [obj.nullable];
+ }
+ else {
+ obj.array++;
+ obj.nullableArray.push(obj.nullable);
+ }
+ obj.nullable = false;
+ }
+ else return;
+ }
+ };
+
+ var single_type = function () {
+ var prim = primitive_type()
+ , ret = { sequence: false, generic: null, nullable: false, array: false, union: false }
+ , name
+ , value
+ ;
+ if (prim) {
+ ret.idlType = prim;
+ }
+ else if (name = consume(ID)) {
+ value = name.value;
+ all_ws();
+ // Generic types
+ if (consume(OTHER, "<")) {
+ // backwards compat
+ if (value === "sequence") {
+ ret.sequence = true;
+ }
+ ret.generic = value;
+ ret.idlType = type() || error("Error parsing generic type " + value);
+ all_ws();
+ if (!consume(OTHER, ">")) error("Unterminated generic type " + value);
+ type_suffix(ret);
+ return ret;
+ }
+ else {
+ ret.idlType = value;
+ }
+ }
+ else {
+ return;
+ }
+ type_suffix(ret);
+ if (ret.nullable && !ret.array && ret.idlType === "any") error("Type any cannot be made nullable");
+ return ret;
+ };
+
+ var union_type = function () {
+ all_ws();
+ if (!consume(OTHER, "(")) return;
+ var ret = { sequence: false, generic: null, nullable: false, array: false, union: true, idlType: [] };
+ var fst = type() || error("Union type with no content");
+ ret.idlType.push(fst);
+ while (true) {
+ all_ws();
+ if (!consume(ID, "or")) break;
+ var typ = type() || error("No type after 'or' in union type");
+ ret.idlType.push(typ);
+ }
+ if (!consume(OTHER, ")")) error("Unterminated union type");
+ type_suffix(ret);
+ return ret;
+ };
+
+ var type = function () {
+ return single_type() || union_type();
+ };
+
+ var argument = function (store) {
+ var ret = { optional: false, variadic: false };
+ ret.extAttrs = extended_attrs(store);
+ all_ws(store, "pea");
+ var opt_token = consume(ID, "optional");
+ if (opt_token) {
+ ret.optional = true;
+ all_ws();
+ }
+ ret.idlType = type();
+ if (!ret.idlType) {
+ if (opt_token) tokens.unshift(opt_token);
+ return;
+ }
+ var type_token = last_token;
+ if (!ret.optional) {
+ all_ws();
+ if (tokens.length >= 3 &&
+ tokens[0].type === "other" && tokens[0].value === "." &&
+ tokens[1].type === "other" && tokens[1].value === "." &&
+ tokens[2].type === "other" && tokens[2].value === "."
+ ) {
+ tokens.shift();
+ tokens.shift();
+ tokens.shift();
+ ret.variadic = true;
+ }
+ }
+ all_ws();
+ var name = consume(ID);
+ if (!name) {
+ if (opt_token) tokens.unshift(opt_token);
+ tokens.unshift(type_token);
+ return;
+ }
+ ret.name = name.value;
+ if (ret.optional) {
+ all_ws();
+ ret["default"] = default_();
+ }
+ return ret;
+ };
+
+ var argument_list = function (store) {
+ var ret = []
+ , arg = argument(store ? ret : null)
+ ;
+ if (!arg) return;
+ ret.push(arg);
+ while (true) {
+ all_ws(store ? ret : null);
+ if (!consume(OTHER, ",")) return ret;
+ var nxt = argument(store ? ret : null) || error("Trailing comma in arguments list");
+ ret.push(nxt);
+ }
+ };
+
+ var type_pair = function () {
+ all_ws();
+ var k = type();
+ if (!k) return;
+ all_ws()
+ if (!consume(OTHER, ",")) return;
+ all_ws();
+ var v = type();
+ if (!v) return;
+ return [k, v];
+ };
+
+ var simple_extended_attr = function (store) {
+ all_ws();
+ var name = consume(ID);
+ if (!name) return;
+ var ret = {
+ name: name.value
+ , "arguments": null
+ };
+ all_ws();
+ var eq = consume(OTHER, "=");
+ if (eq) {
+ var rhs;
+ all_ws();
+ if (rhs = consume(ID)) {
+ ret.rhs = rhs
+ }
+ else if (consume(OTHER, "(")) {
+ // [Exposed=(Window,Worker)]
+ rhs = [];
+ var id = consume(ID);
+ if (id) {
+ rhs = [id.value];
+ }
+ identifiers(rhs);
+ consume(OTHER, ")") || error("Unexpected token in extended attribute argument list or type pair");
+ ret.rhs = {
+ type: "identifier-list",
+ value: rhs
+ };
+ }
+ if (!ret.rhs) return error("No right hand side to extended attribute assignment");
+ }
+ all_ws();
+ if (consume(OTHER, "(")) {
+ var args, pair;
+ // [Constructor(DOMString str)]
+ if (args = argument_list(store)) {
+ ret["arguments"] = args;
+ }
+ // [MapClass(DOMString, DOMString)]
+ else if (pair = type_pair()) {
+ ret.typePair = pair;
+ }
+ // [Constructor()]
+ else {
+ ret["arguments"] = [];
+ }
+ all_ws();
+ consume(OTHER, ")") || error("Unexpected token in extended attribute argument list or type pair");
+ }
+ return ret;
+ };
+
+ // Note: we parse something simpler than the official syntax. It's all that ever
+ // seems to be used
+ var extended_attrs = function (store) {
+ var eas = [];
+ all_ws(store);
+ if (!consume(OTHER, "[")) return eas;
+ eas[0] = simple_extended_attr(store) || error("Extended attribute with not content");
+ all_ws();
+ while (consume(OTHER, ",")) {
+ eas.push(simple_extended_attr(store) || error("Trailing comma in extended attribute"));
+ all_ws();
+ }
+ consume(OTHER, "]") || error("No end of extended attribute");
+ return eas;
+ };
+
+ var default_ = function () {
+ all_ws();
+ if (consume(OTHER, "=")) {
+ all_ws();
+ var def = const_value();
+ if (def) {
+ return def;
+ }
+ else if (consume(OTHER, "[")) {
+ if (!consume(OTHER, "]")) error("Default sequence value must be empty");
+ return { type: "sequence", value: [] };
+ }
+ else {
+ var str = consume(STR) || error("No value for default");
+ str.value = str.value.replace(/^"/, "").replace(/"$/, "");
+ return str;
+ }
+ }
+ };
+
+ var const_ = function (store) {
+ all_ws(store, "pea");
+ if (!consume(ID, "const")) return;
+ var ret = { type: "const", nullable: false };
+ all_ws();
+ var typ = primitive_type();
+ if (!typ) {
+ typ = consume(ID) || error("No type for const");
+ typ = typ.value;
+ }
+ ret.idlType = typ;
+ all_ws();
+ if (consume(OTHER, "?")) {
+ ret.nullable = true;
+ all_ws();
+ }
+ var name = consume(ID) || error("No name for const");
+ ret.name = name.value;
+ all_ws();
+ consume(OTHER, "=") || error("No value assignment for const");
+ all_ws();
+ var cnt = const_value();
+ if (cnt) ret.value = cnt;
+ else error("No value for const");
+ all_ws();
+ consume(OTHER, ";") || error("Unterminated const");
+ return ret;
+ };
+
+ var inheritance = function () {
+ all_ws();
+ if (consume(OTHER, ":")) {
+ all_ws();
+ var inh = consume(ID) || error ("No type in inheritance");
+ return inh.value;
+ }
+ };
+
+ var operation_rest = function (ret, store) {
+ all_ws();
+ if (!ret) ret = {};
+ var name = consume(ID);
+ ret.name = name ? name.value : null;
+ all_ws();
+ consume(OTHER, "(") || error("Invalid operation");
+ ret["arguments"] = argument_list(store) || [];
+ all_ws();
+ consume(OTHER, ")") || error("Unterminated operation");
+ all_ws();
+ consume(OTHER, ";") || error("Unterminated operation");
+ return ret;
+ };
+
+ var callback = function (store) {
+ all_ws(store, "pea");
+ var ret;
+ if (!consume(ID, "callback")) return;
+ all_ws();
+ var tok = consume(ID, "interface");
+ if (tok) {
+ tokens.unshift(tok);
+ ret = interface_();
+ ret.type = "callback interface";
+ return ret;
+ }
+ var name = consume(ID) || error("No name for callback");
+ ret = { type: "callback", name: name.value };
+ all_ws();
+ consume(OTHER, "=") || error("No assignment in callback");
+ all_ws();
+ ret.idlType = return_type();
+ all_ws();
+ consume(OTHER, "(") || error("No arguments in callback");
+ ret["arguments"] = argument_list(store) || [];
+ all_ws();
+ consume(OTHER, ")") || error("Unterminated callback");
+ all_ws();
+ consume(OTHER, ";") || error("Unterminated callback");
+ return ret;
+ };
+
+ var attribute = function (store) {
+ all_ws(store, "pea");
+ var grabbed = []
+ , ret = {
+ type: "attribute"
+ , "static": false
+ , stringifier: false
+ , inherit: false
+ , readonly: false
+ };
+ if (consume(ID, "static")) {
+ ret["static"] = true;
+ grabbed.push(last_token);
+ }
+ else if (consume(ID, "stringifier")) {
+ ret.stringifier = true;
+ grabbed.push(last_token);
+ }
+ var w = all_ws();
+ if (w) grabbed.push(w);
+ if (consume(ID, "inherit")) {
+ if (ret["static"] || ret.stringifier) error("Cannot have a static or stringifier inherit");
+ ret.inherit = true;
+ grabbed.push(last_token);
+ var w = all_ws();
+ if (w) grabbed.push(w);
+ }
+ if (consume(ID, "readonly")) {
+ ret.readonly = true;
+ grabbed.push(last_token);
+ var w = all_ws();
+ if (w) grabbed.push(w);
+ }
+ if (!consume(ID, "attribute")) {
+ tokens = grabbed.concat(tokens);
+ return;
+ }
+ all_ws();
+ ret.idlType = type() || error("No type in attribute");
+ if (ret.idlType.sequence) error("Attributes cannot accept sequence types");
+ all_ws();
+ var name = consume(ID) || error("No name in attribute");
+ ret.name = name.value;
+ all_ws();
+ consume(OTHER, ";") || error("Unterminated attribute");
+ return ret;
+ };
+
+ var return_type = function () {
+ var typ = type();
+ if (!typ) {
+ if (consume(ID, "void")) {
+ return "void";
+ }
+ else error("No return type");
+ }
+ return typ;
+ };
+
+ var operation = function (store) {
+ all_ws(store, "pea");
+ var ret = {
+ type: "operation"
+ , getter: false
+ , setter: false
+ , creator: false
+ , deleter: false
+ , legacycaller: false
+ , "static": false
+ , stringifier: false
+ };
+ while (true) {
+ all_ws();
+ if (consume(ID, "getter")) ret.getter = true;
+ else if (consume(ID, "setter")) ret.setter = true;
+ else if (consume(ID, "creator")) ret.creator = true;
+ else if (consume(ID, "deleter")) ret.deleter = true;
+ else if (consume(ID, "legacycaller")) ret.legacycaller = true;
+ else break;
+ }
+ if (ret.getter || ret.setter || ret.creator || ret.deleter || ret.legacycaller) {
+ all_ws();
+ ret.idlType = return_type();
+ operation_rest(ret, store);
+ return ret;
+ }
+ if (consume(ID, "static")) {
+ ret["static"] = true;
+ ret.idlType = return_type();
+ operation_rest(ret, store);
+ return ret;
+ }
+ else if (consume(ID, "stringifier")) {
+ ret.stringifier = true;-
+ all_ws();
+ if (consume(OTHER, ";")) return ret;
+ ret.idlType = return_type();
+ operation_rest(ret, store);
+ return ret;
+ }
+ ret.idlType = return_type();
+ all_ws();
+ if (consume(ID, "iterator")) {
+ all_ws();
+ ret.type = "iterator";
+ if (consume(ID, "object")) {
+ ret.iteratorObject = "object";
+ }
+ else if (consume(OTHER, "=")) {
+ all_ws();
+ var name = consume(ID) || error("No right hand side in iterator");
+ ret.iteratorObject = name.value;
+ }
+ all_ws();
+ consume(OTHER, ";") || error("Unterminated iterator");
+ return ret;
+ }
+ else {
+ operation_rest(ret, store);
+ return ret;
+ }
+ };
+
+ var identifiers = function (arr) {
+ while (true) {
+ all_ws();
+ if (consume(OTHER, ",")) {
+ all_ws();
+ var name = consume(ID) || error("Trailing comma in identifiers list");
+ arr.push(name.value);
+ }
+ else break;
+ }
+ };
+
+ var serialiser = function (store) {
+ all_ws(store, "pea");
+ if (!consume(ID, "serializer")) return;
+ var ret = { type: "serializer" };
+ all_ws();
+ if (consume(OTHER, "=")) {
+ all_ws();
+ if (consume(OTHER, "{")) {
+ ret.patternMap = true;
+ all_ws();
+ var id = consume(ID);
+ if (id && id.value === "getter") {
+ ret.names = ["getter"];
+ }
+ else if (id && id.value === "inherit") {
+ ret.names = ["inherit"];
+ identifiers(ret.names);
+ }
+ else if (id) {
+ ret.names = [id.value];
+ identifiers(ret.names);
+ }
+ else {
+ ret.names = [];
+ }
+ all_ws();
+ consume(OTHER, "}") || error("Unterminated serializer pattern map");
+ }
+ else if (consume(OTHER, "[")) {
+ ret.patternList = true;
+ all_ws();
+ var id = consume(ID);
+ if (id && id.value === "getter") {
+ ret.names = ["getter"];
+ }
+ else if (id) {
+ ret.names = [id.value];
+ identifiers(ret.names);
+ }
+ else {
+ ret.names = [];
+ }
+ all_ws();
+ consume(OTHER, "]") || error("Unterminated serializer pattern list");
+ }
+ else {
+ var name = consume(ID) || error("Invalid serializer");
+ ret.name = name.value;
+ }
+ all_ws();
+ consume(OTHER, ";") || error("Unterminated serializer");
+ return ret;
+ }
+ else if (consume(OTHER, ";")) {
+ // noop, just parsing
+ }
+ else {
+ ret.idlType = return_type();
+ all_ws();
+ ret.operation = operation_rest(null, store);
+ }
+ return ret;
+ };
+
+ var iterable_type = function() {
+ if (consume(ID, "iterable")) return "iterable";
+ else if (consume(ID, "legacyiterable")) return "legacyiterable";
+ else if (consume(ID, "maplike")) return "maplike";
+ else if (consume(ID, "setlike")) return "setlike";
+ else return;
+ }
+
+ var readonly_iterable_type = function() {
+ if (consume(ID, "maplike")) return "maplike";
+ else if (consume(ID, "setlike")) return "setlike";
+ else return;
+ }
+
+ var iterable = function (store) {
+ all_ws(store, "pea");
+ var grabbed = [],
+ ret = {type: null, idlType: null, readonly: false};
+ if (consume(ID, "readonly")) {
+ ret.readonly = true;
+ grabbed.push(last_token);
+ var w = all_ws();
+ if (w) grabbed.push(w);
+ }
+ var consumeItType = ret.readonly ? readonly_iterable_type : iterable_type;
+
+ var ittype = consumeItType();
+ if (!ittype) {
+ tokens = grabbed.concat(tokens);
+ return;
+ }
+
+ var secondTypeRequired = ittype === "maplike";
+ var secondTypeAllowed = secondTypeRequired || ittype === "iterable";
+ ret.type = ittype;
+ if (ret.type !== 'maplike' && ret.type !== 'setlike')
+ delete ret.readonly;
+ all_ws();
+ if (consume(OTHER, "<")) {
+ ret.idlType = type() || error("Error parsing " + ittype + " declaration");
+ all_ws();
+ if (secondTypeAllowed) {
+ var type2 = null;
+ if (consume(OTHER, ",")) {
+ all_ws();
+ type2 = type();
+ all_ws();
+ }
+ if (type2)
+ ret.idlType = [ret.idlType, type2];
+ else if (secondTypeRequired)
+ error("Missing second type argument in " + ittype + " declaration");
+ }
+ if (!consume(OTHER, ">")) error("Unterminated " + ittype + " declaration");
+ all_ws();
+ if (!consume(OTHER, ";")) error("Missing semicolon after " + ittype + " declaration");
+ }
+ else
+ error("Error parsing " + ittype + " declaration");
+
+ return ret;
+ }
+
+ var interface_ = function (isPartial, store) {
+ all_ws(isPartial ? null : store, "pea");
+ if (!consume(ID, "interface")) return;
+ all_ws();
+ var name = consume(ID) || error("No name for interface");
+ var mems = []
+ , ret = {
+ type: "interface"
+ , name: name.value
+ , partial: false
+ , members: mems
+ };
+ if (!isPartial) ret.inheritance = inheritance() || null;
+ all_ws();
+ consume(OTHER, "{") || error("Bodyless interface");
+ while (true) {
+ all_ws(store ? mems : null);
+ if (consume(OTHER, "}")) {
+ all_ws();
+ consume(OTHER, ";") || error("Missing semicolon after interface");
+ return ret;
+ }
+ var ea = extended_attrs(store ? mems : null);
+ all_ws();
+ var cnt = const_(store ? mems : null);
+ if (cnt) {
+ cnt.extAttrs = ea;
+ ret.members.push(cnt);
+ continue;
+ }
+ var mem = (opt.allowNestedTypedefs && typedef(store ? mems : null)) ||
+ iterable(store ? mems : null) ||
+ serialiser(store ? mems : null) ||
+ attribute(store ? mems : null) ||
+ operation(store ? mems : null) ||
+ error("Unknown member");
+ mem.extAttrs = ea;
+ ret.members.push(mem);
+ }
+ };
+
+ var partial = function (store) {
+ all_ws(store, "pea");
+ if (!consume(ID, "partial")) return;
+ var thing = dictionary(true, store) ||
+ interface_(true, store) ||
+ error("Partial doesn't apply to anything");
+ thing.partial = true;
+ return thing;
+ };
+
+ var dictionary = function (isPartial, store) {
+ all_ws(isPartial ? null : store, "pea");
+ if (!consume(ID, "dictionary")) return;
+ all_ws();
+ var name = consume(ID) || error("No name for dictionary");
+ var mems = []
+ , ret = {
+ type: "dictionary"
+ , name: name.value
+ , partial: false
+ , members: mems
+ };
+ if (!isPartial) ret.inheritance = inheritance() || null;
+ all_ws();
+ consume(OTHER, "{") || error("Bodyless dictionary");
+ while (true) {
+ all_ws(store ? mems : null);
+ if (consume(OTHER, "}")) {
+ all_ws();
+ consume(OTHER, ";") || error("Missing semicolon after dictionary");
+ return ret;
+ }
+ var ea = extended_attrs(store ? mems : null);
+ all_ws(store ? mems : null, "pea");
+ var required = consume(ID, "required");
+ var typ = type() || error("No type for dictionary member");
+ all_ws();
+ var name = consume(ID) || error("No name for dictionary member");
+ var dflt = default_();
+ if (required && dflt) error("Required member must not have a default");
+ ret.members.push({
+ type: "field"
+ , name: name.value
+ , required: !!required
+ , idlType: typ
+ , extAttrs: ea
+ , "default": dflt
+ });
+ all_ws();
+ consume(OTHER, ";") || error("Unterminated dictionary member");
+ }
+ };
+
+ var exception = function (store) {
+ all_ws(store, "pea");
+ if (!consume(ID, "exception")) return;
+ all_ws();
+ var name = consume(ID) || error("No name for exception");
+ var mems = []
+ , ret = {
+ type: "exception"
+ , name: name.value
+ , members: mems
+ };
+ ret.inheritance = inheritance() || null;
+ all_ws();
+ consume(OTHER, "{") || error("Bodyless exception");
+ while (true) {
+ all_ws(store ? mems : null);
+ if (consume(OTHER, "}")) {
+ all_ws();
+ consume(OTHER, ";") || error("Missing semicolon after exception");
+ return ret;
+ }
+ var ea = extended_attrs(store ? mems : null);
+ all_ws(store ? mems : null, "pea");
+ var cnt = const_();
+ if (cnt) {
+ cnt.extAttrs = ea;
+ ret.members.push(cnt);
+ }
+ else {
+ var typ = type();
+ all_ws();
+ var name = consume(ID);
+ all_ws();
+ if (!typ || !name || !consume(OTHER, ";")) error("Unknown member in exception body");
+ ret.members.push({
+ type: "field"
+ , name: name.value
+ , idlType: typ
+ , extAttrs: ea
+ });
+ }
+ }
+ };
+
+ var enum_ = function (store) {
+ all_ws(store, "pea");
+ if (!consume(ID, "enum")) return;
+ all_ws();
+ var name = consume(ID) || error("No name for enum");
+ var vals = []
+ , ret = {
+ type: "enum"
+ , name: name.value
+ , values: vals
+ };
+ all_ws();
+ consume(OTHER, "{") || error("No curly for enum");
+ var saw_comma = false;
+ while (true) {
+ all_ws(store ? vals : null);
+ if (consume(OTHER, "}")) {
+ all_ws();
+ consume(OTHER, ";") || error("No semicolon after enum");
+ return ret;
+ }
+ var val = consume(STR) || error("Unexpected value in enum");
+ ret.values.push(val.value.replace(/"/g, ""));
+ all_ws(store ? vals : null);
+ if (consume(OTHER, ",")) {
+ if (store) vals.push({ type: "," });
+ all_ws(store ? vals : null);
+ saw_comma = true;
+ }
+ else {
+ saw_comma = false;
+ }
+ }
+ };
+
+ var typedef = function (store) {
+ all_ws(store, "pea");
+ if (!consume(ID, "typedef")) return;
+ var ret = {
+ type: "typedef"
+ };
+ all_ws();
+ ret.typeExtAttrs = extended_attrs();
+ all_ws(store, "tpea");
+ ret.idlType = type() || error("No type in typedef");
+ all_ws();
+ var name = consume(ID) || error("No name in typedef");
+ ret.name = name.value;
+ all_ws();
+ consume(OTHER, ";") || error("Unterminated typedef");
+ return ret;
+ };
+
+ var implements_ = function (store) {
+ all_ws(store, "pea");
+ var target = consume(ID);
+ if (!target) return;
+ var w = all_ws();
+ if (consume(ID, "implements")) {
+ var ret = {
+ type: "implements"
+ , target: target.value
+ };
+ all_ws();
+ var imp = consume(ID) || error("Incomplete implements statement");
+ ret["implements"] = imp.value;
+ all_ws();
+ consume(OTHER, ";") || error("No terminating ; for implements statement");
+ return ret;
+ }
+ else {
+ // rollback
+ tokens.unshift(w);
+ tokens.unshift(target);
+ }
+ };
+
+ var definition = function (store) {
+ return callback(store) ||
+ interface_(false, store) ||
+ partial(store) ||
+ dictionary(false, store) ||
+ exception(store) ||
+ enum_(store) ||
+ typedef(store) ||
+ implements_(store)
+ ;
+ };
+
+ var definitions = function (store) {
+ if (!tokens.length) return [];
+ var defs = [];
+ while (true) {
+ var ea = extended_attrs(store ? defs : null)
+ , def = definition(store ? defs : null);
+ if (!def) {
+ if (ea.length) error("Stray extended attributes");
+ break;
+ }
+ def.extAttrs = ea;
+ defs.push(def);
+ }
+ return defs;
+ };
+ var res = definitions(opt.ws);
+ if (tokens.length) error("Unrecognised tokens");
+ return res;
+ };
+
+ var inNode = typeof module !== "undefined" && module.exports
+ , obj = {
+ parse: function (str, opt) {
+ if (!opt) opt = {};
+ var tokens = tokenise(str);
+ return parse(tokens, opt);
+ }
+ };
+
+ if (inNode) module.exports = obj;
+ else self.WebIDL2 = obj;
+}());
diff --git a/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher100.ttf b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher100.ttf
new file mode 100644
index 0000000..68c855c
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher100.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher200.ttf b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher200.ttf
new file mode 100644
index 0000000..a1cfffb
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher200.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher300.ttf b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher300.ttf
new file mode 100644
index 0000000..5d73ff5
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher300.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher400.ttf b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher400.ttf
new file mode 100644
index 0000000..99fcd0f
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher400.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher500.ttf b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher500.ttf
new file mode 100644
index 0000000..22daca4
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher500.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher600.ttf b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher600.ttf
new file mode 100644
index 0000000..f8a66a4
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher600.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher700.ttf b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher700.ttf
new file mode 100644
index 0000000..20011cc
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher700.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher800.ttf b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher800.ttf
new file mode 100644
index 0000000..7a41e5a
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher800.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher900.ttf b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher900.ttf
new file mode 100644
index 0000000..e539809
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/WebKitWeightWatcher900.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/accessibility-helper.js b/bower_components/custom-elements/tests/chromium/resources/accessibility-helper.js
new file mode 100644
index 0000000..3c0d2c8
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/accessibility-helper.js
@@ -0,0 +1,33 @@
+function buildAccessibilityTree(accessibilityObject, indent, allAttributesRequired, rolesToIgnore, targetObject, targetString) {
+ if (rolesToIgnore) {
+ for (var i = 0; i < rolesToIgnore.length; i++) {
+ if (accessibilityObject.role == 'AXRole: ' + rolesToIgnore[i])
+ return true;
+ }
+ }
+
+ var str = "";
+ for (var i = 0; i < indent; i++)
+ str += " ";
+ str += accessibilityObject.role;
+ if (accessibilityObject.value)
+ str += " AXValue: " + accessibilityObject.value;
+ else if (accessibilityObject.name)
+ str += " \"" + accessibilityObject.name + "\"";
+ str += allAttributesRequired && accessibilityObject.role == '' ? accessibilityObject.allAttributes() : '';
+ str += targetObject && accessibilityObject.isEqual(targetObject) ? " " + targetString : '';
+ str += "\n";
+
+ document.getElementById("console").innerText += str;
+
+ if (accessibilityObject.name.indexOf('End of test') >= 0)
+ return false;
+
+ var count = accessibilityObject.childrenCount;
+ for (var i = 0; i < count; i++) {
+ if (!buildAccessibilityTree(accessibilityObject.childAtIndex(i), indent + 1, allAttributesRequired, rolesToIgnore, targetObject, targetString))
+ return false;
+ }
+
+ return true;
+}
diff --git a/bower_components/custom-elements/tests/chromium/resources/ahem.js b/bower_components/custom-elements/tests/chromium/resources/ahem.js
new file mode 100644
index 0000000..88bc9bd
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/ahem.js
@@ -0,0 +1,792 @@
+// This file is included by tests using Ahem font to ensure that the font is
+// loaded before other JavaScript starts running.
+(function() {
+ // This data is a raw binary converted from /resources/Ahem.ttf.
+ // We use ArrayBuffer to pass the font so that it gets ready synchronously.
+ var ahem = new Uint8Array([
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x80, 0x00, 0x03, 0x00, 0x30, 0x4f, 0x53, 0x2f, 0x32,
+ 0x78, 0x50, 0x4a, 0x8d, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x00, 0x60, 0x63, 0x6d, 0x61, 0x70,
+ 0x0f, 0xd6, 0x16, 0x46, 0x00, 0x00, 0x05, 0x6c, 0x00, 0x00, 0x06, 0x72, 0x67, 0x61, 0x73, 0x70,
+ 0x00, 0x17, 0x00, 0x09, 0x00, 0x00, 0x30, 0xb0, 0x00, 0x00, 0x00, 0x10, 0x67, 0x6c, 0x79, 0x66,
+ 0x49, 0xb3, 0x74, 0xda, 0x00, 0x00, 0x0b, 0xe0, 0x00, 0x00, 0x1a, 0x64, 0x68, 0x65, 0x61, 0x64,
+ 0xd6, 0xa2, 0x4e, 0x1c, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61,
+ 0x07, 0x0a, 0x04, 0x16, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78,
+ 0xb9, 0x20, 0x00, 0x7d, 0x00, 0x00, 0x01, 0x98, 0x00, 0x00, 0x03, 0xd4, 0x6c, 0x6f, 0x63, 0x61,
+ 0x20, 0x75, 0x27, 0x22, 0x00, 0x00, 0x26, 0x44, 0x00, 0x00, 0x01, 0xec, 0x6d, 0x61, 0x78, 0x70,
+ 0x00, 0xf8, 0x00, 0x09, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65,
+ 0x7e, 0x14, 0x8c, 0xb8, 0x00, 0x00, 0x28, 0x30, 0x00, 0x00, 0x06, 0x68, 0x70, 0x6f, 0x73, 0x74,
+ 0x8d, 0xd0, 0x1d, 0x8a, 0x00, 0x00, 0x2e, 0x98, 0x00, 0x00, 0x02, 0x18, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x42, 0x12, 0x17, 0x51, 0x67, 0x5f, 0x0f, 0x3c, 0xf5, 0x00, 0x09, 0x03, 0xe8,
+ 0x00, 0x00, 0x00, 0x00, 0xb3, 0x6f, 0x5f, 0x59, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x2d, 0xab, 0x49,
+ 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x20, 0xff, 0x38, 0x00, 0x00, 0x03, 0xe8,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x08,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0xe8, 0x01, 0x90, 0x00, 0x05,
+ 0x00, 0x00, 0x02, 0xbc, 0x02, 0x8a, 0x00, 0x00, 0x00, 0x8f, 0x02, 0xbc, 0x02, 0x8a, 0x00, 0x00,
+ 0x01, 0xc5, 0x00, 0x32, 0x01, 0x03, 0x00, 0x00, 0x02, 0x00, 0x04, 0x09, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0xaf, 0x10, 0x00, 0x20, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x57, 0x33, 0x43, 0x00, 0x00, 0x40, 0x00, 0x20, 0xf0, 0x02, 0x03, 0x20, 0xff, 0x38,
+ 0x00, 0x00, 0x03, 0x20, 0x00, 0xc8, 0x20, 0x00, 0x01, 0x11, 0x40, 0x00, 0x00, 0x00, 0x03, 0x20,
+ 0x03, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00,
+ 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+ 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x02, 0x26, 0x00, 0x06, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09,
+ 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10,
+ 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18,
+ 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20,
+ 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28,
+ 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30,
+ 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38,
+ 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40,
+ 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48,
+ 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50,
+ 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58,
+ 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60,
+ 0x00, 0x00, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67,
+ 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f,
+ 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77,
+ 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, 0x00, 0x7b, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f,
+ 0x00, 0x80, 0x00, 0xdb, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0xdd, 0x00, 0x85,
+ 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0xe3, 0x00, 0x89, 0x00, 0x8a, 0x00, 0xea, 0x00, 0x8b,
+ 0x00, 0x8c, 0x00, 0xe8, 0x00, 0x8d, 0x00, 0xeb, 0x00, 0xec, 0x00, 0x8e, 0x00, 0x8f, 0x00, 0xe4,
+ 0x00, 0xe6, 0x00, 0xe5, 0x00, 0xd4, 0x00, 0xe9, 0x00, 0x90, 0x00, 0x91, 0x00, 0xd3, 0x00, 0x92,
+ 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0xe7, 0x00, 0xd1, 0x00, 0xed, 0x00, 0xd2,
+ 0x00, 0x97, 0x00, 0x98, 0x00, 0xde, 0x00, 0x03, 0x00, 0x9a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xce,
+ 0x00, 0xcf, 0x00, 0xd5, 0x00, 0xd6, 0x00, 0xd8, 0x00, 0xd9, 0x00, 0x9d, 0x00, 0x9e, 0x00, 0x9f,
+ 0x00, 0xee, 0x00, 0xa0, 0x00, 0xd0, 0x00, 0xe2, 0x00, 0xa1, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xdc, 0x00, 0xa2, 0x00, 0xd7, 0x00, 0xda, 0x00, 0xdf, 0x00, 0xa3, 0x00, 0xa4,
+ 0x00, 0xa5, 0x00, 0xa6, 0x00, 0xa7, 0x00, 0xa8, 0x00, 0xa9, 0x00, 0xaa, 0x00, 0xab, 0x00, 0xac,
+ 0x00, 0xad, 0x00, 0x00, 0x00, 0xae, 0x00, 0xaf, 0x00, 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3,
+ 0x00, 0xb4, 0x00, 0xb5, 0x00, 0xb6, 0x00, 0xb7, 0x00, 0xb8, 0x00, 0xb9, 0x00, 0xba, 0x00, 0xbb,
+ 0x00, 0xbc, 0x00, 0x04, 0x02, 0x26, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x40, 0x00, 0x05, 0x00, 0x0e,
+ 0x00, 0x26, 0x00, 0x7e, 0x00, 0xff, 0x01, 0x31, 0x01, 0x53, 0x01, 0x78, 0x01, 0x92, 0x02, 0xc7,
+ 0x02, 0xc9, 0x02, 0xdd, 0x03, 0x94, 0x03, 0xa9, 0x03, 0xbc, 0x03, 0xc0, 0x20, 0x10, 0x20, 0x14,
+ 0x20, 0x1a, 0x20, 0x1e, 0x20, 0x22, 0x20, 0x26, 0x20, 0x30, 0x20, 0x3a, 0x20, 0x44, 0x21, 0x22,
+ 0x21, 0x26, 0x22, 0x02, 0x22, 0x06, 0x22, 0x0f, 0x22, 0x12, 0x22, 0x1a, 0x22, 0x1e, 0x22, 0x2b,
+ 0x22, 0x48, 0x22, 0x60, 0x22, 0x65, 0x22, 0xf2, 0x25, 0xca, 0xf0, 0x02, 0xff, 0xff, 0x00, 0x00,
+ 0x00, 0x20, 0x00, 0x28, 0x00, 0xa0, 0x01, 0x31, 0x01, 0x52, 0x01, 0x78, 0x01, 0x92, 0x02, 0xc6,
+ 0x02, 0xc9, 0x02, 0xd8, 0x03, 0x94, 0x03, 0xa9, 0x03, 0xbc, 0x03, 0xc0, 0x20, 0x10, 0x20, 0x13,
+ 0x20, 0x18, 0x20, 0x1c, 0x20, 0x20, 0x20, 0x26, 0x20, 0x30, 0x20, 0x39, 0x20, 0x44, 0x21, 0x22,
+ 0x21, 0x26, 0x22, 0x02, 0x22, 0x06, 0x22, 0x0f, 0x22, 0x11, 0x22, 0x19, 0x22, 0x1e, 0x22, 0x2b,
+ 0x22, 0x48, 0x22, 0x60, 0x22, 0x64, 0x22, 0xf2, 0x25, 0xca, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xe3,
+ 0xff, 0xe2, 0x00, 0x00, 0xff, 0x81, 0xff, 0x7c, 0xff, 0x58, 0xff, 0x3f, 0x00, 0x00, 0xfd, 0xec,
+ 0x00, 0x00, 0xfd, 0x3e, 0xfd, 0x2a, 0xfc, 0xd3, 0xfd, 0x14, 0xdf, 0xff, 0xe0, 0xc2, 0x00, 0x00,
+ 0xe0, 0xbc, 0xe0, 0xbb, 0xe0, 0xb8, 0xe0, 0xaf, 0xe0, 0xa7, 0xe0, 0x9e, 0xdf, 0xc1, 0xdf, 0xad,
+ 0xde, 0xe2, 0xde, 0xcc, 0xde, 0xd6, 0x00, 0x00, 0x00, 0x00, 0xde, 0xca, 0xde, 0xbe, 0xde, 0xa5,
+ 0xde, 0x8a, 0xde, 0x87, 0xdd, 0xfb, 0xdb, 0x24, 0x10, 0xef, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x95, 0x00, 0x82,
+ 0x00, 0x83, 0x00, 0xa1, 0x00, 0x8e, 0x00, 0xbd, 0x00, 0x84, 0x00, 0x8a, 0x00, 0x88, 0x00, 0x90,
+ 0x00, 0x97, 0x00, 0x96, 0x00, 0xc4, 0x00, 0x87, 0x00, 0xb5, 0x00, 0x81, 0x00, 0x8d, 0x00, 0xc7,
+ 0x00, 0xc8, 0x00, 0x89, 0x00, 0x8f, 0x00, 0x85, 0x00, 0xa2, 0x00, 0xb9, 0x00, 0xc6, 0x00, 0x91,
+ 0x00, 0x98, 0x00, 0xca, 0x00, 0xc9, 0x00, 0xcb, 0x00, 0x94, 0x00, 0x9a, 0x00, 0xa5, 0x00, 0xa3,
+ 0x00, 0x9b, 0x00, 0x61, 0x00, 0x62, 0x00, 0x8b, 0x00, 0x63, 0x00, 0xa7, 0x00, 0x64, 0x00, 0xa4,
+ 0x00, 0xa6, 0x00, 0xab, 0x00, 0xa8, 0x00, 0xa9, 0x00, 0xaa, 0x00, 0xbe, 0x00, 0x65, 0x00, 0xae,
+ 0x00, 0xac, 0x00, 0xad, 0x00, 0x9c, 0x00, 0x66, 0x00, 0xc5, 0x00, 0x8c, 0x00, 0xb1, 0x00, 0xaf,
+ 0x00, 0xb0, 0x00, 0x67, 0x00, 0xc0, 0x00, 0xc2, 0x00, 0x86, 0x00, 0x69, 0x00, 0x68, 0x00, 0x6a,
+ 0x00, 0x6c, 0x00, 0x6b, 0x00, 0x6d, 0x00, 0x92, 0x00, 0x6e, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x71,
+ 0x00, 0x72, 0x00, 0x74, 0x00, 0x73, 0x00, 0x75, 0x00, 0x76, 0x00, 0xbf, 0x00, 0x77, 0x00, 0x79,
+ 0x00, 0x78, 0x00, 0x7a, 0x00, 0x7c, 0x00, 0x7b, 0x00, 0x9f, 0x00, 0x93, 0x00, 0x7e, 0x00, 0x7d,
+ 0x00, 0x7f, 0x00, 0x80, 0x00, 0xc1, 0x00, 0xc3, 0x00, 0xa0, 0x00, 0xb3, 0x00, 0xbc, 0x00, 0xb6,
+ 0x00, 0xb7, 0x00, 0xb8, 0x00, 0xbb, 0x00, 0xb4, 0x00, 0xba, 0x00, 0x9d, 0x00, 0x9e, 0x00, 0xd7,
+ 0x00, 0xe6, 0x00, 0xc4, 0x00, 0xa2, 0x00, 0xe7, 0x00, 0x04, 0x02, 0x26, 0x00, 0x00, 0x00, 0x4e,
+ 0x00, 0x40, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x26, 0x00, 0x7e, 0x00, 0xff, 0x01, 0x31, 0x01, 0x53,
+ 0x01, 0x78, 0x01, 0x92, 0x02, 0xc7, 0x02, 0xc9, 0x02, 0xdd, 0x03, 0x94, 0x03, 0xa9, 0x03, 0xbc,
+ 0x03, 0xc0, 0x20, 0x10, 0x20, 0x14, 0x20, 0x1a, 0x20, 0x1e, 0x20, 0x22, 0x20, 0x26, 0x20, 0x30,
+ 0x20, 0x3a, 0x20, 0x44, 0x21, 0x22, 0x21, 0x26, 0x22, 0x02, 0x22, 0x06, 0x22, 0x0f, 0x22, 0x12,
+ 0x22, 0x1a, 0x22, 0x1e, 0x22, 0x2b, 0x22, 0x48, 0x22, 0x60, 0x22, 0x65, 0x22, 0xf2, 0x25, 0xca,
+ 0xf0, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x20, 0x00, 0x28, 0x00, 0xa0, 0x01, 0x31, 0x01, 0x52,
+ 0x01, 0x78, 0x01, 0x92, 0x02, 0xc6, 0x02, 0xc9, 0x02, 0xd8, 0x03, 0x94, 0x03, 0xa9, 0x03, 0xbc,
+ 0x03, 0xc0, 0x20, 0x10, 0x20, 0x13, 0x20, 0x18, 0x20, 0x1c, 0x20, 0x20, 0x20, 0x26, 0x20, 0x30,
+ 0x20, 0x39, 0x20, 0x44, 0x21, 0x22, 0x21, 0x26, 0x22, 0x02, 0x22, 0x06, 0x22, 0x0f, 0x22, 0x11,
+ 0x22, 0x19, 0x22, 0x1e, 0x22, 0x2b, 0x22, 0x48, 0x22, 0x60, 0x22, 0x64, 0x22, 0xf2, 0x25, 0xca,
+ 0xf0, 0x00, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xe2, 0x00, 0x00, 0xff, 0x81, 0xff, 0x7c, 0xff, 0x58,
+ 0xff, 0x3f, 0x00, 0x00, 0xfd, 0xec, 0x00, 0x00, 0xfd, 0x3e, 0xfd, 0x2a, 0xfc, 0xd3, 0xfd, 0x14,
+ 0xdf, 0xff, 0xe0, 0xc2, 0x00, 0x00, 0xe0, 0xbc, 0xe0, 0xbb, 0xe0, 0xb8, 0xe0, 0xaf, 0xe0, 0xa7,
+ 0xe0, 0x9e, 0xdf, 0xc1, 0xdf, 0xad, 0xde, 0xe2, 0xde, 0xcc, 0xde, 0xd6, 0x00, 0x00, 0x00, 0x00,
+ 0xde, 0xca, 0xde, 0xbe, 0xde, 0xa5, 0xde, 0x8a, 0xde, 0x87, 0xdd, 0xfb, 0xdb, 0x24, 0x10, 0xef,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x00, 0xee, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x99, 0x00, 0x95, 0x00, 0x82, 0x00, 0x83, 0x00, 0xa1, 0x00, 0x8e, 0x00, 0xbd, 0x00, 0x84,
+ 0x00, 0x8a, 0x00, 0x88, 0x00, 0x90, 0x00, 0x97, 0x00, 0x96, 0x00, 0xc4, 0x00, 0x87, 0x00, 0xb5,
+ 0x00, 0x81, 0x00, 0x8d, 0x00, 0xc7, 0x00, 0xc8, 0x00, 0x89, 0x00, 0x8f, 0x00, 0x85, 0x00, 0xa2,
+ 0x00, 0xb9, 0x00, 0xc6, 0x00, 0x91, 0x00, 0x98, 0x00, 0xca, 0x00, 0xc9, 0x00, 0xcb, 0x00, 0x94,
+ 0x00, 0x9a, 0x00, 0xa5, 0x00, 0xa3, 0x00, 0x9b, 0x00, 0x61, 0x00, 0x62, 0x00, 0x8b, 0x00, 0x63,
+ 0x00, 0xa7, 0x00, 0x64, 0x00, 0xa4, 0x00, 0xa6, 0x00, 0xab, 0x00, 0xa8, 0x00, 0xa9, 0x00, 0xaa,
+ 0x00, 0xbe, 0x00, 0x65, 0x00, 0xae, 0x00, 0xac, 0x00, 0xad, 0x00, 0x9c, 0x00, 0x66, 0x00, 0xc5,
+ 0x00, 0x8c, 0x00, 0xb1, 0x00, 0xaf, 0x00, 0xb0, 0x00, 0x67, 0x00, 0xc0, 0x00, 0xc2, 0x00, 0x86,
+ 0x00, 0x69, 0x00, 0x68, 0x00, 0x6a, 0x00, 0x6c, 0x00, 0x6b, 0x00, 0x6d, 0x00, 0x92, 0x00, 0x6e,
+ 0x00, 0x70, 0x00, 0x6f, 0x00, 0x71, 0x00, 0x72, 0x00, 0x74, 0x00, 0x73, 0x00, 0x75, 0x00, 0x76,
+ 0x00, 0xbf, 0x00, 0x77, 0x00, 0x79, 0x00, 0x78, 0x00, 0x7a, 0x00, 0x7c, 0x00, 0x7b, 0x00, 0x9f,
+ 0x00, 0x93, 0x00, 0x7e, 0x00, 0x7d, 0x00, 0x7f, 0x00, 0x80, 0x00, 0xc1, 0x00, 0xc3, 0x00, 0xa0,
+ 0x00, 0xb3, 0x00, 0xbc, 0x00, 0xb6, 0x00, 0xb7, 0x00, 0xb8, 0x00, 0xbb, 0x00, 0xb4, 0x00, 0xba,
+ 0x00, 0x9d, 0x00, 0x9e, 0x00, 0xd7, 0x00, 0xe6, 0x00, 0xc4, 0x00, 0xa2, 0x00, 0xe7, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x7d, 0x00, 0x00, 0x03, 0x6b, 0x03, 0x20, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00,
+ 0x33, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x21, 0x7d, 0x02, 0xee, 0xfd, 0x8f, 0x01, 0xf4, 0xfe,
+ 0x0c, 0x03, 0x20, 0xfc, 0xe0, 0x7d, 0x02, 0x26, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x31, 0x21,
+ 0x15, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0xc8, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0xe0, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03,
+ 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21,
+ 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0xff, 0x38, 0x03, 0xe8, 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8,
+ 0xfc, 0x18, 0x03, 0x20, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x38, 0x03, 0xe8,
+ 0x03, 0x20, 0x00, 0x03, 0x00, 0x00, 0x11, 0x21, 0x11, 0x21, 0x03, 0xe8, 0xfc, 0x18, 0x03, 0x20,
+ 0xfc, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x22,
+ 0x00, 0x30, 0x00, 0x3e, 0x00, 0x4c, 0x00, 0x5a, 0x00, 0x68, 0x00, 0x76, 0x00, 0x84, 0x00, 0x92,
+ 0x00, 0xa0, 0x00, 0xae, 0x00, 0xbc, 0x00, 0xca, 0x00, 0xd8, 0x00, 0xe6, 0x00, 0xf4, 0x01, 0x02,
+ 0x01, 0x10, 0x01, 0x1e, 0x01, 0x2c, 0x01, 0x3a, 0x01, 0x48, 0x01, 0x56, 0x01, 0x64, 0x01, 0x72,
+ 0x01, 0x80, 0x01, 0x8e, 0x01, 0x9c, 0x01, 0xaa, 0x01, 0xb8, 0x01, 0xc6, 0x01, 0xd4, 0x01, 0xe2,
+ 0x01, 0xf0, 0x01, 0xfe, 0x02, 0x0c, 0x02, 0x1a, 0x02, 0x28, 0x02, 0x36, 0x02, 0x44, 0x02, 0x52,
+ 0x02, 0x60, 0x02, 0x6e, 0x02, 0x7c, 0x02, 0x8a, 0x02, 0x98, 0x02, 0xa6, 0x02, 0xb4, 0x02, 0xc2,
+ 0x02, 0xd0, 0x02, 0xde, 0x02, 0xec, 0x02, 0xfa, 0x03, 0x08, 0x03, 0x16, 0x03, 0x24, 0x03, 0x32,
+ 0x03, 0x40, 0x03, 0x4e, 0x03, 0x5c, 0x03, 0x6a, 0x03, 0x78, 0x03, 0x86, 0x03, 0x94, 0x03, 0xa2,
+ 0x03, 0xb0, 0x03, 0xbe, 0x03, 0xcc, 0x03, 0xda, 0x03, 0xe8, 0x03, 0xf6, 0x04, 0x04, 0x04, 0x12,
+ 0x04, 0x20, 0x04, 0x2e, 0x04, 0x3c, 0x04, 0x4a, 0x04, 0x58, 0x04, 0x64, 0x04, 0x72, 0x04, 0x80,
+ 0x04, 0x8e, 0x04, 0x9c, 0x04, 0xaa, 0x04, 0xb8, 0x04, 0xc6, 0x04, 0xd4, 0x04, 0xe2, 0x04, 0xf0,
+ 0x04, 0xfe, 0x05, 0x0c, 0x05, 0x1a, 0x05, 0x28, 0x05, 0x36, 0x05, 0x44, 0x05, 0x52, 0x05, 0x60,
+ 0x05, 0x6e, 0x05, 0x7c, 0x05, 0x8a, 0x05, 0x98, 0x05, 0xa6, 0x05, 0xb4, 0x05, 0xc2, 0x05, 0xd0,
+ 0x05, 0xde, 0x05, 0xec, 0x05, 0xfa, 0x06, 0x08, 0x06, 0x16, 0x06, 0x24, 0x06, 0x32, 0x06, 0x40,
+ 0x06, 0x4e, 0x06, 0x5c, 0x06, 0x6a, 0x06, 0x78, 0x06, 0x86, 0x06, 0x94, 0x06, 0xa2, 0x06, 0xb0,
+ 0x06, 0xbe, 0x06, 0xcc, 0x06, 0xda, 0x06, 0xe8, 0x06, 0xf6, 0x07, 0x04, 0x07, 0x12, 0x07, 0x20,
+ 0x07, 0x2e, 0x07, 0x3c, 0x07, 0x4a, 0x07, 0x58, 0x07, 0x66, 0x07, 0x74, 0x07, 0x82, 0x07, 0x90,
+ 0x07, 0x9e, 0x07, 0xac, 0x07, 0xba, 0x07, 0xc8, 0x07, 0xd6, 0x07, 0xe4, 0x07, 0xf2, 0x08, 0x00,
+ 0x08, 0x0e, 0x08, 0x1c, 0x08, 0x2a, 0x08, 0x38, 0x08, 0x38, 0x08, 0x46, 0x08, 0x54, 0x08, 0x62,
+ 0x08, 0x70, 0x08, 0x7e, 0x08, 0x8c, 0x08, 0x9a, 0x08, 0xa8, 0x08, 0xb6, 0x08, 0xc4, 0x08, 0xd2,
+ 0x08, 0xe0, 0x08, 0xee, 0x08, 0xfc, 0x09, 0x0a, 0x09, 0x18, 0x09, 0x26, 0x09, 0x34, 0x09, 0x42,
+ 0x09, 0x50, 0x09, 0x5e, 0x09, 0x6c, 0x09, 0x7a, 0x09, 0x88, 0x09, 0x96, 0x09, 0xa4, 0x09, 0xb2,
+ 0x09, 0xc0, 0x09, 0xce, 0x09, 0xdc, 0x09, 0xea, 0x09, 0xf8, 0x0a, 0x06, 0x0a, 0x14, 0x0a, 0x22,
+ 0x0a, 0x30, 0x0a, 0x3e, 0x0a, 0x4c, 0x0a, 0x5a, 0x0a, 0x68, 0x0a, 0x76, 0x0a, 0x84, 0x0a, 0x92,
+ 0x0a, 0xa0, 0x0a, 0xae, 0x0a, 0xbc, 0x0a, 0xca, 0x0a, 0xd8, 0x0a, 0xe6, 0x0a, 0xf4, 0x0b, 0x02,
+ 0x0b, 0x10, 0x0b, 0x1e, 0x0b, 0x2c, 0x0b, 0x3a, 0x0b, 0x48, 0x0b, 0x56, 0x0b, 0x64, 0x0b, 0x72,
+ 0x0b, 0x80, 0x0b, 0x8e, 0x0b, 0x9c, 0x0b, 0xaa, 0x0b, 0xb8, 0x0b, 0xc6, 0x0b, 0xd4, 0x0b, 0xe2,
+ 0x0b, 0xf0, 0x0b, 0xfe, 0x0c, 0x0c, 0x0c, 0x1a, 0x0c, 0x28, 0x0c, 0x36, 0x0c, 0x44, 0x0c, 0x52,
+ 0x0c, 0x60, 0x0c, 0x6e, 0x0c, 0x7c, 0x0c, 0x8a, 0x0c, 0x98, 0x0c, 0xa6, 0x0c, 0xb4, 0x0c, 0xc2,
+ 0x0c, 0xd0, 0x0c, 0xde, 0x0c, 0xec, 0x0c, 0xfa, 0x0d, 0x08, 0x0d, 0x16, 0x0d, 0x24, 0x0d, 0x32,
+ 0x00, 0x00, 0x00, 0x1b, 0x01, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x01, 0x9e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x01, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x20, 0x01, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08,
+ 0x01, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16, 0x01, 0xdc, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x01, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xcf, 0x01, 0xfa, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04,
+ 0x02, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x02, 0xcd, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x10, 0x02, 0xd4, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x04, 0x02, 0xe4, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0b,
+ 0x02, 0xe8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x02, 0xf3, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x02, 0xf7, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x11, 0x00, 0x07, 0x02, 0xfb, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x04,
+ 0x03, 0x02, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x00, 0x01, 0x9e, 0x03, 0x06, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x08, 0x04, 0xa4, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
+ 0x00, 0x02, 0x00, 0x0e, 0x04, 0xac, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x20,
+ 0x04, 0xba, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x08, 0x04, 0xda, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x16, 0x04, 0xe2, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
+ 0x00, 0x06, 0x00, 0x08, 0x04, 0xf8, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x10, 0x00, 0x08,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x11, 0x00, 0x0e, 0x05, 0x08, 0x00, 0x03,
+ 0x00, 0x01, 0x04, 0x09, 0x00, 0x12, 0x00, 0x08, 0x05, 0x16, 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x73,
+ 0x00, 0x74, 0x00, 0x20, 0x00, 0x63, 0x00, 0x68, 0x00, 0x61, 0x00, 0x72, 0x00, 0x61, 0x00, 0x63,
+ 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65,
+ 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x20,
+ 0x00, 0x73, 0x00, 0x71, 0x00, 0x75, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x2c, 0x00, 0x20,
+ 0x00, 0x65, 0x00, 0x78, 0x00, 0x63, 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x20, 0x00, 0x26,
+ 0x00, 0x45, 0x00, 0x41, 0x00, 0x63, 0x00, 0x75, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x61,
+ 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x22, 0x00, 0x70, 0x00, 0x22, 0x00, 0x2c, 0x00, 0x20,
+ 0x00, 0x77, 0x00, 0x68, 0x00, 0x69, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x73, 0x00, 0x68,
+ 0x00, 0x6f, 0x00, 0x77, 0x00, 0x20, 0x00, 0x61, 0x00, 0x73, 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e,
+ 0x00, 0x74, 0x00, 0x2f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x73, 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e,
+ 0x00, 0x74, 0x00, 0x20, 0x00, 0x66, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x74,
+ 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x65, 0x00, 0x6c,
+ 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x55, 0x00, 0x73, 0x00, 0x65,
+ 0x00, 0x66, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20,
+ 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20,
+ 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x69, 0x00, 0x74,
+ 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00, 0x74,
+ 0x00, 0x65, 0x00, 0x6d, 0x00, 0x73, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f,
+ 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x62, 0x00, 0x79,
+ 0x00, 0x20, 0x00, 0x54, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x64, 0x00, 0x20, 0x00, 0x46, 0x00, 0x61,
+ 0x00, 0x68, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f,
+ 0x00, 0x72, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x43, 0x00, 0x53,
+ 0x00, 0x53, 0x00, 0x20, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x75, 0x00, 0x72, 0x00, 0x61,
+ 0x00, 0x69, 0x00, 0x27, 0x00, 0x73, 0x00, 0x20, 0x00, 0x62, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x77,
+ 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74,
+ 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x2e, 0x00, 0x41, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d,
+ 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, 0x00, 0x56,
+ 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x31,
+ 0x00, 0x2e, 0x00, 0x31, 0x00, 0x20, 0x00, 0x41, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x41,
+ 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69,
+ 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x41, 0x00, 0x68,
+ 0x00, 0x65, 0x00, 0x6d, 0x4d, 0x6f, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74,
+ 0x65, 0x72, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6d, 0x20, 0x73,
+ 0x71, 0x75, 0x61, 0x72, 0x65, 0x2c, 0x20, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x26, 0x45,
+ 0x41, 0x63, 0x75, 0x74, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x22, 0x70, 0x22, 0x2c, 0x20, 0x77,
+ 0x68, 0x69, 0x63, 0x68, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x74,
+ 0x2f, 0x64, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x20, 0x55, 0x73, 0x65, 0x66,
+ 0x75, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x63,
+ 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
+ 0x6d, 0x73, 0x2e, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20,
+ 0x54, 0x6f, 0x64, 0x64, 0x20, 0x46, 0x61, 0x68, 0x72, 0x6e, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72,
+ 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x53, 0x53, 0x20, 0x53, 0x61, 0x6d, 0x75, 0x72, 0x61, 0x69,
+ 0x27, 0x73, 0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x74, 0x65, 0x73, 0x74, 0x69,
+ 0x6e, 0x67, 0x2e, 0x41, 0x68, 0x65, 0x6d, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x31, 0x20, 0x41, 0x68, 0x65, 0x6d, 0x41, 0x68,
+ 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x31, 0x41, 0x68, 0x65,
+ 0x6d, 0x41, 0x68, 0x65, 0x6d, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x41, 0x68, 0x65, 0x6d,
+ 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x74, 0x00, 0x20, 0x00, 0x63, 0x00, 0x68, 0x00, 0x61,
+ 0x00, 0x72, 0x00, 0x61, 0x00, 0x63, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x20,
+ 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20,
+ 0x00, 0x65, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x73, 0x00, 0x71, 0x00, 0x75, 0x00, 0x61, 0x00, 0x72,
+ 0x00, 0x65, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x65, 0x00, 0x78, 0x00, 0x63, 0x00, 0x65, 0x00, 0x70,
+ 0x00, 0x74, 0x00, 0x20, 0x00, 0x26, 0x00, 0x45, 0x00, 0x41, 0x00, 0x63, 0x00, 0x75, 0x00, 0x74,
+ 0x00, 0x65, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x22, 0x00, 0x70,
+ 0x00, 0x22, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x77, 0x00, 0x68, 0x00, 0x69, 0x00, 0x63, 0x00, 0x68,
+ 0x00, 0x20, 0x00, 0x73, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x20, 0x00, 0x61, 0x00, 0x73,
+ 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x2f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x73,
+ 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x66, 0x00, 0x72, 0x00, 0x6f,
+ 0x00, 0x6d, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x62, 0x00, 0x61,
+ 0x00, 0x73, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x20,
+ 0x00, 0x55, 0x00, 0x73, 0x00, 0x65, 0x00, 0x66, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x66,
+ 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x69,
+ 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x6f,
+ 0x00, 0x73, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x73,
+ 0x00, 0x79, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x73, 0x00, 0x2e, 0x00, 0x20,
+ 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00, 0x65, 0x00, 0x64,
+ 0x00, 0x20, 0x00, 0x62, 0x00, 0x79, 0x00, 0x20, 0x00, 0x54, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x64,
+ 0x00, 0x20, 0x00, 0x46, 0x00, 0x61, 0x00, 0x68, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72,
+ 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65,
+ 0x00, 0x20, 0x00, 0x43, 0x00, 0x53, 0x00, 0x53, 0x00, 0x20, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6d,
+ 0x00, 0x75, 0x00, 0x72, 0x00, 0x61, 0x00, 0x69, 0x00, 0x27, 0x00, 0x73, 0x00, 0x20, 0x00, 0x62,
+ 0x00, 0x72, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x74,
+ 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x2e, 0x00, 0x41,
+ 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, 0x00, 0x6c,
+ 0x00, 0x61, 0x00, 0x72, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f,
+ 0x00, 0x6e, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x20, 0x00, 0x41, 0x00, 0x68,
+ 0x00, 0x65, 0x00, 0x6d, 0x00, 0x41, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x56, 0x00, 0x65,
+ 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2e,
+ 0x00, 0x31, 0x00, 0x41, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x41, 0x00, 0x68, 0x00, 0x65,
+ 0x00, 0x6d, 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72,
+ 0x00, 0x41, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x7b, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02,
+ 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0b,
+ 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13,
+ 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b,
+ 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23,
+ 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b,
+ 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33,
+ 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b,
+ 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43,
+ 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b,
+ 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53,
+ 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b,
+ 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63,
+ 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6b,
+ 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x71, 0x00, 0x72, 0x00, 0x73,
+ 0x00, 0x74, 0x00, 0x75, 0x00, 0x76, 0x00, 0x77, 0x00, 0x78, 0x00, 0x79, 0x00, 0x7a, 0x00, 0x7b,
+ 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, 0x80, 0x00, 0x81, 0x00, 0x83, 0x00, 0x84,
+ 0x00, 0x85, 0x00, 0x86, 0x00, 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, 0x8d, 0x00, 0x8e,
+ 0x00, 0x90, 0x00, 0x91, 0x00, 0x93, 0x00, 0x96, 0x00, 0x97, 0x00, 0x9d, 0x00, 0x9e, 0x00, 0xa0,
+ 0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xaa, 0x00, 0xac, 0x00, 0xad,
+ 0x00, 0xae, 0x00, 0xaf, 0x00, 0xb6, 0x00, 0xb7, 0x00, 0xb8, 0x00, 0xba, 0x00, 0xbd, 0x00, 0xc3,
+ 0x00, 0xc7, 0x00, 0xc8, 0x00, 0xc9, 0x00, 0xca, 0x00, 0xcb, 0x00, 0xcc, 0x00, 0xcd, 0x00, 0xce,
+ 0x00, 0xcf, 0x00, 0xd0, 0x00, 0xd1, 0x00, 0xd3, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0xd6, 0x00, 0xd7,
+ 0x00, 0xd8, 0x00, 0xd9, 0x00, 0xda, 0x00, 0xdb, 0x00, 0xdc, 0x00, 0xdd, 0x00, 0xde, 0x00, 0xdf,
+ 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe8, 0x00, 0xe9, 0x00, 0xea, 0x00, 0xeb, 0x00, 0xec, 0x00, 0xed,
+ 0x00, 0xee, 0x00, 0xef, 0x00, 0xf0, 0x00, 0xf1, 0x00, 0xf2, 0x00, 0xf3, 0x00, 0xf4, 0x00, 0xf5,
+ 0x00, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0xb1, 0x00, 0xbb, 0x00, 0xa6, 0x00, 0xa8,
+ 0x00, 0x9f, 0x00, 0x9b, 0x00, 0xb2, 0x00, 0xb3, 0x00, 0xc4, 0x00, 0xb4, 0x00, 0xb5, 0x00, 0xc5,
+ 0x00, 0x82, 0x00, 0xc2, 0x00, 0x87, 0x00, 0xab, 0x00, 0xc6, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0xbc,
+ 0x00, 0x8c, 0x00, 0x98, 0x00, 0x9a, 0x00, 0x99, 0x00, 0xa5, 0x00, 0x92, 0x00, 0x9c, 0x00, 0x8f,
+ 0x00, 0x94, 0x00, 0x95, 0x00, 0xa7, 0x00, 0xb9, 0x00, 0xd2, 0x00, 0xc0, 0x00, 0xc1, 0x01, 0x03,
+ 0x00, 0x02, 0x01, 0x04, 0x04, 0x4e, 0x55, 0x4c, 0x4c, 0x02, 0x48, 0x54, 0x03, 0x44, 0x45, 0x4c,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x00, 0x02, 0x00, 0x10, 0x00, 0x01, 0xff, 0xff, 0x00, 0x03
+ ]);
+
+ var font = new FontFace('Ahem', ahem.buffer);
+ document.fonts.add(font);
+ font.load();
+}());
diff --git a/bower_components/custom-elements/tests/chromium/resources/bluetooth/bluetooth-helpers.js b/bower_components/custom-elements/tests/chromium/resources/bluetooth/bluetooth-helpers.js
new file mode 100644
index 0000000..fd9719a
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/bluetooth/bluetooth-helpers.js
@@ -0,0 +1,343 @@
+'use strict';
+
+// Bluetooth UUID constants:
+// Services:
+var blacklist_test_service_uuid = "611c954a-263b-4f4a-aab6-01ddb953f985";
+var request_disconnection_service_uuid = "01d7d889-7451-419f-aeb8-d65e7b9277af";
+// Characteristics:
+var blacklist_exclude_reads_characteristic_uuid =
+ "bad1c9a2-9a5b-4015-8b60-1579bbbf2135";
+var request_disconnection_characteristic_uuid =
+ "01d7d88a-7451-419f-aeb8-d65e7b9277af";
+
+// Sometimes we need to test that using either the name, alias, or UUID
+// produces the same result. The following objects help us do that.
+var generic_access = {
+ alias: 0x1800,
+ name: 'generic_access',
+ uuid: '00001800-0000-1000-8000-00805f9b34fb'
+};
+var device_name = {
+ alias: 0x2a00,
+ name: 'gap.device_name',
+ uuid: '00002a00-0000-1000-8000-00805f9b34fb'
+};
+var reconnection_address = {
+ alias: 0x2a03,
+ name: 'gap.reconnection_address',
+ uuid: '00002a03-0000-1000-8000-00805f9b34fb'
+};
+var heart_rate = {
+ alias: 0x180d,
+ name: 'heart_rate',
+ uuid: '0000180d-0000-1000-8000-00805f9b34fb'
+};
+var body_sensor_location = {
+ alias: 0x2a38,
+ name: 'body_sensor_location',
+ uuid: '00002a38-0000-1000-8000-00805f9b34fb'
+};
+var glucose = {
+ alias: 0x1808,
+ name: 'glucose',
+ uuid: '00001808-0000-1000-8000-00805f9b34fb'
+};
+var battery_service = {
+ alias: 0x180f,
+ name: 'battery_service',
+ uuid: '0000180f-0000-1000-8000-00805f9b34fb'
+};
+var battery_level = {
+ alias: 0x2A19,
+ name: 'battery_level',
+ uuid: '00002a19-0000-1000-8000-00805f9b34fb'
+};
+
+// The following tests make sure the Web Bluetooth implementation
+// responds correctly to the different types of errors the
+// underlying platform might return for GATT operations.
+
+// Each browser should map these characteristics to specific code paths
+// that result in different errors thus increasing code coverage
+// when testing. Therefore some of these characteristics might not be useful
+// for all browsers.
+//
+// TODO(ortuno): According to the testing spec errorUUID(0x101) to
+// errorUUID(0x1ff) should be use for the uuids of the characteristics.
+var gatt_errors_tests = [{
+ testName: 'GATT Error: Unknown.',
+ uuid: errorUUID(0xA1),
+ error: new DOMException(
+ 'GATT Error Unknown.',
+ 'NotSupportedError')
+}, {
+ testName: 'GATT Error: Failed.',
+ uuid: errorUUID(0xA2),
+ error: new DOMException(
+ 'GATT operation failed for unknown reason.',
+ 'NotSupportedError')
+}, {
+ testName: 'GATT Error: In Progress.',
+ uuid: errorUUID(0xA3),
+ error: new DOMException(
+ 'GATT operation already in progress.',
+ 'NetworkError')
+}, {
+ testName: 'GATT Error: Invalid Length.',
+ uuid: errorUUID(0xA4),
+ error: new DOMException(
+ 'GATT Error: invalid attribute length.',
+ 'InvalidModificationError')
+}, {
+ testName: 'GATT Error: Not Permitted.',
+ uuid: errorUUID(0xA5),
+ error: new DOMException(
+ 'GATT operation not permitted.',
+ 'NotSupportedError')
+}, {
+ testName: 'GATT Error: Not Authorized.',
+ uuid: errorUUID(0xA6),
+ error: new DOMException(
+ 'GATT operation not authorized.',
+ 'SecurityError')
+}, {
+ testName: 'GATT Error: Not Paired.',
+ uuid: errorUUID(0xA7),
+ // TODO(ortuno): Change to InsufficientAuthenticationError or similiar
+ // once https://github.com/WebBluetoothCG/web-bluetooth/issues/137 is
+ // resolved.
+ error: new DOMException(
+ 'GATT Error: Not paired.',
+ 'NetworkError')
+}, {
+ testName: 'GATT Error: Not Supported.',
+ uuid: errorUUID(0xA8),
+ error: new DOMException(
+ 'GATT Error: Not supported.',
+ 'NotSupportedError')
+}];
+
+// TODO(jyasskin): Upstream this to testharness.js: https://crbug.com/509058.
+function callWithKeyDown(functionCalledOnKeyPress) {
+ return new Promise(resolve => {
+ function onKeyPress() {
+ document.removeEventListener('keypress', onKeyPress, false);
+ resolve(functionCalledOnKeyPress());
+ }
+ document.addEventListener('keypress', onKeyPress, false);
+
+ eventSender.keyDown(' ', []);
+ });
+}
+
+// Calls requestDevice() in a context that's 'allowed to show a popup'.
+function requestDeviceWithKeyDown() {
+ let args = arguments;
+ return callWithKeyDown(() => navigator.bluetooth.requestDevice.apply(navigator.bluetooth, args));
+}
+
+// Calls testRunner.getBluetoothManualChooserEvents() until it's returned
+// |expected_count| events. Or just once if |expected_count| is undefined.
+function getBluetoothManualChooserEvents(expected_count) {
+ return new Promise((resolve, reject) => {
+ let events = [];
+ let accumulate_events = new_events => {
+ events.push(...new_events);
+ if (events.length >= expected_count) {
+ resolve(events);
+ } else {
+ testRunner.getBluetoothManualChooserEvents(accumulate_events);
+ }
+ };
+ testRunner.getBluetoothManualChooserEvents(accumulate_events);
+ });
+}
+
+function setBluetoothFakeAdapter(adapter_name) {
+ return new Promise(resolve => {
+ testRunner.setBluetoothFakeAdapter(adapter_name, resolve);
+ });
+}
+
+// errorUUID(alias) returns a UUID with the top 32 bits of
+// '00000000-97e5-4cd7-b9f1-f5a427670c59' replaced with the bits of |alias|.
+// For example, errorUUID(0xDEADBEEF) returns
+// 'deadbeef-97e5-4cd7-b9f1-f5a427670c59'. The bottom 96 bits of error UUIDs
+// were generated as a type 4 (random) UUID.
+function errorUUID(uuidAlias) {
+ // Make the number positive.
+ uuidAlias >>>= 0;
+ // Append the alias as a hex number.
+ var strAlias = '0000000' + uuidAlias.toString(16);
+ // Get last 8 digits of strAlias.
+ strAlias = strAlias.substr(-8);
+ // Append Base Error UUID
+ return strAlias + '-97e5-4cd7-b9f1-f5a427670c59';
+}
+
+// Function to test that a promise rejects with the expected error type and
+// message.
+function assert_promise_rejects_with_message(promise, expected, description) {
+ return promise.then(() => {
+ assert_unreached('Promise should have rejected: ' + description);
+ }, error => {
+ assert_equals(error.name, expected.name, 'Unexpected Error Name:');
+ if (expected.message) {
+ assert_equals(error.message, expected.message, 'Unexpected Error Message:');
+ }
+ });
+}
+
+// Parses add-device(name)=id lines in
+// testRunner.getBluetoothManualChooserEvents() output, and exposes the name->id
+// mapping.
+class AddDeviceEventSet {
+ constructor() {
+ this._idsByName = new Map();
+ this._addDeviceRegex = /^add-device\(([^)]+)\)=(.+)$/;
+ }
+ assert_add_device_event(event, description) {
+ let match = this._addDeviceRegex.exec(event);
+ assert_true(!!match, event + " isn't an add-device event: " + description);
+ this._idsByName.set(match[1], match[2]);
+ }
+ has(name) {
+ return this._idsByName.has(name);
+ }
+ get(name) {
+ return this._idsByName.get(name);
+ }
+}
+
+function runGarbageCollection()
+{
+ // Run gc() as a promise.
+ return new Promise(
+ function(resolve, reject) {
+ GCController.collect();
+ setTimeout(resolve, 0);
+ });
+}
+
+function eventPromise(target, type, options) {
+ return new Promise(resolve => {
+ let wrapper = function(event) {
+ target.removeEventListener(type, wrapper);
+ resolve(event);
+ };
+ target.addEventListener(type, wrapper, options);
+ });
+}
+
+// Creates |num_listeners| promises. Each adds an event listener
+// to object. The promises resolve once the object fires |event| but
+// reject if the event is fired before |object|.|func|() resolves.
+// Returns a promise that fulfills with the result of |object|.|func()|
+// and |event.target.value| of each of the other promises.
+function assert_event_fires_after_promise(object, func, event, num_listeners) {
+ num_listeners = num_listeners !== undefined ? num_listeners : 1;
+
+ if (object[func] === undefined) {
+ return Promise.reject('Function \'' + func + '\' not available in object.');
+ }
+ let should_resolve = false;
+ let event_promises = [];
+ for (let i = 0; i < num_listeners; i++) {
+ event_promises.push(new Promise((resolve, reject) => {
+ let event_listener = (e) => {
+ object.removeEventListener(event, event_listener);
+ if (should_resolve) {
+ resolve(e.target.value);
+ } else {
+ reject(event + ' was triggered before the promise resolved.');
+ }
+ };
+ object.addEventListener(event, event_listener);
+ }));
+ }
+ return object[func]().then(result => {
+ should_resolve = true;
+ return Promise.all([result, ...event_promises]);
+ });
+}
+
+// Returns a promise that resolves after 100ms unless
+// the the event is fired on the object in which case
+// the promise rejects.
+function assert_no_events(object, event_name) {
+ return new Promise((resolve, reject) => {
+ let event_listener = (e) => {
+ object.removeEventListener(event_name, event_listener);
+ assert_unreached('Object should not fire an event.');
+ };
+ object.addEventListener(event_name, event_listener);
+ // TODO(ortuno): Remove timeout.
+ // http://crbug.com/543884
+ setTimeout(() => {
+ object.removeEventListener(event_name, event_listener);
+ resolve();
+ }, 100);
+ });
+}
+
+class TestCharacteristicProperties {
+ constructor(properties) {
+ this.broadcast = properties.broadcast || false;
+ this.read = properties.read || false;
+ this.writeWithoutResponse = properties.writeWithoutResponse || false;
+ this.write = properties.write || false;
+ this.notify = properties.notify || false;
+ this.indicate = properties.indicate || false;
+ this.authenticatedSignedWrites = properties.authenticatedSignedWrites || false;
+ this.reliableWrite = properties.reliableWrite || false;
+ this.writableAuxiliaries = properties.writableAuxiliaries || false;
+ }
+}
+
+function assert_properties_equal(properties, expected_properties) {
+ for (let key in expected_properties) {
+ assert_equals(properties[key], expected_properties[key]);
+ }
+}
+
+// Generates a string of size |size|.
+function generate_string(size, char) {
+ // When passing an array of n undefined's to String the resulting string
+ // has size n - 1.
+ return char.repeat(size);
+}
+
+class EventCatcher {
+ constructor(object, event) {
+ this.eventFired = false;
+ let event_listener = e => {
+ object.removeEventListener(event, event_listener);
+ this.eventFired = true;
+ }
+ object.addEventListener(event, event_listener);
+ }
+}
+
+function generateRequestDeviceArgsWithServices(services = ['heart_rate']) {
+ return [{
+ filters: [{ services: services }]
+ }, {
+ filters: [{ services: services, name: 'Name' }]
+ }, {
+ filters: [{ services: services, namePrefix: 'Pre' }]
+ }, {
+ filters: [{ services: services, name: 'Name', namePrefix: 'Pre' }]
+ }, {
+ filters: [{ services: services }],
+ optionalServices: ['heart_rate']
+ }, {
+ filters: [{ services: services, name: 'Name' }],
+ optionalServices: ['heart_rate']
+ }, {
+ filters: [{ services: services, namePrefix: 'Pre' }],
+ optionalServices: ['heart_rate']
+ }, {
+ filters: [{ services: services, name: 'Name', namePrefix: 'Pre' }],
+ optionalServices: ['heart_rate']
+ }];
+}
diff --git a/bower_components/custom-elements/tests/chromium/resources/bluetooth/connect-iframe.html b/bower_components/custom-elements/tests/chromium/resources/bluetooth/connect-iframe.html
new file mode 100644
index 0000000..09eb9f2
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/bluetooth/connect-iframe.html
@@ -0,0 +1,18 @@
+
+
diff --git a/bower_components/custom-elements/tests/chromium/resources/bluetooth/requestDevice-in-iframe.html b/bower_components/custom-elements/tests/chromium/resources/bluetooth/requestDevice-in-iframe.html
new file mode 100644
index 0000000..870e7a8
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/bluetooth/requestDevice-in-iframe.html
@@ -0,0 +1,21 @@
+
+
diff --git a/bower_components/custom-elements/tests/chromium/resources/check-layout-th.js b/bower_components/custom-elements/tests/chromium/resources/check-layout-th.js
new file mode 100644
index 0000000..3f257d4
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/check-layout-th.js
@@ -0,0 +1,195 @@
+(function() {
+// Test is initiated from body.onload, so explicit done() call is required.
+setup({ explicit_done: true });
+
+function checkSubtreeExpectedValues(t, parent, prefix)
+{
+ var checkedLayout = checkExpectedValues(t, parent, prefix);
+ Array.prototype.forEach.call(parent.childNodes, function(node) {
+ checkedLayout |= checkSubtreeExpectedValues(t, node, prefix);
+ });
+ return checkedLayout;
+}
+
+function checkAttribute(output, node, attribute)
+{
+ var result = node.getAttribute && node.getAttribute(attribute);
+ output.checked |= !!result;
+ return result;
+}
+
+function assert_tolerance(actual, expected, message)
+{
+ if (isNaN(expected) || Math.abs(actual - expected) >= 1) {
+ assert_equals(actual, Number(expected), message);
+ }
+}
+
+function checkExpectedValues(t, node, prefix)
+{
+ var output = { checked: false };
+
+ var expectedWidth = checkAttribute(output, node, "data-expected-width");
+ if (expectedWidth) {
+ assert_tolerance(node.offsetWidth, expectedWidth, prefix + "width");
+ }
+
+ var expectedHeight = checkAttribute(output, node, "data-expected-height");
+ if (expectedHeight) {
+ assert_tolerance(node.offsetHeight, expectedHeight, prefix + "height");
+ }
+
+ var expectedOffset = checkAttribute(output, node, "data-offset-x");
+ if (expectedOffset) {
+ assert_tolerance(node.offsetLeft, expectedOffset, prefix + "offsetLeft");
+ }
+
+ var expectedOffset = checkAttribute(output, node, "data-offset-y");
+ if (expectedOffset) {
+ assert_tolerance(node.offsetTop, expectedOffset, prefix + "offsetTop");
+ }
+
+ var expectedWidth = checkAttribute(output, node, "data-expected-client-width");
+ if (expectedWidth) {
+ assert_tolerance(node.clientWidth, expectedWidth, prefix + "clientWidth");
+ }
+
+ var expectedHeight = checkAttribute(output, node, "data-expected-client-height");
+ if (expectedHeight) {
+ assert_tolerance(node.clientHeight, expectedHeight, prefix + "clientHeight");
+ }
+
+ var expectedWidth = checkAttribute(output, node, "data-expected-scroll-width");
+ if (expectedWidth) {
+ assert_tolerance(node.scrollWidth, expectedWidth, prefix + "scrollWidth");
+ }
+
+ var expectedHeight = checkAttribute(output, node, "data-expected-scroll-height");
+ if (expectedHeight) {
+ assert_tolerance(node.scrollHeight, expectedHeight, prefix + "scrollHeight");
+ }
+
+ var expectedWidth = checkAttribute(output, node, "data-expected-bounding-client-rect-width");
+ if (expectedWidth) {
+ assert_tolerance(node.getBoundingClientRect().width, expectedWidth, prefix + "getBoundingClientRect().width");
+ }
+
+ var expectedOffset = checkAttribute(output, node, "data-total-x");
+ if (expectedOffset) {
+ var totalLeft = node.clientLeft + node.offsetLeft;
+ assert_tolerance(totalLeft, expectedOffset, prefix +
+ "clientLeft+offsetLeft (" + node.clientLeft + " + " + node.offsetLeft + ")");
+ }
+
+ var expectedOffset = checkAttribute(output, node, "data-total-y");
+ if (expectedOffset) {
+ var totalTop = node.clientTop + node.offsetTop;
+ assert_tolerance(totalTop, expectedOffset, prefix +
+ "clientTop+offsetTop (" + node.clientTop + " + " + node.offsetTop + ")");
+ }
+
+ var expectedDisplay = checkAttribute(output, node, "data-expected-display");
+ if (expectedDisplay) {
+ var actualDisplay = getComputedStyle(node).display;
+ assert_equals(actualDisplay, expectedDisplay, prefix + "display");
+ }
+
+ var expectedPaddingTop = checkAttribute(output, node, "data-expected-padding-top");
+ if (expectedPaddingTop) {
+ var actualPaddingTop = getComputedStyle(node).paddingTop;
+ // Trim the unit "px" from the output.
+ actualPaddingTop = actualPaddingTop.slice(0, -2);
+ assert_equals(actualPaddingTop, expectedPaddingTop, prefix + "padding-top");
+ }
+
+ var expectedPaddingBottom = checkAttribute(output, node, "data-expected-padding-bottom");
+ if (expectedPaddingBottom) {
+ var actualPaddingBottom = getComputedStyle(node).paddingBottom;
+ // Trim the unit "px" from the output.
+ actualPaddingBottom = actualPaddingBottom.slice(0, -2);
+ assert_equals(actualPaddingBottom, expectedPaddingBottom, prefix + "padding-bottom");
+ }
+
+ var expectedPaddingLeft = checkAttribute(output, node, "data-expected-padding-left");
+ if (expectedPaddingLeft) {
+ var actualPaddingLeft = getComputedStyle(node).paddingLeft;
+ // Trim the unit "px" from the output.
+ actualPaddingLeft = actualPaddingLeft.slice(0, -2);
+ assert_equals(actualPaddingLeft, expectedPaddingLeft, prefix + "padding-left");
+ }
+
+ var expectedPaddingRight = checkAttribute(output, node, "data-expected-padding-right");
+ if (expectedPaddingRight) {
+ var actualPaddingRight = getComputedStyle(node).paddingRight;
+ // Trim the unit "px" from the output.
+ actualPaddingRight = actualPaddingRight.slice(0, -2);
+ assert_equals(actualPaddingRight, expectedPaddingRight, prefix + "padding-right");
+ }
+
+ var expectedMarginTop = checkAttribute(output, node, "data-expected-margin-top");
+ if (expectedMarginTop) {
+ var actualMarginTop = getComputedStyle(node).marginTop;
+ // Trim the unit "px" from the output.
+ actualMarginTop = actualMarginTop.slice(0, -2);
+ assert_equals(actualMarginTop, expectedMarginTop, prefix + "margin-top");
+ }
+
+ var expectedMarginBottom = checkAttribute(output, node, "data-expected-margin-bottom");
+ if (expectedMarginBottom) {
+ var actualMarginBottom = getComputedStyle(node).marginBottom;
+ // Trim the unit "px" from the output.
+ actualMarginBottom = actualMarginBottom.slice(0, -2);
+ assert_equals(actualMarginBottom, expectedMarginBottom, prefix + "margin-bottom");
+ }
+
+ var expectedMarginLeft = checkAttribute(output, node, "data-expected-margin-left");
+ if (expectedMarginLeft) {
+ var actualMarginLeft = getComputedStyle(node).marginLeft;
+ // Trim the unit "px" from the output.
+ actualMarginLeft = actualMarginLeft.slice(0, -2);
+ assert_equals(actualMarginLeft, expectedMarginLeft, prefix + "margin-left");
+ }
+
+ var expectedMarginRight = checkAttribute(output, node, "data-expected-margin-right");
+ if (expectedMarginRight) {
+ var actualMarginRight = getComputedStyle(node).marginRight;
+ // Trim the unit "px" from the output.
+ actualMarginRight = actualMarginRight.slice(0, -2);
+ assert_equals(actualMarginRight, expectedMarginRight, prefix + "margin-right");
+ }
+
+ return output.checked;
+}
+
+window.checkLayout = function(selectorList, outputContainer)
+{
+ if (!selectorList) {
+ console.error("You must provide a CSS selector of nodes to check.");
+ return;
+ }
+ var nodes = document.querySelectorAll(selectorList);
+ var testNumber = 0;
+ nodes = Array.prototype.slice.call(nodes);
+ nodes.reverse();
+ var checkedLayout = false;
+ Array.prototype.forEach.call(nodes, function(node) {
+ test(function(t) {
+ var container = node.parentNode.className == 'container' ? node.parentNode : node;
+ var prefix = "\n" + container.outerHTML + "\n";
+ var passed = false;
+ try {
+ checkedLayout |= checkExpectedValues(t, node.parentNode, prefix);
+ checkedLayout |= checkSubtreeExpectedValues(t, node, prefix);
+ passed = true;
+ } finally {
+ checkedLayout |= !passed;
+ }
+ }, selectorList + ' ' + String(++testNumber));
+ });
+ if (!checkedLayout) {
+ console.error("No valid data-* attributes found in selector list : " + selectorList);
+ }
+ done();
+};
+
+})();
diff --git a/bower_components/custom-elements/tests/chromium/resources/check-layout.js b/bower_components/custom-elements/tests/chromium/resources/check-layout.js
new file mode 100644
index 0000000..3c701c9
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/check-layout.js
@@ -0,0 +1,251 @@
+if (window.testRunner)
+ testRunner.dumpAsText();
+
+(function() {
+
+function insertAfter(nodeToAdd, referenceNode)
+{
+ if (referenceNode == document.body) {
+ document.body.appendChild(nodeToAdd);
+ return;
+ }
+
+ if (referenceNode.nextSibling)
+ referenceNode.parentNode.insertBefore(nodeToAdd, referenceNode.nextSibling);
+ else
+ referenceNode.parentNode.appendChild(nodeToAdd);
+}
+
+function positionedAncestor(node)
+{
+ var ancestor = node.parentNode;
+ while (getComputedStyle(ancestor).position == 'static')
+ ancestor = ancestor.parentNode;
+ return ancestor;
+}
+
+function checkSubtreeExpectedValues(parent, failures)
+{
+ var checkedLayout = checkExpectedValues(parent, failures);
+ Array.prototype.forEach.call(parent.childNodes, function(node) {
+ checkedLayout |= checkSubtreeExpectedValues(node, failures);
+ });
+ return checkedLayout;
+}
+
+function checkAttribute(output, node, attribute)
+{
+ var result = node.getAttribute && node.getAttribute(attribute);
+ output.checked |= !!result;
+ return result;
+}
+
+function checkExpectedValues(node, failures)
+{
+ var output = { checked: false };
+ var expectedWidth = checkAttribute(output, node, "data-expected-width");
+ if (expectedWidth) {
+ if (isNaN(expectedWidth) || Math.abs(node.offsetWidth - expectedWidth) >= 1)
+ failures.push("Expected " + expectedWidth + " for width, but got " + node.offsetWidth + ". ");
+ }
+
+ var expectedHeight = checkAttribute(output, node, "data-expected-height");
+ if (expectedHeight) {
+ if (isNaN(expectedHeight) || Math.abs(node.offsetHeight - expectedHeight) >= 1)
+ failures.push("Expected " + expectedHeight + " for height, but got " + node.offsetHeight + ". ");
+ }
+
+ var expectedOffset = checkAttribute(output, node, "data-offset-x");
+ if (expectedOffset) {
+ if (isNaN(expectedOffset) || Math.abs(node.offsetLeft - expectedOffset) >= 1)
+ failures.push("Expected " + expectedOffset + " for offsetLeft, but got " + node.offsetLeft + ". ");
+ }
+
+ var expectedOffset = checkAttribute(output, node, "data-offset-y");
+ if (expectedOffset) {
+ if (isNaN(expectedOffset) || Math.abs(node.offsetTop - expectedOffset) >= 1)
+ failures.push("Expected " + expectedOffset + " for offsetTop, but got " + node.offsetTop + ". ");
+ }
+
+ var expectedOffset = checkAttribute(output, node, "data-positioned-offset-x");
+ if (expectedOffset) {
+ var actualOffset = node.getBoundingClientRect().left - positionedAncestor(node).getBoundingClientRect().left;
+ if (isNaN(expectedOffset) || Math.abs(actualOffset - expectedOffset) >= 1)
+ failures.push("Expected " + expectedOffset + " for getBoundingClientRect().left offset, but got " + actualOffset + ". ");
+ }
+
+ var expectedOffset = checkAttribute(output, node, "data-positioned-offset-y");
+ if (expectedOffset) {
+ var actualOffset = node.getBoundingClientRect().top - positionedAncestor(node).getBoundingClientRect().top;
+ if (isNaN(expectedOffset) || Math.abs(actualOffset - expectedOffset) >= 1)
+ failures.push("Expected " + expectedOffset + " for getBoundingClientRect().top offset, but got " + actualOffset + ". ");
+ }
+
+ var expectedWidth = checkAttribute(output, node, "data-expected-client-width");
+ if (expectedWidth) {
+ if (isNaN(expectedWidth) || Math.abs(node.clientWidth - expectedWidth) >= 1)
+ failures.push("Expected " + expectedWidth + " for clientWidth, but got " + node.clientWidth + ". ");
+ }
+
+ var expectedHeight = checkAttribute(output, node, "data-expected-client-height");
+ if (expectedHeight) {
+ if (isNaN(expectedHeight) || Math.abs(node.clientHeight - expectedHeight) >= 1)
+ failures.push("Expected " + expectedHeight + " for clientHeight, but got " + node.clientHeight + ". ");
+ }
+
+ var expectedWidth = checkAttribute(output, node, "data-expected-scroll-width");
+ if (expectedWidth) {
+ if (isNaN(expectedWidth) || Math.abs(node.scrollWidth - expectedWidth) >= 1)
+ failures.push("Expected " + expectedWidth + " for scrollWidth, but got " + node.scrollWidth + ". ");
+ }
+
+ var expectedHeight = checkAttribute(output, node, "data-expected-scroll-height");
+ if (expectedHeight) {
+ if (isNaN(expectedHeight) || Math.abs(node.scrollHeight - expectedHeight) >= 1)
+ failures.push("Expected " + expectedHeight + " for scrollHeight, but got " + node.scrollHeight + ". ");
+ }
+
+ var expectedOffset = checkAttribute(output, node, "data-total-x");
+ if (expectedOffset) {
+ var totalLeft = node.clientLeft + node.offsetLeft;
+ if (isNaN(expectedOffset) || Math.abs(totalLeft - expectedOffset) >= 1)
+ failures.push("Expected " + expectedOffset + " for clientLeft+offsetLeft, but got " + totalLeft + ", clientLeft: " + node.clientLeft + ", offsetLeft: " + node.offsetLeft + ". ");
+ }
+
+ var expectedOffset = checkAttribute(output, node, "data-total-y");
+ if (expectedOffset) {
+ var totalTop = node.clientTop + node.offsetTop;
+ if (isNaN(expectedOffset) || Math.abs(totalTop - expectedOffset) >= 1)
+ failures.push("Expected " + expectedOffset + " for clientTop+offsetTop, but got " + totalTop + ", clientTop: " + node.clientTop + ", + offsetTop: " + node.offsetTop + ". ");
+ }
+
+ var expectedDisplay = checkAttribute(output, node, "data-expected-display");
+ if (expectedDisplay) {
+ var actualDisplay = getComputedStyle(node).display;
+ if (actualDisplay != expectedDisplay)
+ failures.push("Expected " + expectedDisplay + " for display, but got " + actualDisplay + ". ");
+ }
+
+ var expectedPaddingTop = checkAttribute(output, node, "data-expected-padding-top");
+ if (expectedPaddingTop) {
+ var actualPaddingTop = getComputedStyle(node).paddingTop;
+ // Trim the unit "px" from the output.
+ actualPaddingTop = actualPaddingTop.substring(0, actualPaddingTop.length - 2);
+ if (actualPaddingTop != expectedPaddingTop)
+ failures.push("Expected " + expectedPaddingTop + " for padding-top, but got " + actualPaddingTop + ". ");
+ }
+
+ var expectedPaddingBottom = checkAttribute(output, node, "data-expected-padding-bottom");
+ if (expectedPaddingBottom) {
+ var actualPaddingBottom = getComputedStyle(node).paddingBottom;
+ // Trim the unit "px" from the output.
+ actualPaddingBottom = actualPaddingBottom.substring(0, actualPaddingBottom.length - 2);
+ if (actualPaddingBottom != expectedPaddingBottom)
+ failures.push("Expected " + expectedPaddingBottom + " for padding-bottom, but got " + actualPaddingBottom + ". ");
+ }
+
+ var expectedPaddingLeft = checkAttribute(output, node, "data-expected-padding-left");
+ if (expectedPaddingLeft) {
+ var actualPaddingLeft = getComputedStyle(node).paddingLeft;
+ // Trim the unit "px" from the output.
+ actualPaddingLeft = actualPaddingLeft.substring(0, actualPaddingLeft.length - 2);
+ if (actualPaddingLeft != expectedPaddingLeft)
+ failures.push("Expected " + expectedPaddingLeft + " for padding-left, but got " + actualPaddingLeft + ". ");
+ }
+
+ var expectedPaddingRight = checkAttribute(output, node, "data-expected-padding-right");
+ if (expectedPaddingRight) {
+ var actualPaddingRight = getComputedStyle(node).paddingRight;
+ // Trim the unit "px" from the output.
+ actualPaddingRight = actualPaddingRight.substring(0, actualPaddingRight.length - 2);
+ if (actualPaddingRight != expectedPaddingRight)
+ failures.push("Expected " + expectedPaddingRight + " for padding-right, but got " + actualPaddingRight + ". ");
+ }
+
+ var expectedMarginTop = checkAttribute(output, node, "data-expected-margin-top");
+ if (expectedMarginTop) {
+ var actualMarginTop = getComputedStyle(node).marginTop;
+ // Trim the unit "px" from the output.
+ actualMarginTop = actualMarginTop.substring(0, actualMarginTop.length - 2);
+ if (actualMarginTop != expectedMarginTop)
+ failures.push("Expected " + expectedMarginTop + " for margin-top, but got " + actualMarginTop + ". ");
+ }
+
+ var expectedMarginBottom = checkAttribute(output, node, "data-expected-margin-bottom");
+ if (expectedMarginBottom) {
+ var actualMarginBottom = getComputedStyle(node).marginBottom;
+ // Trim the unit "px" from the output.
+ actualMarginBottom = actualMarginBottom.substring(0, actualMarginBottom.length - 2);
+ if (actualMarginBottom != expectedMarginBottom)
+ failures.push("Expected " + expectedMarginBottom + " for margin-bottom, but got " + actualMarginBottom + ". ");
+ }
+
+ var expectedMarginLeft = checkAttribute(output, node, "data-expected-margin-left");
+ if (expectedMarginLeft) {
+ var actualMarginLeft = getComputedStyle(node).marginLeft;
+ // Trim the unit "px" from the output.
+ actualMarginLeft = actualMarginLeft.substring(0, actualMarginLeft.length - 2);
+ if (actualMarginLeft != expectedMarginLeft)
+ failures.push("Expected " + expectedMarginLeft + " for margin-left, but got " + actualMarginLeft + ". ");
+ }
+
+ var expectedMarginRight = checkAttribute(output, node, "data-expected-margin-right");
+ if (expectedMarginRight) {
+ var actualMarginRight = getComputedStyle(node).marginRight;
+ // Trim the unit "px" from the output.
+ actualMarginRight = actualMarginRight.substring(0, actualMarginRight.length - 2);
+ if (actualMarginRight != expectedMarginRight)
+ failures.push("Expected " + expectedMarginRight + " for margin-right, but got " + actualMarginRight + ". ");
+ }
+
+ return output.checked;
+}
+
+window.checkLayout = function(selectorList, outputContainer)
+{
+ var result = true;
+ if (!selectorList) {
+ console.error("You must provide a CSS selector of nodes to check.");
+ return;
+ }
+ var nodes = document.querySelectorAll(selectorList);
+ nodes = Array.prototype.slice.call(nodes);
+ nodes.reverse();
+ var checkedLayout = false;
+ Array.prototype.forEach.call(nodes, function(node) {
+ var failures = [];
+ checkedLayout |= checkExpectedValues(node.parentNode, failures);
+ checkedLayout |= checkSubtreeExpectedValues(node, failures);
+
+ var container = node.parentNode.className == 'container' ? node.parentNode : node;
+
+ var pre = document.createElement('pre');
+ if (failures.length) {
+ pre.className = 'FAIL';
+ result = false;
+ }
+ pre.appendChild(document.createTextNode(failures.length ? "FAIL:\n" + failures.join('\n') + '\n\n' + container.outerHTML : "PASS"));
+
+ var referenceNode = container;
+ if (outputContainer) {
+ if (!outputContainer.lastChild) {
+ // Inserting a text node so we have something to insertAfter.
+ outputContainer.textContent = " ";
+ }
+ referenceNode = outputContainer.lastChild;
+ }
+ insertAfter(pre, referenceNode);
+ });
+
+ if (!checkedLayout) {
+ document.body.innerHTML = "FAIL: No valid data-* attributes found in selector list : " + selectorList;
+ return false;
+ }
+
+ var pre = document.querySelector('.FAIL');
+ if (pre)
+ setTimeout(function() { pre.previousSibling.scrollIntoView(); }, 0);
+ return result;
+}
+
+})();
diff --git a/bower_components/custom-elements/tests/chromium/resources/dump-as-markup.js b/bower_components/custom-elements/tests/chromium/resources/dump-as-markup.js
new file mode 100644
index 0000000..ee22396
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/dump-as-markup.js
@@ -0,0 +1,366 @@
+/**
+ * There are three basic use cases of dumpAsMarkup
+ *
+ * 1. Dump the entire DOM when the page is loaded
+ * When this script is included but no method of Markup is called,
+ * it dumps the DOM of each frame loaded.
+ *
+ * 2. Dump the content of a specific element when the page is loaded
+ * When Markup.setNodeToDump is called with some element or the id of some element,
+ * it dumps the content of the specified element as supposed to the entire DOM tree.
+ *
+ * 3. Dump the content of a specific element multiple times while the page is loading
+ * Calling Markup.dump would dump the content of the element set by setNodeToDump or the entire DOM.
+ * Optionally specify the node to dump and the description for each call of dump.
+ */
+
+if (window.testRunner)
+ testRunner.dumpAsText();
+
+// Namespace
+// FIXME: Rename dump-as-markup.js to dump-dom.js and Markup to DOM.
+var Markup = {};
+
+// The description of what this test is testing. Gets prepended to the dumped markup.
+Markup.description = function(description)
+{
+ Markup._test_description = description;
+}
+
+// Dumps the markup for the given node (HTML element if no node is given).
+// Over-writes the body's content with the markup in layout test mode. Appends
+// a pre element when loaded manually, in order to aid debugging.
+Markup.dump = function(opt_node, opt_description)
+{
+ if (typeof opt_node == 'string')
+ opt_node = document.getElementById(opt_node);
+
+ var node = opt_node || document
+ var markup = "";
+
+ Markup._dumpCalls++;
+
+ if (Markup._dumpCalls > 1 || opt_description) {
+ if (!opt_description)
+ opt_description = "Dump of markup " + Markup._dumpCalls
+ if (Markup._dumpCalls > 1)
+ markup += '\n';
+ markup += '\n' + opt_description + ':\n';
+ } else
+ Markup._firstCallDidNotHaveDescription = true;
+
+ markup += Markup.get(node);
+
+ if (!Markup._container) {
+ Markup._container = document.createElement('pre');
+ Markup._container.style.width = '100%';
+ }
+
+ if (Markup._dumpCalls == 2 && Markup._firstCallDidNotHaveDescription) {
+ var wrapper = Markup._container.getElementsByClassName('dump-as-markup-span')[0];
+ wrapper.insertBefore(document.createTextNode('\nDump of markup 1:\n'), wrapper.firstChild);
+ }
+
+ // FIXME: Have this respect testRunner.dumpChildFramesAsText?
+ // FIXME: Should we care about framesets?
+ // DocumentFragment doesn't have a getElementsByTagName method.
+ if (node.getElementsByTagName) {
+ var iframes = node.getElementsByTagName('iframe');
+ for (var i = 0; i < iframes.length; i++) {
+ markup += '\n\nFRAME ' + i + ':\n'
+ try {
+ markup += Markup.get(iframes[i].contentDocument.body.parentElement);
+ } catch (e) {
+ markup += 'FIXME: Add method to layout test controller to get access to cross-origin frames.';
+ }
+ }
+ }
+
+ if (Markup._test_description && Markup._dumpCalls == 1)
+ Markup._container.appendChild(document.createTextNode(Markup._test_description + '\n'))
+
+ var wrapper = document.createElement('span');
+ wrapper.className = 'dump-as-markup-span';
+ wrapper.appendChild(document.createTextNode(markup));
+ Markup._container.appendChild(wrapper);
+}
+
+Markup.noAutoDump = function()
+{
+ window.removeEventListener('load', Markup.notifyDone, false);
+}
+
+Markup.waitUntilDone = function()
+{
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+ Markup.noAutoDump();
+}
+
+Markup.notifyDone = function()
+{
+ // Need to waitUntilDone or some tests won't finish appending the markup before the text is dumped.
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ // If dump has already been called, don't bother to dump again
+ if (!Markup._dumpCalls)
+ Markup.dump();
+
+ // In non-layout test mode, append the results in a pre so that we don't
+ // clobber the test itself. But when in layout test mode, we don't want
+ // side effects from the test to be included in the results.
+ if (window.testRunner)
+ document.body.innerHTML = '';
+
+ document.body.appendChild(Markup._container);
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+
+Markup.useHTML5libOutputFormat = function()
+{
+ Markup._useHTML5libOutputFormat = true;
+}
+
+Markup.get = function(node)
+{
+ var shadowRootList = {};
+ var markup = Markup._getShadowHostIfPossible(node, 0, shadowRootList);
+ if (markup)
+ return markup.substring(1);
+
+ if (!node.firstChild)
+ return '| ';
+
+ // Don't print any markup for the root node.
+ for (var i = 0, len = node.childNodes.length; i < len; i++)
+ markup += Markup._get(node.childNodes[i], 0, shadowRootList);
+ return markup.substring(1);
+}
+
+// Returns the markup for the given node. To be used for cases where a test needs
+// to get the markup but not clobber the whole page.
+Markup._get = function(node, depth, shadowRootList)
+{
+ var str = Markup._indent(depth);
+
+ switch (node.nodeType) {
+ case Node.DOCUMENT_TYPE_NODE:
+ str += '';
+ break;
+
+ case Node.COMMENT_NODE:
+ try {
+ str += '';
+ } catch (e) {
+ str += '';
+ }
+ break;
+
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ str += '' + node.nodeName + node.nodeValue + '>';
+ break;
+
+ case Node.CDATA_SECTION_NODE:
+ str += '';
+ break;
+
+ case Node.TEXT_NODE:
+ str += '"' + Markup._getMarkupForTextNode(node) + '"';
+ break;
+
+ case Node.ELEMENT_NODE:
+ str += "<";
+ str += Markup._namespace(node)
+
+ if (node.localName && node.namespaceURI && node.namespaceURI != null)
+ str += node.localName;
+ else
+ str += Markup._toAsciiLowerCase(node.nodeName);
+
+ str += '>';
+
+ if (node.attributes) {
+ var attrNames = [];
+ var attrPos = {};
+ for (var j = 0; j < node.attributes.length; j += 1) {
+ var name = Markup._namespace(node.attributes[j])
+ name += node.attributes[j].localName || node.attributes[j].nodeName;
+ attrNames.push(name);
+ attrPos[name] = j;
+ }
+ if (attrNames.length > 0) {
+ attrNames.sort();
+ for (var j = 0; j < attrNames.length; j += 1) {
+ str += Markup._indent(depth + 1) + attrNames[j];
+ str += '="' + node.attributes[attrPos[attrNames[j]]].value + '"';
+ }
+ }
+ }
+
+ if (!Markup._useHTML5libOutputFormat && window.internals) {
+ var pseudoId = window.internals.shadowPseudoId(node);
+ if (pseudoId)
+ str += Markup._indent(depth + 1) + 'shadow:pseudoId="' + pseudoId + '"';
+ }
+
+ if (!Markup._useHTML5libOutputFormat)
+ if (node.nodeName == "INPUT" || node.nodeName == "TEXTAREA")
+ str += Markup._indent(depth + 1) + 'this.value="' + node.value + '"';
+
+ break;
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ if (shadowRootList && internals.address(node) in shadowRootList)
+ str += "";
+ else
+ str += "content";
+ }
+
+ if (node.namespaceURI = 'http://www.w3.org/1999/xhtml' && node.tagName == 'TEMPLATE')
+ str += Markup._get(node.content, depth + 1, shadowRootList);
+
+ for (var i = 0, len = node.childNodes.length; i < len; i++) {
+ var selection = Markup._getSelectionMarker(node, i);
+ if (selection)
+ str += Markup._indent(depth + 1) + selection;
+
+ str += Markup._get(node.childNodes[i], depth + 1, shadowRootList);
+ }
+
+ str += Markup._getShadowHostIfPossible(node, depth, shadowRootList);
+
+ var selection = Markup._getSelectionMarker(node, i);
+ if (selection)
+ str += Markup._indent(depth + 1) + selection;
+
+ return str;
+}
+
+Markup._getShadowHostIfPossible = function (node, depth, shadowRootList)
+{
+ if (!Markup._useHTML5libOutputFormat && node.nodeType == Node.ELEMENT_NODE && window.internals) {
+ var root = window.internals.shadowRoot(node);
+ if (root) {
+ shadowRootList[internals.address(root)] = true;
+ return Markup._get(root, depth + 1, shadowRootList);
+ }
+ }
+ return '';
+}
+
+Markup._namespace = function(node)
+{
+ if (Markup._NAMESPACE_URI_MAP[node.namespaceURI])
+ return Markup._NAMESPACE_URI_MAP[node.namespaceURI] + ' ';
+ return '';
+}
+
+Markup._dumpCalls = 0
+
+Markup._indent = function(depth)
+{
+ return "\n| " + new Array(depth * 2 + 1).join(' ');
+}
+
+Markup._toAsciiLowerCase = function (str) {
+ var output = "";
+ for (var i = 0, len = this.length; i < len; ++i) {
+ if (str.charCodeAt(i) >= 0x41 && str.charCodeAt(i) <= 0x5A)
+ output += String.fromCharCode(str.charCodeAt(i) + 0x20)
+ else
+ output += str.charAt(i);
+ }
+ return output;
+}
+
+Markup._NAMESPACE_URI_MAP = {
+ "http://www.w3.org/2000/svg": "svg",
+ "http://www.w3.org/1998/Math/MathML": "math",
+ "http://www.w3.org/XML/1998/namespace": "xml",
+ "http://www.w3.org/2000/xmlns/": "xmlns",
+ "http://www.w3.org/1999/xlink": "xlink"
+}
+
+Markup._getSelectionFromNode = function(node)
+{
+ return node.ownerDocument.defaultView ? node.ownerDocument.defaultView.getSelection() : null;
+}
+
+Markup._SELECTION_FOCUS = '<#selection-focus>';
+Markup._SELECTION_ANCHOR = '<#selection-anchor>';
+Markup._SELECTION_CARET = '<#selection-caret>';
+
+Markup._getMarkupForTextNode = function(node)
+{
+ innerMarkup = node.nodeValue;
+ var startOffset, endOffset, startText, endText;
+
+ var sel = Markup._getSelectionFromNode(node);
+ // Firefox doesn't have a sel in a display:none iframe.
+ // https://bugs.webkit.org/show_bug.cgi?id=43655
+ if (sel) {
+ if (node == sel.anchorNode && node == sel.focusNode) {
+ if (sel.isCollapsed) {
+ startOffset = sel.anchorOffset;
+ startText = Markup._SELECTION_CARET;
+ } else {
+ if (sel.focusOffset > sel.anchorOffset) {
+ startOffset = sel.anchorOffset;
+ endOffset = sel.focusOffset;
+ startText = Markup._SELECTION_ANCHOR;
+ endText = Markup._SELECTION_FOCUS;
+ } else {
+ startOffset = sel.focusOffset;
+ endOffset = sel.anchorOffset;
+ startText = Markup._SELECTION_FOCUS;
+ endText = Markup._SELECTION_ANCHOR;
+ }
+ }
+ } else if (node == sel.focusNode) {
+ startOffset = sel.focusOffset;
+ startText = Markup._SELECTION_FOCUS;
+ } else if (node == sel.anchorNode) {
+ startOffset = sel.anchorOffset;
+ startText = Markup._SELECTION_ANCHOR;
+ }
+ }
+
+ if (startText && endText)
+ innerMarkup = innerMarkup.substring(0, startOffset) + startText + innerMarkup.substring(startOffset, endOffset) + endText + innerMarkup.substring(endOffset);
+ else if (startText)
+ innerMarkup = innerMarkup.substring(0, startOffset) + startText + innerMarkup.substring(startOffset);
+
+ return innerMarkup;
+}
+
+Markup._getSelectionMarker = function(node, index)
+{
+ if (node.nodeType != 1)
+ return '';
+
+ var sel = Markup._getSelectionFromNode(node);;
+
+ // Firefox doesn't have a sel in a display:none iframe.
+ // https://bugs.webkit.org/show_bug.cgi?id=43655
+ if (!sel)
+ return '';
+
+ if (index == sel.anchorOffset && node == sel.anchorNode) {
+ if (sel.isCollapsed)
+ return Markup._SELECTION_CARET;
+ else
+ return Markup._SELECTION_ANCHOR;
+ } else if (index == sel.focusOffset && node == sel.focusNode)
+ return Markup._SELECTION_FOCUS;
+
+ return '';
+}
+
+window.addEventListener('load', Markup.notifyDone, false);
diff --git a/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/LICENSE b/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/LICENSE
new file mode 100644
index 0000000..a43e73d
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/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 2014 Christian Robertson
+
+ 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/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/README b/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/README
new file mode 100644
index 0000000..dd5f8cb
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/README
@@ -0,0 +1,7 @@
+Roboto
+Christian Robertson
+Apache License, version 2.0
+http://www.google.com/fonts/specimen/Roboto
+
+test.ttf is a subset of Roboto Light that has only glyphs for the string "tes ".
+test-fixed is the same font, with isFixedPitch set to 1.
diff --git a/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/test-fixed.ttf b/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/test-fixed.ttf
new file mode 100644
index 0000000..6657d4b
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/test-fixed.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/test.ttf b/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/test.ttf
new file mode 100644
index 0000000..294421d
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/fixed-pitch-font/test.ttf differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/gc.js b/bower_components/custom-elements/tests/chromium/resources/gc.js
new file mode 100644
index 0000000..95a005f
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/gc.js
@@ -0,0 +1,20 @@
+// If there is no window.gc() already defined, define one using the best
+// method we can find.
+// The slow fallback should not hit in the actual test environment.
+if (!window.gc)
+{
+ window.gc = function()
+ {
+ if (window.GCController)
+ return GCController.collectAll();
+ function gcRec(n) {
+ if (n < 1)
+ return {};
+ var temp = {i: "ab" + i + (i / 100000)};
+ temp += "foo";
+ gcRec(n-1);
+ }
+ for (var i = 0; i < 10000; i++)
+ gcRec(10);
+ }
+}
diff --git a/bower_components/custom-elements/tests/chromium/resources/idlharness.js b/bower_components/custom-elements/tests/chromium/resources/idlharness.js
new file mode 100644
index 0000000..5002ec5
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/idlharness.js
@@ -0,0 +1,1850 @@
+/*
+Distributed under both the W3C Test Suite License [1] and the W3C
+3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
+policies and contribution forms [3].
+
+[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
+[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
+[3] http://www.w3.org/2004/10/27-testcases
+*/
+
+/* For user documentation see docs/idlharness.md */
+
+/**
+ * Notes for people who want to edit this file (not just use it as a library):
+ *
+ * Most of the interesting stuff happens in the derived classes of IdlObject,
+ * especially IdlInterface. The entry point for all IdlObjects is .test(),
+ * which is called by IdlArray.test(). An IdlObject is conceptually just
+ * "thing we want to run tests on", and an IdlArray is an array of IdlObjects
+ * with some additional data thrown in.
+ *
+ * The object model is based on what WebIDLParser.js produces, which is in turn
+ * based on its pegjs grammar. If you want to figure out what properties an
+ * object will have from WebIDLParser.js, the best way is to look at the
+ * grammar:
+ *
+ * https://github.com/darobin/webidl.js/blob/master/lib/grammar.peg
+ *
+ * So for instance:
+ *
+ * // interface definition
+ * interface
+ * = extAttrs:extendedAttributeList? S? "interface" S name:identifier w herit:ifInheritance? w "{" w mem:ifMember* w "}" w ";" w
+ * { return { type: "interface", name: name, inheritance: herit, members: mem, extAttrs: extAttrs }; }
+ *
+ * This means that an "interface" object will have a .type property equal to
+ * the string "interface", a .name property equal to the identifier that the
+ * parser found, an .inheritance property equal to either null or the result of
+ * the "ifInheritance" production found elsewhere in the grammar, and so on.
+ * After each grammatical production is a JavaScript function in curly braces
+ * that gets called with suitable arguments and returns some JavaScript value.
+ *
+ * (Note that the version of WebIDLParser.js we use might sometimes be
+ * out-of-date or forked.)
+ *
+ * The members and methods of the classes defined by this file are all at least
+ * briefly documented, hopefully.
+ */
+(function(){
+"use strict";
+/// Helpers ///
+function constValue (cnt) {
+ if (cnt.type === "null") return null;
+ if (cnt.type === "NaN") return NaN;
+ if (cnt.type === "Infinity") return cnt.negative ? -Infinity : Infinity;
+ return cnt.value;
+}
+
+function minOverloadLength(overloads) {
+ if (!overloads.length) {
+ return 0;
+ }
+
+ return overloads.map(function(attr) {
+ return attr.arguments ? attr.arguments.filter(function(arg) {
+ return !arg.optional && !arg.variadic;
+ }).length : 0;
+ })
+ .reduce(function(m, n) { return Math.min(m, n); });
+}
+
+function throwOrReject(a_test, operation, fn, obj, args, message, cb) {
+ if (operation.idlType.generic !== "Promise") {
+ assert_throws(new TypeError(), function() {
+ fn.apply(obj, args);
+ }, message);
+ cb();
+ } else {
+ try {
+ promise_rejects(a_test, new TypeError(), fn.apply(obj, args)).then(cb, cb);
+ } catch (e){
+ a_test.step(function() {
+ assert_unreached("Throws \"" + e + "\" instead of rejecting promise");
+ cb();
+ });
+ }
+ }
+}
+
+function awaitNCallbacks(n, cb, ctx) {
+ var counter = 0;
+ return function() {
+ counter++;
+ if (counter >= n) {
+ cb();
+ }
+ };
+}
+
+var fround = (function(){
+ if (Math.fround) return Math.fround;
+
+ var arr = new Float32Array(1);
+ return function fround(n) {
+ arr[0] = n;
+ return arr[0];
+ };
+})();
+
+/// IdlArray ///
+// Entry point
+self.IdlArray = function()
+//@{
+{
+ /**
+ * A map from strings to the corresponding named IdlObject, such as
+ * IdlInterface or IdlException. These are the things that test() will run
+ * tests on.
+ */
+ this.members = {};
+
+ /**
+ * A map from strings to arrays of strings. The keys are interface or
+ * exception names, and are expected to also exist as keys in this.members
+ * (otherwise they'll be ignored). This is populated by add_objects() --
+ * see documentation at the start of the file. The actual tests will be
+ * run by calling this.members[name].test_object(obj) for each obj in
+ * this.objects[name]. obj is a string that will be eval'd to produce a
+ * JavaScript value, which is supposed to be an object implementing the
+ * given IdlObject (interface, exception, etc.).
+ */
+ this.objects = {};
+
+ /**
+ * When adding multiple collections of IDLs one at a time, an earlier one
+ * might contain a partial interface or implements statement that depends
+ * on a later one. Save these up and handle them right before we run
+ * tests.
+ *
+ * .partials is simply an array of objects from WebIDLParser.js'
+ * "partialinterface" production. .implements maps strings to arrays of
+ * strings, such that
+ *
+ * A implements B;
+ * A implements C;
+ * D implements E;
+ *
+ * results in { A: ["B", "C"], D: ["E"] }.
+ */
+ this.partials = [];
+ this["implements"] = {};
+};
+
+//@}
+IdlArray.prototype.add_idls = function(raw_idls)
+//@{
+{
+ /** Entry point. See documentation at beginning of file. */
+ this.internal_add_idls(WebIDL2.parse(raw_idls));
+};
+
+//@}
+IdlArray.prototype.add_untested_idls = function(raw_idls)
+//@{
+{
+ /** Entry point. See documentation at beginning of file. */
+ var parsed_idls = WebIDL2.parse(raw_idls);
+ for (var i = 0; i < parsed_idls.length; i++)
+ {
+ parsed_idls[i].untested = true;
+ if ("members" in parsed_idls[i])
+ {
+ for (var j = 0; j < parsed_idls[i].members.length; j++)
+ {
+ parsed_idls[i].members[j].untested = true;
+ }
+ }
+ }
+ this.internal_add_idls(parsed_idls);
+};
+
+//@}
+IdlArray.prototype.internal_add_idls = function(parsed_idls)
+//@{
+{
+ /**
+ * Internal helper called by add_idls() and add_untested_idls().
+ * parsed_idls is an array of objects that come from WebIDLParser.js's
+ * "definitions" production. The add_untested_idls() entry point
+ * additionally sets an .untested property on each object (and its
+ * .members) so that they'll be skipped by test() -- they'll only be
+ * used for base interfaces of tested interfaces, return types, etc.
+ */
+ parsed_idls.forEach(function(parsed_idl)
+ {
+ if (parsed_idl.type == "interface" && parsed_idl.partial)
+ {
+ this.partials.push(parsed_idl);
+ return;
+ }
+
+ if (parsed_idl.type == "implements")
+ {
+ if (!(parsed_idl.target in this["implements"]))
+ {
+ this["implements"][parsed_idl.target] = [];
+ }
+ this["implements"][parsed_idl.target].push(parsed_idl["implements"]);
+ return;
+ }
+
+ parsed_idl.array = this;
+ if (parsed_idl.name in this.members)
+ {
+ throw "Duplicate identifier " + parsed_idl.name;
+ }
+ switch(parsed_idl.type)
+ {
+ case "interface":
+ this.members[parsed_idl.name] =
+ new IdlInterface(parsed_idl, /* is_callback = */ false);
+ break;
+
+ case "dictionary":
+ // Nothing to test, but we need the dictionary info around for type
+ // checks
+ this.members[parsed_idl.name] = new IdlDictionary(parsed_idl);
+ break;
+
+ case "typedef":
+ this.members[parsed_idl.name] = new IdlTypedef(parsed_idl);
+ break;
+
+ case "callback":
+ // TODO
+ console.log("callback not yet supported");
+ break;
+
+ case "enum":
+ this.members[parsed_idl.name] = new IdlEnum(parsed_idl);
+ break;
+
+ case "callback interface":
+ this.members[parsed_idl.name] =
+ new IdlInterface(parsed_idl, /* is_callback = */ true);
+ break;
+
+ default:
+ throw parsed_idl.name + ": " + parsed_idl.type + " not yet supported";
+ }
+ }.bind(this));
+};
+
+//@}
+IdlArray.prototype.add_objects = function(dict)
+//@{
+{
+ /** Entry point. See documentation at beginning of file. */
+ for (var k in dict)
+ {
+ if (k in this.objects)
+ {
+ this.objects[k] = this.objects[k].concat(dict[k]);
+ }
+ else
+ {
+ this.objects[k] = dict[k];
+ }
+ }
+};
+
+//@}
+IdlArray.prototype.prevent_multiple_testing = function(name)
+//@{
+{
+ /** Entry point. See documentation at beginning of file. */
+ this.members[name].prevent_multiple_testing = true;
+};
+
+//@}
+IdlArray.prototype.recursively_get_implements = function(interface_name)
+//@{
+{
+ /**
+ * Helper function for test(). Returns an array of things that implement
+ * interface_name, so if the IDL contains
+ *
+ * A implements B;
+ * B implements C;
+ * B implements D;
+ *
+ * then recursively_get_implements("A") should return ["B", "C", "D"].
+ */
+ var ret = this["implements"][interface_name];
+ if (ret === undefined)
+ {
+ return [];
+ }
+ for (var i = 0; i < this["implements"][interface_name].length; i++)
+ {
+ ret = ret.concat(this.recursively_get_implements(ret[i]));
+ if (ret.indexOf(ret[i]) != ret.lastIndexOf(ret[i]))
+ {
+ throw "Circular implements statements involving " + ret[i];
+ }
+ }
+ return ret;
+};
+
+function exposed_in(globals) {
+ if ('document' in self) {
+ return globals.indexOf("Window") >= 0;
+ }
+ if ('DedicatedWorkerGlobalScope' in self &&
+ self instanceof DedicatedWorkerGlobalScope) {
+ return globals.indexOf("Worker") >= 0 ||
+ globals.indexOf("DedicatedWorker") >= 0;
+ }
+ if ('SharedWorkerGlobalScope' in self &&
+ self instanceof SharedWorkerGlobalScope) {
+ return globals.indexOf("Worker") >= 0 ||
+ globals.indexOf("SharedWorker") >= 0;
+ }
+ if ('ServiceWorkerGlobalScope' in self &&
+ self instanceof ServiceWorkerGlobalScope) {
+ return globals.indexOf("Worker") >= 0 ||
+ globals.indexOf("ServiceWorker") >= 0;
+ }
+ throw "Unexpected global object";
+}
+
+//@}
+IdlArray.prototype.test = function()
+//@{
+{
+ /** Entry point. See documentation at beginning of file. */
+
+ // First merge in all the partial interfaces and implements statements we
+ // encountered.
+ this.partials.forEach(function(parsed_idl)
+ {
+ if (!(parsed_idl.name in this.members)
+ || !(this.members[parsed_idl.name] instanceof IdlInterface))
+ {
+ throw "Partial interface " + parsed_idl.name + " with no original interface";
+ }
+ if (parsed_idl.extAttrs)
+ {
+ parsed_idl.extAttrs.forEach(function(extAttr)
+ {
+ this.members[parsed_idl.name].extAttrs.push(extAttr);
+ }.bind(this));
+ }
+ parsed_idl.members.forEach(function(member)
+ {
+ this.members[parsed_idl.name].members.push(new IdlInterfaceMember(member));
+ }.bind(this));
+ }.bind(this));
+ this.partials = [];
+
+ for (var lhs in this["implements"])
+ {
+ this.recursively_get_implements(lhs).forEach(function(rhs)
+ {
+ var errStr = lhs + " implements " + rhs + ", but ";
+ if (!(lhs in this.members)) throw errStr + lhs + " is undefined.";
+ if (!(this.members[lhs] instanceof IdlInterface)) throw errStr + lhs + " is not an interface.";
+ if (!(rhs in this.members)) throw errStr + rhs + " is undefined.";
+ if (!(this.members[rhs] instanceof IdlInterface)) throw errStr + rhs + " is not an interface.";
+ this.members[rhs].members.forEach(function(member)
+ {
+ this.members[lhs].members.push(new IdlInterfaceMember(member));
+ }.bind(this));
+ }.bind(this));
+ }
+ this["implements"] = {};
+
+ Object.getOwnPropertyNames(this.members).forEach(function(memberName) {
+ var member = this.members[memberName];
+ if (!(member instanceof IdlInterface)) {
+ return;
+ }
+
+ var exposed = member.extAttrs.filter(function(a) { return a.name == "Exposed" });
+ if (exposed.length > 1) {
+ throw "Unexpected Exposed extended attributes on " + memberName + ": " + exposed;
+ }
+
+ var globals = exposed.length === 1
+ ? exposed[0].rhs.value
+ : ["Window"];
+ member.exposed = exposed_in(globals);
+ }.bind(this));
+
+ // Now run test() on every member, and test_object() for every object.
+ for (var name in this.members)
+ {
+ this.members[name].test();
+ if (name in this.objects)
+ {
+ this.objects[name].forEach(function(str)
+ {
+ this.members[name].test_object(str);
+ }.bind(this));
+ }
+ }
+};
+
+//@}
+IdlArray.prototype.assert_type_is = function(value, type)
+//@{
+{
+ /**
+ * Helper function that tests that value is an instance of type according
+ * to the rules of WebIDL. value is any JavaScript value, and type is an
+ * object produced by WebIDLParser.js' "type" production. That production
+ * is fairly elaborate due to the complexity of WebIDL's types, so it's
+ * best to look at the grammar to figure out what properties it might have.
+ */
+ if (type.idlType == "any")
+ {
+ // No assertions to make
+ return;
+ }
+
+ if (type.nullable && value === null)
+ {
+ // This is fine
+ return;
+ }
+
+ if (type.array)
+ {
+ // TODO: not supported yet
+ return;
+ }
+
+ if (type.sequence)
+ {
+ assert_true(Array.isArray(value), "is not array");
+ if (!value.length)
+ {
+ // Nothing we can do.
+ return;
+ }
+ this.assert_type_is(value[0], type.idlType.idlType);
+ return;
+ }
+
+ type = type.idlType;
+
+ switch(type)
+ {
+ case "void":
+ assert_equals(value, undefined);
+ return;
+
+ case "boolean":
+ assert_equals(typeof value, "boolean");
+ return;
+
+ case "byte":
+ assert_equals(typeof value, "number");
+ assert_equals(value, Math.floor(value), "not an integer");
+ assert_true(-128 <= value && value <= 127, "byte " + value + " not in range [-128, 127]");
+ return;
+
+ case "octet":
+ assert_equals(typeof value, "number");
+ assert_equals(value, Math.floor(value), "not an integer");
+ assert_true(0 <= value && value <= 255, "octet " + value + " not in range [0, 255]");
+ return;
+
+ case "short":
+ assert_equals(typeof value, "number");
+ assert_equals(value, Math.floor(value), "not an integer");
+ assert_true(-32768 <= value && value <= 32767, "short " + value + " not in range [-32768, 32767]");
+ return;
+
+ case "unsigned short":
+ assert_equals(typeof value, "number");
+ assert_equals(value, Math.floor(value), "not an integer");
+ assert_true(0 <= value && value <= 65535, "unsigned short " + value + " not in range [0, 65535]");
+ return;
+
+ case "long":
+ assert_equals(typeof value, "number");
+ assert_equals(value, Math.floor(value), "not an integer");
+ assert_true(-2147483648 <= value && value <= 2147483647, "long " + value + " not in range [-2147483648, 2147483647]");
+ return;
+
+ case "unsigned long":
+ assert_equals(typeof value, "number");
+ assert_equals(value, Math.floor(value), "not an integer");
+ assert_true(0 <= value && value <= 4294967295, "unsigned long " + value + " not in range [0, 4294967295]");
+ return;
+
+ case "long long":
+ assert_equals(typeof value, "number");
+ return;
+
+ case "unsigned long long":
+ case "DOMTimeStamp":
+ assert_equals(typeof value, "number");
+ assert_true(0 <= value, "unsigned long long is negative");
+ return;
+
+ case "float":
+ assert_equals(typeof value, "number");
+ assert_equals(value, fround(value), "float rounded to 32-bit float should be itself");
+ assert_not_equals(value, Infinity);
+ assert_not_equals(value, -Infinity);
+ assert_not_equals(value, NaN);
+ return;
+
+ case "DOMHighResTimeStamp":
+ case "double":
+ assert_equals(typeof value, "number");
+ assert_not_equals(value, Infinity);
+ assert_not_equals(value, -Infinity);
+ assert_not_equals(value, NaN);
+ return;
+
+ case "unrestricted float":
+ assert_equals(typeof value, "number");
+ assert_equals(value, fround(value), "unrestricted float rounded to 32-bit float should be itself");
+ return;
+
+ case "unrestricted double":
+ assert_equals(typeof value, "number");
+ return;
+
+ case "DOMString":
+ assert_equals(typeof value, "string");
+ return;
+
+ case "ByteString":
+ assert_equals(typeof value, "string");
+ assert_regexp_match(value, /^[\x00-\x7F]*$/);
+ return;
+
+ case "USVString":
+ assert_equals(typeof value, "string");
+ assert_regexp_match(value, /^([\x00-\ud7ff\ue000-\uffff]|[\ud800-\udbff][\udc00-\udfff])*$/);
+ return;
+
+ case "object":
+ assert_true(typeof value == "object" || typeof value == "function", "wrong type: not object or function");
+ return;
+ }
+
+ if (!(type in this.members))
+ {
+ throw "Unrecognized type " + type;
+ }
+
+ if (this.members[type] instanceof IdlInterface)
+ {
+ // We don't want to run the full
+ // IdlInterface.prototype.test_instance_of, because that could result
+ // in an infinite loop. TODO: This means we don't have tests for
+ // NoInterfaceObject interfaces, and we also can't test objects that
+ // come from another self.
+ assert_true(typeof value == "object" || typeof value == "function", "wrong type: not object or function");
+ if (value instanceof Object
+ && !this.members[type].has_extended_attribute("NoInterfaceObject")
+ && type in self)
+ {
+ assert_true(value instanceof self[type], "not instanceof " + type);
+ }
+ }
+ else if (this.members[type] instanceof IdlEnum)
+ {
+ assert_equals(typeof value, "string");
+ }
+ else if (this.members[type] instanceof IdlDictionary)
+ {
+ // TODO: Test when we actually have something to test this on
+ }
+ else if (this.members[type] instanceof IdlTypedef)
+ {
+ // TODO: Test when we actually have something to test this on
+ }
+ else
+ {
+ throw "Type " + type + " isn't an interface or dictionary";
+ }
+};
+//@}
+
+/// IdlObject ///
+function IdlObject() {}
+IdlObject.prototype.test = function()
+//@{
+{
+ /**
+ * By default, this does nothing, so no actual tests are run for IdlObjects
+ * that don't define any (e.g., IdlDictionary at the time of this writing).
+ */
+};
+
+//@}
+IdlObject.prototype.has_extended_attribute = function(name)
+//@{
+{
+ /**
+ * This is only meaningful for things that support extended attributes,
+ * such as interfaces, exceptions, and members.
+ */
+ return this.extAttrs.some(function(o)
+ {
+ return o.name == name;
+ });
+};
+
+//@}
+
+/// IdlDictionary ///
+// Used for IdlArray.prototype.assert_type_is
+function IdlDictionary(obj)
+//@{
+{
+ /**
+ * obj is an object produced by the WebIDLParser.js "dictionary"
+ * production.
+ */
+
+ /** Self-explanatory. */
+ this.name = obj.name;
+
+ /** An array of objects produced by the "dictionaryMember" production. */
+ this.members = obj.members;
+
+ /**
+ * The name (as a string) of the dictionary type we inherit from, or null
+ * if there is none.
+ */
+ this.base = obj.inheritance;
+}
+
+//@}
+IdlDictionary.prototype = Object.create(IdlObject.prototype);
+
+/// IdlInterface ///
+function IdlInterface(obj, is_callback) {
+ /**
+ * obj is an object produced by the WebIDLParser.js "interface" production.
+ */
+
+ /** Self-explanatory. */
+ this.name = obj.name;
+
+ /** A back-reference to our IdlArray. */
+ this.array = obj.array;
+
+ /**
+ * An indicator of whether we should run tests on the interface object and
+ * interface prototype object. Tests on members are controlled by .untested
+ * on each member, not this.
+ */
+ this.untested = obj.untested;
+
+ /** An array of objects produced by the "ExtAttr" production. */
+ this.extAttrs = obj.extAttrs;
+
+ /** An array of IdlInterfaceMembers. */
+ this.members = obj.members.map(function(m){return new IdlInterfaceMember(m); });
+ if (this.has_extended_attribute("Unforgeable")) {
+ this.members
+ .filter(function(m) { return !m["static"] && (m.type == "attribute" || m.type == "operation"); })
+ .forEach(function(m) { return m.isUnforgeable = true; });
+ }
+
+ /**
+ * The name (as a string) of the type we inherit from, or null if there is
+ * none.
+ */
+ this.base = obj.inheritance;
+
+ this._is_callback = is_callback;
+}
+IdlInterface.prototype = Object.create(IdlObject.prototype);
+IdlInterface.prototype.is_callback = function()
+//@{
+{
+ return this._is_callback;
+};
+//@}
+
+IdlInterface.prototype.has_constants = function()
+//@{
+{
+ return this.members.some(function(member) {
+ return member.type === "const";
+ });
+};
+//@}
+
+IdlInterface.prototype.is_global = function()
+//@{
+{
+ return this.extAttrs.some(function(attribute) {
+ return attribute.name === "Global" ||
+ attribute.name === "PrimaryGlobal";
+ });
+};
+//@}
+
+IdlInterface.prototype.test = function()
+//@{
+{
+ if (this.has_extended_attribute("NoInterfaceObject"))
+ {
+ // No tests to do without an instance. TODO: We should still be able
+ // to run tests on the prototype object, if we obtain one through some
+ // other means.
+ return;
+ }
+
+ if (!this.exposed) {
+ test(function() {
+ assert_false(this.name in self);
+ }.bind(this), this.name + " interface: existence and properties of interface object");
+ return;
+ }
+
+ if (!this.untested)
+ {
+ // First test things to do with the exception/interface object and
+ // exception/interface prototype object.
+ this.test_self();
+ }
+ // Then test things to do with its members (constants, fields, attributes,
+ // operations, . . .). These are run even if .untested is true, because
+ // members might themselves be marked as .untested. This might happen to
+ // interfaces if the interface itself is untested but a partial interface
+ // that extends it is tested -- then the interface itself and its initial
+ // members will be marked as untested, but the members added by the partial
+ // interface are still tested.
+ this.test_members();
+};
+//@}
+
+IdlInterface.prototype.test_self = function()
+//@{
+{
+ test(function()
+ {
+ // This function tests WebIDL as of 2015-01-13.
+
+ // "For every interface that is exposed in a given ECMAScript global
+ // environment and:
+ // * is a callback interface that has constants declared on it, or
+ // * is a non-callback interface that is not declared with the
+ // [NoInterfaceObject] extended attribute,
+ // a corresponding property MUST exist on the ECMAScript global object.
+ // The name of the property is the identifier of the interface, and its
+ // value is an object called the interface object.
+ // The property has the attributes { [[Writable]]: true,
+ // [[Enumerable]]: false, [[Configurable]]: true }."
+ if (this.is_callback() && !this.has_constants()) {
+ return;
+ }
+
+ // TODO: Should we test here that the property is actually writable
+ // etc., or trust getOwnPropertyDescriptor?
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+ var desc = Object.getOwnPropertyDescriptor(self, this.name);
+ assert_false("get" in desc, "self's property " + format_value(this.name) + " has getter");
+ assert_false("set" in desc, "self's property " + format_value(this.name) + " has setter");
+ assert_true(desc.writable, "self's property " + format_value(this.name) + " is not writable");
+ assert_false(desc.enumerable, "self's property " + format_value(this.name) + " is enumerable");
+ assert_true(desc.configurable, "self's property " + format_value(this.name) + " is not configurable");
+
+ if (this.is_callback()) {
+ // "The internal [[Prototype]] property of an interface object for
+ // a callback interface MUST be the Object.prototype object."
+ assert_equals(Object.getPrototypeOf(self[this.name]), Object.prototype,
+ "prototype of self's property " + format_value(this.name) + " is not Object.prototype");
+
+ return;
+ }
+
+ // "The interface object for a given non-callback interface is a
+ // function object."
+ // "If an object is defined to be a function object, then it has
+ // characteristics as follows:"
+
+ // Its [[Prototype]] internal property is otherwise specified (see
+ // below).
+
+ // "* Its [[Get]] internal property is set as described in ECMA-262
+ // section 9.1.8."
+ // Not much to test for this.
+
+ // "* Its [[Construct]] internal property is set as described in
+ // ECMA-262 section 19.2.2.3."
+ // Tested below if no constructor is defined. TODO: test constructors
+ // if defined.
+
+ // "* Its @@hasInstance property is set as described in ECMA-262
+ // section 19.2.3.8, unless otherwise specified."
+ // TODO
+
+ // ES6 (rev 30) 19.1.3.6:
+ // "Else, if O has a [[Call]] internal method, then let builtinTag be
+ // "Function"."
+ assert_class_string(self[this.name], "Function", "class string of " + this.name);
+
+ // "The [[Prototype]] internal property of an interface object for a
+ // non-callback interface is determined as follows:"
+ var prototype = Object.getPrototypeOf(self[this.name]);
+ if (this.base) {
+ // "* If the interface inherits from some other interface, the
+ // value of [[Prototype]] is the interface object for that other
+ // interface."
+ var has_interface_object =
+ !this.array
+ .members[this.base]
+ .has_extended_attribute("NoInterfaceObject");
+ if (has_interface_object) {
+ assert_own_property(self, this.base,
+ 'should inherit from ' + this.base +
+ ', but self has no such property');
+ assert_equals(prototype, self[this.base],
+ 'prototype of ' + this.name + ' is not ' +
+ this.base);
+ }
+ } else {
+ // "If the interface doesn't inherit from any other interface, the
+ // value of [[Prototype]] is %FunctionPrototype% ([ECMA-262],
+ // section 6.1.7.4)."
+ assert_equals(prototype, Function.prototype,
+ "prototype of self's property " + format_value(this.name) + " is not Function.prototype");
+ }
+
+ if (!this.has_extended_attribute("Constructor")) {
+ // "The internal [[Call]] method of the interface object behaves as
+ // follows . . .
+ //
+ // "If I was not declared with a [Constructor] extended attribute,
+ // then throw a TypeError."
+ assert_throws(new TypeError(), function() {
+ self[this.name]();
+ }.bind(this), "interface object didn't throw TypeError when called as a function");
+ assert_throws(new TypeError(), function() {
+ new self[this.name]();
+ }.bind(this), "interface object didn't throw TypeError when called as a constructor");
+ }
+ }.bind(this), this.name + " interface: existence and properties of interface object");
+
+ if (!this.is_callback()) {
+ test(function() {
+ // This function tests WebIDL as of 2014-10-25.
+ // https://heycam.github.io/webidl/#es-interface-call
+
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+
+ // "Interface objects for non-callback interfaces MUST have a
+ // property named “length” with attributes { [[Writable]]: false,
+ // [[Enumerable]]: false, [[Configurable]]: true } whose value is
+ // a Number."
+ assert_own_property(self[this.name], "length");
+ var desc = Object.getOwnPropertyDescriptor(self[this.name], "length");
+ assert_false("get" in desc, this.name + ".length has getter");
+ assert_false("set" in desc, this.name + ".length has setter");
+ assert_false(desc.writable, this.name + ".length is writable");
+ assert_false(desc.enumerable, this.name + ".length is enumerable");
+ assert_true(desc.configurable, this.name + ".length is not configurable");
+
+ var constructors = this.extAttrs
+ .filter(function(attr) { return attr.name == "Constructor"; });
+ var expected_length = minOverloadLength(constructors);
+ assert_equals(self[this.name].length, expected_length, "wrong value for " + this.name + ".length");
+ }.bind(this), this.name + " interface object length");
+ }
+
+ if (!this.is_callback() || this.has_constants()) {
+ test(function() {
+ // This function tests WebIDL as of 2015-11-17.
+ // https://heycam.github.io/webidl/#interface-object
+
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+
+ // "All interface objects must have a property named “name” with
+ // attributes { [[Writable]]: false, [[Enumerable]]: false,
+ // [[Configurable]]: true } whose value is the identifier of the
+ // corresponding interface."
+
+ assert_own_property(self[this.name], "name");
+ var desc = Object.getOwnPropertyDescriptor(self[this.name], "name");
+ assert_false("get" in desc, this.name + ".name has getter");
+ assert_false("set" in desc, this.name + ".name has setter");
+ assert_false(desc.writable, this.name + ".name is writable");
+ assert_false(desc.enumerable, this.name + ".name is enumerable");
+ assert_true(desc.configurable, this.name + ".name is not configurable");
+ assert_equals(self[this.name].name, this.name, "wrong value for " + this.name + ".name");
+ }.bind(this), this.name + " interface object name");
+ }
+
+ // TODO: Test named constructors if I find any interfaces that have them.
+
+ test(function()
+ {
+ // This function tests WebIDL as of 2015-01-21.
+ // https://heycam.github.io/webidl/#interface-object
+
+ if (this.is_callback() && !this.has_constants()) {
+ return;
+ }
+
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+
+ if (this.is_callback()) {
+ assert_false("prototype" in self[this.name],
+ this.name + ' should not have a "prototype" property');
+ return;
+ }
+
+ // "An interface object for a non-callback interface must have a
+ // property named “prototype” with attributes { [[Writable]]: false,
+ // [[Enumerable]]: false, [[Configurable]]: false } whose value is an
+ // object called the interface prototype object. This object has
+ // properties that correspond to the regular attributes and regular
+ // operations defined on the interface, and is described in more detail
+ // in section 4.5.4 below."
+ assert_own_property(self[this.name], "prototype",
+ 'interface "' + this.name + '" does not have own property "prototype"');
+ var desc = Object.getOwnPropertyDescriptor(self[this.name], "prototype");
+ assert_false("get" in desc, this.name + ".prototype has getter");
+ assert_false("set" in desc, this.name + ".prototype has setter");
+ assert_false(desc.writable, this.name + ".prototype is writable");
+ assert_false(desc.enumerable, this.name + ".prototype is enumerable");
+ assert_false(desc.configurable, this.name + ".prototype is configurable");
+
+ // Next, test that the [[Prototype]] of the interface prototype object
+ // is correct. (This is made somewhat difficult by the existence of
+ // [NoInterfaceObject].)
+ // TODO: Aryeh thinks there's at least other place in this file where
+ // we try to figure out if an interface prototype object is
+ // correct. Consolidate that code.
+
+ // "The interface prototype object for a given interface A must have an
+ // internal [[Prototype]] property whose value is returned from the
+ // following steps:
+ // "If A is declared with the [Global] or [PrimaryGlobal] extended
+ // attribute, and A supports named properties, then return the named
+ // properties object for A, as defined in section 4.5.5 below.
+ // "Otherwise, if A is declared to inherit from another interface, then
+ // return the interface prototype object for the inherited interface.
+ // "Otherwise, if A is declared with the [ArrayClass] extended
+ // attribute, then return %ArrayPrototype% ([ECMA-262], section
+ // 6.1.7.4).
+ // "Otherwise, return %ObjectPrototype% ([ECMA-262], section 6.1.7.4).
+ // ([ECMA-262], section 15.2.4).
+ if (this.name === "Window") {
+ assert_class_string(Object.getPrototypeOf(self[this.name].prototype),
+ 'WindowProperties',
+ 'Class name for prototype of Window' +
+ '.prototype is not "WindowProperties"');
+ } else {
+ var inherit_interface, inherit_interface_has_interface_object;
+ if (this.base) {
+ inherit_interface = this.base;
+ inherit_interface_has_interface_object =
+ !this.array
+ .members[inherit_interface]
+ .has_extended_attribute("NoInterfaceObject");
+ } else if (this.has_extended_attribute('ArrayClass')) {
+ inherit_interface = 'Array';
+ inherit_interface_has_interface_object = true;
+ } else {
+ inherit_interface = 'Object';
+ inherit_interface_has_interface_object = true;
+ }
+ if (inherit_interface_has_interface_object) {
+ assert_own_property(self, inherit_interface,
+ 'should inherit from ' + inherit_interface + ', but self has no such property');
+ assert_own_property(self[inherit_interface], 'prototype',
+ 'should inherit from ' + inherit_interface + ', but that object has no "prototype" property');
+ assert_equals(Object.getPrototypeOf(self[this.name].prototype),
+ self[inherit_interface].prototype,
+ 'prototype of ' + this.name + '.prototype is not ' + inherit_interface + '.prototype');
+ } else {
+ // We can't test that we get the correct object, because this is the
+ // only way to get our hands on it. We only test that its class
+ // string, at least, is correct.
+ assert_class_string(Object.getPrototypeOf(self[this.name].prototype),
+ inherit_interface + 'Prototype',
+ 'Class name for prototype of ' + this.name +
+ '.prototype is not "' + inherit_interface + 'Prototype"');
+ }
+ }
+
+ // "The class string of an interface prototype object is the
+ // concatenation of the interface’s identifier and the string
+ // “Prototype”."
+ assert_class_string(self[this.name].prototype, this.name + "Prototype",
+ "class string of " + this.name + ".prototype");
+ // String() should end up calling {}.toString if nothing defines a
+ // stringifier.
+ if (!this.has_stringifier()) {
+ assert_equals(String(self[this.name].prototype), "[object " + this.name + "Prototype]",
+ "String(" + this.name + ".prototype)");
+ }
+ }.bind(this), this.name + " interface: existence and properties of interface prototype object");
+
+ test(function()
+ {
+ if (this.is_callback() && !this.has_constants()) {
+ return;
+ }
+
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+
+ if (this.is_callback()) {
+ assert_false("prototype" in self[this.name],
+ this.name + ' should not have a "prototype" property');
+ return;
+ }
+
+ assert_own_property(self[this.name], "prototype",
+ 'interface "' + this.name + '" does not have own property "prototype"');
+
+ // "If the [NoInterfaceObject] extended attribute was not specified on
+ // the interface, then the interface prototype object must also have a
+ // property named “constructor” with attributes { [[Writable]]: true,
+ // [[Enumerable]]: false, [[Configurable]]: true } whose value is a
+ // reference to the interface object for the interface."
+ assert_own_property(self[this.name].prototype, "constructor",
+ this.name + '.prototype does not have own property "constructor"');
+ var desc = Object.getOwnPropertyDescriptor(self[this.name].prototype, "constructor");
+ assert_false("get" in desc, this.name + ".prototype.constructor has getter");
+ assert_false("set" in desc, this.name + ".prototype.constructor has setter");
+ assert_true(desc.writable, this.name + ".prototype.constructor is not writable");
+ assert_false(desc.enumerable, this.name + ".prototype.constructor is enumerable");
+ assert_true(desc.configurable, this.name + ".prototype.constructor in not configurable");
+ assert_equals(self[this.name].prototype.constructor, self[this.name],
+ this.name + '.prototype.constructor is not the same object as ' + this.name);
+ }.bind(this), this.name + ' interface: existence and properties of interface prototype object\'s "constructor" property');
+};
+
+//@}
+IdlInterface.prototype.test_member_const = function(member)
+//@{
+{
+ if (!this.has_constants()) {
+ throw "Internal error: test_member_const called without any constants";
+ }
+
+ test(function()
+ {
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+
+ // "For each constant defined on an interface A, there must be
+ // a corresponding property on the interface object, if it
+ // exists."
+ assert_own_property(self[this.name], member.name);
+ // "The value of the property is that which is obtained by
+ // converting the constant’s IDL value to an ECMAScript
+ // value."
+ assert_equals(self[this.name][member.name], constValue(member.value),
+ "property has wrong value");
+ // "The property has attributes { [[Writable]]: false,
+ // [[Enumerable]]: true, [[Configurable]]: false }."
+ var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name);
+ assert_false("get" in desc, "property has getter");
+ assert_false("set" in desc, "property has setter");
+ assert_false(desc.writable, "property is writable");
+ assert_true(desc.enumerable, "property is not enumerable");
+ assert_false(desc.configurable, "property is configurable");
+ }.bind(this), this.name + " interface: constant " + member.name + " on interface object");
+
+ // "In addition, a property with the same characteristics must
+ // exist on the interface prototype object."
+ test(function()
+ {
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+
+ if (this.is_callback()) {
+ assert_false("prototype" in self[this.name],
+ this.name + ' should not have a "prototype" property');
+ return;
+ }
+
+ assert_own_property(self[this.name], "prototype",
+ 'interface "' + this.name + '" does not have own property "prototype"');
+
+ assert_own_property(self[this.name].prototype, member.name);
+ assert_equals(self[this.name].prototype[member.name], constValue(member.value),
+ "property has wrong value");
+ var desc = Object.getOwnPropertyDescriptor(self[this.name], member.name);
+ assert_false("get" in desc, "property has getter");
+ assert_false("set" in desc, "property has setter");
+ assert_false(desc.writable, "property is writable");
+ assert_true(desc.enumerable, "property is not enumerable");
+ assert_false(desc.configurable, "property is configurable");
+ }.bind(this), this.name + " interface: constant " + member.name + " on interface prototype object");
+};
+
+
+//@}
+IdlInterface.prototype.test_member_attribute = function(member)
+//@{
+{
+ test(function()
+ {
+ if (this.is_callback() && !this.has_constants()) {
+ return;
+ }
+
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+ assert_own_property(self[this.name], "prototype",
+ 'interface "' + this.name + '" does not have own property "prototype"');
+
+ if (member["static"]) {
+ assert_own_property(self[this.name], member.name,
+ "The interface object must have a property " +
+ format_value(member.name));
+ } else if (this.is_global()) {
+ assert_own_property(self, member.name,
+ "The global object must have a property " +
+ format_value(member.name));
+ assert_false(member.name in self[this.name].prototype,
+ "The prototype object must not have a property " +
+ format_value(member.name));
+
+ var getter = Object.getOwnPropertyDescriptor(self, member.name).get;
+ assert_equals(typeof(getter), "function",
+ format_value(member.name) + " must have a getter");
+
+ // Try/catch around the get here, since it can legitimately throw.
+ // If it does, we obviously can't check for equality with direct
+ // invocation of the getter.
+ var gotValue;
+ var propVal;
+ try {
+ propVal = self[member.name];
+ gotValue = true;
+ } catch (e) {
+ gotValue = false;
+ }
+ if (gotValue) {
+ assert_equals(propVal, getter.call(undefined),
+ "Gets on a global should not require an explicit this");
+ }
+
+ this.do_interface_attribute_asserts(self, member);
+ } else {
+ assert_true(member.name in self[this.name].prototype,
+ "The prototype object must have a property " +
+ format_value(member.name));
+
+ if (!member.has_extended_attribute("LenientThis")) {
+ assert_throws(new TypeError(), function() {
+ self[this.name].prototype[member.name];
+ }.bind(this), "getting property on prototype object must throw TypeError");
+ } else {
+ assert_equals(self[this.name].prototype[member.name], undefined,
+ "getting property on prototype object must return undefined");
+ }
+ this.do_interface_attribute_asserts(self[this.name].prototype, member);
+ }
+ }.bind(this), this.name + " interface: attribute " + member.name);
+};
+
+//@}
+IdlInterface.prototype.test_member_operation = function(member)
+//@{
+{
+ var a_test = async_test(this.name + " interface: operation " + member.name +
+ "(" + member.arguments.map(
+ function(m) {return m.idlType.idlType; } )
+ +")");
+ a_test.step(function()
+ {
+ // This function tests WebIDL as of 2015-12-29.
+ // https://heycam.github.io/webidl/#es-operations
+
+ if (this.is_callback() && !this.has_constants()) {
+ a_test.done();
+ return;
+ }
+
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+
+ if (this.is_callback()) {
+ assert_false("prototype" in self[this.name],
+ this.name + ' should not have a "prototype" property');
+ a_test.done();
+ return;
+ }
+
+ assert_own_property(self[this.name], "prototype",
+ 'interface "' + this.name + '" does not have own property "prototype"');
+
+ // "For each unique identifier of an exposed operation defined on the
+ // interface, there must exist a corresponding property, unless the
+ // effective overload set for that identifier and operation and with an
+ // argument count of 0 has no entries."
+
+ // TODO: Consider [Exposed].
+
+ // "The location of the property is determined as follows:"
+ var memberHolderObject;
+ // "* If the operation is static, then the property exists on the
+ // interface object."
+ if (member["static"]) {
+ assert_own_property(self[this.name], member.name,
+ "interface object missing static operation");
+ memberHolderObject = self[this.name];
+ // "* Otherwise, [...] if the interface was declared with the [Global]
+ // or [PrimaryGlobal] extended attribute, then the property exists
+ // on every object that implements the interface."
+ } else if (this.is_global()) {
+ assert_own_property(self, member.name,
+ "global object missing non-static operation");
+ memberHolderObject = self;
+ // "* Otherwise, the property exists solely on the interface’s
+ // interface prototype object."
+ } else {
+ assert_own_property(self[this.name].prototype, member.name,
+ "interface prototype object missing non-static operation");
+ memberHolderObject = self[this.name].prototype;
+ }
+ this.do_member_operation_asserts(memberHolderObject, member, a_test);
+ }.bind(this));
+};
+
+//@}
+IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject, member, a_test)
+//@{
+{
+ var done = a_test.done.bind(a_test);
+ var operationUnforgeable = member.isUnforgeable;
+ var desc = Object.getOwnPropertyDescriptor(memberHolderObject, member.name);
+ // "The property has attributes { [[Writable]]: B,
+ // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the
+ // operation is unforgeable on the interface, and true otherwise".
+ assert_false("get" in desc, "property has getter");
+ assert_false("set" in desc, "property has setter");
+ assert_equals(desc.writable, !operationUnforgeable,
+ "property should be writable if and only if not unforgeable");
+ assert_true(desc.enumerable, "property is not enumerable");
+ assert_equals(desc.configurable, !operationUnforgeable,
+ "property should be configurable if and only if not unforgeable");
+ // "The value of the property is a Function object whose
+ // behavior is as follows . . ."
+ assert_equals(typeof memberHolderObject[member.name], "function",
+ "property must be a function");
+ // "The value of the Function object’s “length” property is
+ // a Number determined as follows:
+ // ". . .
+ // "Return the length of the shortest argument list of the
+ // entries in S."
+ assert_equals(memberHolderObject[member.name].length,
+ minOverloadLength(this.members.filter(function(m) {
+ return m.type == "operation" && m.name == member.name;
+ })),
+ "property has wrong .length");
+
+ // Make some suitable arguments
+ var args = member.arguments.map(function(arg) {
+ return create_suitable_object(arg.idlType);
+ });
+
+ // "Let O be a value determined as follows:
+ // ". . .
+ // "Otherwise, throw a TypeError."
+ // This should be hit if the operation is not static, there is
+ // no [ImplicitThis] attribute, and the this value is null.
+ //
+ // TODO: We currently ignore the [ImplicitThis] case. Except we manually
+ // check for globals, since otherwise we'll invoke window.close(). And we
+ // have to skip this test for anything that on the proto chain of "self",
+ // since that does in fact have implicit-this behavior.
+ if (!member["static"]) {
+ var cb;
+ if (!this.is_global() &&
+ memberHolderObject[member.name] != self[member.name])
+ {
+ cb = awaitNCallbacks(2, done);
+ throwOrReject(a_test, member, memberHolderObject[member.name], null, args,
+ "calling operation with this = null didn't throw TypeError", cb);
+ } else {
+ cb = awaitNCallbacks(1, done);
+ }
+
+ // ". . . If O is not null and is also not a platform object
+ // that implements interface I, throw a TypeError."
+ //
+ // TODO: Test a platform object that implements some other
+ // interface. (Have to be sure to get inheritance right.)
+ throwOrReject(a_test, member, memberHolderObject[member.name], {}, args,
+ "calling operation with this = {} didn't throw TypeError", cb);
+ } else {
+ done();
+ }
+}
+
+//@}
+IdlInterface.prototype.test_member_stringifier = function(member)
+//@{
+{
+ test(function()
+ {
+ if (this.is_callback() && !this.has_constants()) {
+ return;
+ }
+
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+
+ if (this.is_callback()) {
+ assert_false("prototype" in self[this.name],
+ this.name + ' should not have a "prototype" property');
+ return;
+ }
+
+ assert_own_property(self[this.name], "prototype",
+ 'interface "' + this.name + '" does not have own property "prototype"');
+
+ // ". . . the property exists on the interface prototype object."
+ var interfacePrototypeObject = self[this.name].prototype;
+ assert_own_property(self[this.name].prototype, "toString",
+ "interface prototype object missing non-static operation");
+
+ var stringifierUnforgeable = member.isUnforgeable;
+ var desc = Object.getOwnPropertyDescriptor(interfacePrototypeObject, "toString");
+ // "The property has attributes { [[Writable]]: B,
+ // [[Enumerable]]: true, [[Configurable]]: B }, where B is false if the
+ // stringifier is unforgeable on the interface, and true otherwise."
+ assert_false("get" in desc, "property has getter");
+ assert_false("set" in desc, "property has setter");
+ assert_equals(desc.writable, !stringifierUnforgeable,
+ "property should be writable if and only if not unforgeable");
+ assert_true(desc.enumerable, "property is not enumerable");
+ assert_equals(desc.configurable, !stringifierUnforgeable,
+ "property should be configurable if and only if not unforgeable");
+ // "The value of the property is a Function object, which behaves as
+ // follows . . ."
+ assert_equals(typeof interfacePrototypeObject.toString, "function",
+ "property must be a function");
+ // "The value of the Function object’s “length” property is the Number
+ // value 0."
+ assert_equals(interfacePrototypeObject.toString.length, 0,
+ "property has wrong .length");
+
+ // "Let O be the result of calling ToObject on the this value."
+ assert_throws(new TypeError(), function() {
+ self[this.name].prototype.toString.apply(null, []);
+ }, "calling stringifier with this = null didn't throw TypeError");
+
+ // "If O is not an object that implements the interface on which the
+ // stringifier was declared, then throw a TypeError."
+ //
+ // TODO: Test a platform object that implements some other
+ // interface. (Have to be sure to get inheritance right.)
+ assert_throws(new TypeError(), function() {
+ self[this.name].prototype.toString.apply({}, []);
+ }, "calling stringifier with this = {} didn't throw TypeError");
+ }.bind(this), this.name + " interface: stringifier");
+};
+
+//@}
+IdlInterface.prototype.test_members = function()
+//@{
+{
+ for (var i = 0; i < this.members.length; i++)
+ {
+ var member = this.members[i];
+ if (member.untested) {
+ continue;
+ }
+
+ switch (member.type) {
+ case "const":
+ this.test_member_const(member);
+ break;
+
+ case "attribute":
+ // For unforgeable attributes, we do the checks in
+ // test_interface_of instead.
+ if (!member.isUnforgeable)
+ {
+ this.test_member_attribute(member);
+ }
+ break;
+
+ case "operation":
+ // TODO: Need to correctly handle multiple operations with the same
+ // identifier.
+ // For unforgeable operations, we do the checks in
+ // test_interface_of instead.
+ if (member.name) {
+ if (!member.isUnforgeable)
+ {
+ this.test_member_operation(member);
+ }
+ } else if (member.stringifier) {
+ this.test_member_stringifier(member);
+ }
+ break;
+
+ default:
+ // TODO: check more member types.
+ break;
+ }
+ }
+};
+
+//@}
+IdlInterface.prototype.test_object = function(desc)
+//@{
+{
+ var obj, exception = null;
+ try
+ {
+ obj = eval(desc);
+ }
+ catch(e)
+ {
+ exception = e;
+ }
+
+ var expected_typeof =
+ this.members.some(function(member) { return member.legacycaller; })
+ ? "function"
+ : "object";
+
+ this.test_primary_interface_of(desc, obj, exception, expected_typeof);
+ var current_interface = this;
+ while (current_interface)
+ {
+ if (!(current_interface.name in this.array.members))
+ {
+ throw "Interface " + current_interface.name + " not found (inherited by " + this.name + ")";
+ }
+ if (current_interface.prevent_multiple_testing && current_interface.already_tested)
+ {
+ return;
+ }
+ current_interface.test_interface_of(desc, obj, exception, expected_typeof);
+ current_interface = this.array.members[current_interface.base];
+ }
+};
+
+//@}
+IdlInterface.prototype.test_primary_interface_of = function(desc, obj, exception, expected_typeof)
+//@{
+{
+ // We can't easily test that its prototype is correct if there's no
+ // interface object, or the object is from a different global environment
+ // (not instanceof Object). TODO: test in this case that its prototype at
+ // least looks correct, even if we can't test that it's actually correct.
+ if (!this.has_extended_attribute("NoInterfaceObject")
+ && (typeof obj != expected_typeof || obj instanceof Object))
+ {
+ test(function()
+ {
+ assert_equals(exception, null, "Unexpected exception when evaluating object");
+ assert_equals(typeof obj, expected_typeof, "wrong typeof object");
+ assert_own_property(self, this.name,
+ "self does not have own property " + format_value(this.name));
+ assert_own_property(self[this.name], "prototype",
+ 'interface "' + this.name + '" does not have own property "prototype"');
+
+ // "The value of the internal [[Prototype]] property of the
+ // platform object is the interface prototype object of the primary
+ // interface from the platform object’s associated global
+ // environment."
+ assert_equals(Object.getPrototypeOf(obj),
+ self[this.name].prototype,
+ desc + "'s prototype is not " + this.name + ".prototype");
+ }.bind(this), this.name + " must be primary interface of " + desc);
+ }
+
+ // "The class string of a platform object that implements one or more
+ // interfaces must be the identifier of the primary interface of the
+ // platform object."
+ test(function()
+ {
+ assert_equals(exception, null, "Unexpected exception when evaluating object");
+ assert_equals(typeof obj, expected_typeof, "wrong typeof object");
+ assert_class_string(obj, this.name, "class string of " + desc);
+ if (!this.has_stringifier())
+ {
+ assert_equals(String(obj), "[object " + this.name + "]", "String(" + desc + ")");
+ }
+ }.bind(this), "Stringification of " + desc);
+};
+
+//@}
+IdlInterface.prototype.test_interface_of = function(desc, obj, exception, expected_typeof)
+//@{
+{
+ // TODO: Indexed and named properties, more checks on interface members
+ this.already_tested = true;
+
+ for (var i = 0; i < this.members.length; i++)
+ {
+ var member = this.members[i];
+ if (member.type == "attribute" && member.isUnforgeable)
+ {
+ test(function()
+ {
+ assert_equals(exception, null, "Unexpected exception when evaluating object");
+ assert_equals(typeof obj, expected_typeof, "wrong typeof object");
+ this.do_interface_attribute_asserts(obj, member);
+ }.bind(this), this.name + " interface: " + desc + ' must have own property "' + member.name + '"');
+ }
+ else if (member.type == "operation" &&
+ member.name &&
+ member.isUnforgeable)
+ {
+ var a_test = async_test(this.name + " interface: " + desc + ' must have own property "' + member.name + '"');
+ a_test.step(function()
+ {
+ assert_equals(exception, null, "Unexpected exception when evaluating object");
+ assert_equals(typeof obj, expected_typeof, "wrong typeof object");
+ assert_own_property(obj, member.name,
+ "Doesn't have the unforgeable operation property");
+ this.do_member_operation_asserts(obj, member, a_test);
+ }.bind(this));
+ }
+ else if ((member.type == "const"
+ || member.type == "attribute"
+ || member.type == "operation")
+ && member.name)
+ {
+ test(function()
+ {
+ assert_equals(exception, null, "Unexpected exception when evaluating object");
+ assert_equals(typeof obj, expected_typeof, "wrong typeof object");
+ if (!member["static"]) {
+ if (!this.is_global()) {
+ assert_inherits(obj, member.name);
+ } else {
+ assert_own_property(obj, member.name);
+ }
+
+ if (member.type == "const")
+ {
+ assert_equals(obj[member.name], constValue(member.value));
+ }
+ if (member.type == "attribute")
+ {
+ // Attributes are accessor properties, so they might
+ // legitimately throw an exception rather than returning
+ // anything.
+ var property, thrown = false;
+ try
+ {
+ property = obj[member.name];
+ }
+ catch (e)
+ {
+ thrown = true;
+ }
+ if (!thrown)
+ {
+ this.array.assert_type_is(property, member.idlType);
+ }
+ }
+ if (member.type == "operation")
+ {
+ assert_equals(typeof obj[member.name], "function");
+ }
+ }
+ }.bind(this), this.name + " interface: " + desc + ' must inherit property "' + member.name + '" with the proper type (' + i + ')');
+ }
+ // TODO: This is wrong if there are multiple operations with the same
+ // identifier.
+ // TODO: Test passing arguments of the wrong type.
+ if (member.type == "operation" && member.name && member.arguments.length)
+ {
+ var a_test = async_test( this.name + " interface: calling " + member.name +
+ "(" + member.arguments.map(function(m) { return m.idlType.idlType; }) +
+ ") on " + desc + " with too few arguments must throw TypeError");
+ a_test.step(function()
+ {
+ assert_equals(exception, null, "Unexpected exception when evaluating object");
+ assert_equals(typeof obj, expected_typeof, "wrong typeof object");
+ if (!member["static"]) {
+ if (!this.is_global() && !member.isUnforgeable) {
+ assert_inherits(obj, member.name);
+ } else {
+ assert_own_property(obj, member.name);
+ }
+ }
+ else
+ {
+ assert_false(member.name in obj);
+ }
+
+ var minLength = minOverloadLength(this.members.filter(function(m) {
+ return m.type == "operation" && m.name == member.name;
+ }));
+ var args = [];
+ var cb = awaitNCallbacks(minLength, a_test.done.bind(a_test));
+ for (var i = 0; i < minLength; i++) {
+ throwOrReject(a_test, member, obj[member.name], obj, args, "Called with " + i + " arguments", cb);
+
+ args.push(create_suitable_object(member.arguments[i].idlType));
+ }
+ if (minLength === 0) {
+ cb();
+ }
+ }.bind(this));
+ }
+ }
+};
+
+//@}
+IdlInterface.prototype.has_stringifier = function()
+//@{
+{
+ if (this.members.some(function(member) { return member.stringifier; })) {
+ return true;
+ }
+ if (this.base &&
+ this.array.members[this.base].has_stringifier()) {
+ return true;
+ }
+ return false;
+};
+
+//@}
+IdlInterface.prototype.do_interface_attribute_asserts = function(obj, member)
+//@{
+{
+ // This function tests WebIDL as of 2015-01-27.
+ // TODO: Consider [Exposed].
+
+ // This is called by test_member_attribute() with the prototype as obj if
+ // it is not a global, and the global otherwise, and by test_interface_of()
+ // with the object as obj.
+
+ // "For each exposed attribute of the interface, whether it was declared on
+ // the interface itself or one of its consequential interfaces, there MUST
+ // exist a corresponding property. The characteristics of this property are
+ // as follows:"
+
+ // "The name of the property is the identifier of the attribute."
+ assert_own_property(obj, member.name);
+
+ // "The property has attributes { [[Get]]: G, [[Set]]: S, [[Enumerable]]:
+ // true, [[Configurable]]: configurable }, where:
+ // "configurable is false if the attribute was declared with the
+ // [Unforgeable] extended attribute and true otherwise;
+ // "G is the attribute getter, defined below; and
+ // "S is the attribute setter, also defined below."
+ var desc = Object.getOwnPropertyDescriptor(obj, member.name);
+ assert_false("value" in desc, 'property descriptor has value but is supposed to be accessor');
+ assert_false("writable" in desc, 'property descriptor has "writable" field but is supposed to be accessor');
+ assert_true(desc.enumerable, "property is not enumerable");
+ if (member.isUnforgeable)
+ {
+ assert_false(desc.configurable, "[Unforgeable] property must not be configurable");
+ }
+ else
+ {
+ assert_true(desc.configurable, "property must be configurable");
+ }
+
+
+ // "The attribute getter is a Function object whose behavior when invoked
+ // is as follows:"
+ assert_equals(typeof desc.get, "function", "getter must be Function");
+
+ // "If the attribute is a regular attribute, then:"
+ if (!member["static"]) {
+ // "If O is not a platform object that implements I, then:
+ // "If the attribute was specified with the [LenientThis] extended
+ // attribute, then return undefined.
+ // "Otherwise, throw a TypeError."
+ if (!member.has_extended_attribute("LenientThis")) {
+ assert_throws(new TypeError(), function() {
+ desc.get.call({});
+ }.bind(this), "calling getter on wrong object type must throw TypeError");
+ } else {
+ assert_equals(desc.get.call({}), undefined,
+ "calling getter on wrong object type must return undefined");
+ }
+ }
+
+ // "The value of the Function object’s “length” property is the Number
+ // value 0."
+ assert_equals(desc.get.length, 0, "getter length must be 0");
+
+
+ // TODO: Test calling setter on the interface prototype (should throw
+ // TypeError in most cases).
+ if (member.readonly
+ && !member.has_extended_attribute("PutForwards")
+ && !member.has_extended_attribute("Replaceable"))
+ {
+ // "The attribute setter is undefined if the attribute is declared
+ // readonly and has neither a [PutForwards] nor a [Replaceable]
+ // extended attribute declared on it."
+ assert_equals(desc.set, undefined, "setter must be undefined for readonly attributes");
+ }
+ else
+ {
+ // "Otherwise, it is a Function object whose behavior when
+ // invoked is as follows:"
+ assert_equals(typeof desc.set, "function", "setter must be function for PutForwards, Replaceable, or non-readonly attributes");
+
+ // "If the attribute is a regular attribute, then:"
+ if (!member["static"]) {
+ // "If /validThis/ is false and the attribute was not specified
+ // with the [LenientThis] extended attribute, then throw a
+ // TypeError."
+ // "If the attribute is declared with a [Replaceable] extended
+ // attribute, then: ..."
+ // "If validThis is false, then return."
+ if (!member.has_extended_attribute("LenientThis")) {
+ assert_throws(new TypeError(), function() {
+ desc.set.call({});
+ }.bind(this), "calling setter on wrong object type must throw TypeError");
+ } else {
+ assert_equals(desc.set.call({}), undefined,
+ "calling setter on wrong object type must return undefined");
+ }
+ }
+
+ // "The value of the Function object’s “length” property is the Number
+ // value 1."
+ assert_equals(desc.set.length, 1, "setter length must be 1");
+ }
+}
+//@}
+
+/// IdlInterfaceMember ///
+function IdlInterfaceMember(obj)
+//@{
+{
+ /**
+ * obj is an object produced by the WebIDLParser.js "ifMember" production.
+ * We just forward all properties to this object without modification,
+ * except for special extAttrs handling.
+ */
+ for (var k in obj)
+ {
+ this[k] = obj[k];
+ }
+ if (!("extAttrs" in this))
+ {
+ this.extAttrs = [];
+ }
+
+ this.isUnforgeable = this.has_extended_attribute("Unforgeable");
+}
+
+//@}
+IdlInterfaceMember.prototype = Object.create(IdlObject.prototype);
+
+/// Internal helper functions ///
+function create_suitable_object(type)
+//@{
+{
+ /**
+ * type is an object produced by the WebIDLParser.js "type" production. We
+ * return a JavaScript value that matches the type, if we can figure out
+ * how.
+ */
+ if (type.nullable)
+ {
+ return null;
+ }
+ switch (type.idlType)
+ {
+ case "any":
+ case "boolean":
+ return true;
+
+ case "byte": case "octet": case "short": case "unsigned short":
+ case "long": case "unsigned long": case "long long":
+ case "unsigned long long": case "float": case "double":
+ case "unrestricted float": case "unrestricted double":
+ return 7;
+
+ case "DOMString":
+ case "ByteString":
+ case "USVString":
+ return "foo";
+
+ case "object":
+ return {a: "b"};
+
+ case "Node":
+ return document.createTextNode("abc");
+ }
+ return null;
+}
+//@}
+
+/// IdlEnum ///
+// Used for IdlArray.prototype.assert_type_is
+function IdlEnum(obj)
+//@{
+{
+ /**
+ * obj is an object produced by the WebIDLParser.js "dictionary"
+ * production.
+ */
+
+ /** Self-explanatory. */
+ this.name = obj.name;
+
+ /** An array of values produced by the "enum" production. */
+ this.values = obj.values;
+
+}
+//@}
+
+IdlEnum.prototype = Object.create(IdlObject.prototype);
+
+/// IdlTypedef ///
+// Used for IdlArray.prototype.assert_type_is
+function IdlTypedef(obj)
+//@{
+{
+ /**
+ * obj is an object produced by the WebIDLParser.js "typedef"
+ * production.
+ */
+
+ /** Self-explanatory. */
+ this.name = obj.name;
+
+ /** An array of values produced by the "typedef" production. */
+ this.values = obj.values;
+
+}
+//@}
+
+IdlTypedef.prototype = Object.create(IdlObject.prototype);
+
+}());
+// vim: set expandtab shiftwidth=4 tabstop=4 foldmarker=@{,@} foldmethod=marker:
diff --git a/bower_components/custom-elements/tests/chromium/resources/intersection-observer-helper-functions.js b/bower_components/custom-elements/tests/chromium/resources/intersection-observer-helper-functions.js
new file mode 100644
index 0000000..050274d
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/intersection-observer-helper-functions.js
@@ -0,0 +1,109 @@
+// Some of the js-test.js boilerplate will add stuff to the top of the document early
+// enough to screw with frame offsets that are measured by the test. Delay all that
+// jazz until the actual test code is finished.
+if (self.isJsTest) {
+ setPrintTestResultsLazily();
+ self.jsTestIsAsync = true;
+}
+
+// waitForNotification is a requestIdleCallback wrapped in a setTimeout wrapped in a
+// requestAnimationFrame. What in the wide, wide world of sports is going on here?
+//
+// Here's the order of events:
+//
+// - firstTestFunction
+// - Change layout to generate new IntersectionObserver notifications.
+// - waitForNotification(secondTestFunction)
+// - requestAnimationFrame
+// - BeginFrame
+// - requestAnimationFrame handler runs.
+// - setTimeout
+// - FrameView::updateAllLifecyclePhases
+// - IntersectionObserver generates notification based on the new layout.
+// - Post idle task to deliver notification.
+// - setTimeout handler runs.
+// - testRunner.runIdleTasks or requestIdleCallback.
+// - Idle tasks run -- more or less immediately if (self.testRunner),
+// possibly delayed if (!self.testRunner).
+// - IntersectionObserver notifications are delivered.
+// - secondTestFunction
+// - Verify notifications generated by firstTestFunction.
+// - Change layout to generate new IntersectionObserver notifications.
+// - waitForNotification(thirdTestFunction)
+//
+// Note that this should work equally well in these operation conditions:
+//
+// - layout test using single-threaded compositing (the default)
+// - layout test using multi-threaded compositing (virtual/threaded/)
+// - Not in a layout test and using multi-threaded compositing (the only configuration we ship)
+function waitForNotification(f) {
+ requestAnimationFrame(() => {
+ setTimeout(() => {
+ if (self.testRunner)
+ testRunner.runIdleTasks(f);
+ else
+ requestIdleCallback(f);
+ });
+ });
+}
+
+function rectToString(rect) {
+ return "[" + rect.left + ", " + rect.right + ", " + rect.top + ", " + rect.bottom + "]";
+}
+
+function entryToString(entry) {
+ var ratio = ((entry.intersectionRect.width * entry.intersectionRect.height) /
+ (entry.boundingClientRect.width * entry.boundingClientRect.height));
+ return (
+ "boundingClientRect=" + rectToString(entry.boundingClientRect) + "\n" +
+ "intersectionRect=" + rectToString(entry.intersectionRect) + "\n" +
+ "visibleRatio=" + ratio + "\n" +
+ "rootBounds=" + rectToString(entry.rootBounds) + "\n" +
+ "target=" + entry.target + "\n" +
+ "time=" + entry.time);
+}
+
+function rectArea(rect) {
+ return (rect.left - rect.right) * (rect.bottom - rect.top);
+}
+
+function intersectionRatio(entry) {
+ var targetArea = rectArea(entry.boundingClientRect);
+ if (!targetArea)
+ return 0;
+ return rectArea(entry.intersectionRect) / targetArea;
+}
+
+function clientRectToJson(rect) {
+ if (!rect)
+ return null;
+ return {
+ top: rect.top,
+ right: rect.right,
+ bottom: rect.bottom,
+ left: rect.left,
+ width: rect.width,
+ height: rect.height
+ };
+}
+
+function coordinatesToClientRectJson(top, right, bottom, left) {
+ return {
+ top: top,
+ right: right,
+ bottom: bottom,
+ left: left,
+ width: right - left,
+ height: bottom - top
+ };
+}
+
+function entryToJson(entry) {
+ return {
+ boundingClientRect: clientRectToJson(entry.boundingClientRect),
+ intersectionRect: clientRectToJson(entry.intersectionRect),
+ rootBounds: clientRectToJson(entry.rootBounds),
+ time: entry.time,
+ target: entry.target.id
+ };
+}
diff --git a/bower_components/custom-elements/tests/chromium/resources/intersection-observer-subframe.html b/bower_components/custom-elements/tests/chromium/resources/intersection-observer-subframe.html
new file mode 100644
index 0000000..ee63a06
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/intersection-observer-subframe.html
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/resources/intersection-observer-timestamp-subframe.html b/bower_components/custom-elements/tests/chromium/resources/intersection-observer-timestamp-subframe.html
new file mode 100644
index 0000000..1515ff2
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/intersection-observer-timestamp-subframe.html
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/chromium/resources/js-test.js b/bower_components/custom-elements/tests/chromium/resources/js-test.js
new file mode 100644
index 0000000..77b85c3
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/js-test.js
@@ -0,0 +1,912 @@
+// js-test now supports lazily printing test results which dumps all test
+// results once at the end of the test instead of building them up. To enable
+// this option, call setPrintTestResultsLazily() before running any tests.
+var _lazyTestResults; // Set by setPrintTestResultsLazily().
+var _lazyDescription; // Set by description() after setPrintTestResultsLazily().
+
+// svg/dynamic-updates tests set enablePixelTesting=true, as we want to dump text + pixel results
+if (self.testRunner) {
+ if (self.enablePixelTesting)
+ testRunner.dumpAsTextWithPixelResults();
+ else
+ testRunner.dumpAsText();
+}
+
+var isJsTest = true;
+
+var description, debug, successfullyParsed, getOrCreateTestElement;
+
+var expectingError; // set by shouldHaveError()
+var expectedErrorMessage; // set by onerror when expectingError is true
+var unexpectedErrorMessage; // set by onerror when expectingError is not true
+
+(function() {
+
+ getOrCreateTestElement = function(id, tagName)
+ {
+ var element = document.getElementById(id);
+ if (element)
+ return element;
+
+ element = document.createElement(tagName);
+ element.id = id;
+ var refNode;
+ var parent = document.body || document.documentElement;
+ if (id == "description")
+ refNode = getOrCreateTestElement("console", "div");
+ else
+ refNode = parent.firstChild;
+
+ parent.insertBefore(element, refNode);
+ return element;
+ }
+
+ description = function description(msg, quiet)
+ {
+ // For MSIE 6 compatibility
+ var span = document.createElement("span");
+ if (quiet)
+ span.innerHTML = '
' + msg + '
On success, you will see no "FAIL" messages, followed by "TEST COMPLETE".
';
+ else
+ span.innerHTML = '
' + msg + '
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
';
+
+ if (_lazyTestResults) {
+ _lazyDescription = span;
+ return;
+ }
+
+ var description = getOrCreateTestElement("description", "p");
+ if (description.firstChild)
+ description.replaceChild(span, description.firstChild);
+ else
+ description.appendChild(span);
+ };
+
+ debug = function debug(msg)
+ {
+ if (self._lazyTestResults) {
+ self._lazyTestResults.push(msg);
+ } else {
+ var span = document.createElement("span");
+ // insert it first so XHTML knows the namespace;
+ getOrCreateTestElement("console", "div").appendChild(span);
+ span.innerHTML = msg + ' ';
+ }
+ };
+
+ var css =
+ ".pass {" +
+ "font-weight: bold;" +
+ "color: green;" +
+ "}" +
+ ".fail {" +
+ "font-weight: bold;" +
+ "color: red;" +
+ "}" +
+ "#console {" +
+ "white-space: pre-wrap;" +
+ "font-family: monospace;" +
+ "}";
+
+ function insertStyleSheet()
+ {
+ var styleElement = document.createElement("style");
+ styleElement.textContent = css;
+ (document.head || document.documentElement).appendChild(styleElement);
+ }
+
+ function handleTestFinished()
+ {
+ // FIXME: Get rid of this boolean.
+ wasPostTestScriptParsed = true;
+ if (window.jsTestIsAsync) {
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+ if (window.wasFinishJSTestCalled)
+ finishJSTest();
+ } else
+ finishJSTest();
+ }
+
+ if (!isWorker()) {
+ window.addEventListener('DOMContentLoaded', handleTestFinished, false);
+ insertStyleSheet();
+ }
+
+ if (!self.isOnErrorTest) {
+ self.onerror = function(message)
+ {
+ if (self.expectingError) {
+ self.expectedErrorMessage = message;
+ self.expectingError = false;
+ return;
+ }
+ self.unexpectedErrorMessage = message;
+ if (self.jsTestIsAsync) {
+ self.testFailed("Unexpected error: " + message);
+ finishJSTest();
+ }
+ };
+ }
+})();
+
+function isWorker()
+{
+ // It's conceivable that someone would stub out 'document' in a worker so
+ // also check for childNodes, an arbitrary DOM-related object that is
+ // meaningless in a WorkerContext.
+ return (typeof document === 'undefined' || typeof document.childNodes === 'undefined') && !!self.importScripts;
+}
+
+function descriptionQuiet(msg) { description(msg, true); }
+
+function escapeHTML(text)
+{
+ return text.replace(/&/g, "&").replace(/PASS ' + escapeHTML(msg) + '');
+}
+
+function testFailed(msg)
+{
+ debug('FAIL ' + escapeHTML(msg) + '');
+}
+
+function areArraysEqual(a, b)
+{
+ try {
+ if (a.length !== b.length)
+ return false;
+ for (var i = 0; i < a.length; i++)
+ if (a[i] !== b[i])
+ return false;
+ } catch (ex) {
+ return false;
+ }
+ return true;
+}
+
+function isMinusZero(n)
+{
+ // the only way to tell 0 from -0 in JS is the fact that 1/-0 is
+ // -Infinity instead of Infinity
+ return n === 0 && 1/n < 0;
+}
+
+function isNewSVGTearOffType(v)
+{
+ return ['[object SVGLength]', '[object SVGLengthList]', '[object SVGPoint]', '[object SVGPointList]', '[object SVGNumber]', '[object SVGTransform]', '[object SVGTransformList]'].indexOf(""+v) != -1;
+}
+
+function isResultCorrect(actual, expected)
+{
+ if (expected === 0)
+ return actual === expected && (1/actual) === (1/expected);
+ if (actual === expected)
+ return true;
+ // http://crbug.com/308818 : The new implementation of SVGListProperties do not necessary return the same wrapper object, so === operator would not work. We compare for their string representation instead.
+ if (isNewSVGTearOffType(expected) && typeof(expected) == typeof(actual) && actual.valueAsString == expected.valueAsString)
+ return true;
+ if (typeof(expected) == "number" && isNaN(expected))
+ return typeof(actual) == "number" && isNaN(actual);
+ if (expected && (Object.prototype.toString.call(expected) == Object.prototype.toString.call([])))
+ return areArraysEqual(actual, expected);
+ return false;
+}
+
+// Returns a sorted array of property names of object. This function returns
+// not only own properties but also properties on prototype chains.
+function getAllPropertyNames(object) {
+ var properties = [];
+ for (var property in object) {
+ properties.push(property);
+ }
+ return properties.sort();
+}
+
+function stringify(v)
+{
+ if (isNewSVGTearOffType(v))
+ return v.valueAsString;
+ if (v === 0 && 1/v < 0)
+ return "-0";
+ else return "" + v;
+}
+
+function evalAndLog(_a, _quiet)
+{
+ if (typeof _a != "string")
+ debug("WARN: tryAndLog() expects a string argument");
+
+ // Log first in case things go horribly wrong or this causes a sync event.
+ if (!_quiet)
+ debug(_a);
+
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ testFailed(_a + " threw exception " + e);
+ }
+ return _av;
+}
+
+function shouldBe(_a, _b, quiet, opt_tolerance)
+{
+ if (typeof _a != "string" || typeof _b != "string")
+ debug("WARN: shouldBe() expects string arguments");
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+ var _bv = eval(_b);
+
+ if (_exception)
+ testFailed(_a + " should be " + _bv + ". Threw exception " + _exception);
+ else if (isResultCorrect(_av, _bv) || (typeof opt_tolerance == 'number' && typeof _av == 'number' && Math.abs(_av - _bv) <= opt_tolerance)) {
+ if (!quiet) {
+ testPassed(_a + " is " + _b);
+ }
+ } else if (typeof(_av) == typeof(_bv))
+ testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + ".");
+ else
+ testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
+}
+
+// Execute condition every animation frame until it succeeds or failureTime is reached.
+// completionHandler is executed on success, failureHandler is executed on timeout.
+function _waitForCondition(condition, failureTime, completionHandler, failureHandler)
+{
+ if (condition()) {
+ completionHandler();
+ } else if (Date.now() > failureTime) {
+ failureHandler();
+ } else {
+ requestAnimationFrame(function() {
+ _waitForCondition(condition, failureTime, completionHandler, failureHandler);
+ });
+ }
+}
+
+function shouldBecomeEqual(_a, _b, _completionHandler, _timeout)
+{
+ if (typeof _a != "string" || typeof _b != "string")
+ debug("WARN: shouldBecomeEqual() expects string arguments");
+
+ if (_timeout === undefined)
+ _timeout = 500;
+
+ var _bv;
+ var _condition = function() {
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+ _bv = eval(_b);
+ if (_exception)
+ testFailed(_a + " should become " + _bv + ". Threw exception " + _exception);
+ if (isResultCorrect(_av, _bv)) {
+ testPassed(_a + " became " + _b);
+ return true;
+ }
+ return false;
+ };
+ var _failureTime = Date.now() + _timeout;
+ var _failureHandler = function () {
+ testFailed(_a + " failed to change to " + _bv + " in " + (_timeout / 1000) + " seconds.");
+ _completionHandler();
+ };
+ _waitForCondition(_condition, _failureTime, _completionHandler, _failureHandler);
+}
+
+function shouldBecomeEqualToString(value, reference, completionHandler, timeout)
+{
+ if (typeof value !== "string" || typeof reference !== "string")
+ debug("WARN: shouldBecomeEqualToString() expects string arguments");
+ var unevaledString = JSON.stringify(reference);
+ shouldBecomeEqual(value, unevaledString, completionHandler, timeout);
+}
+
+function shouldBeType(_a, _type) {
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+
+ var _typev = eval(_type);
+ if (_av instanceof _typev) {
+ testPassed(_a + " is an instance of " + _type);
+ } else {
+ testFailed(_a + " is not an instance of " + _type);
+ }
+}
+
+// Variant of shouldBe()--confirms that result of eval(_a_raw) is within
+// numeric _tolerance of _b_raw.
+function shouldBeCloseTo(_a_raw, _b_raw, _tolerance, _quiet)
+{
+ if (typeof _a_raw != "string") {
+ testFailed("shouldBeCloseTo() requires string argument _a_raw. was type " + typeof _a_raw);
+ return;
+ }
+ if (typeof _b_raw != "number" && typeof _b_raw != "string") {
+ testFailed("shouldBeCloseTo() requires numeric or string argument _b_raw. was type " + typeof _b_raw);
+ return;
+ }
+ if (typeof _tolerance != "number") {
+ testFailed("shouldBeCloseTo() requires numeric argument _tolerance. was type " + typeof _tolerance);
+ return;
+ }
+
+ var _a_evaled;
+ try {
+ _a_evaled = eval(_a_raw);
+ } catch (e) {
+ testFailed(_a_raw + " should be within " + _tolerance + " of "
+ + _b_raw + ". Threw exception " + e);
+ return;
+ }
+
+ var _b_evaled;
+ if (typeof _b_raw == "number") {
+ _b_evaled = _b_raw;
+ } else {
+ try {
+ _b_evaled = eval(_b_raw);
+ } catch (e) {
+ testFailed(_a_raw + " should be within " + _tolerance + " of "
+ + _b_raw + ". Threw exception " + e);
+ return;
+ }
+ }
+
+ if (typeof(_a_evaled) != typeof(_b_evaled)) {
+ testFailed(_a_raw + " should be of type " + typeof _b_evaled
+ + " but was of type " + typeof _a_evaled);
+ } else if (Math.abs(_a_evaled - _b_evaled) <= _tolerance) {
+ if (!_quiet) {
+ testPassed(_a_raw + " is within " + _tolerance + " of " + _b_raw);
+ }
+ } else {
+ testFailed(_a_raw + " should be within " + _tolerance + " of " + _b_raw
+ + ". Was " + _a_evaled + ".");
+ }
+}
+
+function shouldNotBe(_a, _b, _quiet)
+{
+ if (typeof _a != "string" || typeof _b != "string")
+ debug("WARN: shouldNotBe() expects string arguments");
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+ var _bv = eval(_b);
+
+ if (_exception)
+ testFailed(_a + " should not be " + _bv + ". Threw exception " + _exception);
+ else if (!isResultCorrect(_av, _bv)) {
+ if (!_quiet) {
+ testPassed(_a + " is not " + _b);
+ }
+ } else
+ testFailed(_a + " should not be " + _bv + ".");
+}
+
+function shouldBecomeDifferent(_a, _b, _completionHandler, _timeout)
+{
+ if (typeof _a != "string" || typeof _b != "string")
+ debug("WARN: shouldBecomeDifferent() expects string arguments");
+ if (_timeout === undefined)
+ _timeout = 500;
+
+ var _bv;
+ var _condition = function() {
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+ _bv = eval(_b);
+ if (_exception)
+ testFailed(_a + " should became not equal to " + _bv + ". Threw exception " + _exception);
+ if (!isResultCorrect(_av, _bv)) {
+ testPassed(_a + " became different from " + _b);
+ return true;
+ }
+ return false;
+ };
+ var _failureTime = Date.now() + _timeout;
+ var _failureHandler = function () {
+ testFailed(_a + " did not become different from " + _bv + " in " + (_timeout / 1000) + " seconds.");
+ _completionHandler();
+ };
+ _waitForCondition(_condition, _failureTime, _completionHandler, _failureHandler);
+}
+
+function shouldBeTrue(a, quiet) { shouldBe(a, "true", quiet); }
+function shouldBeTrueQuiet(a) { shouldBe(a, "true", true); }
+function shouldBeFalse(a, quiet) { shouldBe(a, "false", quiet); }
+function shouldBeNaN(a, quiet) { shouldBe(a, "NaN", quiet); }
+function shouldBeNull(a, quiet) { shouldBe(a, "null", quiet); }
+function shouldBeZero(a, quiet) { shouldBe(a, "0", quiet); }
+
+function shouldBeEqualToString(a, b)
+{
+ if (typeof a !== "string" || typeof b !== "string")
+ debug("WARN: shouldBeEqualToString() expects string arguments");
+ var unevaledString = JSON.stringify(b);
+ shouldBe(a, unevaledString);
+}
+
+function shouldBeEqualToNumber(a, b)
+{
+ if (typeof a !== "string" || typeof b !== "number")
+ debug("WARN: shouldBeEqualToNumber() expects a string and a number arguments");
+ var unevaledString = JSON.stringify(b);
+ shouldBe(a, unevaledString);
+}
+
+function shouldBeEmptyString(a) { shouldBeEqualToString(a, ""); }
+
+function shouldEvaluateTo(actual, expected, opt_tolerance) {
+ // A general-purpose comparator. 'actual' should be a string to be
+ // evaluated, as for shouldBe(). 'expected' may be any type and will be
+ // used without being eval'ed.
+ if (expected == null) {
+ // Do this before the object test, since null is of type 'object'.
+ shouldBeNull(actual);
+ } else if (typeof expected == "undefined") {
+ shouldBeUndefined(actual);
+ } else if (typeof expected == "function") {
+ // All this fuss is to avoid the string-arg warning from shouldBe().
+ try {
+ var actualValue = eval(actual);
+ } catch (e) {
+ testFailed("Evaluating " + actual + ": Threw exception " + e);
+ return;
+ }
+ shouldBe("'" + actualValue.toString().replace(/\n/g, "") + "'",
+ "'" + expected.toString().replace(/\n/g, "") + "'");
+ } else if (typeof expected == "object") {
+ shouldBeTrue(actual + " == '" + expected + "'");
+ } else if (typeof expected == "string") {
+ shouldBe(actual, expected, undefined, opt_tolerance);
+ } else if (typeof expected == "boolean") {
+ shouldBe("typeof " + actual, "'boolean'");
+ if (expected)
+ shouldBeTrue(actual);
+ else
+ shouldBeFalse(actual);
+ } else if (typeof expected == "number") {
+ if (opt_tolerance)
+ shouldBeCloseTo(actual, expected, opt_tolerance);
+ else
+ shouldBe(actual, stringify(expected));
+ } else {
+ debug(expected + " is unknown type " + typeof expected);
+ shouldBeTrue(actual, "'" +expected.toString() + "'");
+ }
+}
+
+function shouldEvaluateToSameObject(actual, expected, quiet) {
+ if (typeof actual != "string")
+ debug("WARN: shouldEvaluateToSameObject() expects the first argument (actual) to be a string.");
+ try {
+ actualEvaled = eval(actual);
+ } catch (e) {
+ testFailed("Evaluating " + actual + ": Threw exception " + e);
+ return;
+ }
+ if (isResultCorrect(actualEvaled, expected)) {
+ if (!quiet)
+ testPassed(actual + " is " + stringify(expected));
+ } else {
+ testFailed(actual + " should be " + stringify(expected) + ". Was " + stringify(actualEvaled));
+ }
+}
+
+function shouldBeNonZero(_a)
+{
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+
+ if (_exception)
+ testFailed(_a + " should be non-zero. Threw exception " + _exception);
+ else if (_av != 0)
+ testPassed(_a + " is non-zero.");
+ else
+ testFailed(_a + " should be non-zero. Was " + _av);
+}
+
+function shouldBeNonNull(_a)
+{
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+
+ if (_exception)
+ testFailed(_a + " should be non-null. Threw exception " + _exception);
+ else if (_av != null)
+ testPassed(_a + " is non-null.");
+ else
+ testFailed(_a + " should be non-null. Was " + _av);
+}
+
+function shouldBeUndefined(_a)
+{
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+
+ if (_exception)
+ testFailed(_a + " should be undefined. Threw exception " + _exception);
+ else if (typeof _av == "undefined")
+ testPassed(_a + " is undefined.");
+ else
+ testFailed(_a + " should be undefined. Was " + _av);
+}
+
+function shouldBeDefined(_a)
+{
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+
+ if (_exception)
+ testFailed(_a + " should be defined. Threw exception " + _exception);
+ else if (_av !== undefined)
+ testPassed(_a + " is defined.");
+ else
+ testFailed(_a + " should be defined. Was " + _av);
+}
+
+function shouldBeGreaterThan(_a, _b) {
+ if (typeof _a != "string" || typeof _b != "string")
+ debug("WARN: shouldBeGreaterThan expects string arguments");
+
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+ var _bv = eval(_b);
+
+ if (_exception)
+ testFailed(_a + " should be > " + _b + ". Threw exception " + _exception);
+ else if (typeof _av == "undefined" || _av <= _bv)
+ testFailed(_a + " should be > " + _b + ". Was " + _av + " (of type " + typeof _av + ").");
+ else
+ testPassed(_a + " is > " + _b);
+}
+
+function shouldBeGreaterThanOrEqual(_a, _b) {
+ if (typeof _a != "string" || typeof _b != "string")
+ debug("WARN: shouldBeGreaterThanOrEqual expects string arguments");
+
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+ var _bv = eval(_b);
+
+ if (_exception)
+ testFailed(_a + " should be >= " + _b + ". Threw exception " + _exception);
+ else if (typeof _av == "undefined" || _av < _bv)
+ testFailed(_a + " should be >= " + _b + ". Was " + _av + " (of type " + typeof _av + ").");
+ else
+ testPassed(_a + " is >= " + _b);
+}
+
+function shouldNotThrow(_a) {
+ try {
+ eval(_a);
+ testPassed(_a + " did not throw exception.");
+ } catch (e) {
+ testFailed(_a + " should not throw exception. Threw exception " + e + ".");
+ }
+}
+
+function shouldThrow(_a, _e)
+{
+ var _exception;
+ var _av;
+ try {
+ _av = eval(_a);
+ } catch (e) {
+ _exception = e;
+ }
+
+ var _ev;
+ if (_e)
+ _ev = eval(_e);
+
+ if (_exception) {
+ if (typeof _e == "undefined" || _exception == _ev)
+ testPassed(_a + " threw exception " + _exception + ".");
+ else
+ testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + _exception + ".");
+ } else if (typeof _av == "undefined")
+ testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined.");
+ else
+ testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
+}
+
+function shouldBeNow(a, delta)
+{
+ // Right now, V8 and Chromium / Blink use two different clock
+ // implementations. On Windows, the implementations are non-trivial and can
+ // be slightly out of sync. The delta is intended to compensate for that.
+ //
+ // FIXME: reconsider this when the V8 and Blink clocks get unified, see http://crbug.com/324110
+ if (delta === undefined)
+ delta = 1000;
+
+ for (var i = 0; i < 1000; ++i) {
+ var startDate = Date.now();
+ var av = eval(a);
+ var date = av.valueOf();
+ var endDate = Date.now();
+
+ // On some occasions such as NTP updates, the current time can go
+ // backwards. This should only happen rarely, so we can get away with
+ // retrying the test a few times if we detect the time going backwards.
+ if (startDate > endDate)
+ continue;
+
+ if (typeof date !== "number") {
+ testFailed(a + " is not a number or a Date. Got " + av);
+ return;
+ }
+ if (date < startDate - delta) {
+ testFailed(a + " is not the curent time. Got " + av + " which is " + (startDate - date) / 1000 + " seconds in the past.");
+ return;
+ }
+ if (date > endDate + delta) {
+ testFailed(a + " is not the current time. Got " + av + " which is " + (date - endDate) / 1000 + " seconds in the future.");
+ return;
+ }
+
+ testPassed(a + " is equivalent to Date.now().");
+ return;
+ }
+ testFailed(a + " cannot be tested against the current time. The clock is going backwards too often.");
+}
+
+function expectError()
+{
+ if (expectingError) {
+ testFailed("shouldHaveError() called twice before an error occurred!");
+ }
+ expectingError = true;
+}
+
+function shouldHaveHadError(message)
+{
+ if (expectingError) {
+ testFailed("No error thrown between expectError() and shouldHaveHadError()");
+ return;
+ }
+
+ if (expectedErrorMessage) {
+ if (!message)
+ testPassed("Got expected error");
+ else if (expectedErrorMessage.indexOf(message) !== -1)
+ testPassed("Got expected error: '" + message + "'");
+ else
+ testFailed("Unexpected error '" + message + "'");
+ expectedErrorMessage = undefined;
+ return;
+ }
+
+ testFailed("expectError() not called before shouldHaveHadError()");
+}
+
+// With Oilpan tests that rely on garbage collection need to go through
+// the event loop in order to get precise garbage collections. Oilpan
+// uses conservative stack scanning when not at the event loop and that
+// can artificially keep objects alive. Therefore, tests that need to check
+// that something is dead need to use this asynchronous collectGarbage
+// function.
+function asyncGC(callback) {
+ var documentsBefore = window.internals.numberOfLiveDocuments();
+ GCController.collectAll();
+ // FIXME: we need a better way of waiting for chromium events to happen
+ setTimeout(function () {
+ var documentsAfter = window.internals.numberOfLiveDocuments();
+ if (documentsAfter < documentsBefore)
+ asyncGC(callback);
+ else
+ callback();
+ }, 0);
+}
+
+function gc() {
+ if (typeof GCController !== "undefined")
+ GCController.collectAll();
+ else {
+ var gcRec = function (n) {
+ if (n < 1)
+ return {};
+ var temp = {i: "ab" + i + (i / 100000)};
+ temp += "foo";
+ gcRec(n-1);
+ };
+ for (var i = 0; i < 1000; i++)
+ gcRec(10);
+ }
+}
+
+function asyncMinorGC(callback) {
+ if (typeof GCController !== "undefined")
+ GCController.minorCollect();
+ else
+ testFailed("Minor GC is available only when you enable the --expose-gc option in V8.");
+ // FIXME: we need a better way of waiting for chromium events to happen
+ setTimeout(callback, 0);
+}
+
+function setPrintTestResultsLazily() {
+ self._lazyTestResults = self._lazyTestResults || [];
+}
+
+function isSuccessfullyParsed()
+{
+ // FIXME: Remove this and only report unexpected syntax errors.
+ successfullyParsed = !unexpectedErrorMessage;
+ shouldBeTrue("successfullyParsed");
+ debug(' TEST COMPLETE');
+}
+
+var wasPostTestScriptParsed, wasFinishJSTestCalled, jsTestIsAsync;
+
+// It's possible for an async test to call finishJSTest() before js-test-post.js
+// has been parsed.
+function finishJSTest()
+{
+ wasFinishJSTestCalled = true;
+ if (!self.wasPostTestScriptParsed)
+ return;
+ isSuccessfullyParsed();
+
+ if (self._lazyDescription)
+ getOrCreateTestElement("description", "p").appendChild(self._lazyDescription);
+
+ if (self._lazyTestResults && self._lazyTestResults.length > 0) {
+ var consoleElement = getOrCreateTestElement("console", "div");
+ self._lazyTestResults.forEach(function(msg) {
+ var span = document.createElement("span");
+ consoleElement.appendChild(span);
+ span.innerHTML = msg + ' ';
+ });
+ }
+
+ if (self.jsTestIsAsync && self.testRunner)
+ testRunner.notifyDone();
+}
+
+function startWorker(testScriptURL, workerType)
+{
+ self.jsTestIsAsync = true;
+ debug('Starting worker: ' + testScriptURL);
+ var worker;
+ if (workerType == 'shared')
+ worker = new SharedWorker(testScriptURL, "Shared Worker");
+ else if (workerType == 'compositor')
+ worker = new CompositorWorker(testScriptURL);
+ else
+ worker = new Worker(testScriptURL);
+ worker.onmessage = function(event)
+ {
+ var workerPrefix = "[Worker] ";
+ if (event.data.length < 5 || event.data.charAt(4) != ':') {
+ debug(workerPrefix + event.data);
+ return;
+ }
+ var code = event.data.substring(0, 4);
+ var payload = workerPrefix + event.data.substring(5);
+ if (code == "PASS")
+ testPassed(payload);
+ else if (code == "FAIL")
+ testFailed(payload);
+ else if (code == "DESC")
+ description(payload);
+ else if (code == "DONE")
+ finishJSTest();
+ else
+ debug(workerPrefix + event.data);
+ };
+
+ worker.onerror = function(event)
+ {
+ debug('Got error from worker: ' + event.message);
+ finishJSTest();
+ };
+
+ if (workerType == 'shared') {
+ worker.port.onmessage = function(event) { worker.onmessage(event); };
+ worker.port.start();
+ }
+ return worker;
+}
+
+if (isWorker()) {
+ var workerPort = self;
+ if (self.name == "Shared Worker") {
+ self.onconnect = function(e) {
+ workerPort = e.ports[0];
+ workerPort.onmessage = function(event)
+ {
+ var colon = event.data.indexOf(":");
+ if (colon == -1) {
+ testFailed("Unrecognized message to shared worker: " + event.data);
+ return;
+ }
+ var code = event.data.substring(0, colon);
+ var payload = event.data.substring(colon + 1);
+ try {
+ if (code == "IMPORT")
+ importScripts(payload);
+ else
+ testFailed("Unrecognized message to shared worker: " + event.data);
+ } catch (ex) {
+ testFailed("Caught exception in shared worker onmessage: " + ex);
+ }
+ };
+ };
+ }
+ description = function(msg, quiet) {
+ workerPort.postMessage('DESC:' + msg);
+ };
+ testFailed = function(msg) {
+ workerPort.postMessage('FAIL:' + msg);
+ };
+ testPassed = function(msg) {
+ workerPort.postMessage('PASS:' + msg);
+ };
+ finishJSTest = function() {
+ workerPort.postMessage('DONE:');
+ };
+ debug = function(msg) {
+ workerPort.postMessage(msg);
+ };
+}
diff --git a/bower_components/custom-elements/tests/chromium/resources/magnitude-perf.js b/bower_components/custom-elements/tests/chromium/resources/magnitude-perf.js
new file mode 100644
index 0000000..4dfd21d
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/magnitude-perf.js
@@ -0,0 +1,444 @@
+// Magnitude verifies time complexity of a function.
+// Magnitude.run can be called multiple times in a single script if desired,
+// optionally with different parameters each time.
+//
+// Usage:
+//
+//
+//
+// setup: function to run once before the test-loop. Takes a magnitude
+// argument that is the value of 'n'.
+// test: function whose runtime is being tested. Also takes a magnitude
+// argument.
+// expected: one of the run-time constants listed below, e.g.:
+// Magnitude.CONSTANT, Magnitude.LINEAR, etc.
+
+if (window.testRunner)
+ testRunner.dumpAsText();
+
+// Namespace
+var Magnitude = {};
+
+// Description of test; prepended to the dumped markup
+Magnitude.description = function(description)
+{
+ Magnitude._log(description);
+};
+
+// Parameters (customize per test)
+// See "Time Complexity Tests" document for details:
+// http://dev.chromium.org/developers/testing/time-complexity-tests
+// Specify over which range the growth rate should hold:
+// 2^n ... 2^(n+k-1) where n = initialExponent, k = numPoints
+Magnitude.initialExponent = 0;
+Magnitude.numPoints = 8;
+// Number of trials to run
+// (Trial = compute times for all magnitudes, compute statistical test,
+// decide if for this dataset, the data fits the model)
+Magnitude.numTrials = 3;
+// Fraction of trials that must succeed for test overall to PASS
+// (Default 50% means 2 out of 3 must succeed)
+Magnitude.successThreshold = 0.50;
+// Run = for each magnitude, run test function until pass this time limit,
+// then stop and compute average time
+Magnitude.millisecondsPerRun = 25;
+// Strict tolerance, so noisy tests explicitly state noisiness
+// Ok to relax for noisy tests;
+// try tolerance = 0.10 or 0.20, and/or trim = 1 or 2 to relax slightly
+// tolerance is "max (trimmed) deviation from expected",
+// where "expected" is:
+// * expected slope (linear, polynomial),
+// * median value (constant),
+// * predicted value in linear regression (logarithmic).
+// For log this often needs to be very large (due to scaling), and 1.00 is ok.
+Magnitude.trim = 0; // trim = 1 useful if unusual value on initial run
+Magnitude.tolerance = 0.05;
+
+Magnitude.CONSTANT = 'O(1)';
+Magnitude.LINEAR = 'O(n)';
+Magnitude.POLYNOMIAL = '>=O(n^2)';
+
+// Utility functions
+Magnitude._max = function(array) {
+ return Math.max.apply(null, array);
+};
+
+Magnitude._min = function(array) {
+ return Math.min.apply(null, array);
+};
+
+Magnitude._sortTrimArray = function(array, trim) {
+ // sort array, then trim both ends
+ // used for computing trimmed maximum absolute deviation
+ var sorted_array = array.map(Math.abs).sort(function(a, b) { return a - b; });
+ if (!trim)
+ return sorted_array;
+ else
+ return sorted_array.slice(trim, -trim);
+};
+
+Magnitude._relativeDeviations = function(array, ref)
+{
+ return array.map(function(x) { return (x - ref) / ref; });
+};
+
+Magnitude._absSortDownTrimTop = function(array, trim) {
+ // only trim the top of array
+ // used for computing trimmed maximum absolute deviation
+ if (trim === undefined)
+ trim = 0;
+ return array.map(Math.abs).sort(
+ function(a, b) { return b - a; }).slice(trim);
+};
+
+Magnitude._median = function(array) {
+ array.sort(function(a, b) { return a - b; });
+ var len = array.length;
+ if (!len)
+ return;
+ var half = Math.floor(len / 2);
+ if (len % 2)
+ return array[half];
+ return (array[half - 1] + array[half]) / 2;
+};
+
+// Logging functions
+Magnitude._log = function(msg)
+{
+ if (!Magnitude._container)
+ Magnitude._container = document.createElement('pre');
+ Magnitude._container.appendChild(document.createTextNode(msg + '\n'));
+};
+
+Magnitude._debug = function(msg)
+{
+ Magnitude._debugLog += msg + '\n';
+};
+
+Magnitude._logRunTimes = function()
+{
+ // Print out the magnitudes and times in CSV
+ // to afford easy copy-paste to a charting application.
+ Magnitude._debug('magnitudes: ' + Magnitude._magnitudes.join(','));
+ Magnitude._debug('times: ' + Magnitude._times.join(','));
+};
+
+Magnitude._for = function(n, body, callback)
+{
+ var i = 0;
+ var results = [];
+
+ function iteration(result) {
+ results.push(result);
+ if (++i === n)
+ callback(results);
+ else
+ body(i, iteration);
+ }
+
+ if (Magnitude._async) {
+ body(i, iteration);
+ } else {
+ for (; i < n; ++i) {
+ body(i, function(result) {
+ results.push(result);
+ });
+ }
+ callback(results);
+ }
+};
+
+Magnitude._while = function(condition, body, callback)
+{
+ function iteration() {
+ if (condition())
+ body(iteration);
+ else
+ callback();
+ }
+
+ if (Magnitude._async) {
+ iteration();
+ } else {
+ while (condition()) {
+ body(function() {});
+ }
+ callback();
+ }
+};
+
+// Main
+Magnitude.run = function(setup, test, expected)
+{
+ function runTest(magnitude, callback) {
+ test(magnitude);
+ callback();
+ }
+ Magnitude._run(setup, runTest, expected, false);
+};
+
+Magnitude.runAsync = function(setup, test, expected)
+{
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+ window.addEventListener('load', function() {
+ Magnitude._run(setup, test, expected, true);
+ }, false);
+};
+
+Magnitude._run = function(setup, test, expected, async)
+{
+ Magnitude._async = async;
+ Magnitude._debugLog = '\nDEBUG LOG:\n';
+ Magnitude._debug('Expected complexity: ' + expected);
+
+ Magnitude._exponents = [];
+ Magnitude._magnitudes = [];
+ var maxExponent = Magnitude.initialExponent + Magnitude.numPoints;
+ for (var i = Magnitude.initialExponent; i < maxExponent; i++) {
+ Magnitude._exponents.push(i);
+ Magnitude._magnitudes.push(Math.pow(2, i));
+ }
+
+ Magnitude._numSuccesses = 0;
+ function runTrial(trialNumber, nextTrial)
+ {
+ Magnitude._trialNumber = trialNumber;
+ Magnitude._debug('\nTrial #' + trialNumber);
+ Magnitude._for(Magnitude.numPoints, Magnitude._runTime.bind(null, setup, test), completeTrial.bind(null, nextTrial));
+ }
+ function completeTrial(nextTrial, times)
+ {
+ Magnitude._times = times;
+ Magnitude._logRunTimes();
+ switch (expected) {
+ case Magnitude.CONSTANT:
+ passed = Magnitude._isConstant();
+ break;
+ case Magnitude.LINEAR:
+ passed = Magnitude._isLinear();
+ break;
+ case Magnitude.POLYNOMIAL:
+ passed = Magnitude._isPolynomial();
+ break;
+ default:
+ Magnitude._log('FAIL: unrecognized order of growth: ' + expected);
+ passed = false;
+ break;
+ }
+ Magnitude._debug('Trial #' + Magnitude._trialNumber + ': ' +
+ (passed ? 'SUCCESS' : 'FAILURE'));
+ if (passed)
+ Magnitude._numSuccesses++;
+ nextTrial();
+ }
+ Magnitude._for(Magnitude.numTrials, runTrial, Magnitude._finish);
+};
+
+Magnitude._finish = function()
+{
+ var neededToPass = Magnitude.numTrials * Magnitude.successThreshold;
+ Magnitude._debug('Successes: ' + Magnitude._numSuccesses + ', need ' +
+ neededToPass + ' (' + (100 * Magnitude.successThreshold) + '%) ' +
+ 'to pass');
+ var passedOverall = (Magnitude._numSuccesses >= neededToPass);
+ Magnitude._log(passedOverall ? 'PASS' : 'FAIL');
+
+ // By default don't log detailed information to layout test results,
+ // in order to keep expected results consistent from run to run.
+ if (!window.testRunner || !passedOverall)
+ Magnitude._log(Magnitude._debugLog);
+
+ if (Magnitude._async && window.testRunner)
+ testRunner.notifyDone();
+};
+
+Magnitude._runTime = function(setup, test, pointIndex, callback)
+{
+ var magnitude = Magnitude._magnitudes[pointIndex];
+ setup(magnitude);
+
+ var debugStr = 'run for magnitude ' + magnitude;
+ if (window.GCController) {
+ if (GCController.getJSObjectCount)
+ debugStr += ' jsObjectCountBefore ' + GCController.getJSObjectCount();
+
+ GCController.collectAll();
+
+ if (GCController.getJSObjectCount)
+ debugStr += ' jsObjectCountAfter ' + GCController.getJSObjectCount();
+ }
+
+ Magnitude._debug(debugStr);
+
+ var nowFunction = window.performance && window.performance.now ?
+ window.performance.now.bind(window.performance) : Date.now;
+
+ // Possibly run multiple times, to deal with delays at end
+ var runOk = false;
+ var attempt = 0;
+ var maxAttempts = 5;
+ var millisecondsPerIteration;
+ var totalTimeMilliseconds;
+ var iterations;
+
+ function iteration(nextIteration)
+ {
+ var start = nowFunction();
+ iterations = 0;
+ totalTimeMilliseconds = 0;
+ function completeRun(nextRun)
+ {
+ iterations++;
+ totalTimeMilliseconds = nowFunction() - start;
+ nextRun();
+ }
+ Magnitude._while(function() { return totalTimeMilliseconds < Magnitude.millisecondsPerRun; }, function(nextRun) { test(magnitude, completeRun.bind(null, nextRun)); }, completeIteration.bind(null, nextIteration));
+ }
+
+ function completeIteration(nextIteration)
+ {
+ millisecondsPerIteration = totalTimeMilliseconds / iterations;
+ Magnitude._debug(iterations + ' iterations in ' +
+ totalTimeMilliseconds + ' milliseconds, ' +
+ 'average ' + millisecondsPerIteration +
+ ' milliseconds per iteration');
+
+ var overTime = totalTimeMilliseconds - Magnitude.millisecondsPerRun;
+ var relativeOverTimeTolerance = 0.001;
+ var overTimeTolerance = Magnitude.millisecondsPerRun *
+ relativeOverTimeTolerance;
+ // If overTime is more than the duration of a run,
+ // there was some delay, which introduces noise.
+ // Allow a small amount of tolerance.
+ if (overTime < (millisecondsPerIteration + overTimeTolerance))
+ runOk = true;
+ else {
+ Magnitude._debug('over-time: ' + overTime +
+ ' exceeds average run-time ' + millisecondsPerIteration +
+ ' by more than tolerance of ' + overTimeTolerance +
+ ' assuming delay');
+ attempt++;
+ if (attempt < maxAttempts)
+ Magnitude._debug('Retrying to reduce delay noise');
+ else {
+ Magnitude._debug('Failed to reduce delay noise after ' +
+ maxAttempts + ' attempts, proceeding with noisy data');
+ runOk = true;
+ }
+ }
+ nextIteration();
+ }
+ Magnitude._while(function() { return !runOk; }, iteration, function() { callback(millisecondsPerIteration); });
+};
+
+// Auxiliary computations
+Magnitude._log2Ratios = function()
+{
+ // Compute base-2 logarithm of ratios of times,
+ // equivalently the difference of the base-2 logarithms:
+ // log_2(t[i+1]/t[i]) = log_2(t[i+1]) - log_2(t[i])
+ // Since times are exponentially spaced (base 2),
+ // this is the slope of the step on the log-log scale,
+ // and hence for O(n^k) growth should be k (the exponent).
+ var ratioArray = [];
+ var log2RatioArray = [];
+ for (var i = 0; i < Magnitude.numPoints - 1; i++) {
+ var ratio = Magnitude._times[i + 1] / Magnitude._times[i];
+ var log2Ratio = Math.log(ratio) / Math.log(2);
+ ratioArray.push(ratio);
+ log2RatioArray.push(log2Ratio);
+ }
+ Magnitude._debug('ratios: ' + ratioArray.join(','));
+ Magnitude._debug('log-ratios (base 2): ' + log2RatioArray.join(','));
+ return log2RatioArray;
+};
+
+// Statistical tests
+Magnitude._isConstant = function()
+{
+ // Time should be approximately constant.
+ // To deal with noise, instead of constant, check that
+ // (trimmed) abs relative deviation from median is within tolerance of 0.
+ var times = Magnitude._times;
+ var median = Magnitude._median(times);
+ var relativeDeviations = Magnitude._relativeDeviations(times, median);
+ Magnitude._debug('Median time: ' + median);
+ Magnitude._debug('Relative deviations: ' + relativeDeviations.join(','));
+ var trimmedAbsRelativeDeviations = Magnitude._absSortDownTrimTop(relativeDeviations, Magnitude.trim);
+ Magnitude._debug('Trimmed sorted absolute relative deviations: ' +
+ trimmedAbsRelativeDeviations.join(','));
+ var maxAbsDeviation = trimmedAbsRelativeDeviations[0];
+ Magnitude._debug('Maximum Absolute Relative Deviation: ' + maxAbsDeviation);
+ return maxAbsDeviation <= Magnitude.tolerance;
+};
+
+Magnitude._isLinear = function()
+{
+ // Exponent of a monomial is the slope on the log-log scale.
+ // Magnitudes are exponentially stepped, so log ratio is slope
+ // of secant on log-log scale.
+ // In linear growth, (trimmed) log2Ratio should equal 1, to within tolerance
+ // (Special case of polynomial; see below for why this is separate.)
+ //
+ // Can do better by removing outlying points (and then computing the
+ // slope between the neighboring points) instead of trimming ratios,
+ // so we retain the data of the slope of that double step, but since we are
+ // only looking at the Maximum (Absolute) Deviation, in practice these
+ // generally amount to the same: given an outlier, the slope coming into
+ // the point and the slope going out will generally be high/low or low/high,
+ // and thus both be trimmed, while the slope of the double step will
+ // generally not be extreme, so not informative.
+ var logRatios = Magnitude._log2Ratios();
+ var trimmedLogRatios = Magnitude._sortTrimArray(logRatios, Magnitude.trim);
+ var minLogRatio = Magnitude._min(trimmedLogRatios);
+ var maxLogRatio = Magnitude._max(trimmedLogRatios);
+ var maxAbsDeviation = Math.max(Math.abs(1 - minLogRatio),
+ Math.abs(maxLogRatio - 1));
+ Magnitude._debug('Maximum Absolute Deviation: ' + maxAbsDeviation);
+ Magnitude._debug('Tolerance: ' + Magnitude.tolerance);
+ return maxAbsDeviation <= Magnitude.tolerance;
+};
+
+Magnitude._isPolynomial = function()
+{
+ // Exponent of a monomial is the slope on the log-log scale.
+ // Magnitudes are exponentially stepped, so log ratio is slope
+ // of secant on log-log scale.
+ // Polynomial growth is expected to be O(n^2) or greater,
+ // so logRatio should be at least 2: check (trimmed) min with tolerance
+ //
+ // Linear is fundamentally a special case of polynomial,
+ // but here not specifying a specific exponent, and instead testing
+ // that it grows *at least* quadratically (>= 2, rather than = 2 or = 3).
+ // Thus we have separate functions.
+ var logRatios = Magnitude._log2Ratios();
+ var trimmedLogRatios = Magnitude._sortTrimArray(logRatios, Magnitude.trim);
+ var minLogRatio = Magnitude._min(trimmedLogRatios);
+ var absDeviationMin = Math.abs(2 - minLogRatio);
+ Magnitude._debug('Absolute Deviation of Minimum: ' + absDeviationMin);
+ Magnitude._debug('Tolerance: ' + Magnitude.tolerance);
+ return absDeviationMin <= Magnitude.tolerance;
+};
+
+// Register listener
+window.addEventListener('load', function() {
+ // FIXME: Add Magnitude.waitUntilDone/notifyDone for tests that need to
+ // operate after the load event has fired.
+ if (window.testRunner)
+ document.body.innerHTML = '';
+ document.body.appendChild(Magnitude._container);
+}, false);
diff --git a/bower_components/custom-elements/tests/chromium/resources/mojo-helpers.js b/bower_components/custom-elements/tests/chromium/resources/mojo-helpers.js
new file mode 100644
index 0000000..7553fa5
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/mojo-helpers.js
@@ -0,0 +1,92 @@
+/*
+ * mojo-helpers contains extensions to testharness.js useful for consuming
+ * and mocking Mojo services directly within test code.
+ */
+'use strict';
+
+// Fix up the global window.define, since all baked-in Mojo modules expect to
+// find it there. This define() also returns a promise to the module.
+let define = (function(){
+ let moduleCache = new Map();
+
+ return function(name, deps, factory) {
+ let promise = moduleCache.get(name);
+ if (promise === undefined) {
+ // This promise must be cached as mojo.define will only call the factory
+ // function the first time the module is defined.
+ promise = new Promise(resolve => {
+ mojo.define(name, deps, (...modules) => {
+ let result = factory(...modules);
+ resolve(result);
+ return result;
+ });
+ });
+ moduleCache.set(name, promise);
+ }
+ return promise;
+ }
+})();
+
+define('Mojo Helpers', [
+ 'mojo/public/js/core',
+ 'mojo/public/js/router',
+ 'mojo/public/js/support',
+ 'content/public/renderer/frame_interfaces',
+ 'content/public/renderer/interfaces',
+], (core, router, support, frameInterfaces, interfaces) => {
+ let tearDown = () => {
+ frameInterfaces.clearInterfaceOverridesForTesting();
+ interfaces.clearInterfaceOverridesForTesting();
+ };
+ addEventListener('unload', tearDown);
+ if (window.add_completion_callback)
+ add_completion_callback(tearDown);
+
+ return {
+ core,
+ router,
+ support,
+ frameInterfaces,
+ interfaces,
+ };
+});
+
+// Returns a promise to an object that exposes common Mojo module interfaces.
+// Additional modules to load can be specified in the |modules| parameter. The
+// result will contain them, in the same order, in the |modules| field.
+function loadMojoModules(name, modules = []) {
+ return define('Mojo modules: ' + name,
+ [ 'Mojo Helpers' ].concat(modules),
+ (mojo, ...rest) => {
+ mojo.modules = rest
+ return mojo;
+ });
+}
+
+// Runs a promise_test which depends on the Mojo system API modules available to
+// all layout tests. The test implementation function is called with an Object
+// that exposes common Mojo module interfaces.
+function mojo_test(func, name, properties) {
+ promise_test(() => loadMojoModules(name).then(mojo => {
+ return Promise.resolve(func(mojo));
+ }), name, properties);
+}
+
+// Waits for a message to become available on a pipe.
+function mojo_wait_for_incoming_message(mojo, pipe) {
+ return new Promise((resolve, reject) => {
+ mojo.support.asyncWait(pipe, mojo.core.HANDLE_SIGNAL_READABLE, result => {
+ if (result != mojo.core.RESULT_OK) {
+ reject(result);
+ return;
+ }
+ let buffer, handles;
+ ({ result, buffer, handles } = mojo.core.readMessage(pipe, 0));
+ if (result !== mojo.core.RESULT_OK) {
+ reject(result);
+ return;
+ }
+ resolve({ buffer, handles });
+ });
+ });
+};
diff --git a/bower_components/custom-elements/tests/chromium/resources/opensans/LICENSE b/bower_components/custom-elements/tests/chromium/resources/opensans/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/opensans/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/bower_components/custom-elements/tests/chromium/resources/opensans/OpenSans-Regular.woff b/bower_components/custom-elements/tests/chromium/resources/opensans/OpenSans-Regular.woff
new file mode 100644
index 0000000..55b25f8
Binary files /dev/null and b/bower_components/custom-elements/tests/chromium/resources/opensans/OpenSans-Regular.woff differ
diff --git a/bower_components/custom-elements/tests/chromium/resources/opensans/README b/bower_components/custom-elements/tests/chromium/resources/opensans/README
new file mode 100644
index 0000000..902c420
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/opensans/README
@@ -0,0 +1,5 @@
+Open Sans is a humanist sans serif typeface designed by Steve Matteson,
+Type Director of Ascender Corp. It was commissioned by Google.
+
+More information:
+ http://www.google.com/fonts/specimen/Open+Sans
diff --git a/bower_components/custom-elements/tests/chromium/resources/plugin.js b/bower_components/custom-elements/tests/chromium/resources/plugin.js
new file mode 100644
index 0000000..d12c336
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/plugin.js
@@ -0,0 +1,12 @@
+// Ensure plugin load, run the speicified function, then finish the test.
+function startAfterLoadAndFinish(f, node) {
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+ window.addEventListener('load', function() {
+ if (window.internals)
+ internals.updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(node);
+ if (f)
+ f();
+ testRunner.notifyDone();
+ }, false);
+}
diff --git a/bower_components/custom-elements/tests/chromium/resources/run-after-layout-and-paint.js b/bower_components/custom-elements/tests/chromium/resources/run-after-layout-and-paint.js
new file mode 100644
index 0000000..e317341
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/run-after-layout-and-paint.js
@@ -0,0 +1,43 @@
+// Run a callback after layout and paint of all pending document changes.
+//
+// It has two modes:
+// - traditional mode, for existing tests, and tests needing customized notifyDone timing:
+// Usage:
+// if (window.testRunner)
+// testRunner.waitUntilDone();
+// runAfterLayoutAndPaint(function() {
+// ... // some code which modifies style/layout
+// if (window.testRunner)
+// testRunner.notifyDone();
+// // Or to ensure the next paint is executed before the test finishes:
+// // if (window.testRunner)
+// // runAfterAfterLayoutAndPaint(function() { testRunner.notifyDone() });
+// // Or notifyDone any time later if needed.
+// });
+//
+// - autoNotifyDone mode, for new tests which just need to change style/layout and finish:
+// Usage:
+// runAfterLayoutAndPaint(function() {
+// ... // some code which modifies style/layout
+// }, true);
+
+if (window.internals)
+ internals.runtimeFlags.paintUnderInvalidationCheckingEnabled = true;
+
+function runAfterLayoutAndPaint(callback, autoNotifyDone) {
+ if (!window.testRunner) {
+ // For manual test. Delay 500ms to allow us to see the visual change
+ // caused by the callback.
+ setTimeout(callback, 500);
+ return;
+ }
+
+ if (autoNotifyDone)
+ testRunner.waitUntilDone();
+
+ testRunner.layoutAndPaintAsyncThen(function() {
+ callback();
+ if (autoNotifyDone)
+ testRunner.notifyDone();
+ });
+}
diff --git a/bower_components/custom-elements/tests/chromium/resources/testharness.css b/bower_components/custom-elements/tests/chromium/resources/testharness.css
new file mode 100644
index 0000000..e2ed5a0
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/testharness.css
@@ -0,0 +1,102 @@
+html {
+ font-family:DejaVu Sans, Bitstream Vera Sans, Arial, Sans;
+}
+
+#log .warning,
+#log .warning a {
+ color: black;
+ background: yellow;
+}
+
+#log .error,
+#log .error a {
+ color: white;
+ background: red;
+}
+
+section#summary {
+ margin-bottom:1em;
+}
+
+table#results {
+ border-collapse:collapse;
+ table-layout:fixed;
+ width:100%;
+}
+
+table#results th:first-child,
+table#results td:first-child {
+ width:4em;
+}
+
+table#results th:last-child,
+table#results td:last-child {
+ width:50%;
+}
+
+table#results.assertions th:last-child,
+table#results.assertions td:last-child {
+ width:35%;
+}
+
+table#results th {
+ padding:0;
+ padding-bottom:0.5em;
+ border-bottom:medium solid black;
+}
+
+table#results td {
+ padding:1em;
+ padding-bottom:0.5em;
+ border-bottom:thin solid black;
+}
+
+tr.pass > td:first-child {
+ color:green;
+}
+
+tr.fail > td:first-child {
+ color:red;
+}
+
+tr.timeout > td:first-child {
+ color:red;
+}
+
+tr.notrun > td:first-child {
+ color:blue;
+}
+
+.pass > td:first-child, .fail > td:first-child, .timeout > td:first-child, .notrun > td:first-child {
+ font-variant:small-caps;
+}
+
+table#results span {
+ display:block;
+}
+
+table#results span.expected {
+ font-family:DejaVu Sans Mono, Bitstream Vera Sans Mono, Monospace;
+ white-space:pre;
+}
+
+table#results span.actual {
+ font-family:DejaVu Sans Mono, Bitstream Vera Sans Mono, Monospace;
+ white-space:pre;
+}
+
+span.ok {
+ color:green;
+}
+
+tr.error {
+ color:red;
+}
+
+span.timeout {
+ color:red;
+}
+
+span.ok, span.timeout, span.error {
+ font-variant:small-caps;
+}
\ No newline at end of file
diff --git a/bower_components/custom-elements/tests/chromium/resources/testharness.js b/bower_components/custom-elements/tests/chromium/resources/testharness.js
new file mode 100644
index 0000000..91dfab5
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/testharness.js
@@ -0,0 +1,2684 @@
+/*global self*/
+/*jshint latedef: nofunc*/
+/*
+Distributed under both the W3C Test Suite License [1] and the W3C
+3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
+policies and contribution forms [3].
+
+[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
+[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
+[3] http://www.w3.org/2004/10/27-testcases
+*/
+
+/* Documentation is in docs/api.md */
+
+(function ()
+{
+ var debug = false;
+ // default timeout is 10 seconds, test can override if needed
+ var settings = {
+ output:true,
+ harness_timeout:{
+ "normal":10000,
+ "long":60000
+ },
+ test_timeout:null,
+ message_events: ["start", "test_state", "result", "completion"]
+ };
+
+ var xhtml_ns = "http://www.w3.org/1999/xhtml";
+
+ /*
+ * TestEnvironment is an abstraction for the environment in which the test
+ * harness is used. Each implementation of a test environment has to provide
+ * the following interface:
+ *
+ * interface TestEnvironment {
+ * // Invoked after the global 'tests' object has been created and it's
+ * // safe to call add_*_callback() to register event handlers.
+ * void on_tests_ready();
+ *
+ * // Invoked after setup() has been called to notify the test environment
+ * // of changes to the test harness properties.
+ * void on_new_harness_properties(object properties);
+ *
+ * // Should return a new unique default test name.
+ * DOMString next_default_test_name();
+ *
+ * // Should return the test harness timeout duration in milliseconds.
+ * float test_timeout();
+ *
+ * // Should return the global scope object.
+ * object global_scope();
+ * };
+ */
+
+ /*
+ * A test environment with a DOM. The global object is 'window'. By default
+ * test results are displayed in a table. Any parent windows receive
+ * callbacks or messages via postMessage() when test events occur. See
+ * apisample11.html and apisample12.html.
+ */
+ function WindowTestEnvironment() {
+ this.name_counter = 0;
+ this.window_cache = null;
+ this.output_handler = null;
+ this.all_loaded = false;
+ var this_obj = this;
+ this.message_events = [];
+
+ this.message_functions = {
+ start: [add_start_callback, remove_start_callback,
+ function (properties) {
+ this_obj._dispatch("start_callback", [properties],
+ {type: "start", properties: properties});
+ }],
+
+ test_state: [add_test_state_callback, remove_test_state_callback,
+ function(test) {
+ this_obj._dispatch("test_state_callback", [test],
+ {type: "test_state",
+ test: test.structured_clone()});
+ }],
+ result: [add_result_callback, remove_result_callback,
+ function (test) {
+ this_obj.output_handler.show_status();
+ this_obj._dispatch("result_callback", [test],
+ {type: "result",
+ test: test.structured_clone()});
+ }],
+ completion: [add_completion_callback, remove_completion_callback,
+ function (tests, harness_status) {
+ var cloned_tests = map(tests, function(test) {
+ return test.structured_clone();
+ });
+ this_obj._dispatch("completion_callback", [tests, harness_status],
+ {type: "complete",
+ tests: cloned_tests,
+ status: harness_status.structured_clone()});
+ }]
+ }
+
+ on_event(window, 'load', function() {
+ this_obj.all_loaded = true;
+ });
+ }
+
+ WindowTestEnvironment.prototype._dispatch = function(selector, callback_args, message_arg) {
+ this._forEach_windows(
+ function(w, same_origin) {
+ if (same_origin) {
+ try {
+ var has_selector = selector in w;
+ } catch(e) {
+ // If document.domain was set at some point same_origin can be
+ // wrong and the above will fail.
+ has_selector = false;
+ }
+ if (has_selector) {
+ try {
+ w[selector].apply(undefined, callback_args);
+ } catch (e) {
+ if (debug) {
+ throw e;
+ }
+ }
+ }
+ }
+ if (supports_post_message(w) && w !== self) {
+ w.postMessage(message_arg, "*");
+ }
+ });
+ };
+
+ WindowTestEnvironment.prototype._forEach_windows = function(callback) {
+ // Iterate of the the windows [self ... top, opener]. The callback is passed
+ // two objects, the first one is the windows object itself, the second one
+ // is a boolean indicating whether or not its on the same origin as the
+ // current window.
+ var cache = this.window_cache;
+ if (!cache) {
+ cache = [[self, true]];
+ var w = self;
+ var i = 0;
+ var so;
+ var origins = location.ancestorOrigins;
+ while (w != w.parent) {
+ w = w.parent;
+ // In WebKit, calls to parent windows' properties that aren't on the same
+ // origin cause an error message to be displayed in the error console but
+ // don't throw an exception. This is a deviation from the current HTML5
+ // spec. See: https://bugs.webkit.org/show_bug.cgi?id=43504
+ // The problem with WebKit's behavior is that it pollutes the error console
+ // with error messages that can't be caught.
+ //
+ // This issue can be mitigated by relying on the (for now) proprietary
+ // `location.ancestorOrigins` property which returns an ordered list of
+ // the origins of enclosing windows. See:
+ // http://trac.webkit.org/changeset/113945.
+ if (origins) {
+ so = (location.origin == origins[i]);
+ } else {
+ so = is_same_origin(w);
+ }
+ cache.push([w, so]);
+ i++;
+ }
+ w = window.opener;
+ if (w) {
+ // window.opener isn't included in the `location.ancestorOrigins` prop.
+ // We'll just have to deal with a simple check and an error msg on WebKit
+ // browsers in this case.
+ cache.push([w, is_same_origin(w)]);
+ }
+ this.window_cache = cache;
+ }
+
+ forEach(cache,
+ function(a) {
+ callback.apply(null, a);
+ });
+ };
+
+ WindowTestEnvironment.prototype.on_tests_ready = function() {
+ var output = new Output();
+ this.output_handler = output;
+
+ var this_obj = this;
+
+ add_start_callback(function (properties) {
+ this_obj.output_handler.init(properties);
+ });
+
+ add_test_state_callback(function(test) {
+ this_obj.output_handler.show_status();
+ });
+
+ add_result_callback(function (test) {
+ this_obj.output_handler.show_status();
+ });
+
+ add_completion_callback(function (tests, harness_status) {
+ this_obj.output_handler.show_results(tests, harness_status);
+ });
+ this.setup_messages(settings.message_events);
+ };
+
+ WindowTestEnvironment.prototype.setup_messages = function(new_events) {
+ var this_obj = this;
+ forEach(settings.message_events, function(x) {
+ var current_dispatch = this_obj.message_events.indexOf(x) !== -1;
+ var new_dispatch = new_events.indexOf(x) !== -1;
+ if (!current_dispatch && new_dispatch) {
+ this_obj.message_functions[x][0](this_obj.message_functions[x][2]);
+ } else if (current_dispatch && !new_dispatch) {
+ this_obj.message_functions[x][1](this_obj.message_functions[x][2]);
+ }
+ });
+ this.message_events = new_events;
+ }
+
+ WindowTestEnvironment.prototype.next_default_test_name = function() {
+ //Don't use document.title to work around an Opera bug in XHTML documents
+ var title = document.getElementsByTagName("title")[0];
+ var prefix = (title && title.firstChild && title.firstChild.data) || "Untitled";
+ var suffix = this.name_counter > 0 ? " " + this.name_counter : "";
+ this.name_counter++;
+ return prefix + suffix;
+ };
+
+ WindowTestEnvironment.prototype.on_new_harness_properties = function(properties) {
+ this.output_handler.setup(properties);
+ if (properties.hasOwnProperty("message_events")) {
+ this.setup_messages(properties.message_events);
+ }
+ };
+
+ WindowTestEnvironment.prototype.add_on_loaded_callback = function(callback) {
+ on_event(window, 'load', callback);
+ };
+
+ WindowTestEnvironment.prototype.test_timeout = function() {
+ var metas = document.getElementsByTagName("meta");
+ for (var i = 0; i < metas.length; i++) {
+ if (metas[i].name == "timeout") {
+ if (metas[i].content == "long") {
+ return settings.harness_timeout.long;
+ }
+ break;
+ }
+ }
+ return settings.harness_timeout.normal;
+ };
+
+ WindowTestEnvironment.prototype.global_scope = function() {
+ return window;
+ };
+
+ /*
+ * Base TestEnvironment implementation for a generic web worker.
+ *
+ * Workers accumulate test results. One or more clients can connect and
+ * retrieve results from a worker at any time.
+ *
+ * WorkerTestEnvironment supports communicating with a client via a
+ * MessagePort. The mechanism for determining the appropriate MessagePort
+ * for communicating with a client depends on the type of worker and is
+ * implemented by the various specializations of WorkerTestEnvironment
+ * below.
+ *
+ * A client document using testharness can use fetch_tests_from_worker() to
+ * retrieve results from a worker. See apisample16.html.
+ */
+ function WorkerTestEnvironment() {
+ this.name_counter = 0;
+ this.all_loaded = true;
+ this.message_list = [];
+ this.message_ports = [];
+ }
+
+ WorkerTestEnvironment.prototype._dispatch = function(message) {
+ this.message_list.push(message);
+ for (var i = 0; i < this.message_ports.length; ++i)
+ {
+ this.message_ports[i].postMessage(message);
+ }
+ };
+
+ // The only requirement is that port has a postMessage() method. It doesn't
+ // have to be an instance of a MessagePort, and often isn't.
+ WorkerTestEnvironment.prototype._add_message_port = function(port) {
+ this.message_ports.push(port);
+ for (var i = 0; i < this.message_list.length; ++i)
+ {
+ port.postMessage(this.message_list[i]);
+ }
+ };
+
+ WorkerTestEnvironment.prototype.next_default_test_name = function() {
+ var suffix = this.name_counter > 0 ? " " + this.name_counter : "";
+ this.name_counter++;
+ return "Untitled" + suffix;
+ };
+
+ WorkerTestEnvironment.prototype.on_new_harness_properties = function() {};
+
+ WorkerTestEnvironment.prototype.on_tests_ready = function() {
+ var this_obj = this;
+ add_start_callback(
+ function(properties) {
+ this_obj._dispatch({
+ type: "start",
+ properties: properties,
+ });
+ });
+ add_test_state_callback(
+ function(test) {
+ this_obj._dispatch({
+ type: "test_state",
+ test: test.structured_clone()
+ });
+ });
+ add_result_callback(
+ function(test) {
+ this_obj._dispatch({
+ type: "result",
+ test: test.structured_clone()
+ });
+ });
+ add_completion_callback(
+ function(tests, harness_status) {
+ this_obj._dispatch({
+ type: "complete",
+ tests: map(tests,
+ function(test) {
+ return test.structured_clone();
+ }),
+ status: harness_status.structured_clone()
+ });
+ });
+ };
+
+ WorkerTestEnvironment.prototype.add_on_loaded_callback = function() {};
+
+ WorkerTestEnvironment.prototype.test_timeout = function() {
+ // Tests running in a worker don't have a default timeout. I.e. all
+ // worker tests behave as if settings.explicit_timeout is true.
+ return null;
+ };
+
+ WorkerTestEnvironment.prototype.global_scope = function() {
+ return self;
+ };
+
+ /*
+ * Dedicated web workers.
+ * https://html.spec.whatwg.org/multipage/workers.html#dedicatedworkerglobalscope
+ *
+ * This class is used as the test_environment when testharness is running
+ * inside a dedicated worker.
+ */
+ function DedicatedWorkerTestEnvironment() {
+ WorkerTestEnvironment.call(this);
+ // self is an instance of DedicatedWorkerGlobalScope which exposes
+ // a postMessage() method for communicating via the message channel
+ // established when the worker is created.
+ this._add_message_port(self);
+ }
+ DedicatedWorkerTestEnvironment.prototype = Object.create(WorkerTestEnvironment.prototype);
+
+ DedicatedWorkerTestEnvironment.prototype.on_tests_ready = function() {
+ WorkerTestEnvironment.prototype.on_tests_ready.call(this);
+ // In the absence of an onload notification, we a require dedicated
+ // workers to explicitly signal when the tests are done.
+ tests.wait_for_finish = true;
+ };
+
+ /*
+ * Shared web workers.
+ * https://html.spec.whatwg.org/multipage/workers.html#sharedworkerglobalscope
+ *
+ * This class is used as the test_environment when testharness is running
+ * inside a shared web worker.
+ */
+ function SharedWorkerTestEnvironment() {
+ WorkerTestEnvironment.call(this);
+ var this_obj = this;
+ // Shared workers receive message ports via the 'onconnect' event for
+ // each connection.
+ self.addEventListener("connect",
+ function(message_event) {
+ this_obj._add_message_port(message_event.source);
+ });
+ }
+ SharedWorkerTestEnvironment.prototype = Object.create(WorkerTestEnvironment.prototype);
+
+ SharedWorkerTestEnvironment.prototype.on_tests_ready = function() {
+ WorkerTestEnvironment.prototype.on_tests_ready.call(this);
+ // In the absence of an onload notification, we a require shared
+ // workers to explicitly signal when the tests are done.
+ tests.wait_for_finish = true;
+ };
+
+ /*
+ * Service workers.
+ * http://www.w3.org/TR/service-workers/
+ *
+ * This class is used as the test_environment when testharness is running
+ * inside a service worker.
+ */
+ function ServiceWorkerTestEnvironment() {
+ WorkerTestEnvironment.call(this);
+ this.all_loaded = false;
+ this.on_loaded_callback = null;
+ var this_obj = this;
+ self.addEventListener("message",
+ function(event) {
+ if (event.data.type && event.data.type === "connect") {
+ if (event.ports && event.ports[0]) {
+ // If a MessageChannel was passed, then use it to
+ // send results back to the main window. This
+ // allows the tests to work even if the browser
+ // does not fully support MessageEvent.source in
+ // ServiceWorkers yet.
+ this_obj._add_message_port(event.ports[0]);
+ event.ports[0].start();
+ } else {
+ // If there is no MessageChannel, then attempt to
+ // use the MessageEvent.source to send results
+ // back to the main window.
+ this_obj._add_message_port(event.source);
+ }
+ }
+ });
+
+ // The oninstall event is received after the service worker script and
+ // all imported scripts have been fetched and executed. It's the
+ // equivalent of an onload event for a document. All tests should have
+ // been added by the time this event is received, thus it's not
+ // necessary to wait until the onactivate event.
+ on_event(self, "install",
+ function(event) {
+ this_obj.all_loaded = true;
+ if (this_obj.on_loaded_callback) {
+ this_obj.on_loaded_callback();
+ }
+ });
+ }
+ ServiceWorkerTestEnvironment.prototype = Object.create(WorkerTestEnvironment.prototype);
+
+ ServiceWorkerTestEnvironment.prototype.add_on_loaded_callback = function(callback) {
+ if (this.all_loaded) {
+ callback();
+ } else {
+ this.on_loaded_callback = callback;
+ }
+ };
+
+ function create_test_environment() {
+ if ('document' in self) {
+ return new WindowTestEnvironment();
+ }
+ if ('DedicatedWorkerGlobalScope' in self &&
+ self instanceof DedicatedWorkerGlobalScope) {
+ return new DedicatedWorkerTestEnvironment();
+ }
+ if ('SharedWorkerGlobalScope' in self &&
+ self instanceof SharedWorkerGlobalScope) {
+ return new SharedWorkerTestEnvironment();
+ }
+ if ('ServiceWorkerGlobalScope' in self &&
+ self instanceof ServiceWorkerGlobalScope) {
+ return new ServiceWorkerTestEnvironment();
+ }
+ if ('WorkerGlobalScope' in self &&
+ self instanceof WorkerGlobalScope) {
+ return new DedicatedWorkerTestEnvironment();
+ }
+
+ throw new Error("Unsupported test environment");
+ }
+
+ var test_environment = create_test_environment();
+
+ function is_shared_worker(worker) {
+ return 'SharedWorker' in self && worker instanceof SharedWorker;
+ }
+
+ function is_service_worker(worker) {
+ return 'ServiceWorker' in self && worker instanceof ServiceWorker;
+ }
+
+ /*
+ * API functions
+ */
+
+ function test(func, name, properties)
+ {
+ var test_name = name ? name : test_environment.next_default_test_name();
+ properties = properties ? properties : {};
+ var test_obj = new Test(test_name, properties);
+ test_obj.step(func, test_obj, test_obj);
+ if (test_obj.phase === test_obj.phases.STARTED) {
+ test_obj.done();
+ }
+ }
+
+ function async_test(func, name, properties)
+ {
+ if (typeof func !== "function") {
+ properties = name;
+ name = func;
+ func = null;
+ }
+ var test_name = name ? name : test_environment.next_default_test_name();
+ properties = properties ? properties : {};
+ var test_obj = new Test(test_name, properties);
+ if (func) {
+ test_obj.step(func, test_obj, test_obj);
+ }
+ return test_obj;
+ }
+
+ function promise_test(func, name, properties) {
+ var test = async_test(name, properties);
+ // If there is no promise tests queue make one.
+ test.step(function() {
+ if (!tests.promise_tests) {
+ tests.promise_tests = Promise.resolve();
+ }
+ });
+ tests.promise_tests = tests.promise_tests.then(function() {
+ return Promise.resolve(test.step(func, test, test))
+ .then(
+ function() {
+ test.done();
+ })
+ .catch(test.step_func(
+ function(value) {
+ if (value instanceof AssertionError) {
+ throw value;
+ }
+ assert(false, "promise_test", null,
+ "Unhandled rejection with value: ${value}", {value:value});
+ }));
+ });
+ }
+
+ function promise_rejects(test, expected, promise, description) {
+ return promise.then(test.unreached_func("Should have rejected: " + description)).catch(function(e) {
+ assert_throws(expected, function() { throw e }, description);
+ });
+ }
+
+ /**
+ * This constructor helper allows DOM events to be handled using Promises,
+ * which can make it a lot easier to test a very specific series of events,
+ * including ensuring that unexpected events are not fired at any point.
+ */
+ function EventWatcher(test, watchedNode, eventTypes)
+ {
+ if (typeof eventTypes == 'string') {
+ eventTypes = [eventTypes];
+ }
+
+ var waitingFor = null;
+
+ var eventHandler = test.step_func(function(evt) {
+ assert_true(!!waitingFor,
+ 'Not expecting event, but got ' + evt.type + ' event');
+ assert_equals(evt.type, waitingFor.types[0],
+ 'Expected ' + waitingFor.types[0] + ' event, but got ' +
+ evt.type + ' event instead');
+ if (waitingFor.types.length > 1) {
+ // Pop first event from array
+ waitingFor.types.shift();
+ return;
+ }
+ // We need to null out waitingFor before calling the resolve function
+ // since the Promise's resolve handlers may call wait_for() which will
+ // need to set waitingFor.
+ var resolveFunc = waitingFor.resolve;
+ waitingFor = null;
+ resolveFunc(evt);
+ });
+
+ for (var i = 0; i < eventTypes.length; i++) {
+ watchedNode.addEventListener(eventTypes[i], eventHandler);
+ }
+
+ /**
+ * Returns a Promise that will resolve after the specified event or
+ * series of events has occured.
+ */
+ this.wait_for = function(types) {
+ if (waitingFor) {
+ return Promise.reject('Already waiting for an event or events');
+ }
+ if (typeof types == 'string') {
+ types = [types];
+ }
+ return new Promise(function(resolve, reject) {
+ waitingFor = {
+ types: types,
+ resolve: resolve,
+ reject: reject
+ };
+ });
+ };
+
+ function stop_watching() {
+ for (var i = 0; i < eventTypes.length; i++) {
+ watchedNode.removeEventListener(eventTypes[i], eventHandler);
+ }
+ };
+
+ test.add_cleanup(stop_watching);
+
+ return this;
+ }
+ expose(EventWatcher, 'EventWatcher');
+
+ function setup(func_or_properties, maybe_properties)
+ {
+ var func = null;
+ var properties = {};
+ if (arguments.length === 2) {
+ func = func_or_properties;
+ properties = maybe_properties;
+ } else if (func_or_properties instanceof Function) {
+ func = func_or_properties;
+ } else {
+ properties = func_or_properties;
+ }
+ tests.setup(func, properties);
+ test_environment.on_new_harness_properties(properties);
+ }
+
+ function done() {
+ if (tests.tests.length === 0) {
+ tests.set_file_is_test();
+ }
+ if (tests.file_is_test) {
+ tests.tests[0].done();
+ }
+ tests.end_wait();
+ }
+
+ function generate_tests(func, args, properties) {
+ forEach(args, function(x, i)
+ {
+ var name = x[0];
+ test(function()
+ {
+ func.apply(this, x.slice(1));
+ },
+ name,
+ Array.isArray(properties) ? properties[i] : properties);
+ });
+ }
+
+ function on_event(object, event, callback)
+ {
+ object.addEventListener(event, callback, false);
+ }
+
+ function step_timeout(f, t) {
+ var outer_this = this;
+ var args = Array.prototype.slice.call(arguments, 2);
+ return setTimeout(function() {
+ f.apply(outer_this, args);
+ }, t * tests.timeout_multiplier);
+ }
+
+ expose(test, 'test');
+ expose(async_test, 'async_test');
+ expose(promise_test, 'promise_test');
+ expose(promise_rejects, 'promise_rejects');
+ expose(generate_tests, 'generate_tests');
+ expose(setup, 'setup');
+ expose(done, 'done');
+ expose(on_event, 'on_event');
+ expose(step_timeout, 'step_timeout');
+
+ /*
+ * Return a string truncated to the given length, with ... added at the end
+ * if it was longer.
+ */
+ function truncate(s, len)
+ {
+ if (s.length > len) {
+ return s.substring(0, len - 3) + "...";
+ }
+ return s;
+ }
+
+ /*
+ * Return true if object is probably a Node object.
+ */
+ function is_node(object)
+ {
+ // I use duck-typing instead of instanceof, because
+ // instanceof doesn't work if the node is from another window (like an
+ // iframe's contentWindow):
+ // http://www.w3.org/Bugs/Public/show_bug.cgi?id=12295
+ try {
+ var has_node_properties = ("nodeType" in object &&
+ "nodeName" in object &&
+ "nodeValue" in object &&
+ "childNodes" in object);
+ } catch (e) {
+ // We're probably cross-origin, which means we aren't a node
+ return false;
+ }
+
+ if (has_node_properties) {
+ try {
+ object.nodeType;
+ } catch (e) {
+ // The object is probably Node.prototype or another prototype
+ // object that inherits from it, and not a Node instance.
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ var replacements = {
+ "0": "0",
+ "1": "x01",
+ "2": "x02",
+ "3": "x03",
+ "4": "x04",
+ "5": "x05",
+ "6": "x06",
+ "7": "x07",
+ "8": "b",
+ "9": "t",
+ "10": "n",
+ "11": "v",
+ "12": "f",
+ "13": "r",
+ "14": "x0e",
+ "15": "x0f",
+ "16": "x10",
+ "17": "x11",
+ "18": "x12",
+ "19": "x13",
+ "20": "x14",
+ "21": "x15",
+ "22": "x16",
+ "23": "x17",
+ "24": "x18",
+ "25": "x19",
+ "26": "x1a",
+ "27": "x1b",
+ "28": "x1c",
+ "29": "x1d",
+ "30": "x1e",
+ "31": "x1f",
+ "0xfffd": "ufffd",
+ "0xfffe": "ufffe",
+ "0xffff": "uffff",
+ };
+
+ /*
+ * Convert a value to a nice, human-readable string
+ */
+ function format_value(val, seen)
+ {
+ if (!seen) {
+ seen = [];
+ }
+ if (typeof val === "object" && val !== null) {
+ if (seen.indexOf(val) >= 0) {
+ return "[...]";
+ }
+ seen.push(val);
+ }
+ if (Array.isArray(val)) {
+ return "[" + val.map(function(x) {return format_value(x, seen);}).join(", ") + "]";
+ }
+
+ switch (typeof val) {
+ case "string":
+ val = val.replace("\\", "\\\\");
+ for (var p in replacements) {
+ var replace = "\\" + replacements[p];
+ val = val.replace(RegExp(String.fromCharCode(p), "g"), replace);
+ }
+ return '"' + val.replace(/"/g, '\\"') + '"';
+ case "boolean":
+ case "undefined":
+ return String(val);
+ case "number":
+ // In JavaScript, -0 === 0 and String(-0) == "0", so we have to
+ // special-case.
+ if (val === -0 && 1/val === -Infinity) {
+ return "-0";
+ }
+ return String(val);
+ case "object":
+ if (val === null) {
+ return "null";
+ }
+
+ // Special-case Node objects, since those come up a lot in my tests. I
+ // ignore namespaces.
+ if (is_node(val)) {
+ switch (val.nodeType) {
+ case Node.ELEMENT_NODE:
+ var ret = "<" + val.localName;
+ for (var i = 0; i < val.attributes.length; i++) {
+ ret += " " + val.attributes[i].name + '="' + val.attributes[i].value + '"';
+ }
+ ret += ">" + val.innerHTML + "" + val.localName + ">";
+ return "Element node " + truncate(ret, 60);
+ case Node.TEXT_NODE:
+ return 'Text node "' + truncate(val.data, 60) + '"';
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ return "ProcessingInstruction node with target " + format_value(truncate(val.target, 60)) + " and data " + format_value(truncate(val.data, 60));
+ case Node.COMMENT_NODE:
+ return "Comment node ";
+ case Node.DOCUMENT_NODE:
+ return "Document node with " + val.childNodes.length + (val.childNodes.length == 1 ? " child" : " children");
+ case Node.DOCUMENT_TYPE_NODE:
+ return "DocumentType node";
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ return "DocumentFragment node with " + val.childNodes.length + (val.childNodes.length == 1 ? " child" : " children");
+ default:
+ return "Node object of unknown type";
+ }
+ }
+
+ /* falls through */
+ default:
+ try {
+ return typeof val + ' "' + truncate(String(val), 1000) + '"';
+ } catch(e) {
+ return ("[stringifying object threw " + String(e) +
+ " with type " + String(typeof e) + "]");
+ }
+ }
+ }
+ expose(format_value, "format_value");
+
+ /*
+ * Assertions
+ */
+
+ function assert_true(actual, description)
+ {
+ assert(actual === true, "assert_true", description,
+ "expected true got ${actual}", {actual:actual});
+ }
+ expose(assert_true, "assert_true");
+
+ function assert_false(actual, description)
+ {
+ assert(actual === false, "assert_false", description,
+ "expected false got ${actual}", {actual:actual});
+ }
+ expose(assert_false, "assert_false");
+
+ function same_value(x, y) {
+ if (y !== y) {
+ //NaN case
+ return x !== x;
+ }
+ if (x === 0 && y === 0) {
+ //Distinguish +0 and -0
+ return 1/x === 1/y;
+ }
+ return x === y;
+ }
+
+ function assert_equals(actual, expected, description)
+ {
+ /*
+ * Test if two primitives are equal or two objects
+ * are the same object
+ */
+ if (typeof actual != typeof expected) {
+ assert(false, "assert_equals", description,
+ "expected (" + typeof expected + ") ${expected} but got (" + typeof actual + ") ${actual}",
+ {expected:expected, actual:actual});
+ return;
+ }
+ assert(same_value(actual, expected), "assert_equals", description,
+ "expected ${expected} but got ${actual}",
+ {expected:expected, actual:actual});
+ }
+ expose(assert_equals, "assert_equals");
+
+ function assert_not_equals(actual, expected, description)
+ {
+ /*
+ * Test if two primitives are unequal or two objects
+ * are different objects
+ */
+ assert(!same_value(actual, expected), "assert_not_equals", description,
+ "got disallowed value ${actual}",
+ {actual:actual});
+ }
+ expose(assert_not_equals, "assert_not_equals");
+
+ function assert_in_array(actual, expected, description)
+ {
+ assert(expected.indexOf(actual) != -1, "assert_in_array", description,
+ "value ${actual} not in array ${expected}",
+ {actual:actual, expected:expected});
+ }
+ expose(assert_in_array, "assert_in_array");
+
+ function assert_object_equals(actual, expected, description)
+ {
+ //This needs to be improved a great deal
+ function check_equal(actual, expected, stack)
+ {
+ stack.push(actual);
+
+ var p;
+ for (p in actual) {
+ assert(expected.hasOwnProperty(p), "assert_object_equals", description,
+ "unexpected property ${p}", {p:p});
+
+ if (typeof actual[p] === "object" && actual[p] !== null) {
+ if (stack.indexOf(actual[p]) === -1) {
+ check_equal(actual[p], expected[p], stack);
+ }
+ } else {
+ assert(same_value(actual[p], expected[p]), "assert_object_equals", description,
+ "property ${p} expected ${expected} got ${actual}",
+ {p:p, expected:expected, actual:actual});
+ }
+ }
+ for (p in expected) {
+ assert(actual.hasOwnProperty(p),
+ "assert_object_equals", description,
+ "expected property ${p} missing", {p:p});
+ }
+ stack.pop();
+ }
+ check_equal(actual, expected, []);
+ }
+ expose(assert_object_equals, "assert_object_equals");
+
+ function assert_array_equals(actual, expected, description)
+ {
+ assert(actual.length === expected.length,
+ "assert_array_equals", description,
+ "lengths differ, expected ${expected} got ${actual}",
+ {expected:expected.length, actual:actual.length});
+
+ for (var i = 0; i < actual.length; i++) {
+ assert(actual.hasOwnProperty(i) === expected.hasOwnProperty(i),
+ "assert_array_equals", description,
+ "property ${i}, property expected to be ${expected} but was ${actual}",
+ {i:i, expected:expected.hasOwnProperty(i) ? "present" : "missing",
+ actual:actual.hasOwnProperty(i) ? "present" : "missing"});
+ assert(same_value(expected[i], actual[i]),
+ "assert_array_equals", description,
+ "property ${i}, expected ${expected} but got ${actual}",
+ {i:i, expected:expected[i], actual:actual[i]});
+ }
+ }
+ expose(assert_array_equals, "assert_array_equals");
+
+ function assert_approx_equals(actual, expected, epsilon, description)
+ {
+ /*
+ * Test if two primitive numbers are equal withing +/- epsilon
+ */
+ assert(typeof actual === "number",
+ "assert_approx_equals", description,
+ "expected a number but got a ${type_actual}",
+ {type_actual:typeof actual});
+
+ assert(Math.abs(actual - expected) <= epsilon,
+ "assert_approx_equals", description,
+ "expected ${expected} +/- ${epsilon} but got ${actual}",
+ {expected:expected, actual:actual, epsilon:epsilon});
+ }
+ expose(assert_approx_equals, "assert_approx_equals");
+
+ function assert_less_than(actual, expected, description)
+ {
+ /*
+ * Test if a primitive number is less than another
+ */
+ assert(typeof actual === "number",
+ "assert_less_than", description,
+ "expected a number but got a ${type_actual}",
+ {type_actual:typeof actual});
+
+ assert(actual < expected,
+ "assert_less_than", description,
+ "expected a number less than ${expected} but got ${actual}",
+ {expected:expected, actual:actual});
+ }
+ expose(assert_less_than, "assert_less_than");
+
+ function assert_greater_than(actual, expected, description)
+ {
+ /*
+ * Test if a primitive number is greater than another
+ */
+ assert(typeof actual === "number",
+ "assert_greater_than", description,
+ "expected a number but got a ${type_actual}",
+ {type_actual:typeof actual});
+
+ assert(actual > expected,
+ "assert_greater_than", description,
+ "expected a number greater than ${expected} but got ${actual}",
+ {expected:expected, actual:actual});
+ }
+ expose(assert_greater_than, "assert_greater_than");
+
+ function assert_between_exclusive(actual, lower, upper, description)
+ {
+ /*
+ * Test if a primitive number is between two others
+ */
+ assert(typeof actual === "number",
+ "assert_between_exclusive", description,
+ "expected a number but got a ${type_actual}",
+ {type_actual:typeof actual});
+
+ assert(actual > lower && actual < upper,
+ "assert_between_exclusive", description,
+ "expected a number greater than ${lower} " +
+ "and less than ${upper} but got ${actual}",
+ {lower:lower, upper:upper, actual:actual});
+ }
+ expose(assert_between_exclusive, "assert_between_exclusive");
+
+ function assert_less_than_equal(actual, expected, description)
+ {
+ /*
+ * Test if a primitive number is less than or equal to another
+ */
+ assert(typeof actual === "number",
+ "assert_less_than_equal", description,
+ "expected a number but got a ${type_actual}",
+ {type_actual:typeof actual});
+
+ assert(actual <= expected,
+ "assert_less_than_equal", description,
+ "expected a number less than or equal to ${expected} but got ${actual}",
+ {expected:expected, actual:actual});
+ }
+ expose(assert_less_than_equal, "assert_less_than_equal");
+
+ function assert_greater_than_equal(actual, expected, description)
+ {
+ /*
+ * Test if a primitive number is greater than or equal to another
+ */
+ assert(typeof actual === "number",
+ "assert_greater_than_equal", description,
+ "expected a number but got a ${type_actual}",
+ {type_actual:typeof actual});
+
+ assert(actual >= expected,
+ "assert_greater_than_equal", description,
+ "expected a number greater than or equal to ${expected} but got ${actual}",
+ {expected:expected, actual:actual});
+ }
+ expose(assert_greater_than_equal, "assert_greater_than_equal");
+
+ function assert_between_inclusive(actual, lower, upper, description)
+ {
+ /*
+ * Test if a primitive number is between to two others or equal to either of them
+ */
+ assert(typeof actual === "number",
+ "assert_between_inclusive", description,
+ "expected a number but got a ${type_actual}",
+ {type_actual:typeof actual});
+
+ assert(actual >= lower && actual <= upper,
+ "assert_between_inclusive", description,
+ "expected a number greater than or equal to ${lower} " +
+ "and less than or equal to ${upper} but got ${actual}",
+ {lower:lower, upper:upper, actual:actual});
+ }
+ expose(assert_between_inclusive, "assert_between_inclusive");
+
+ function assert_regexp_match(actual, expected, description) {
+ /*
+ * Test if a string (actual) matches a regexp (expected)
+ */
+ assert(expected.test(actual),
+ "assert_regexp_match", description,
+ "expected ${expected} but got ${actual}",
+ {expected:expected, actual:actual});
+ }
+ expose(assert_regexp_match, "assert_regexp_match");
+
+ function assert_class_string(object, class_string, description) {
+ assert_equals({}.toString.call(object), "[object " + class_string + "]",
+ description);
+ }
+ expose(assert_class_string, "assert_class_string");
+
+
+ function _assert_own_property(name) {
+ return function(object, property_name, description)
+ {
+ assert(object.hasOwnProperty(property_name),
+ name, description,
+ "expected property ${p} missing", {p:property_name});
+ };
+ }
+ expose(_assert_own_property("assert_exists"), "assert_exists");
+ expose(_assert_own_property("assert_own_property"), "assert_own_property");
+
+ function assert_not_exists(object, property_name, description)
+ {
+ assert(!object.hasOwnProperty(property_name),
+ "assert_not_exists", description,
+ "unexpected property ${p} found", {p:property_name});
+ }
+ expose(assert_not_exists, "assert_not_exists");
+
+ function _assert_inherits(name) {
+ return function (object, property_name, description)
+ {
+ assert(typeof object === "object" || typeof object === "function",
+ name, description,
+ "provided value is not an object");
+
+ assert("hasOwnProperty" in object,
+ name, description,
+ "provided value is an object but has no hasOwnProperty method");
+
+ assert(!object.hasOwnProperty(property_name),
+ name, description,
+ "property ${p} found on object expected in prototype chain",
+ {p:property_name});
+
+ assert(property_name in object,
+ name, description,
+ "property ${p} not found in prototype chain",
+ {p:property_name});
+ };
+ }
+ expose(_assert_inherits("assert_inherits"), "assert_inherits");
+ expose(_assert_inherits("assert_idl_attribute"), "assert_idl_attribute");
+
+ function assert_readonly(object, property_name, description)
+ {
+ var initial_value = object[property_name];
+ try {
+ //Note that this can have side effects in the case where
+ //the property has PutForwards
+ object[property_name] = initial_value + "a"; //XXX use some other value here?
+ assert(same_value(object[property_name], initial_value),
+ "assert_readonly", description,
+ "changing property ${p} succeeded",
+ {p:property_name});
+ } finally {
+ object[property_name] = initial_value;
+ }
+ }
+ expose(assert_readonly, "assert_readonly");
+
+ function assert_throws(code, func, description)
+ {
+ try {
+ func.call(this);
+ assert(false, "assert_throws", description,
+ "${func} did not throw", {func:func});
+ } catch (e) {
+ if (e instanceof AssertionError) {
+ throw e;
+ }
+ if (code === null) {
+ return;
+ }
+ if (typeof code === "object") {
+ assert(typeof e == "object" && "name" in e && e.name == code.name,
+ "assert_throws", description,
+ "${func} threw ${actual} (${actual_name}) expected ${expected} (${expected_name})",
+ {func:func, actual:e, actual_name:e.name,
+ expected:code,
+ expected_name:code.name});
+ return;
+ }
+
+ var code_name_map = {
+ INDEX_SIZE_ERR: 'IndexSizeError',
+ HIERARCHY_REQUEST_ERR: 'HierarchyRequestError',
+ WRONG_DOCUMENT_ERR: 'WrongDocumentError',
+ INVALID_CHARACTER_ERR: 'InvalidCharacterError',
+ NO_MODIFICATION_ALLOWED_ERR: 'NoModificationAllowedError',
+ NOT_FOUND_ERR: 'NotFoundError',
+ NOT_SUPPORTED_ERR: 'NotSupportedError',
+ INUSE_ATTRIBUTE_ERR: 'InUseAttributeError',
+ INVALID_STATE_ERR: 'InvalidStateError',
+ SYNTAX_ERR: 'SyntaxError',
+ INVALID_MODIFICATION_ERR: 'InvalidModificationError',
+ NAMESPACE_ERR: 'NamespaceError',
+ INVALID_ACCESS_ERR: 'InvalidAccessError',
+ TYPE_MISMATCH_ERR: 'TypeMismatchError',
+ SECURITY_ERR: 'SecurityError',
+ NETWORK_ERR: 'NetworkError',
+ ABORT_ERR: 'AbortError',
+ URL_MISMATCH_ERR: 'URLMismatchError',
+ QUOTA_EXCEEDED_ERR: 'QuotaExceededError',
+ TIMEOUT_ERR: 'TimeoutError',
+ INVALID_NODE_TYPE_ERR: 'InvalidNodeTypeError',
+ DATA_CLONE_ERR: 'DataCloneError'
+ };
+
+ var name = code in code_name_map ? code_name_map[code] : code;
+
+ var name_code_map = {
+ IndexSizeError: 1,
+ HierarchyRequestError: 3,
+ WrongDocumentError: 4,
+ InvalidCharacterError: 5,
+ NoModificationAllowedError: 7,
+ NotFoundError: 8,
+ NotSupportedError: 9,
+ InUseAttributeError: 10,
+ InvalidStateError: 11,
+ SyntaxError: 12,
+ InvalidModificationError: 13,
+ NamespaceError: 14,
+ InvalidAccessError: 15,
+ TypeMismatchError: 17,
+ SecurityError: 18,
+ NetworkError: 19,
+ AbortError: 20,
+ URLMismatchError: 21,
+ QuotaExceededError: 22,
+ TimeoutError: 23,
+ InvalidNodeTypeError: 24,
+ DataCloneError: 25,
+
+ EncodingError: 0,
+ NotReadableError: 0,
+ UnknownError: 0,
+ ConstraintError: 0,
+ DataError: 0,
+ TransactionInactiveError: 0,
+ ReadOnlyError: 0,
+ VersionError: 0,
+ OperationError: 0,
+ };
+
+ if (!(name in name_code_map)) {
+ throw new AssertionError('Test bug: unrecognized DOMException code "' + code + '" passed to assert_throws()');
+ }
+
+ var required_props = { code: name_code_map[name] };
+
+ if (required_props.code === 0 ||
+ (typeof e == "object" &&
+ "name" in e &&
+ e.name !== e.name.toUpperCase() &&
+ e.name !== "DOMException")) {
+ // New style exception: also test the name property.
+ required_props.name = name;
+ }
+
+ //We'd like to test that e instanceof the appropriate interface,
+ //but we can't, because we don't know what window it was created
+ //in. It might be an instanceof the appropriate interface on some
+ //unknown other window. TODO: Work around this somehow?
+
+ assert(typeof e == "object",
+ "assert_throws", description,
+ "${func} threw ${e} with type ${type}, not an object",
+ {func:func, e:e, type:typeof e});
+
+ for (var prop in required_props) {
+ assert(typeof e == "object" && prop in e && e[prop] == required_props[prop],
+ "assert_throws", description,
+ "${func} threw ${e} that is not a DOMException " + code + ": property ${prop} is equal to ${actual}, expected ${expected}",
+ {func:func, e:e, prop:prop, actual:e[prop], expected:required_props[prop]});
+ }
+ }
+ }
+ expose(assert_throws, "assert_throws");
+
+ function assert_unreached(description) {
+ assert(false, "assert_unreached", description,
+ "Reached unreachable code");
+ }
+ expose(assert_unreached, "assert_unreached");
+
+ function assert_any(assert_func, actual, expected_array)
+ {
+ var args = [].slice.call(arguments, 3);
+ var errors = [];
+ var passed = false;
+ forEach(expected_array,
+ function(expected)
+ {
+ try {
+ assert_func.apply(this, [actual, expected].concat(args));
+ passed = true;
+ } catch (e) {
+ errors.push(e.message);
+ }
+ });
+ if (!passed) {
+ throw new AssertionError(errors.join("\n\n"));
+ }
+ }
+ expose(assert_any, "assert_any");
+
+ function Test(name, properties)
+ {
+ if (tests.file_is_test && tests.tests.length) {
+ throw new Error("Tried to create a test with file_is_test");
+ }
+ this.name = name;
+
+ this.phase = this.phases.INITIAL;
+
+ this.status = this.NOTRUN;
+ this.timeout_id = null;
+ this.index = null;
+
+ this.properties = properties;
+ var timeout = properties.timeout ? properties.timeout : settings.test_timeout;
+ if (timeout !== null) {
+ this.timeout_length = timeout * tests.timeout_multiplier;
+ } else {
+ this.timeout_length = null;
+ }
+
+ this.message = null;
+ this.stack = null;
+
+ this.steps = [];
+
+ this.cleanup_callbacks = [];
+
+ tests.push(this);
+ }
+
+ Test.statuses = {
+ PASS:0,
+ FAIL:1,
+ TIMEOUT:2,
+ NOTRUN:3
+ };
+
+ Test.prototype = merge({}, Test.statuses);
+
+ Test.prototype.phases = {
+ INITIAL:0,
+ STARTED:1,
+ HAS_RESULT:2,
+ COMPLETE:3
+ };
+
+ Test.prototype.structured_clone = function()
+ {
+ if (!this._structured_clone) {
+ var msg = this.message;
+ msg = msg ? String(msg) : msg;
+ this._structured_clone = merge({
+ name:String(this.name),
+ properties:merge({}, this.properties),
+ }, Test.statuses);
+ }
+ this._structured_clone.status = this.status;
+ this._structured_clone.message = this.message;
+ this._structured_clone.stack = this.stack;
+ this._structured_clone.index = this.index;
+ return this._structured_clone;
+ };
+
+ Test.prototype.step = function(func, this_obj)
+ {
+ if (this.phase > this.phases.STARTED) {
+ return;
+ }
+ this.phase = this.phases.STARTED;
+ //If we don't get a result before the harness times out that will be a test timout
+ this.set_status(this.TIMEOUT, "Test timed out");
+
+ tests.started = true;
+ tests.notify_test_state(this);
+
+ if (this.timeout_id === null) {
+ this.set_timeout();
+ }
+
+ this.steps.push(func);
+
+ if (arguments.length === 1) {
+ this_obj = this;
+ }
+
+ try {
+ return func.apply(this_obj, Array.prototype.slice.call(arguments, 2));
+ } catch (e) {
+ if (this.phase >= this.phases.HAS_RESULT) {
+ return;
+ }
+ var message = String((typeof e === "object" && e !== null) ? e.message : e);
+ var stack = e.stack ? e.stack : null;
+
+ this.set_status(this.FAIL, message, stack);
+ this.phase = this.phases.HAS_RESULT;
+ this.done();
+ }
+ };
+
+ Test.prototype.step_func = function(func, this_obj)
+ {
+ var test_this = this;
+
+ if (arguments.length === 1) {
+ this_obj = test_this;
+ }
+
+ return function()
+ {
+ return test_this.step.apply(test_this, [func, this_obj].concat(
+ Array.prototype.slice.call(arguments)));
+ };
+ };
+
+ Test.prototype.step_func_done = function(func, this_obj)
+ {
+ var test_this = this;
+
+ if (arguments.length === 1) {
+ this_obj = test_this;
+ }
+
+ return function()
+ {
+ if (func) {
+ test_this.step.apply(test_this, [func, this_obj].concat(
+ Array.prototype.slice.call(arguments)));
+ }
+ test_this.done();
+ };
+ };
+
+ Test.prototype.unreached_func = function(description)
+ {
+ return this.step_func(function() {
+ assert_unreached(description);
+ });
+ };
+
+ Test.prototype.step_timeout = function(f, timeout) {
+ var test_this = this;
+ var args = Array.prototype.slice.call(arguments, 2);
+ return setTimeout(this.step_func(function() {
+ return f.apply(test_this, args);
+ }), timeout * tests.timeout_multiplier);
+ }
+
+ Test.prototype.add_cleanup = function(callback) {
+ this.cleanup_callbacks.push(callback);
+ };
+
+ Test.prototype.force_timeout = function() {
+ this.set_status(this.TIMEOUT);
+ this.phase = this.phases.HAS_RESULT;
+ };
+
+ Test.prototype.set_timeout = function()
+ {
+ if (this.timeout_length !== null) {
+ var this_obj = this;
+ this.timeout_id = setTimeout(function()
+ {
+ this_obj.timeout();
+ }, this.timeout_length);
+ }
+ };
+
+ Test.prototype.set_status = function(status, message, stack)
+ {
+ this.status = status;
+ this.message = message;
+ this.stack = stack ? stack : null;
+ };
+
+ Test.prototype.timeout = function()
+ {
+ this.timeout_id = null;
+ this.set_status(this.TIMEOUT, "Test timed out");
+ this.phase = this.phases.HAS_RESULT;
+ this.done();
+ };
+
+ Test.prototype.done = function()
+ {
+ if (this.phase == this.phases.COMPLETE) {
+ return;
+ }
+
+ if (this.phase <= this.phases.STARTED) {
+ this.set_status(this.PASS, null);
+ }
+
+ this.phase = this.phases.COMPLETE;
+
+ clearTimeout(this.timeout_id);
+ tests.result(this);
+ this.cleanup();
+ };
+
+ Test.prototype.cleanup = function() {
+ forEach(this.cleanup_callbacks,
+ function(cleanup_callback) {
+ cleanup_callback();
+ });
+ };
+
+ /*
+ * A RemoteTest object mirrors a Test object on a remote worker. The
+ * associated RemoteWorker updates the RemoteTest object in response to
+ * received events. In turn, the RemoteTest object replicates these events
+ * on the local document. This allows listeners (test result reporting
+ * etc..) to transparently handle local and remote events.
+ */
+ function RemoteTest(clone) {
+ var this_obj = this;
+ Object.keys(clone).forEach(
+ function(key) {
+ this_obj[key] = clone[key];
+ });
+ this.index = null;
+ this.phase = this.phases.INITIAL;
+ this.update_state_from(clone);
+ tests.push(this);
+ }
+
+ RemoteTest.prototype.structured_clone = function() {
+ var clone = {};
+ Object.keys(this).forEach(
+ (function(key) {
+ if (typeof(this[key]) === "object") {
+ clone[key] = merge({}, this[key]);
+ } else {
+ clone[key] = this[key];
+ }
+ }).bind(this));
+ clone.phases = merge({}, this.phases);
+ return clone;
+ };
+
+ RemoteTest.prototype.cleanup = function() {};
+ RemoteTest.prototype.phases = Test.prototype.phases;
+ RemoteTest.prototype.update_state_from = function(clone) {
+ this.status = clone.status;
+ this.message = clone.message;
+ this.stack = clone.stack;
+ if (this.phase === this.phases.INITIAL) {
+ this.phase = this.phases.STARTED;
+ }
+ };
+ RemoteTest.prototype.done = function() {
+ this.phase = this.phases.COMPLETE;
+ }
+
+ /*
+ * A RemoteWorker listens for test events from a worker. These events are
+ * then used to construct and maintain RemoteTest objects that mirror the
+ * tests running on the remote worker.
+ */
+ function RemoteWorker(worker) {
+ this.running = true;
+ this.tests = new Array();
+
+ var this_obj = this;
+ worker.onerror = function(error) { this_obj.worker_error(error); };
+
+ var message_port;
+
+ if (is_service_worker(worker)) {
+ if (window.MessageChannel) {
+ // The ServiceWorker's implicit MessagePort is currently not
+ // reliably accessible from the ServiceWorkerGlobalScope due to
+ // Blink setting MessageEvent.source to null for messages sent
+ // via ServiceWorker.postMessage(). Until that's resolved,
+ // create an explicit MessageChannel and pass one end to the
+ // worker.
+ var message_channel = new MessageChannel();
+ message_port = message_channel.port1;
+ message_port.start();
+ worker.postMessage({type: "connect"}, [message_channel.port2]);
+ } else {
+ // If MessageChannel is not available, then try the
+ // ServiceWorker.postMessage() approach using MessageEvent.source
+ // on the other end.
+ message_port = navigator.serviceWorker;
+ worker.postMessage({type: "connect"});
+ }
+ } else if (is_shared_worker(worker)) {
+ message_port = worker.port;
+ } else {
+ message_port = worker;
+ }
+
+ // Keeping a reference to the worker until worker_done() is seen
+ // prevents the Worker object and its MessageChannel from going away
+ // before all the messages are dispatched.
+ this.worker = worker;
+
+ message_port.onmessage =
+ function(message) {
+ if (this_obj.running && (message.data.type in this_obj.message_handlers)) {
+ this_obj.message_handlers[message.data.type].call(this_obj, message.data);
+ }
+ };
+ }
+
+ RemoteWorker.prototype.worker_error = function(error) {
+ var message = error.message || String(error);
+ var filename = (error.filename ? " " + error.filename: "");
+ // FIXME: Display worker error states separately from main document
+ // error state.
+ this.worker_done({
+ status: {
+ status: tests.status.ERROR,
+ message: "Error in worker" + filename + ": " + message,
+ stack: error.stack
+ }
+ });
+ error.preventDefault();
+ };
+
+ RemoteWorker.prototype.test_state = function(data) {
+ var remote_test = this.tests[data.test.index];
+ if (!remote_test) {
+ remote_test = new RemoteTest(data.test);
+ this.tests[data.test.index] = remote_test;
+ }
+ remote_test.update_state_from(data.test);
+ tests.notify_test_state(remote_test);
+ };
+
+ RemoteWorker.prototype.test_done = function(data) {
+ var remote_test = this.tests[data.test.index];
+ remote_test.update_state_from(data.test);
+ remote_test.done();
+ tests.result(remote_test);
+ };
+
+ RemoteWorker.prototype.worker_done = function(data) {
+ if (tests.status.status === null &&
+ data.status.status !== data.status.OK) {
+ tests.status.status = data.status.status;
+ tests.status.message = data.status.message;
+ tests.status.stack = data.status.stack;
+ }
+ this.running = false;
+ this.worker = null;
+ if (tests.all_done()) {
+ tests.complete();
+ }
+ };
+
+ RemoteWorker.prototype.message_handlers = {
+ test_state: RemoteWorker.prototype.test_state,
+ result: RemoteWorker.prototype.test_done,
+ complete: RemoteWorker.prototype.worker_done
+ };
+
+ /*
+ * Harness
+ */
+
+ function TestsStatus()
+ {
+ this.status = null;
+ this.message = null;
+ this.stack = null;
+ }
+
+ TestsStatus.statuses = {
+ OK:0,
+ ERROR:1,
+ TIMEOUT:2
+ };
+
+ TestsStatus.prototype = merge({}, TestsStatus.statuses);
+
+ TestsStatus.prototype.structured_clone = function()
+ {
+ if (!this._structured_clone) {
+ var msg = this.message;
+ msg = msg ? String(msg) : msg;
+ this._structured_clone = merge({
+ status:this.status,
+ message:msg,
+ stack:this.stack
+ }, TestsStatus.statuses);
+ }
+ return this._structured_clone;
+ };
+
+ function Tests()
+ {
+ this.tests = [];
+ this.num_pending = 0;
+
+ this.phases = {
+ INITIAL:0,
+ SETUP:1,
+ HAVE_TESTS:2,
+ HAVE_RESULTS:3,
+ COMPLETE:4
+ };
+ this.phase = this.phases.INITIAL;
+
+ this.properties = {};
+
+ this.wait_for_finish = false;
+ this.processing_callbacks = false;
+
+ this.allow_uncaught_exception = false;
+
+ this.file_is_test = false;
+
+ this.timeout_multiplier = 1;
+ this.timeout_length = test_environment.test_timeout();
+ this.timeout_id = null;
+
+ this.start_callbacks = [];
+ this.test_state_callbacks = [];
+ this.test_done_callbacks = [];
+ this.all_done_callbacks = [];
+
+ this.pending_workers = [];
+
+ this.status = new TestsStatus();
+
+ var this_obj = this;
+
+ test_environment.add_on_loaded_callback(function() {
+ if (this_obj.all_done()) {
+ this_obj.complete();
+ }
+ });
+
+ this.set_timeout();
+ }
+
+ Tests.prototype.setup = function(func, properties)
+ {
+ if (this.phase >= this.phases.HAVE_RESULTS) {
+ return;
+ }
+
+ if (this.phase < this.phases.SETUP) {
+ this.phase = this.phases.SETUP;
+ }
+
+ this.properties = properties;
+
+ for (var p in properties) {
+ if (properties.hasOwnProperty(p)) {
+ var value = properties[p];
+ if (p == "allow_uncaught_exception") {
+ this.allow_uncaught_exception = value;
+ } else if (p == "explicit_done" && value) {
+ this.wait_for_finish = true;
+ } else if (p == "explicit_timeout" && value) {
+ this.timeout_length = null;
+ if (this.timeout_id)
+ {
+ clearTimeout(this.timeout_id);
+ }
+ } else if (p == "timeout_multiplier") {
+ this.timeout_multiplier = value;
+ }
+ }
+ }
+
+ if (func) {
+ try {
+ func();
+ } catch (e) {
+ this.status.status = this.status.ERROR;
+ this.status.message = String(e);
+ this.status.stack = e.stack ? e.stack : null;
+ }
+ }
+ this.set_timeout();
+ };
+
+ Tests.prototype.set_file_is_test = function() {
+ if (this.tests.length > 0) {
+ throw new Error("Tried to set file as test after creating a test");
+ }
+ this.wait_for_finish = true;
+ this.file_is_test = true;
+ // Create the test, which will add it to the list of tests
+ async_test();
+ };
+
+ Tests.prototype.set_timeout = function() {
+ var this_obj = this;
+ clearTimeout(this.timeout_id);
+ if (this.timeout_length !== null) {
+ this.timeout_id = setTimeout(function() {
+ this_obj.timeout();
+ }, this.timeout_length);
+ }
+ };
+
+ Tests.prototype.timeout = function() {
+ if (this.status.status === null) {
+ this.status.status = this.status.TIMEOUT;
+ }
+ this.complete();
+ };
+
+ Tests.prototype.end_wait = function()
+ {
+ this.wait_for_finish = false;
+ if (this.all_done()) {
+ this.complete();
+ }
+ };
+
+ Tests.prototype.push = function(test)
+ {
+ if (this.phase < this.phases.HAVE_TESTS) {
+ this.start();
+ }
+ this.num_pending++;
+ test.index = this.tests.push(test);
+ this.notify_test_state(test);
+ };
+
+ Tests.prototype.notify_test_state = function(test) {
+ var this_obj = this;
+ forEach(this.test_state_callbacks,
+ function(callback) {
+ callback(test, this_obj);
+ });
+ };
+
+ Tests.prototype.all_done = function() {
+ return (this.tests.length > 0 && test_environment.all_loaded &&
+ this.num_pending === 0 && !this.wait_for_finish &&
+ !this.processing_callbacks &&
+ !this.pending_workers.some(function(w) { return w.running; }));
+ };
+
+ Tests.prototype.start = function() {
+ this.phase = this.phases.HAVE_TESTS;
+ this.notify_start();
+ };
+
+ Tests.prototype.notify_start = function() {
+ var this_obj = this;
+ forEach (this.start_callbacks,
+ function(callback)
+ {
+ callback(this_obj.properties);
+ });
+ };
+
+ Tests.prototype.result = function(test)
+ {
+ if (this.phase > this.phases.HAVE_RESULTS) {
+ return;
+ }
+ this.phase = this.phases.HAVE_RESULTS;
+ this.num_pending--;
+ this.notify_result(test);
+ };
+
+ Tests.prototype.notify_result = function(test) {
+ var this_obj = this;
+ this.processing_callbacks = true;
+ forEach(this.test_done_callbacks,
+ function(callback)
+ {
+ callback(test, this_obj);
+ });
+ this.processing_callbacks = false;
+ if (this_obj.all_done()) {
+ this_obj.complete();
+ }
+ };
+
+ Tests.prototype.complete = function() {
+ if (this.phase === this.phases.COMPLETE) {
+ return;
+ }
+ this.phase = this.phases.COMPLETE;
+ var this_obj = this;
+ this.tests.forEach(
+ function(x)
+ {
+ if (x.phase < x.phases.COMPLETE) {
+ this_obj.notify_result(x);
+ x.cleanup();
+ x.phase = x.phases.COMPLETE;
+ }
+ }
+ );
+ this.notify_complete();
+ };
+
+ Tests.prototype.notify_complete = function() {
+ var this_obj = this;
+ if (this.status.status === null) {
+ this.status.status = this.status.OK;
+ }
+
+ forEach (this.all_done_callbacks,
+ function(callback)
+ {
+ callback(this_obj.tests, this_obj.status);
+ });
+ };
+
+ Tests.prototype.fetch_tests_from_worker = function(worker) {
+ if (this.phase >= this.phases.COMPLETE) {
+ return;
+ }
+
+ this.pending_workers.push(new RemoteWorker(worker));
+ };
+
+ function fetch_tests_from_worker(port) {
+ tests.fetch_tests_from_worker(port);
+ }
+ expose(fetch_tests_from_worker, 'fetch_tests_from_worker');
+
+ function timeout() {
+ if (tests.timeout_length === null) {
+ tests.timeout();
+ }
+ }
+ expose(timeout, 'timeout');
+
+ function add_start_callback(callback) {
+ tests.start_callbacks.push(callback);
+ }
+
+ function add_test_state_callback(callback) {
+ tests.test_state_callbacks.push(callback);
+ }
+
+ function add_result_callback(callback) {
+ tests.test_done_callbacks.push(callback);
+ }
+
+ function add_completion_callback(callback) {
+ tests.all_done_callbacks.push(callback);
+ }
+
+ expose(add_start_callback, 'add_start_callback');
+ expose(add_test_state_callback, 'add_test_state_callback');
+ expose(add_result_callback, 'add_result_callback');
+ expose(add_completion_callback, 'add_completion_callback');
+
+ function remove(array, item) {
+ var index = array.indexOf(item);
+ if (index > -1) {
+ array.splice(index, 1);
+ }
+ }
+
+ function remove_start_callback(callback) {
+ remove(tests.start_callbacks, callback);
+ }
+
+ function remove_test_state_callback(callback) {
+ remove(tests.test_state_callbacks, callback);
+ }
+
+ function remove_result_callback(callback) {
+ remove(tests.test_done_callbacks, callback);
+ }
+
+ function remove_completion_callback(callback) {
+ remove(tests.all_done_callbacks, callback);
+ }
+
+ /*
+ * Output listener
+ */
+
+ function Output() {
+ this.output_document = document;
+ this.output_node = null;
+ this.enabled = settings.output;
+ this.phase = this.INITIAL;
+ }
+
+ Output.prototype.INITIAL = 0;
+ Output.prototype.STARTED = 1;
+ Output.prototype.HAVE_RESULTS = 2;
+ Output.prototype.COMPLETE = 3;
+
+ Output.prototype.setup = function(properties) {
+ if (this.phase > this.INITIAL) {
+ return;
+ }
+
+ //If output is disabled in testharnessreport.js the test shouldn't be
+ //able to override that
+ this.enabled = this.enabled && (properties.hasOwnProperty("output") ?
+ properties.output : settings.output);
+ };
+
+ Output.prototype.init = function(properties) {
+ if (this.phase >= this.STARTED) {
+ return;
+ }
+ if (properties.output_document) {
+ this.output_document = properties.output_document;
+ } else {
+ this.output_document = document;
+ }
+ this.phase = this.STARTED;
+ };
+
+ Output.prototype.resolve_log = function() {
+ var output_document;
+ if (typeof this.output_document === "function") {
+ output_document = this.output_document.apply(undefined);
+ } else {
+ output_document = this.output_document;
+ }
+ if (!output_document) {
+ return;
+ }
+ var node = output_document.getElementById("log");
+ if (!node) {
+ if (!document.body || document.readyState == "loading") {
+ return;
+ }
+ node = output_document.createElement("div");
+ node.id = "log";
+ output_document.body.appendChild(node);
+ }
+ this.output_document = output_document;
+ this.output_node = node;
+ };
+
+ Output.prototype.show_status = function() {
+ if (this.phase < this.STARTED) {
+ this.init();
+ }
+ if (!this.enabled) {
+ return;
+ }
+ if (this.phase < this.HAVE_RESULTS) {
+ this.resolve_log();
+ this.phase = this.HAVE_RESULTS;
+ }
+ var done_count = tests.tests.length - tests.num_pending;
+ if (this.output_node) {
+ if (done_count < 100 ||
+ (done_count < 1000 && done_count % 100 === 0) ||
+ done_count % 1000 === 0) {
+ this.output_node.textContent = "Running, " +
+ done_count + " complete, " +
+ tests.num_pending + " remain";
+ }
+ }
+ };
+
+ Output.prototype.show_results = function (tests, harness_status) {
+ if (this.phase >= this.COMPLETE) {
+ return;
+ }
+ if (!this.enabled) {
+ return;
+ }
+ if (!this.output_node) {
+ this.resolve_log();
+ }
+ this.phase = this.COMPLETE;
+
+ var log = this.output_node;
+ if (!log) {
+ return;
+ }
+ var output_document = this.output_document;
+
+ while (log.lastChild) {
+ log.removeChild(log.lastChild);
+ }
+
+ var harness_url = get_harness_url();
+ if (harness_url !== null) {
+ var stylesheet = output_document.createElementNS(xhtml_ns, "link");
+ stylesheet.setAttribute("rel", "stylesheet");
+ stylesheet.setAttribute("href", harness_url + "testharness.css");
+ var heads = output_document.getElementsByTagName("head");
+ if (heads.length) {
+ heads[0].appendChild(stylesheet);
+ }
+ }
+
+ var status_text_harness = {};
+ status_text_harness[harness_status.OK] = "OK";
+ status_text_harness[harness_status.ERROR] = "Error";
+ status_text_harness[harness_status.TIMEOUT] = "Timeout";
+
+ var status_text = {};
+ status_text[Test.prototype.PASS] = "Pass";
+ status_text[Test.prototype.FAIL] = "Fail";
+ status_text[Test.prototype.TIMEOUT] = "Timeout";
+ status_text[Test.prototype.NOTRUN] = "Not Run";
+
+ var status_number = {};
+ forEach(tests,
+ function(test) {
+ var status = status_text[test.status];
+ if (status_number.hasOwnProperty(status)) {
+ status_number[status] += 1;
+ } else {
+ status_number[status] = 1;
+ }
+ });
+
+ function status_class(status)
+ {
+ return status.replace(/\s/g, '').toLowerCase();
+ }
+
+ var summary_template = ["section", {"id":"summary"},
+ ["h2", {}, "Summary"],
+ function()
+ {
+
+ var status = status_text_harness[harness_status.status];
+ var rv = [["section", {},
+ ["p", {},
+ "Harness status: ",
+ ["span", {"class":status_class(status)},
+ status
+ ],
+ ]
+ ]];
+
+ if (harness_status.status === harness_status.ERROR) {
+ rv[0].push(["pre", {}, harness_status.message]);
+ if (harness_status.stack) {
+ rv[0].push(["pre", {}, harness_status.stack]);
+ }
+ }
+ return rv;
+ },
+ ["p", {}, "Found ${num_tests} tests"],
+ function() {
+ var rv = [["div", {}]];
+ var i = 0;
+ while (status_text.hasOwnProperty(i)) {
+ if (status_number.hasOwnProperty(status_text[i])) {
+ var status = status_text[i];
+ rv[0].push(["div", {"class":status_class(status)},
+ ["label", {},
+ ["input", {type:"checkbox", checked:"checked"}],
+ status_number[status] + " " + status]]);
+ }
+ i++;
+ }
+ return rv;
+ },
+ ];
+
+ log.appendChild(render(summary_template, {num_tests:tests.length}, output_document));
+
+ forEach(output_document.querySelectorAll("section#summary label"),
+ function(element)
+ {
+ on_event(element, "click",
+ function(e)
+ {
+ if (output_document.getElementById("results") === null) {
+ e.preventDefault();
+ return;
+ }
+ var result_class = element.parentNode.getAttribute("class");
+ var style_element = output_document.querySelector("style#hide-" + result_class);
+ var input_element = element.querySelector("input");
+ if (!style_element && !input_element.checked) {
+ style_element = output_document.createElementNS(xhtml_ns, "style");
+ style_element.id = "hide-" + result_class;
+ style_element.textContent = "table#results > tbody > tr."+result_class+"{display:none}";
+ output_document.body.appendChild(style_element);
+ } else if (style_element && input_element.checked) {
+ style_element.parentNode.removeChild(style_element);
+ }
+ });
+ });
+
+ // This use of innerHTML plus manual escaping is not recommended in
+ // general, but is necessary here for performance. Using textContent
+ // on each individual
adds tens of seconds of execution time for
+ // large test suites (tens of thousands of tests).
+ function escape_html(s)
+ {
+ return s.replace(/\&/g, "&")
+ .replace(/Details
" +
+ "
Result
Test Name
" +
+ (assertions ? "
Assertion
" : "") +
+ "
Message
" +
+ "";
+ for (var i = 0; i < tests.length; i++) {
+ html += '
";
+ try {
+ log.lastChild.innerHTML = html;
+ } catch (e) {
+ log.appendChild(document.createElementNS(xhtml_ns, "p"))
+ .textContent = "Setting innerHTML for the log threw an exception.";
+ log.appendChild(document.createElementNS(xhtml_ns, "pre"))
+ .textContent = html;
+ }
+ };
+
+ /*
+ * Template code
+ *
+ * A template is just a javascript structure. An element is represented as:
+ *
+ * [tag_name, {attr_name:attr_value}, child1, child2]
+ *
+ * the children can either be strings (which act like text nodes), other templates or
+ * functions (see below)
+ *
+ * A text node is represented as
+ *
+ * ["{text}", value]
+ *
+ * String values have a simple substitution syntax; ${foo} represents a variable foo.
+ *
+ * It is possible to embed logic in templates by using a function in a place where a
+ * node would usually go. The function must either return part of a template or null.
+ *
+ * In cases where a set of nodes are required as output rather than a single node
+ * with children it is possible to just use a list
+ * [node1, node2, node3]
+ *
+ * Usage:
+ *
+ * render(template, substitutions) - take a template and an object mapping
+ * variable names to parameters and return either a DOM node or a list of DOM nodes
+ *
+ * substitute(template, substitutions) - take a template and variable mapping object,
+ * make the variable substitutions and return the substituted template
+ *
+ */
+
+ function is_single_node(template)
+ {
+ return typeof template[0] === "string";
+ }
+
+ function substitute(template, substitutions)
+ {
+ if (typeof template === "function") {
+ var replacement = template(substitutions);
+ if (!replacement) {
+ return null;
+ }
+
+ return substitute(replacement, substitutions);
+ }
+
+ if (is_single_node(template)) {
+ return substitute_single(template, substitutions);
+ }
+
+ return filter(map(template, function(x) {
+ return substitute(x, substitutions);
+ }), function(x) {return x !== null;});
+ }
+
+ function substitute_single(template, substitutions)
+ {
+ var substitution_re = /\$\{([^ }]*)\}/g;
+
+ function do_substitution(input) {
+ var components = input.split(substitution_re);
+ var rv = [];
+ for (var i = 0; i < components.length; i += 2) {
+ rv.push(components[i]);
+ if (components[i + 1]) {
+ rv.push(String(substitutions[components[i + 1]]));
+ }
+ }
+ return rv;
+ }
+
+ function substitute_attrs(attrs, rv)
+ {
+ rv[1] = {};
+ for (var name in template[1]) {
+ if (attrs.hasOwnProperty(name)) {
+ var new_name = do_substitution(name).join("");
+ var new_value = do_substitution(attrs[name]).join("");
+ rv[1][new_name] = new_value;
+ }
+ }
+ }
+
+ function substitute_children(children, rv)
+ {
+ for (var i = 0; i < children.length; i++) {
+ if (children[i] instanceof Object) {
+ var replacement = substitute(children[i], substitutions);
+ if (replacement !== null) {
+ if (is_single_node(replacement)) {
+ rv.push(replacement);
+ } else {
+ extend(rv, replacement);
+ }
+ }
+ } else {
+ extend(rv, do_substitution(String(children[i])));
+ }
+ }
+ return rv;
+ }
+
+ var rv = [];
+ rv.push(do_substitution(String(template[0])).join(""));
+
+ if (template[0] === "{text}") {
+ substitute_children(template.slice(1), rv);
+ } else {
+ substitute_attrs(template[1], rv);
+ substitute_children(template.slice(2), rv);
+ }
+
+ return rv;
+ }
+
+ function make_dom_single(template, doc)
+ {
+ var output_document = doc || document;
+ var element;
+ if (template[0] === "{text}") {
+ element = output_document.createTextNode("");
+ for (var i = 1; i < template.length; i++) {
+ element.data += template[i];
+ }
+ } else {
+ element = output_document.createElementNS(xhtml_ns, template[0]);
+ for (var name in template[1]) {
+ if (template[1].hasOwnProperty(name)) {
+ element.setAttribute(name, template[1][name]);
+ }
+ }
+ for (var i = 2; i < template.length; i++) {
+ if (template[i] instanceof Object) {
+ var sub_element = make_dom(template[i]);
+ element.appendChild(sub_element);
+ } else {
+ var text_node = output_document.createTextNode(template[i]);
+ element.appendChild(text_node);
+ }
+ }
+ }
+
+ return element;
+ }
+
+ function make_dom(template, substitutions, output_document)
+ {
+ if (is_single_node(template)) {
+ return make_dom_single(template, output_document);
+ }
+
+ return map(template, function(x) {
+ return make_dom_single(x, output_document);
+ });
+ }
+
+ function render(template, substitutions, output_document)
+ {
+ return make_dom(substitute(template, substitutions), output_document);
+ }
+
+ /*
+ * Utility funcions
+ */
+ function assert(expected_true, function_name, description, error, substitutions)
+ {
+ if (tests.tests.length === 0) {
+ tests.set_file_is_test();
+ }
+ if (expected_true !== true) {
+ var msg = make_message(function_name, description,
+ error, substitutions);
+ throw new AssertionError(msg);
+ }
+ }
+
+ function AssertionError(message)
+ {
+ this.message = message;
+ this.stack = this.get_stack();
+ }
+
+ AssertionError.prototype = Object.create(Error.prototype);
+
+ AssertionError.prototype.get_stack = function() {
+ var stack = new Error().stack;
+ // IE11 does not initialize 'Error.stack' until the object is thrown.
+ if (!stack) {
+ try {
+ throw new Error();
+ } catch (e) {
+ stack = e.stack;
+ }
+ }
+
+ var lines = stack.split("\n");
+
+ // Create a pattern to match stack frames originating within testharness.js. These include the
+ // script URL, followed by the line/col (e.g., '/resources/testharness.js:120:21').
+ // Escape the URL per http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
+ // in case it contains RegExp characters.
+ var script_url = get_script_url();
+ var re_text = script_url ? script_url.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') : "\\btestharness.js";
+ var re = new RegExp(re_text + ":\\d+:\\d+");
+
+ // Some browsers include a preamble that specifies the type of the error object. Skip this by
+ // advancing until we find the first stack frame originating from testharness.js.
+ var i = 0;
+ while (!re.test(lines[i]) && i < lines.length) {
+ i++;
+ }
+
+ // Then skip the top frames originating from testharness.js to begin the stack at the test code.
+ while (re.test(lines[i]) && i < lines.length) {
+ i++;
+ }
+
+ // Paranoid check that we didn't skip all frames. If so, return the original stack unmodified.
+ if (i >= lines.length) {
+ return stack;
+ }
+
+ return lines.slice(i).join("\n");
+ }
+
+ function make_message(function_name, description, error, substitutions)
+ {
+ for (var p in substitutions) {
+ if (substitutions.hasOwnProperty(p)) {
+ substitutions[p] = format_value(substitutions[p]);
+ }
+ }
+ var node_form = substitute(["{text}", "${function_name}: ${description}" + error],
+ merge({function_name:function_name,
+ description:(description?description + " ":"")},
+ substitutions));
+ return node_form.slice(1).join("");
+ }
+
+ function filter(array, callable, thisObj) {
+ var rv = [];
+ for (var i = 0; i < array.length; i++) {
+ if (array.hasOwnProperty(i)) {
+ var pass = callable.call(thisObj, array[i], i, array);
+ if (pass) {
+ rv.push(array[i]);
+ }
+ }
+ }
+ return rv;
+ }
+
+ function map(array, callable, thisObj)
+ {
+ var rv = [];
+ rv.length = array.length;
+ for (var i = 0; i < array.length; i++) {
+ if (array.hasOwnProperty(i)) {
+ rv[i] = callable.call(thisObj, array[i], i, array);
+ }
+ }
+ return rv;
+ }
+
+ function extend(array, items)
+ {
+ Array.prototype.push.apply(array, items);
+ }
+
+ function forEach(array, callback, thisObj)
+ {
+ for (var i = 0; i < array.length; i++) {
+ if (array.hasOwnProperty(i)) {
+ callback.call(thisObj, array[i], i, array);
+ }
+ }
+ }
+
+ function merge(a,b)
+ {
+ var rv = {};
+ var p;
+ for (p in a) {
+ rv[p] = a[p];
+ }
+ for (p in b) {
+ rv[p] = b[p];
+ }
+ return rv;
+ }
+
+ function expose(object, name)
+ {
+ var components = name.split(".");
+ var target = test_environment.global_scope();
+ for (var i = 0; i < components.length - 1; i++) {
+ if (!(components[i] in target)) {
+ target[components[i]] = {};
+ }
+ target = target[components[i]];
+ }
+ target[components[components.length - 1]] = object;
+ }
+
+ function is_same_origin(w) {
+ try {
+ 'random_prop' in w;
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ /** Returns the 'src' URL of the first
+ data-prefixed-objects lets prefix objects in the global space
+ data-prefixed-prototypes adds prefixes to interfaces, for objects that
+ get created during the tests
+
+ NB: vendor prefixes are expected to go away in favor of putting
+ new features behind flag, so hopefully there will be only limited
+ need to use this
+*/
+
+(function () {
+ var aliases = {};
+ var documentingPrefixUsage = document.createElement('div');
+ var vendorPrefixes = ["moz", "ms", "o", "webkit", "Moz", "MS", "O", "WebKit", "op"];
+
+ function getParentObject(ancestors) {
+ var parent = window;
+ var currentName = "";
+ ancestors.forEach(function (p) {
+ currentName = currentName ? currentName + "." + p : p;
+ if (parent[p] === undefined) {
+ throw currentName + " is undefined, cannot set prefix alias on child object";
+ }
+ parent = parent[p];
+ });
+ return parent;
+ }
+
+ function prependPrefix(prefix, name) {
+ var newName = name[0].toUpperCase() + name.substr(1, name.length);
+ return prefix + newName;
+ }
+
+ function setPrototypeAlias(obj) {
+ var parent = getParentObject(obj.ancestors);
+ if (!parent.prototype.hasOwnProperty(obj.name)) {
+ vendorPrefixes.forEach(function (prefix) {
+ if (parent.prototype.hasOwnProperty(prependPrefix(prefix, obj.name))) {
+ Object.defineProperty(parent.prototype, obj.name,
+ {get: function() {return this[prependPrefix(prefix, obj.name)];},
+ set: function(v) {this[prependPrefix(prefix, obj.name)] = v;}
+ });
+ aliases[obj.ancestors.join(".") + ".prototype." + obj.name] = obj.ancestors.join(".") + ".prototype." + prependPrefix(prefix, obj.name);
+ return;
+ }
+ });
+ }
+ }
+
+ function setAlias(obj) {
+ var parent = getParentObject(obj.ancestors);
+ if (parent[obj.name] === undefined) {
+ vendorPrefixes.forEach(function (prefix) {
+ if (parent[prependPrefix(prefix, obj.name)] !== undefined) {
+ parent[obj.name] = parent[prependPrefix(prefix, obj.name)];
+ aliases[obj.ancestors.join(".") + "." + obj.name] = obj.ancestors.join(".") + "." + prependPrefix(prefix, obj.name);
+ return;
+ }
+ });
+ }
+ }
+
+ // For this version of vendor-prefixes.js, always replace the prefixes.
+ if (document.querySelector("script[data-prefixed-objects]")) {
+ var prefixObjectsData = document.querySelector("script[data-prefixed-objects]").dataset["prefixedObjects"];
+ try {
+ var prefixedObjects = JSON.parse(prefixObjectsData);
+ } catch (e) {
+ throw "couldn't parse data-prefixed-objects as JSON:" + e;
+ }
+ prefixedObjects.forEach(setAlias);
+ }
+ if (document.querySelector("script[data-prefixed-prototypes]")) {
+ var prefixProtoData = document.querySelector("script[data-prefixed-prototypes]").dataset["prefixedPrototypes"];
+ try {
+ var prefixedPrototypes = JSON.parse(prefixProtoData);
+ } catch (e) {
+ throw "couldn't parse data-prefixed-prototypes as JSON:" + e;
+ }
+ prefixedPrototypes.forEach(setPrototypeAlias);
+ }
+})();
diff --git a/bower_components/custom-elements/tests/chromium/resources/window-postmessage-open-close.html b/bower_components/custom-elements/tests/chromium/resources/window-postmessage-open-close.html
new file mode 100644
index 0000000..3adb8ce
--- /dev/null
+++ b/bower_components/custom-elements/tests/chromium/resources/window-postmessage-open-close.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Document/createElement.html b/bower_components/custom-elements/tests/html/Document/createElement.html
new file mode 100644
index 0000000..9e11766
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Document/createElement.html
@@ -0,0 +1,58 @@
+
+
+
+Document#createElement
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Document/createElementNS.html b/bower_components/custom-elements/tests/html/Document/createElementNS.html
new file mode 100644
index 0000000..339bf5c
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Document/createElementNS.html
@@ -0,0 +1,74 @@
+
+
+
+Document#createElement
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Document/importNode.html b/bower_components/custom-elements/tests/html/Document/importNode.html
new file mode 100644
index 0000000..e61f4f8
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Document/importNode.html
@@ -0,0 +1,87 @@
+
+
+
+Document#importNode
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Document/index.html b/bower_components/custom-elements/tests/html/Document/index.html
new file mode 100644
index 0000000..67f6fae
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Document/index.html
@@ -0,0 +1,9 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Element/attachShadow.html b/bower_components/custom-elements/tests/html/Element/attachShadow.html
new file mode 100644
index 0000000..6620367
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Element/attachShadow.html
@@ -0,0 +1,91 @@
+
+
+
+Element#attachShadow
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Element/index.html b/bower_components/custom-elements/tests/html/Element/index.html
new file mode 100644
index 0000000..b771d37
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Element/index.html
@@ -0,0 +1,13 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Element/innerHTML.html b/bower_components/custom-elements/tests/html/Element/innerHTML.html
new file mode 100644
index 0000000..5179952
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Element/innerHTML.html
@@ -0,0 +1,169 @@
+
+
+
+Element#innerHTML
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Element/insertAdjacentElement.html b/bower_components/custom-elements/tests/html/Element/insertAdjacentElement.html
new file mode 100644
index 0000000..f11cbc4
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Element/insertAdjacentElement.html
@@ -0,0 +1,115 @@
+
+
+
+Element#insertAdjacentElement
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Element/removeAttribute.html b/bower_components/custom-elements/tests/html/Element/removeAttribute.html
new file mode 100644
index 0000000..b9302f3
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Element/removeAttribute.html
@@ -0,0 +1,103 @@
+
+
+
+Element#removeAttribute
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Element/removeAttributeNS.html b/bower_components/custom-elements/tests/html/Element/removeAttributeNS.html
new file mode 100644
index 0000000..372db24
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Element/removeAttributeNS.html
@@ -0,0 +1,108 @@
+
+
+
+Element#removeAttributeNS
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Element/setAttribute.html b/bower_components/custom-elements/tests/html/Element/setAttribute.html
new file mode 100644
index 0000000..6be9a08
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Element/setAttribute.html
@@ -0,0 +1,118 @@
+
+
+
+Element#setAttribute
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Element/setAttributeNS.html b/bower_components/custom-elements/tests/html/Element/setAttributeNS.html
new file mode 100644
index 0000000..ddb79d5
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Element/setAttributeNS.html
@@ -0,0 +1,123 @@
+
+
+
+Element#setAttributeNS
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/HTMLElement/constructor.html b/bower_components/custom-elements/tests/html/HTMLElement/constructor.html
new file mode 100644
index 0000000..1198fbf
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/HTMLElement/constructor.html
@@ -0,0 +1,97 @@
+
+
+
+HTMLElement
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/HTMLElement/index.html b/bower_components/custom-elements/tests/html/HTMLElement/index.html
new file mode 100644
index 0000000..a05bd11
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/HTMLElement/index.html
@@ -0,0 +1,7 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Interface/ChildNode/index.html b/bower_components/custom-elements/tests/html/Interface/ChildNode/index.html
new file mode 100644
index 0000000..71209c2
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Interface/ChildNode/index.html
@@ -0,0 +1,555 @@
+
+
+
+ChildNode
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Interface/ParentNode/index.html b/bower_components/custom-elements/tests/html/Interface/ParentNode/index.html
new file mode 100644
index 0000000..f19a77c
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Interface/ParentNode/index.html
@@ -0,0 +1,349 @@
+
+
+
+ParentNode
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Interface/index.html b/bower_components/custom-elements/tests/html/Interface/index.html
new file mode 100644
index 0000000..1bf1166
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Interface/index.html
@@ -0,0 +1,8 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Node/appendChild.html b/bower_components/custom-elements/tests/html/Node/appendChild.html
new file mode 100644
index 0000000..80965d1
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Node/appendChild.html
@@ -0,0 +1,281 @@
+
+
+
+Node#appendChild
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Node/cloneNode.html b/bower_components/custom-elements/tests/html/Node/cloneNode.html
new file mode 100644
index 0000000..0b0efcd
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Node/cloneNode.html
@@ -0,0 +1,77 @@
+
+
+
+Node#cloneNode
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Node/index.html b/bower_components/custom-elements/tests/html/Node/index.html
new file mode 100644
index 0000000..b4e08b0
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Node/index.html
@@ -0,0 +1,11 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Node/insertBefore.html b/bower_components/custom-elements/tests/html/Node/insertBefore.html
new file mode 100644
index 0000000..f616b0a
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Node/insertBefore.html
@@ -0,0 +1,281 @@
+
+
+
+Node#insertBefore
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Node/removeChild.html b/bower_components/custom-elements/tests/html/Node/removeChild.html
new file mode 100644
index 0000000..eab1c25
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Node/removeChild.html
@@ -0,0 +1,74 @@
+
+
+
+Node#removeChild
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/Node/replaceChild.html b/bower_components/custom-elements/tests/html/Node/replaceChild.html
new file mode 100644
index 0000000..7ded832
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/Node/replaceChild.html
@@ -0,0 +1,333 @@
+
+
+
+Node#appendChild
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/async-import.html b/bower_components/custom-elements/tests/html/async-import.html
new file mode 100644
index 0000000..b87f43c
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/async-import.html
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/bower_components/custom-elements/tests/html/imported-doc.html b/bower_components/custom-elements/tests/html/imported-doc.html
new file mode 100644
index 0000000..ed889cc
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/imported-doc.html
@@ -0,0 +1,2 @@
+
+
diff --git a/bower_components/custom-elements/tests/html/imports.html b/bower_components/custom-elements/tests/html/imports.html
new file mode 100644
index 0000000..8ba7020
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/imports.html
@@ -0,0 +1,108 @@
+
+
+
+
+ Custom Elements: imports integration
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/incorrectly-imported-doc.html b/bower_components/custom-elements/tests/html/incorrectly-imported-doc.html
new file mode 100644
index 0000000..ccc2ea7
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/incorrectly-imported-doc.html
@@ -0,0 +1,2 @@
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/defaultSyncFlush.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/defaultSyncFlush.html
new file mode 100644
index 0000000..1ba0bfd
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/defaultSyncFlush.html
@@ -0,0 +1,41 @@
+
+
+
+customElements#polyfillWrapFlushCallback
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/defineDoesNotWalk.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/defineDoesNotWalk.html
new file mode 100644
index 0000000..cabd19a
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/defineDoesNotWalk.html
@@ -0,0 +1,42 @@
+
+
+
+customElements#polyfillWrapFlushCallback
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/flushCallbackIsCalled.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/flushCallbackIsCalled.html
new file mode 100644
index 0000000..055133d
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/flushCallbackIsCalled.html
@@ -0,0 +1,35 @@
+
+
+
+customElements#polyfillWrapFlushCallback
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/imperativelyCreatedBeforeFlush.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/imperativelyCreatedBeforeFlush.html
new file mode 100644
index 0000000..3517359
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/imperativelyCreatedBeforeFlush.html
@@ -0,0 +1,42 @@
+
+
+
+customElements#polyfillWrapFlushCallback
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/index.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/index.html
new file mode 100644
index 0000000..7c2489e
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/index.html
@@ -0,0 +1,16 @@
+
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/multipleDefineCalls.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/multipleDefineCalls.html
new file mode 100644
index 0000000..675e5e3
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/multipleDefineCalls.html
@@ -0,0 +1,43 @@
+
+
+
+customElements#polyfillWrapFlushCallback
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/multipleFlushCallbacks_blocking.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/multipleFlushCallbacks_blocking.html
new file mode 100644
index 0000000..7eeddc4
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/multipleFlushCallbacks_blocking.html
@@ -0,0 +1,65 @@
+
+
+
+customElements#polyfillWrapFlushCallback
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/multipleFlushCallbacks_ordering.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/multipleFlushCallbacks_ordering.html
new file mode 100644
index 0000000..00aad8d
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/multipleFlushCallbacks_ordering.html
@@ -0,0 +1,44 @@
+
+
+
+customElements#polyfillWrapFlushCallback
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/upgradeInDefineCallOrder.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/upgradeInDefineCallOrder.html
new file mode 100644
index 0000000..6d09f97
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/upgradeInDefineCallOrder.html
@@ -0,0 +1,79 @@
+
+
+
+customElements#polyfillWrapFlushCallback
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/whenDefined_after.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/whenDefined_after.html
new file mode 100644
index 0000000..37f6073
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/whenDefined_after.html
@@ -0,0 +1,62 @@
+
+
+
+customElements#whenDefined
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/whenDefined_before.html b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/whenDefined_before.html
new file mode 100644
index 0000000..2ba77c1
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/polyfillWrapFlushCallback/whenDefined_before.html
@@ -0,0 +1,62 @@
+
+
+
+customElements#whenDefined
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/shim.html b/bower_components/custom-elements/tests/html/shim.html
new file mode 100644
index 0000000..a68f878
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/shim.html
@@ -0,0 +1,117 @@
+
+
+Custom Elements Tests
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/html/sub-import.html b/bower_components/custom-elements/tests/html/sub-import.html
new file mode 100644
index 0000000..7c89b54
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/sub-import.html
@@ -0,0 +1 @@
+
diff --git a/bower_components/custom-elements/tests/html/template-polyfill.html b/bower_components/custom-elements/tests/html/template-polyfill.html
new file mode 100644
index 0000000..62bde3e
--- /dev/null
+++ b/bower_components/custom-elements/tests/html/template-polyfill.html
@@ -0,0 +1,45 @@
+
+
+
+
+ Template polyfill integration
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/index.html b/bower_components/custom-elements/tests/index.html
new file mode 100644
index 0000000..1a72a7d
--- /dev/null
+++ b/bower_components/custom-elements/tests/index.html
@@ -0,0 +1,41 @@
+
+
+Custom Elements Tests
+
+
+
+
+
+
+
diff --git a/bower_components/custom-elements/tests/js/babel.js b/bower_components/custom-elements/tests/js/babel.js
new file mode 100644
index 0000000..4523a82
--- /dev/null
+++ b/bower_components/custom-elements/tests/js/babel.js
@@ -0,0 +1,77 @@
+/**
+ * @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
+ */
+
+suite('Babel ES5 Output', function() {
+
+ customElements.enableFlush = true;
+
+ test('Babel generated ES5 works via new()', function() {
+ 'use strict';
+
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+ function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+ var XBabel = function (_HTMLElement) {
+ _inherits(XBabel, _HTMLElement);
+
+ function XBabel() {
+ _classCallCheck(this, XBabel);
+
+ return _possibleConstructorReturn(this, Object.getPrototypeOf(XBabel).call(this));
+ }
+
+ return XBabel;
+ }(HTMLElement);
+
+ // register x-foo
+ customElements.define('x-babel', XBabel);
+ // create an instance via new
+ var e = new XBabel();
+ // test localName
+ assert.equal(e.localName, 'x-babel');
+ // test instanceof
+ assert.instanceOf(e, XBabel);
+ });
+
+ test('Babel generated ES5 works via createElement', function() {
+ 'use strict';
+
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+ function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+ var XBabel2 = function (_HTMLElement) {
+ _inherits(XBabel2, _HTMLElement);
+
+ function XBabel2() {
+ _classCallCheck(this, XBabel2);
+
+ return _possibleConstructorReturn(this, Object.getPrototypeOf(XBabel2).call(this));
+ }
+
+ return XBabel2;
+ }(HTMLElement);
+
+ // register x-foo
+ customElements.define('x-babel2', XBabel2);
+ // create an instance via new
+ var e = document.createElement('x-babel2');
+ // test localName
+ assert.equal(e.localName, 'x-babel2');
+ // test instanceof
+ assert.instanceOf(e, XBabel2);
+ });
+
+});
diff --git a/bower_components/custom-elements/tests/js/closure.js b/bower_components/custom-elements/tests/js/closure.js
new file mode 100644
index 0000000..9a31d9e
--- /dev/null
+++ b/bower_components/custom-elements/tests/js/closure.js
@@ -0,0 +1,52 @@
+/**
+ * @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
+ */
+
+suite('Closure ES5 Output', function() {
+
+ customElements.enableFlush = true;
+
+ // Fails at a.prototype.constructor = a;
+ // Closure needs to use Object.defineProperty?
+ test.skip('Closure generated ES5 works', function() {
+ 'use strict';
+
+ // Closure standard library code
+ var $jscomp = {scope:{}, getGlobal:function(a) {
+ return "undefined" != typeof window && window === a ? a : "undefined" != typeof global ? global : a;
+ }};
+ $jscomp.global = $jscomp.getGlobal(this);
+ $jscomp.inherits = function(a, b) {
+ function c() {
+ }
+ c.prototype = b.prototype;
+ a.prototype = new c;
+ a.prototype.constructor = a;
+ for (var d in b) {
+ if ($jscomp.global.Object.defineProperties) {
+ var e = $jscomp.global.Object.getOwnPropertyDescriptor(b, d);
+ e && $jscomp.global.Object.defineProperty(a, d, e);
+ } else {
+ a[d] = b[d];
+ }
+ }
+ };
+
+ // Compiled test
+ var XFoo = function(a) {
+ HTMLElement.apply(this, arguments);
+ };
+ $jscomp.inherits(XFoo, HTMLElement);
+ customElements.define("x-foo", XFoo);
+ var xfoo = new XFoo;
+ assert.equal(xfoo.localName, "x-foo");
+ assert.instanceOf(xfoo, XFoo);
+ });
+
+});
diff --git a/bower_components/custom-elements/tests/js/instanceof.js b/bower_components/custom-elements/tests/js/instanceof.js
new file mode 100644
index 0000000..2fc596e
--- /dev/null
+++ b/bower_components/custom-elements/tests/js/instanceof.js
@@ -0,0 +1,143 @@
+/**
+ * @license
+ * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+suite('Built-in Element instanceof', function() {
+
+ test('Built-in Elements are instanceof HTMLElement', function() {
+ 'use strict';
+
+ // All tags implementing the HTMLElement interface, according to:
+ // https://html.spec.whatwg.org/multipage/indices.html#element-interfaces
+ var elements = [
+ 'a',
+ 'abbr',
+ 'address',
+ 'area',
+ 'article',
+ 'aside',
+ 'audio',
+ 'b',
+ 'base',
+ 'bdi',
+ 'bdo',
+ 'blockquote',
+ 'body',
+ 'br',
+ 'button',
+ 'canvas',
+ 'caption',
+ 'cite',
+ 'code',
+ 'col',
+ 'colgroup',
+ 'menuitem',
+ 'data',
+ 'datalist',
+ 'dd',
+ 'del',
+ 'details',
+ 'dfn',
+ 'dialog',
+ 'div',
+ 'dl',
+ 'dt',
+ 'em',
+ 'embed',
+ 'fieldset',
+ 'figcaption',
+ 'figure',
+ 'footer',
+ 'form',
+ 'h1',
+ 'h2',
+ 'h3',
+ 'h4',
+ 'h5',
+ 'h6',
+ 'head',
+ 'header',
+ 'hgroup',
+ 'hr',
+ 'html',
+ 'i',
+ 'iframe',
+ 'img',
+ 'input',
+ 'ins',
+ 'kbd',
+ 'keygen',
+ 'label',
+ 'legend',
+ 'li',
+ 'link',
+ 'main',
+ 'map',
+ 'mark',
+ 'menu',
+ 'meta',
+ 'meter',
+ 'nav',
+ 'noscript',
+ 'object',
+ 'ol',
+ 'optgroup',
+ 'option',
+ 'output',
+ 'p',
+ 'param',
+ 'picture',
+ 'pre',
+ 'progress',
+ 'q',
+ 'rp',
+ 'rt',
+ 'ruby',
+ 's',
+ 'samp',
+ 'script',
+ 'section',
+ 'select',
+ 'slot',
+ 'small',
+ 'source',
+ 'span',
+ 'strong',
+ 'style',
+ 'sub',
+ 'summary',
+ 'sup',
+ 'table',
+ 'tbody',
+ 'td',
+ 'template',
+ 'textarea',
+ 'tfoot',
+ 'th',
+ 'thead',
+ 'time',
+ 'title',
+ 'tr',
+ 'track',
+ 'u',
+ 'ul',
+ 'var',
+ 'video',
+ 'wbr',
+ ];
+
+ for (var i = 0; i < elements.length; i++) {
+ var tag = elements[i];
+ var e = document.createElement(tag);
+ assert.isTrue(e instanceof HTMLElement, tag + ' not instanceof HTMLElement');
+ }
+
+ });
+
+});
diff --git a/bower_components/custom-elements/tests/js/reactions.js b/bower_components/custom-elements/tests/js/reactions.js
new file mode 100644
index 0000000..f71d53f
--- /dev/null
+++ b/bower_components/custom-elements/tests/js/reactions.js
@@ -0,0 +1,527 @@
+/**
+ * @license
+ * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+suite('Custom Element Reactions', function() {
+ var work;
+ var assert = chai.assert;
+ var HTMLNS = 'http://www.w3.org/1999/xhtml';
+
+ setup(function() {
+ work = document.createElement('div');
+ document.body.appendChild(work);
+ });
+
+ teardown(function() {
+ document.body.removeChild(work);
+ });
+
+ suite('constructor', function() {
+
+ test('new E() instantiates a new customized element', function() {
+ class XNew extends HTMLElement {}
+ customElements.define('x-new', XNew);
+ var xnew = new XNew();
+
+ assert.equal(xnew.localName, 'x-new');
+ assert.instanceOf(xnew, XNew);
+ });
+
+ test('new E() instantiates subclasses', function() {
+ class XSuper extends HTMLElement {}
+ class XSub extends XSuper {}
+ customElements.define('x-super', XSuper);
+ customElements.define('x-sub', XSub);
+
+ var xsuper = new XSuper();
+ assert.equal(xsuper.localName, 'x-super');
+ assert.instanceOf(xsuper, XSuper);
+
+ var xsub = new XSub();
+ assert.equal(xsub.localName, 'x-sub');
+ assert.instanceOf(xsub, XSub);
+ });
+
+ test('new E() works with ES5-style classes', function() {
+ // To work with ES5-style classes we require a complete definition:
+ function XES5() {
+ // 1) constructors must return the result of the super call
+ return HTMLElement.call(this);
+ }
+ // 2) HTMLElement.prototype must be on the prototype chain
+ XES5.prototype = Object.create(HTMLElement.prototype);
+ // 3) The `constructor` property must point to the classes constructor
+ Object.defineProperty(XES5.prototype, 'constructor', {value: XES5, configurable: true, writable: true,});
+
+ customElements.define('x-es5', XES5);
+
+ var es5 = new XES5();
+ assert.equal(es5.localName, 'x-es5');
+ assert.instanceOf(es5, XES5);
+ });
+
+ test('constructor is called when instantiated via createElement', function() {
+ var pass = false;
+ class XFoo2 extends HTMLElement {
+ constructor() {
+ super();
+ pass = true;
+ }
+ }
+ var XFoo = customElements.define('x-foo2', XFoo2);
+ var xfoo = document.createElement('x-foo2');
+ assert.equal(xfoo.localName, 'x-foo2');
+ assert.instanceOf(xfoo, XFoo2);
+ assert.isTrue(pass);
+ });
+
+ test('subclass constructor is called when instantiated via createElement', function() {
+ class XSuper2 extends HTMLElement {}
+ var pass = false;
+ class XSub2 extends XSuper2 {
+ constructor() {
+ super();
+ pass = true;
+ }
+ }
+ customElements.define('x-super-2', XSuper2);
+ customElements.define('x-sub-2', XSub2);
+
+ var xsuper = document.createElement('x-super-2');
+ assert.equal(xsuper.localName, 'x-super-2');
+ assert.instanceOf(xsuper, XSuper2);
+
+ var xsub = document.createElement('x-sub-2');
+ assert.equal(xsub.localName, 'x-sub-2');
+ assert.instanceOf(xsub, XSub2);
+ assert.isTrue(pass);
+ });
+
+ test('ES5 constructor is called when instantiated via createElement', function() {
+ var pass = false;
+ function XBarES5() {
+ pass = true;
+ return HTMLElement.call(this);
+ }
+ XBarES5.prototype = Object.create(HTMLElement.prototype);
+ Object.defineProperty(XBarES5.prototype, 'constructor', {value: XBarES5, configurable: true, writable: true});
+ customElements.define('x-bar-es5', XBarES5);
+ var xbar = document.createElement('x-bar-es5');
+ assert.equal(xbar.localName, 'x-bar-es5');
+ assert.instanceOf(xbar, XBarES5);
+ assert.isTrue(pass);
+ });
+
+ test('constructor is called when instantiated via createElementNS', function() {
+ var pass = false;
+ class XFoo3 extends HTMLElement {
+ constructor() {
+ super();
+ pass = true;
+ }
+ }
+ customElements.define('x-foo3', XFoo3);
+ var xfoo = document.createElementNS(HTMLNS, 'x-foo3');
+ assert.instanceOf(xfoo, XFoo3);
+ assert.equal(xfoo.localName, 'x-foo3');
+ assert.isTrue(pass);
+ });
+
+ test('constructor is called for each instance', function() {
+ var count = 0;
+ class XFoo4 extends HTMLElement {
+ constructor() {
+ super();
+ count++;
+ }
+ }
+ customElements.define('x-foo4', XFoo4);
+ var e1 = document.createElement('x-foo4');
+ var e2 = document.createElement('x-foo4');
+
+ assert.notStrictEqual(e1, e2);
+ assert.equal(count, 2);
+ });
+
+ test('calls constructor only once', function() {
+ var count = 0;
+ class XConstructor extends HTMLElement {
+ constructor() {
+ super();
+ count++;
+ }
+ }
+ customElements.define('x-constructor', XConstructor);
+ var xconstructor = new XConstructor();
+ assert.equal(count, 1);
+ });
+
+ test('innerHTML on disconnected elements customizes contents', function() {
+ var passed = false;
+ class XInner extends HTMLElement {
+ constructor() {
+ super();
+ passed = true;
+ }
+ }
+ customElements.define('x-inner', XInner);
+ var div = document.createElement('div');
+ div.innerHTML = '';
+ assert.isTrue(passed);
+ });
+
+ });
+
+ suite('attributeChangedCallback', function() {
+
+ // TODO(justinfagnani): test for observedAttributes
+
+ test('if not defined, observedAttributes is not read', function() {
+ customElements.define('x-no-attr-callback', class extends HTMLElement {
+ static get observedAttributes() {
+ assert.fail();
+ }
+ });
+ });
+
+ test('called when setting observed attribute via setAttribute', function(done) {
+ class XBoo extends HTMLElement {
+ static get observedAttributes() {
+ return ['foo'];
+ }
+
+ attributeChangedCallback(inName, inOldValue) {
+ if (inName == 'foo' && inOldValue == 'bar'
+ && this.attributes.foo.value == 'zot') {
+ done();
+ }
+ }
+ }
+ customElements.define('x-boo-acp', XBoo);
+ var xboo = new XBoo();
+ xboo.setAttribute('foo', 'bar');
+ xboo.setAttribute('foo', 'zot');
+ });
+
+ test('called for existing observed attributes', function () {
+ var changed = [];
+ class XBoo extends HTMLElement {
+ static get observedAttributes () {
+ return ['test1'];
+ }
+ attributeChangedCallback(name, oldValue, newValue) {
+ changed.push({
+ name: name,
+ oldValue: oldValue,
+ newValue: newValue
+ });
+ }
+ connectedCallback() {
+ this.innerHTML = 'testing';
+ }
+ }
+
+ var element = document.createElement('x-boo-at1');
+ element.setAttribute('test1', 'test1');
+ element.setAttribute('test2', 'test2');
+ work.appendChild(element);
+
+ customElements.define('x-boo-at1', XBoo);
+
+ assert.equal(changed.length, 1, 'should only trigger for observed attributes');
+ assert.equal(changed[0].name, 'test1', 'name');
+ assert.equal(changed[0].oldValue, null, 'oldValue');
+ assert.equal(changed[0].newValue, 'test1', 'newValue');
+ });
+
+ test('called even if attribute value hasn\'t changed', function () {
+ var calls = 0;
+ class XBoo extends HTMLElement {
+ static get observedAttributes () {
+ return ['foo'];
+ }
+ attributeChangedCallback(name, oldValue, newValue) {
+ calls += 1;
+ }
+ }
+ var element = document.createElement('x-boo-at2');
+
+ customElements.define('x-boo-at2', XBoo);
+ work.appendChild(element);
+ element.setAttribute('foo', 'foo');
+ element.setAttribute('foo', 'foo');
+
+ assert.equal(calls, 2);
+ })
+
+ });
+
+ suite('connectedCallback', function() {
+ var connectedCount;
+ class XConnected extends HTMLElement {
+ connectedCallback() {
+ connectedCount++;
+ }
+ }
+ customElements.define('x-connected', XConnected);
+
+ setup(function() {
+ connectedCount = 0;
+ });
+
+ test('is not called for disconnected custom elements', function() {
+ new XConnected();
+ assert.equal(connectedCount, 0);
+ });
+
+ test('is not called for deeply disconnected custom elements', function() {
+ var parent = new XConnected();
+ var child = new XConnected();
+ parent.appendChild(child);
+ assert.equal(connectedCount, 0);
+ });
+
+ test('called when appended to main document', function() {
+ work.appendChild(new XConnected());
+ assert.equal(connectedCount, 1);
+ });
+
+ test('called when re-appended to main document', function() {
+ var el = new XConnected();
+ work.appendChild(el);
+ work.removeChild(el);
+ work.appendChild(el);
+ assert.equal(connectedCount, 2);
+ });
+
+ test('called in tree order', function() {
+ var log = [];
+
+ class XOrdering extends HTMLElement {
+ connectedCallback() {
+ log.push(this.id);
+ }
+ }
+
+ customElements.define('x-ordering', XOrdering);
+
+ work.innerHTML =
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '';
+
+ assert.deepEqual(log, ['a', 'b', 'c', 'd', 'e']);
+ });
+
+ });
+
+ suite('disconnectedCallback', function() {
+
+ test('called when disconnected from main document', function() {
+ var ready, inserted, removed;
+ class XBoo extends HTMLElement {
+ disconnectedCallback() {
+ removed = true;
+ }
+ }
+ customElements.define('x-boo-ir2', XBoo);
+ var xboo = new XBoo();
+ assert(!removed, 'removed must be false [XBoo]');
+ work.appendChild(xboo);
+ work.removeChild(xboo);
+ assert(removed, 'removed must be true [XBoo]');
+
+ ready = inserted = removed = false;
+ class XBooBoo extends HTMLElement {
+ disconnectedCallback() {
+ removed = true;
+ }
+ }
+ customElements.define('x-booboo-ir2', XBooBoo);
+ var xbooboo = new XBooBoo();
+ assert(!removed, 'removed must be false [XBooBoo]');
+ work.appendChild(xbooboo);
+ work.removeChild(xbooboo);
+ assert(removed, 'removed must be true [XBooBoo]');
+ });
+
+ test('called in tree order', function() {
+ var log = [];
+ class XOrdering2 extends HTMLElement {
+ disconnectedCallback() {
+ log.push(this.id);
+ }
+ }
+ customElements.define('x-ordering2', XOrdering2);
+
+ work.innerHTML =
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '';
+
+ work.removeChild(work.firstElementChild);
+ assert.deepEqual(['a', 'b', 'c', 'd', 'e'], log);
+ });
+
+ });
+
+ suite('clone/import/adopt', function() {
+
+ test('imported custom elements are customized', function() {
+ class XImported extends HTMLElement {}
+ customElements.define('x-imported', XImported);
+
+ // most imports happen on nodes in a different document, but elements
+ // in another document woudn't be customized in the first place
+ var original = document.createElement('x-imported');
+ assert.instanceOf(original, XImported);
+
+ var imported = document.importNode(original, true);
+ assert.instanceOf(imported, XImported);
+ });
+
+ test.skip('cloned custom elements are customized', function() {
+ class XCloned extends HTMLElement {}
+ customElements.define('x-cloned', XCloned);
+
+ var original = document.createElement('x-cloned');
+ assert.instanceOf(original, XCloned);
+
+ var imported = original.cloneNode(true);
+ assert.instanceOf(imported, XCloned);
+ });
+
+ test.skip('adopted custom elements are customized', function() {
+ class XAdopted extends HTMLElement {}
+ customElements.define('x-adopted', XAdopted);
+
+ var otherDoc = document.implementation.createHTMLDocument('adopt');
+ var original = otherDoc.createElement('x-adopted');
+ // x-adopted is not defined in its document
+ assert.notInstanceOf(original, XAdopted);
+
+ var imported = document.adoptNode(original);
+ assert.notInstanceOf(imported, XAdopted);
+ });
+
+ });
+
+ suite('moving and reconnecting', function() {
+
+ test('connected then disconnected', function() {
+ class XCallbacks extends HTMLElement {
+ constructor() {
+ super();
+ this.connected = false;
+ this.disconnected = false;
+ }
+
+ connectedCallback() {
+ this.connected = true;
+ }
+
+ disconnectedCallback() {
+ this.disconnected = true;
+ }
+ }
+ customElements.define('x-callbacks', XCallbacks);
+ var e = new XCallbacks();
+ assert.isFalse(e.connected);
+ assert.isFalse(e.disconnected);
+
+ work.appendChild(e);
+ assert.isTrue(e.connected);
+ assert.isFalse(e.disconnected);
+
+ work.removeChild(e);
+ assert.isTrue(e.connected);
+ assert.isTrue(e.disconnected);
+ });
+
+ // TODO(justinfagnani): old, ported test. Rendundant?
+ test('entered left apply to view', function() {
+ var invocations = [];
+ var tagName = 'x-entered-left';
+ class XEnteredLeft extends HTMLElement {
+ constructor() {
+ super();
+ invocations.push('constructor');
+ }
+ connectedCallback() {
+ invocations.push('entered');
+ }
+ disconnectedCallback() {
+ invocations.push('left');
+ }
+ }
+ customElements.define(tagName, XEnteredLeft);
+
+ var element = document.createElement(tagName);
+ assert.deepEqual(invocations, ['constructor'], 'created but not entered view');
+
+ // // note, cannot use instanceof due to IE
+ assert.equal(element.__proto__, XEnteredLeft.prototype, 'element is correct type');
+
+ work.appendChild(element)
+ assert.deepEqual(invocations, ['constructor', 'entered'],
+ 'created and entered view');
+
+ element.parentNode.removeChild(element);
+ assert.deepEqual(invocations, ['constructor', 'entered', 'left'],
+ 'created, entered then left view');
+ });
+
+ test('connected then disconnected in same task', function() {
+ var log = [];
+ class XAD extends HTMLElement {
+ connectedCallback() {
+ log.push('connected');
+ }
+ disconnectedCallback() {
+ log.push('disconnected');
+ }
+ }
+
+ customElements.define('x-ad', XAD);
+ var el = document.createElement('x-ad');
+ work.appendChild(el);
+ work.removeChild(el);
+ assert.deepEqual(log, ['connected', 'disconnected']);
+ });
+
+ test('disconnected then re-connected in same task', function() {
+ var log = [];
+ class XDA extends HTMLElement {
+ connectedCallback() {
+ log.push('connected');
+ }
+ disconnectedCallback() {
+ log.push('disconnected');
+ }
+ }
+ customElements.define('x-da', XDA);
+ var el = document.createElement('x-da');
+ work.appendChild(el);
+ log = [];
+ work.removeChild(el);
+ work.appendChild(el);
+ assert.deepEqual(log, ['disconnected', 'connected']);
+ });
+
+ });
+
+});
diff --git a/bower_components/custom-elements/tests/js/registry.js b/bower_components/custom-elements/tests/js/registry.js
new file mode 100644
index 0000000..b2d52ae
--- /dev/null
+++ b/bower_components/custom-elements/tests/js/registry.js
@@ -0,0 +1,120 @@
+/**
+ * @license
+ * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+suite('CustomElementsRegistry', function() {
+ var work;
+ var assert = chai.assert;
+ var HTMLNS = 'http://www.w3.org/1999/xhtml';
+
+ customElements.enableFlush = true;
+
+ setup(function() {
+ work = document.createElement('div');
+ document.body.appendChild(work);
+ });
+
+ teardown(function() {
+ document.body.removeChild(work);
+ });
+
+ suite('window', function () {
+
+ test('customElements.define exists', function() {
+ assert.isFunction(customElements.define);
+ });
+
+ });
+
+ suite('define', function() {
+
+ test('requires a name argument', function() {
+ assert.throws(function() {
+ customElements.define();
+ }, '', 'customElements.define failed to throw when given no arguments');
+ });
+
+ test('name must contain a dash', function() {
+ assert.throws(function () {
+ customElements.define('xfoo', {prototype: Object.create(HTMLElement.prototype)});
+ }, '', 'customElements.define failed to throw when given no arguments');
+ });
+
+ test('name must not be a reserved name', function() {
+ assert.throws(function() {
+ customElements.define('font-face', {prototype: Object.create(HTMLElement.prototype)});
+ }, '', 'Failed to execute \'defineElement\' on \'Document\': Registration failed for type \'font-face\'. The type name is invalid.');
+ });
+
+ test('name must be unique', function() {
+ class XDuplicate extends HTMLElement {}
+ customElements.define('x-duplicate', XDuplicate);
+ assert.throws(function() {
+ customElements.define('x-duplicate', XDuplicate);
+ }, '', 'customElements.define failed to throw when called multiple times with the same element name');
+ });
+
+ test('names are case-sensitive', function() {
+ class XCase extends HTMLElement {}
+ assert.throws(function() { customElements.define('X-CASE', XCase); });
+ });
+
+ test('requires a constructor argument', function() {
+ assert.throws(function () {
+ customElements.define('x-no-options');
+ }, '', 'customElements.define failed to throw without a constructor argument');
+ });
+
+ test('second argument prototype property is required', function() {
+ assert.throws(function () {
+ customElements.define('x-no-proto', {});
+ }, '', 'customElements.define failed to throw with a constructor argument with no prototype');
+ });
+
+ });
+
+ suite('get', function() {
+
+ test('returns a defined constructor', function () {
+ class XGet extends HTMLElement {}
+ customElements.define('x-get', XGet);
+ assert.equal(XGet, customElements.get('x-get'));
+ });
+
+ test('returns undefined for an undefined constructor', function () {
+ assert.isUndefined(customElements.get('x-undefined'));
+ });
+
+ });
+
+ suite('whenDefined', function() {
+
+ test('resolves when a tag is defined', function () {
+ var promise = customElements.whenDefined('x-when-defined').then(function (r) {
+ assert.isUndefined(r);
+ });
+ class XDefined extends HTMLElement {}
+ customElements.define('x-when-defined', XDefined);
+ return promise;
+ });
+
+ test('throws for an invalid element name', function () {
+ return customElements.whenDefined('div').then(
+ function() {
+ assert.fail();
+ },
+ function() {
+ // pass
+ return;
+ });
+ });
+
+ });
+
+});
diff --git a/bower_components/custom-elements/tests/js/shadow-dom.js b/bower_components/custom-elements/tests/js/shadow-dom.js
new file mode 100644
index 0000000..850d904
--- /dev/null
+++ b/bower_components/custom-elements/tests/js/shadow-dom.js
@@ -0,0 +1,60 @@
+/**
+ * @license
+ * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+suite('Shadow DOM Support', function() {
+
+ var work;
+ var assert = chai.assert;
+
+ setup(function() {
+ work = document.createElement('div');
+ document.body.appendChild(work);
+ });
+
+ teardown(function() {
+ document.body.removeChild(work);
+ });
+
+ // Tests should be skipped in browsers that don't have native Shadow DOM
+ var testFn = Element.prototype.attachShadow ? test : test.skip;
+
+ testFn('custom elements are created in shadow roots', function() {
+ class XShadow extends HTMLElement {}
+ customElements.define('x-shadow', XShadow);
+
+ var shadowRoot = work.attachShadow({mode: 'open'});
+ var container = document.createElement('div');
+ shadowRoot.appendChild(container);
+ container.innerHTML = '';
+
+ var el = container.querySelector('x-shadow');
+ assert.instanceOf(el, XShadow);
+ });
+
+ testFn('custom elements are upgraded in shadow roots', function() {
+ class XShadow2 extends HTMLElement {}
+
+ // setup shadow root
+ var shadowRoot = work.attachShadow({mode: 'open'});
+ var container = document.createElement('div');
+ shadowRoot.appendChild(container);
+ container.innerHTML = '';
+ var el = container.querySelector('x-shadow2');
+
+ // undefined elements are not upgraded
+ assert.notInstanceOf(el, XShadow2);
+
+ // elements are upgraded on definition
+ customElements.define('x-shadow2', XShadow2);
+ assert.instanceOf(el, XShadow2);
+ });
+
+
+});
diff --git a/bower_components/custom-elements/tests/js/typescript.js b/bower_components/custom-elements/tests/js/typescript.js
new file mode 100644
index 0000000..baf5dbd
--- /dev/null
+++ b/bower_components/custom-elements/tests/js/typescript.js
@@ -0,0 +1,66 @@
+/**
+ * @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
+ */
+
+suite('TypeScript ES5 Output', function() {
+
+ customElements.enableFlush = true;
+
+ // Fails because the XTypescript constructor does not return the result of
+ // the super call. See: https://github.com/Microsoft/TypeScript/issues/7574
+ test.skip('TypeScript generated ES5 works via new()', function() {
+ var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+ var XTypescript = (function (_super) {
+ __extends(XTypescript, _super);
+ function XTypescript() {
+ _super.call(this);
+ }
+ return XTypescript;
+ }(HTMLElement));
+
+ // register x-foo
+ customElements.define('x-typescript', XTypescript);
+ // create an instance via new
+ var e = new XTypescript();
+ // test localName
+ assert.equal(e.localName, 'x-typescript');
+ // test instanceof
+ assert.instanceOf(e, XTypescript);
+ });
+
+ test.skip('TypeScript generated ES5 works via createElement', function() {
+ var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+ var XTypescript2 = (function (_super) {
+ __extends(XTypescript2, _super);
+ function XTypescript2() {
+ _super.call(this);
+ }
+ return XTypescript2;
+ }(HTMLElement));
+
+ // register x-foo
+ customElements.define('x-typescript2', XTypescript2);
+ // create an instance via new
+ var e = document.createElement('x-typescript2');
+ // test localName
+ assert.equal(e.localName, 'x-typescript2');
+ // test instanceof
+ assert.instanceOf(e, XTypescript2);
+
+ });
+
+});
diff --git a/bower_components/custom-elements/tests/js/upgrade.js b/bower_components/custom-elements/tests/js/upgrade.js
new file mode 100644
index 0000000..653f902
--- /dev/null
+++ b/bower_components/custom-elements/tests/js/upgrade.js
@@ -0,0 +1,58 @@
+/**
+ * @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
+ */
+
+suite('Upgrades', function() {
+ var work;
+ var assert = chai.assert;
+
+ setup(function() {
+ work = document.createElement('div');
+ document.body.appendChild(work);
+ });
+
+ teardown(function() {
+ document.body.removeChild(work);
+ });
+
+ test('connected elements upgrade when defined', function() {
+ work.innerHTML = '';
+ var e1 = work.firstChild;
+ var e2 = e1.firstChild;
+
+ class X1 extends HTMLElement {}
+ class X2 extends HTMLElement {}
+ customElements.define('x-markup-1', X1);
+ customElements.define('x-markup-2', X2);
+
+ assert.instanceOf(e1, X1);
+ assert.instanceOf(e2, X2);
+ });
+
+ test('defined disconnected elements upgrade when connected', function() {
+ var e1 = document.createElement('x-disconnected-1');
+ var e2 = document.createElement('x-disconnected-2');
+ e1.appendChild(e2);
+
+ class X1 extends HTMLElement {}
+ class X2 extends HTMLElement {}
+ customElements.define('x-disconnected-1', X1);
+ customElements.define('x-disconnected-2', X2);
+
+ // disconnected elements should not be upgraded
+ assert.notInstanceOf(e1, X1);
+ assert.notInstanceOf(e2, X2);
+
+ // they should upgrade when connected
+ work.appendChild(e1);
+ assert.instanceOf(e1, X1);
+ assert.instanceOf(e2, X2);
+ });
+
+});
diff --git a/bower_components/custom-elements/tests/new/index.html b/bower_components/custom-elements/tests/new/index.html
new file mode 100644
index 0000000..0a2be18
--- /dev/null
+++ b/bower_components/custom-elements/tests/new/index.html
@@ -0,0 +1,7 @@
+
+
+
diff --git a/bower_components/custom-elements/wct.conf.json b/bower_components/custom-elements/wct.conf.json
new file mode 100644
index 0000000..3ef8123
--- /dev/null
+++ b/bower_components/custom-elements/wct.conf.json
@@ -0,0 +1,6 @@
+{
+ "suites": ["tests/index.html"],
+ "clientOptions": {
+ "environmentImports": []
+ }
+}
diff --git a/bower_components/webcomponentsjs/.bower.json b/bower_components/webcomponentsjs/.bower.json
new file mode 100644
index 0000000..cfa8653
--- /dev/null
+++ b/bower_components/webcomponentsjs/.bower.json
@@ -0,0 +1,35 @@
+{
+ "name": "webcomponentsjs",
+ "description": "Web components polyfill",
+ "main": "webcomponents.js",
+ "homepage": "http://webcomponents.org",
+ "authors": [
+ "The Polymer Authors"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/webcomponents/webcomponentsjs.git"
+ },
+ "keywords": [
+ "webcomponents",
+ "web-components",
+ "polyfill",
+ "shim"
+ ],
+ "license": "BSD-3-Clause",
+ "ignore": [],
+ "devDependencies": {
+ "web-component-tester": "^v6.0.0"
+ },
+ "version": "1.0.20",
+ "_release": "1.0.20",
+ "_resolution": {
+ "type": "version",
+ "tag": "v1.0.20",
+ "commit": "e83a68eb7d74f7d03e6ed111085730c10cb58507"
+ },
+ "_source": "https://github.com/webcomponents/webcomponentsjs.git",
+ "_target": "^1.0.20",
+ "_originalSource": "webcomponents/webcomponentsjs",
+ "_direct": true
+}
\ No newline at end of file
diff --git a/bower_components/webcomponentsjs/.eslintrc.json b/bower_components/webcomponentsjs/.eslintrc.json
new file mode 100644
index 0000000..fcf4db6
--- /dev/null
+++ b/bower_components/webcomponentsjs/.eslintrc.json
@@ -0,0 +1,11 @@
+{
+ "extends": "eslint:recommended",
+ "env": {
+ "browser": true,
+ "es6": true
+ },
+ "parserOptions": {
+ "ecmaVersion": 6,
+ "sourceType": "module"
+ }
+}
diff --git a/bower_components/webcomponentsjs/.gitattributes b/bower_components/webcomponentsjs/.gitattributes
new file mode 100644
index 0000000..2140426
--- /dev/null
+++ b/bower_components/webcomponentsjs/.gitattributes
@@ -0,0 +1,3 @@
+/webcomponents*.js binary
+/webcomponents*.js.map binary
+/webcomponents-loader.js -binary
\ No newline at end of file
diff --git a/bower_components/webcomponentsjs/.gitignore b/bower_components/webcomponentsjs/.gitignore
new file mode 100644
index 0000000..d781733
--- /dev/null
+++ b/bower_components/webcomponentsjs/.gitignore
@@ -0,0 +1,3 @@
+node_modules
+bower_components
+dist
diff --git a/bower_components/webcomponentsjs/.travis.yml b/bower_components/webcomponentsjs/.travis.yml
new file mode 100644
index 0000000..a72b5cf
--- /dev/null
+++ b/bower_components/webcomponentsjs/.travis.yml
@@ -0,0 +1,25 @@
+language: node_js
+sudo: required
+dist: trusty
+node_js: stable
+addons:
+ firefox: latest
+ apt:
+ sources:
+ - google-chrome
+ packages:
+ - google-chrome-stable
+before_script:
+- export DISPLAY=:99.0
+- sh -e /etc/init.d/xvfb start
+- sleep 3
+script:
+- npm install -g bower
+- bower install
+- wct -l chrome
+- wct -l firefox
+- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then wct -s 'windows 10/microsoftedge@14' -s 'windows 8.1/internet explorer@11' -s 'os x 10.11/safari@10' -s 'os x 10.11/safari@9' -s 'Linux/chrome@41'; fi
+env:
+ global:
+ - secure: Fpp9LwJSGOdTrSIImQTlbzxozBsqe/2AJN5OfTXSe12FZxqzz50gevdxQcIlLypKaNyCtjb980DJbwdJR2cXUqaunLZAPWxrKa7ZPwamUxW+zVL7EHqy5zuvD+yJ+Vmk3ahs3WBTVyJ8T3XoaSfo9VumDIcKggWGJwgvM3blIMg=
+ - secure: Bj8MgzUVP0X8MLgK3d9eF48V7x0rPJyrN1IyguzKyJJVC8LV2XZXF+6o/M+zNsVMSsjhgXMkS3RRuaUShxO/OS6gHeG31FWcZqbXfZfgMMyH8a8zDls+r8m2lGEICaZo1OTXR0uiR/VNVt7n2xoBnTmjmRFwkaxAZk4yCjbXYzQ=
diff --git a/bower_components/webcomponentsjs/CONTRIBUTING.md b/bower_components/webcomponentsjs/CONTRIBUTING.md
new file mode 100644
index 0000000..d511daf
--- /dev/null
+++ b/bower_components/webcomponentsjs/CONTRIBUTING.md
@@ -0,0 +1,64 @@
+# Contributing
+
+Want to contribute to webcomponents.js? Great!
+
+We are more than happy to accept external contributions to the project in the form of [bug reports](../../issues) and pull requests.
+
+## Contributor License Agreement
+
+Before we can accept patches, there's a quick web form you need to fill out.
+
+- If you're contributing as an individual (e.g. you own the intellectual property), fill out [this form](http://code.google.com/legal/individual-cla-v1.0.html).
+- If you're contributing under a company, fill out [this form](http://code.google.com/legal/corporate-cla-v1.0.html) instead.
+
+This CLA asserts that contributions are owned by you and that we can license all work under our [license](LICENSE).
+
+Other projects require a similar agreement: jQuery, Firefox, Apache, Node, and many more.
+
+[More about CLAs](https://www.google.com/search?q=Contributor%20License%20Agreement)
+
+## Initial setup
+
+1. Setup Gulp: `sudo npm install -g gulp`
+1. Fork the project on github and pull down your copy.
+ > replace the {{ username }} with your username and {{ repository }} with the repository name
+
+ git clone git@github.com:{{ username }}/{{ repository }}.git
+
+1. Test your change results in a working build.
+ > in the repo you've made changes to, try generating a build:
+
+ cd $REPO
+ npm install
+ gulp
+
+The builds will be placed into the `dist/` directory if all goes well.
+
+1. Commit your code and make a pull request.
+
+That's it for the one time setup. Now you're ready to make a change.
+
+## Submitting a pull request
+
+We iterate fast! To avoid potential merge conflicts, it's a good idea to pull from the main project before making a change and submitting a pull request. The easiest way to do this is setup a remote called `upstream` and do a pull before working on a change:
+
+ git remote add upstream git://github.com/polymer/webcomponentsjs.git
+
+Then before making a change, do a pull from the upstream `master` branch:
+
+ git pull upstream master
+
+To make life easier, add a "pull upstream" alias in your `.gitconfig`:
+
+ [alias]
+ pu = !"git fetch origin -v; git fetch upstream -v; git merge upstream/master"
+
+That will pull in changes from your forked repo, the main (upstream) repo, and merge the two. Then it's just a matter of running `git pu` before a change and pushing to your repo:
+
+ git checkout master
+ git pu
+ # make change
+ git commit -a -m 'Awesome things.'
+ git push
+
+Lastly, don't forget to submit the pull request.
\ No newline at end of file
diff --git a/bower_components/webcomponentsjs/LICENSE.md b/bower_components/webcomponentsjs/LICENSE.md
new file mode 100644
index 0000000..bb3f440
--- /dev/null
+++ b/bower_components/webcomponentsjs/LICENSE.md
@@ -0,0 +1,19 @@
+# License
+
+Everything in this repo is BSD style license unless otherwise specified.
+
+Copyright (c) 2015 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.
\ No newline at end of file
diff --git a/bower_components/webcomponentsjs/README.md b/bower_components/webcomponentsjs/README.md
new file mode 100644
index 0000000..dc1b41c
--- /dev/null
+++ b/bower_components/webcomponentsjs/README.md
@@ -0,0 +1,169 @@
+webcomponents.js (v1 spec polyfills)
+================
+
+[](https://travis-ci.org/webcomponents/webcomponentsjs)
+
+> **Note**. For polyfills that work with the older Custom Elements and Shadow DOM v0 specs, see the [v0 branch](https://github.com/webcomponents/webcomponentsjs/tree/v0).
+
+A suite of polyfills supporting the [Web Components](http://webcomponents.org) specs:
+
+- **Custom Elements v1**: allows authors to define their own custom tags ([spec](https://w3c.github.io/webcomponents/spec/custom/), [tutorial](https://developers.google.com/web/fundamentals/getting-started/primers/customelements)).
+- **HTML Imports**: a way to include and reuse HTML documents via other HTML documents ([spec](https://w3c.github.io/webcomponents/spec/imports/), [tutorial](https://www.html5rocks.com/en/tutorials/webcomponents/imports/)).
+- **Shadow DOM v1**: provides encapsulation by hiding DOM subtrees under shadow roots ([spec](https://w3c.github.io/webcomponents/spec/shadow/), [tutorial](https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom)).
+
+For browsers that need it, there are also some minor polyfills included:
+- [`HTMLTemplateElement`](https://github.com/webcomponents/template)
+- [`Promise`](https://github.com/stefanpenner/es6-promise)
+- `Event`, `CustomEvent`, `MouseEvent` constructors and `Object.assign`, `Array.from` (see [webcomponents-platform](https://github.com/webcomponents/webcomponents-platform))
+
+## How to use
+
+The polyfills are built (concatenated & minified) into several bundles that target
+different browsers and spec readiness:
+
+- `webcomponents-hi.js` -- HTML Imports (needed by Safari Tech Preview)
+- `webcomponents-hi-ce.js` -- HTML Imports and Custom Elements v1 (needed by Safari 10)
+- `webcomponents-hi-sd-ce.js` -- HTML Imports, Custom Elements v1 and Shady DOM/CSS (needed by Safari 9, Firefox, Edge)
+- `webcomponents-sd-ce.js` -- Custom Elements and Shady DOM/CSS (no HTML Imports)
+- `webcomponents-lite.js` -- all of the polyfills: HTML Imports, Custom Elements, Shady DOM/CSS and generic platform polyfills (such as ES6 Promise, Constructable events, etc.) (needed by Internet Explorer 11), and Template (needed by IE 11 and Edge)
+
+If you are only targeting a specific browser, you can just use the bundle that's
+needed by it; alternatively, if your server is capable of serving different assets based on user agent, you can send the polyfill bundle that's necessary for the browser making that request.
+
+## `webcomponents-loader.js`
+Alternatively, this repo also comes with `webcomponents-loader.js`, a client-side
+loader that dynamically loads the minimum polyfill bundle, using feature detection.
+Note that because the bundle will be loaded asynchronously, you should wait for the `WebComponentsReady` before you can safely assume that all the polyfills have
+loaded and are ready to be used (i.e. if you want to dynamically load other custom
+elements, etc.).
+
+Additionally, you can check if `window.WebComponents` exists to know if the `WebComponentsReady` event will fire, and you can check if `window.WebComponents.ready` is true to check if the `WebComponentsReady` event has already fired.
+
+Here's an example:
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+```
+
+## `custom-elements-es5-adapter.js`
+According to the spec, Custom Elements must be ES6 classes (https://html.spec.whatwg.org/multipage/scripting.html#custom-element-conformance). Since most projects need to support a wide range of browsers that don't necessary support ES6, it may make sense to compile your project to ES5. However, ES5-style custom element classes will **not** work with native Custom Elements because ES5-style classes cannot properly extend ES6 classes, like `HTMLElement`.
+
+To work around this, load `custom-elements-es5-adapter.js` before declaring new Custom Elements.
+
+**The adapter must NOT be compiled.**
+
+```html
+
+
+
+
+
+
+
+
+
+```
+
+## Browser Support
+
+The polyfills are intended to work in the latest versions of evergreen browsers. See below
+for our complete browser support matrix:
+
+| Polyfill | IE11+ | Chrome* | Firefox* | Safari 9+* | Chrome Android* | Mobile Safari* |
+| ---------- |:-----:|:-------:|:--------:|:----------:|:---------------:|:--------------:|
+| Custom Elements | ✓ | ✓ | ✓ | ✓ | ✓| ✓ |
+| HTML Imports | ✓ | ✓ | ✓ | ✓| ✓| ✓ |
+| Shady CSS/DOM | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
+
+\*Indicates the current version of the browser
+
+The polyfills may work in older browsers, however require additional polyfills (such as classList, or other [platform](https://github.com/webcomponents/webcomponents-platform)
+polyfills) to be used. We cannot guarantee support for browsers outside of our compatibility matrix.
+
+
+### Manually Building
+
+If you wish to build the bundles yourself, you'll need `node` and `npm` 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
+ bower install
+ # build
+ gulp
+
+The builds will be placed into the root 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, `
+
+
+
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/ce-import-upgrade.html b/bower_components/webcomponentsjs/tests/ce-import-upgrade.html
new file mode 100644
index 0000000..f0d8b50
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/ce-import-upgrade.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/ce-import.html b/bower_components/webcomponentsjs/tests/ce-import.html
new file mode 100644
index 0000000..7917342
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/ce-import.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/ce-upgrade-order.html b/bower_components/webcomponentsjs/tests/ce-upgrade-order.html
new file mode 100644
index 0000000..6a28c3b
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/ce-upgrade-order.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+ Custom Element Upgrade Order
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/ce-upgradedocumenttree.html b/bower_components/webcomponentsjs/tests/ce-upgradedocumenttree.html
new file mode 100644
index 0000000..b5b473f
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/ce-upgradedocumenttree.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/dev-loader-swizzled.html b/bower_components/webcomponentsjs/tests/dev-loader-swizzled.html
new file mode 100644
index 0000000..5edb485
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/dev-loader-swizzled.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/dev-loader.html b/bower_components/webcomponentsjs/tests/dev-loader.html
new file mode 100644
index 0000000..19564d4
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/dev-loader.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/force-polyfills.html b/bower_components/webcomponentsjs/tests/force-polyfills.html
new file mode 100644
index 0000000..8d4c39a
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/force-polyfills.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+ Force polyfills
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bower_components/webcomponentsjs/tests/imports/a1-define.html b/bower_components/webcomponentsjs/tests/imports/a1-define.html
new file mode 100644
index 0000000..7b88009
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/a1-define.html
@@ -0,0 +1,32 @@
+
+
diff --git a/bower_components/webcomponentsjs/tests/imports/a1-import.html b/bower_components/webcomponentsjs/tests/imports/a1-import.html
new file mode 100644
index 0000000..6b0a1e0
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/a1-import.html
@@ -0,0 +1,11 @@
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/imports/a1-instance.html b/bower_components/webcomponentsjs/tests/imports/a1-instance.html
new file mode 100644
index 0000000..0864bc5
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/a1-instance.html
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/imports/a1-reference.html b/bower_components/webcomponentsjs/tests/imports/a1-reference.html
new file mode 100644
index 0000000..908edc9
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/a1-reference.html
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/imports/csp-import-1.html b/bower_components/webcomponentsjs/tests/imports/csp-import-1.html
new file mode 100644
index 0000000..65a535a
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/csp-import-1.html
@@ -0,0 +1,11 @@
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/imports/csp-import-2.html b/bower_components/webcomponentsjs/tests/imports/csp-import-2.html
new file mode 100644
index 0000000..e619553
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/csp-import-2.html
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/bower_components/webcomponentsjs/tests/imports/csp-script-1.js b/bower_components/webcomponentsjs/tests/imports/csp-script-1.js
new file mode 100644
index 0000000..bcff149
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/csp-script-1.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
+ */
+
+window.externalScriptParsed1 = new Date().getTime();
diff --git a/bower_components/webcomponentsjs/tests/imports/csp-script-2.js b/bower_components/webcomponentsjs/tests/imports/csp-script-2.js
new file mode 100644
index 0000000..0f3534c
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/csp-script-2.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
+ */
+
+window.externalScriptParsed2 = new Date().getTime();
diff --git a/bower_components/webcomponentsjs/tests/imports/current-script.js b/bower_components/webcomponentsjs/tests/imports/current-script.js
new file mode 100644
index 0000000..402c32c
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/current-script.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
+ */
+
+remoteCurrentScriptExecuted = window.remoteCurrentScriptExecuted || 0;
+remoteCurrentScriptExecuted++;
+assert.ok(document._currentScript);
diff --git a/bower_components/webcomponentsjs/tests/imports/element-import-a.html b/bower_components/webcomponentsjs/tests/imports/element-import-a.html
new file mode 100644
index 0000000..775c360
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/element-import-a.html
@@ -0,0 +1,11 @@
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/imports/element-import-b.html b/bower_components/webcomponentsjs/tests/imports/element-import-b.html
new file mode 100644
index 0000000..a48c169
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/element-import-b.html
@@ -0,0 +1,11 @@
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/imports/element-import.html b/bower_components/webcomponentsjs/tests/imports/element-import.html
new file mode 100644
index 0000000..6b8935f
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/element-import.html
@@ -0,0 +1,20 @@
+
+
+
diff --git a/bower_components/webcomponentsjs/tests/imports/import-file.html b/bower_components/webcomponentsjs/tests/imports/import-file.html
new file mode 100644
index 0000000..82e57c7
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/import-file.html
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/bower_components/webcomponentsjs/tests/imports/import-upgrade-order.html b/bower_components/webcomponentsjs/tests/imports/import-upgrade-order.html
new file mode 100644
index 0000000..fb88f66
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/import-upgrade-order.html
@@ -0,0 +1,10 @@
+
+
diff --git a/bower_components/webcomponentsjs/tests/imports/script-1.html b/bower_components/webcomponentsjs/tests/imports/script-1.html
new file mode 100644
index 0000000..dedaaee
--- /dev/null
+++ b/bower_components/webcomponentsjs/tests/imports/script-1.html
@@ -0,0 +1,16 @@
+
+