| Index: appengine/swarming/elements/build/index-build.html | 
| diff --git a/appengine/swarming/elements/build/index-build.html b/appengine/swarming/elements/build/index-build.html | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..64869933d151529ae0d5553a77d9f50620796927 | 
| --- /dev/null | 
| +++ b/appengine/swarming/elements/build/index-build.html | 
| @@ -0,0 +1,10348 @@ | 
| +<!DOCTYPE html><html><head><!-- | 
| +@license | 
| +Copyright (c) 2015 The Polymer Project Authors. All rights reserved. | 
| +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt | 
| +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | 
| +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt | 
| +Code distributed by Google as part of the polymer project is also | 
| +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt | 
| +--><!-- | 
| +@license | 
| +Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | 
| +This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt | 
| +The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | 
| +The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt | 
| +Code distributed by Google as part of the polymer project is also | 
| +subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt | 
| +--> | 
| +  <title>Many World, wow such hello</title> | 
| +  <meta charset="utf-8"> | 
| +  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> | 
| +  <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes"> | 
| + | 
| +  <script>/** | 
| + * @license | 
| + * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | 
| + * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt | 
| + * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | 
| + * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt | 
| + * Code distributed by Google as part of the polymer project is also | 
| + * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt | 
| + */ | 
| +// @version 0.7.22 | 
| +!function(){window.WebComponents=window.WebComponents||{flags:{}};var e="webcomponents-lite.js",t=document.querySelector('script[src*="'+e+'"]'),n={};if(!n.noOpts){if(location.search.slice(1).split("&").forEach(function(e){var t,o=e.split("=");o[0]&&(t=o[0].match(/wc-(.+)/))&&(n[t[1]]=o[1]||!0)}),t)for(var o,r=0;o=t.attributes[r];r++)"src"!==o.name&&(n[o.name]=o.value||!0);if(n.log&&n.log.split){var i=n.log.split(",");n.log={},i.forEach(function(e){n.log[e]=!0})}else n.log={}}n.register&&(window.CustomElements=window.CustomElements||{flags:{}},window.CustomElements.flags.register=n.register),WebComponents.flags=n}(),function(e){"use strict";function t(e){return void 0!==h[e]}function n(){s.call(this),this._isInvalid=!0}function o(e){return""==e&&n.call(this),e.toLowerCase()}function r(e){var t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,63,96].indexOf(t)?e:encodeURIComponent(e)}function i(e){var t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,96].indexOf(t)?e:encodeURIComponent(e)}function a(e,a,s){function c(e){g.push(e)}var d=a||"scheme start",l=0,u="",w=!1,_=!1,g=[];e:for(;(e[l-1]!=p||0==l)&&!this._isInvalid;){var b=e[l];switch(d){case"scheme start":if(!b||!m.test(b)){if(a){c("Invalid scheme.");break e}u="",d="no scheme";continue}u+=b.toLowerCase(),d="scheme";break;case"scheme":if(b&&v.test(b))u+=b.toLowerCase();else{if(":"!=b){if(a){if(p==b)break e;c("Code point not allowed in scheme: "+b);break e}u="",l=0,d="no scheme";continue}if(this._scheme=u,u="",a)break e;t(this._scheme)&&(this._isRelative=!0),d="file"==this._scheme?"relative":this._isRelative&&s&&s._scheme==this._scheme?"relative or authority":this._isRelative?"authority first slash":"scheme data"}break;case"scheme data":"?"==b?(this._query="?",d="query"):"#"==b?(this._fragment="#",d="fragment"):p!=b&&"	"!=b&&"\n"!=b&&"\r"!=b&&(this._schemeData+=r(b));break;case"no scheme":if(s&&t(s._scheme)){d="relative";continue}c("Missing scheme."),n.call(this);break;case"relative or authority":if("/"!=b||"/"!=e[l+1]){c("Expected /, got: "+b),d="relative";continue}d="authority ignore slashes";break;case"relative":if(this._isRelative=!0,"file"!=this._scheme&&(this._scheme=s._scheme),p==b){this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._query,this._username=s._username,this._password=s._password;break e}if("/"==b||"\\"==b)"\\"==b&&c("\\ is an invalid code point."),d="relative slash";else if("?"==b)this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query="?",this._username=s._username,this._password=s._password,d="query";else{if("#"!=b){var y=e[l+1],E=e[l+2];("file"!=this._scheme||!m.test(b)||":"!=y&&"|"!=y||p!=E&&"/"!=E&&"\\"!=E&&"?"!=E&&"#"!=E)&&(this._host=s._host,this._port=s._port,this._username=s._username,this._password=s._password,this._path=s._path.slice(),this._path.pop()),d="relative path";continue}this._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._query,this._fragment="#",this._username=s._username,this._password=s._password,d="fragment"}break;case"relative slash":if("/"!=b&&"\\"!=b){"file"!=this._scheme&&(this._host=s._host,this._port=s._port,this._username=s._username,this._password=s._password),d="relative path";continue}"\\"==b&&c("\\ is an invalid code point."),d="file"==this._scheme?"file host":"authority ignore slashes";break;case"authority first slash":if("/"!=b){c("Expected '/', got: "+b),d="authority ignore slashes";continue}d="authority second slash";break;case"authority second slash":if(d="authority ignore slashes","/"!=b){c("Expected '/', got: "+b);continue}break;case"authority ignore slashes":if("/"!=b&&"\\"!=b){d="authority";continue}c("Expected authority, got: "+b);break;case"authority":if("@"==b){w&&(c("@ already seen."),u+="%40"),w=!0;for(var L=0;L<u.length;L++){var N=u[L];if("	"!=N&&"\n"!=N&&"\r"!=N)if(":"!=N||null!==this._password){var M=r(N);null!==this._password?this._password+=M:this._username+=M}else this._password="";else c("Invalid whitespace in authority.")}u=""}else{if(p==b||"/"==b||"\\"==b||"?"==b||"#"==b){l-=u.length,u="",d="host";continue}u+=b}break;case"file host":if(p==b||"/"==b||"\\"==b||"?"==b||"#"==b){2!=u.length||!m.test(u[0])||":"!=u[1]&&"|"!=u[1]?0==u.length?d="relative path start":(this._host=o.call(this,u),u="",d="relative path start"):d="relative path";continue}"	"==b||"\n"==b||"\r"==b?c("Invalid whitespace in file host."):u+=b;break;case"host":case"hostname":if(":"!=b||_){if(p==b||"/"==b||"\\"==b||"?"==b||"#"==b){if(this._host=o.call(this,u),u="",d="relative path start",a)break e;continue}"	"!=b&&"\n"!=b&&"\r"!=b?("["==b?_=!0:"]"==b&&(_=!1),u+=b):c("Invalid code point in host/hostname: "+b)}else if(this._host=o.call(this,u),u="",d="port","hostname"==a)break e;break;case"port":if(/[0-9]/.test(b))u+=b;else{if(p==b||"/"==b||"\\"==b||"?"==b||"#"==b||a){if(""!=u){var T=parseInt(u,10);T!=h[this._scheme]&&(this._port=T+""),u=""}if(a)break e;d="relative path start";continue}"	"==b||"\n"==b||"\r"==b?c("Invalid code point in port: "+b):n.call(this)}break;case"relative path start":if("\\"==b&&c("'\\' not allowed in path."),d="relative path","/"!=b&&"\\"!=b)continue;break;case"relative path":if(p!=b&&"/"!=b&&"\\"!=b&&(a||"?"!=b&&"#"!=b))"	"!=b&&"\n"!=b&&"\r"!=b&&(u+=r(b));else{"\\"==b&&c("\\ not allowed in relative path.");var O;(O=f[u.toLowerCase()])&&(u=O),".."==u?(this._path.pop(),"/"!=b&&"\\"!=b&&this._path.push("")):"."==u&&"/"!=b&&"\\"!=b?this._path.push(""):"."!=u&&("file"==this._scheme&&0==this._path.length&&2==u.length&&m.test(u[0])&&"|"==u[1]&&(u=u[0]+":"),this._path.push(u)),u="","?"==b?(this._query="?",d="query"):"#"==b&&(this._fragment="#",d="fragment")}break;case"query":a||"#"!=b?p!=b&&"	"!=b&&"\n"!=b&&"\r"!=b&&(this._query+=i(b)):(this._fragment="#",d="fragment");break;case"fragment":p!=b&&"	"!=b&&"\n"!=b&&"\r"!=b&&(this._fragment+=b)}l++}}function s(){this._scheme="",this._schemeData="",this._username="",this._password=null,this._host="",this._port="",this._path=[],this._query="",this._fragment="",this._isInvalid=!1,this._isRelative=!1}function c(e,t){void 0===t||t instanceof c||(t=new c(String(t))),this._url=e,s.call(this);var n=e.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g,"");a.call(this,n,null,t)}var d=!1;if(!e.forceJURL)try{var l=new URL("b","http://a");l.pathname="c%20d",d="http://a/c%20d"===l.href}catch(u){}if(!d){var h=Object.create(null);h.ftp=21,h.file=0,h.gopher=70,h.http=80,h.https=443,h.ws=80,h.wss=443;var f=Object.create(null);f["%2e"]=".",f[".%2e"]="..",f["%2e."]="..",f["%2e%2e"]="..";var p=void 0,m=/[a-zA-Z]/,v=/[a-zA-Z0-9\+\-\.]/;c.prototype={toString:function(){return this.href},get href(){if(this._isInvalid)return this._url;var e="";return""==this._username&&null==this._password||(e=this._username+(null!=this._password?":"+this._password:"")+"@"),this.protocol+(this._isRelative?"//"+e+this.host:"")+this.pathname+this._query+this._fragment},set href(e){s.call(this),a.call(this,e)},get protocol(){return this._scheme+":"},set protocol(e){this._isInvalid||a.call(this,e+":","scheme start")},get host(){return this._isInvalid?"":this._port?this._host+":"+this._port:this._host},set host(e){!this._isInvalid&&this._isRelative&&a.call(this,e,"host")},get hostname(){return this._host},set hostname(e){!this._isInvalid&&this._isRelative&&a.call(this,e,"hostname")},get port(){return this._port},set port(e){!this._isInvalid&&this._isRelative&&a.call(this,e,"port")},get pathname(){return this._isInvalid?"":this._isRelative?"/"+this._path.join("/"):this._schemeData},set pathname(e){!this._isInvalid&&this._isRelative&&(this._path=[],a.call(this,e,"relative path start"))},get search(){return this._isInvalid||!this._query||"?"==this._query?"":this._query},set search(e){!this._isInvalid&&this._isRelative&&(this._query="?","?"==e[0]&&(e=e.slice(1)),a.call(this,e,"query"))},get hash(){return this._isInvalid||!this._fragment||"#"==this._fragment?"":this._fragment},set hash(e){this._isInvalid||(this._fragment="#","#"==e[0]&&(e=e.slice(1)),a.call(this,e,"fragment"))},get origin(){var e;if(this._isInvalid||!this._scheme)return"";switch(this._scheme){case"data":case"file":case"javascript":case"mailto":return"null"}return e=this.host,e?this._scheme+"://"+e:""}};var w=e.URL;w&&(c.createObjectURL=function(e){return w.createObjectURL.apply(w,arguments)},c.revokeObjectURL=function(e){w.revokeObjectURL(e)}),e.URL=c}}(self),"undefined"==typeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=function(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:function(t,n){var o=t[this.name];return o&&o[0]===t?o[1]=n:e(t,this.name,{value:[t,n],writable:!0}),this},get:function(e){var t;return(t=e[this.name])&&t[0]===e?t[1]:void 0},"delete":function(e){var t=e[this.name];return t&&t[0]===e?(t[0]=t[1]=void 0,!0):!1},has:function(e){var t=e[this.name];return t?t[0]===e:!1}},window.WeakMap=n}(),function(e){function t(e){b.push(e),g||(g=!0,m(o))}function n(e){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}function o(){g=!1;var e=b;b=[],e.sort(function(e,t){return e.uid_-t.uid_});var t=!1;e.forEach(function(e){var n=e.takeRecords();r(e),n.length&&(e.callback_(n,e),t=!0)}),t&&o()}function r(e){e.nodes_.forEach(function(t){var n=v.get(t);n&&n.forEach(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){for(var n=e;n;n=n.parentNode){var o=v.get(n);if(o)for(var r=0;r<o.length;r++){var i=o[r],a=i.options;if(n===e||a.subtree){var s=t(a);s&&i.enqueue(s)}}}}function a(e){this.callback_=e,this.nodes_=[],this.records_=[],this.uid_=++y}function s(e,t){this.type=e,this.target=t,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function c(e){var t=new s(e.type,e.target);return t.addedNodes=e.addedNodes.slice(),t.removedNodes=e.removedNodes.slice(),t.previousSibling=e.previousSibling,t.nextSibling=e.nextSibling,t.attributeName=e.attributeName,t.attributeNamespace=e.attributeNamespace,t.oldValue=e.oldValue,t}function d(e,t){return E=new s(e,t)}function l(e){return L?L:(L=c(E),L.oldValue=e,L)}function u(){E=L=void 0}function h(e){return e===L||e===E}function f(e,t){return e===t?e:L&&h(e)?L:null}function p(e,t,n){this.observer=e,this.target=t,this.options=n,this.transientObservedNodes=[]}if(!e.JsMutationObserver){var m,v=new WeakMap;if(/Trident|Edge/.test(navigator.userAgent))m=setTimeout;else if(window.setImmediate)m=window.setImmediate;else{var w=[],_=String(Math.random());window.addEventListener("message",function(e){if(e.data===_){var t=w;w=[],t.forEach(function(e){e()})}}),m=function(e){w.push(e),window.postMessage(_,"*")}}var g=!1,b=[],y=0;a.prototype={observe:function(e,t){if(e=n(e),!t.childList&&!t.attributes&&!t.characterData||t.attributeOldValue&&!t.attributes||t.attributeFilter&&t.attributeFilter.length&&!t.attributes||t.characterDataOldValue&&!t.characterData)throw new SyntaxError;var o=v.get(e);o||v.set(e,o=[]);for(var r,i=0;i<o.length;i++)if(o[i].observer===this){r=o[i],r.removeListeners(),r.options=t;break}r||(r=new p(this,e,t),o.push(r),this.nodes_.push(e)),r.addListeners()},disconnect:function(){this.nodes_.forEach(function(e){for(var t=v.get(e),n=0;n<t.length;n++){var o=t[n];if(o.observer===this){o.removeListeners(),t.splice(n,1);break}}},this),this.records_=[]},takeRecords:function(){var e=this.records_;return this.records_=[],e}};var E,L;p.prototype={enqueue:function(e){var n=this.observer.records_,o=n.length;if(n.length>0){var r=n[o-1],i=f(r,e);if(i)return void(n[o-1]=i)}else t(this.observer);n[o]=e},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrModified",this,!0),t.characterData&&e.addEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.addEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=this.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.characterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList&&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){if(e!==this.target){this.addListeners_(e),this.transientObservedNodes.push(e);var t=v.get(e);t||v.set(e,t=[]),t.push(this)}},removeTransientObservers:function(){var e=this.transientObservedNodes;this.transientObservedNodes=[],e.forEach(function(e){this.removeListeners_(e);for(var t=v.get(e),n=0;n<t.length;n++)if(t[n]===this){t.splice(n,1);break}},this)},handleEvent:function(e){switch(e.stopImmediatePropagation(),e.type){case"DOMAttrModified":var t=e.attrName,n=e.relatedNode.namespaceURI,o=e.target,r=new d("attributes",o);r.attributeName=t,r.attributeNamespace=n;var a=e.attrChange===MutationEvent.ADDITION?null:e.prevValue;i(o,function(e){return!e.attributes||e.attributeFilter&&e.attributeFilter.length&&-1===e.attributeFilter.indexOf(t)&&-1===e.attributeFilter.indexOf(n)?void 0:e.attributeOldValue?l(a):r});break;case"DOMCharacterDataModified":var o=e.target,r=d("characterData",o),a=e.prevValue;i(o,function(e){return e.characterData?e.characterDataOldValue?l(a):r:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(e.target);case"DOMNodeInserted":var s,c,h=e.target;"DOMNodeInserted"===e.type?(s=[h],c=[]):(s=[],c=[h]);var f=h.previousSibling,p=h.nextSibling,r=d("childList",e.target.parentNode);r.addedNodes=s,r.removedNodes=c,r.previousSibling=f,r.nextSibling=p,i(e.relatedNode,function(e){return e.childList?r:void 0})}u()}},e.JsMutationObserver=a,e.MutationObserver||(e.MutationObserver=a,a._isPolyfilled=!0)}}(self),function(){function e(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case" ":return" "}}function t(t){return t.replace(u,e)}var n="undefined"==typeof HTMLTemplateElement;/Trident/.test(navigator.userAgent)&&!function(){var e=document.importNode;document.importNode=function(){var t=e.apply(document,arguments);if(t.nodeType===Node.DOCUMENT_FRAGMENT_NODE){var n=document.createDocumentFragment();return n.appendChild(t),n}return t}}();var o=function(){if(!n){var e=document.createElement("template"),t=document.createElement("template");t.content.appendChild(document.createElement("div")),e.content.appendChild(t);var o=e.cloneNode(!0);return 0===o.content.childNodes.length||0===o.content.firstChild.content.childNodes.length}}(),r="template",i=function(){};if(n){var a=document.implementation.createHTMLDocument("template"),s=!0,c=document.createElement("style");c.textContent=r+"{display:none;}";var d=document.head;d.insertBefore(c,d.firstElementChild),i.prototype=Object.create(HTMLElement.prototype),i.decorate=function(e){if(!e.content){e.content=a.createDocumentFragment();for(var n;n=e.firstChild;)e.content.appendChild(n);if(e.cloneNode=function(e){return i.cloneNode(this,e)},s)try{Object.defineProperty(e,"innerHTML",{get:function(){for(var e="",n=this.content.firstChild;n;n=n.nextSibling)e+=n.outerHTML||t(n.data);return e},set:function(e){for(a.body.innerHTML=e,i.bootstrap(a);this.content.firstChild;)this.content.removeChild(this.content.firstChild);for(;a.body.firstChild;)this.content.appendChild(a.body.firstChild)},configurable:!0})}catch(o){s=!1}i.bootstrap(e.content)}},i.bootstrap=function(e){for(var t,n=e.querySelectorAll(r),o=0,a=n.length;a>o&&(t=n[o]);o++)i.decorate(t)},document.addEventListener("DOMContentLoaded",function(){i.bootstrap(document)});var l=document.createElement;document.createElement=function(){"use strict";var e=l.apply(document,arguments);return"template"===e.localName&&i.decorate(e),e};var u=/[&\u00A0<>]/g}if(n||o){var h=Node.prototype.cloneNode;i.cloneNode=function(e,t){var n=h.call(e,!1);return this.decorate&&this.decorate(n),t&&(n.content.appendChild(h.call(e.content,!0)),this.fixClonedDom(n.content,e.content)),n},i.fixClonedDom=function(e,t){if(t.querySelectorAll)for(var n,o,i=t.querySelectorAll(r),a=e.querySelectorAll(r),s=0,c=a.length;c>s;s++)o=i[s],n=a[s],this.decorate&&this.decorate(o),n.parentNode.replaceChild(o.cloneNode(!0),n)};var f=document.importNode;Node.prototype.cloneNode=function(e){var t=h.call(this,e);return e&&i.fixClonedDom(t,this),t},document.importNode=function(e,t){if(e.localName===r)return i.cloneNode(e,t);var n=f.call(document,e,t);return t&&i.fixClonedDom(n,e),n},o&&(HTMLTemplateElement.prototype.cloneNode=function(e){return i.cloneNode(this,e)})}n&&(window.HTMLTemplateElement=i)}(),function(e){"use strict";if(!window.performance){var t=Date.now();window.performance={now:function(){return Date.now()-t}}}window.requestAnimationFrame||(window.requestAnimationFrame=function(){var e=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;return e?function(t){return e(function(){t(performance.now())})}:function(e){return window.setTimeout(e,1e3/60)}}()),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(){return window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(e){clearTimeout(e)}}());var n=function(){var e=document.createEvent("Event");return e.initEvent("foo",!0,!0),e.preventDefault(),e.defaultPrevented}();if(!n){var o=Event.prototype.preventDefault;Event.prototype.preventDefault=function(){this.cancelable&&(o.call(this),Object.defineProperty(this,"defaultPrevented",{get:function(){return!0},configurable:!0}))}}var r=/Trident/.test(navigator.userAgent);if((!window.CustomEvent||r&&"function"!=typeof window.CustomEvent)&&(window.CustomEvent=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initCustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.CustomEvent.prototype=window.Event.prototype),!window.Event||r&&"function"!=typeof window.Event){var i=window.Event;window.Event=function(e,t){t=t||{};var n=document.createEvent("Event");return n.initEvent(e,Boolean(t.bubbles),Boolean(t.cancelable)),n},window.Event.prototype=i.prototype}}(window.WebComponents),window.HTMLImports=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||p,o(function(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===w}function o(e,t){if(n(t))e&&e();else{var r=function(){"complete"!==t.readyState&&t.readyState!==w||(t.removeEventListener(_,r),o(e,t))};t.addEventListener(_,r)}}function r(e){e.target.__loaded=!0}function i(e,t){function n(){c==d&&e&&e({allImports:s,loadedImports:l,errorImports:u})}function o(e){r(e),l.push(this),c++,n()}function i(e){u.push(this),c++,n()}var s=t.querySelectorAll("link[rel=import]"),c=0,d=s.length,l=[],u=[];if(d)for(var h,f=0;d>f&&(h=s[f]);f++)a(h)?(l.push(this),c++,n()):(h.addEventListener("load",o),h.addEventListener("error",i));else n()}function a(e){return u?e.__loaded||e["import"]&&"loading"!==e["import"].readyState:e.__importParsed}function s(e){for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)c(t)&&d(t)}function c(e){return"link"===e.localName&&"import"===e.rel}function d(e){var t=e["import"];t?r({target:e}):(e.addEventListener("load",r),e.addEventListener("error",r))}var l="import",u=Boolean(l in document.createElement("link")),h=Boolean(window.ShadowDOMPolyfill),f=function(e){return h?window.ShadowDOMPolyfill.wrapIfNeeded(e):e},p=f(document),m={get:function(){var e=window.HTMLImports.currentScript||document.currentScript||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null);return f(e)},configurable:!0};Object.defineProperty(document,"_currentScript",m),Object.defineProperty(p,"_currentScript",m);var v=/Trident/.test(navigator.userAgent),w=v?"complete":"interactive",_="readystatechange";u&&(new MutationObserver(function(e){for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)t.addedNodes&&s(t.addedNodes)}).observe(document.head,{childList:!0}),function(){if("loading"===document.readyState)for(var e,t=document.querySelectorAll("link[rel=import]"),n=0,o=t.length;o>n&&(e=t[n]);n++)d(e)}()),t(function(e){window.HTMLImports.ready=!0,window.HTMLImports.readyTime=(new Date).getTime();var t=p.createEvent("CustomEvent");t.initCustomEvent("HTMLImportsLoaded",!0,!0,e),p.dispatchEvent(t)}),e.IMPORT_LINK_TYPE=l,e.useNative=u,e.rootDocument=p,e.whenReady=t,e.isIE=v}(window.HTMLImports),function(e){var t=[],n=function(e){t.push(e)},o=function(){t.forEach(function(t){t(e)})};e.addModule=n,e.initializeModules=o}(window.HTMLImports),window.HTMLImports.addModule(function(e){var t=/(url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,o={resolveUrlsInStyle:function(e,t){var n=e.ownerDocument,o=n.createElement("a");return e.textContent=this.resolveUrlsInCssText(e.textContent,t,o),e},resolveUrlsInCssText:function(e,o,r){var i=this.replaceUrls(e,r,o,t);return i=this.replaceUrls(i,r,o,n)},replaceUrls:function(e,t,n,o){return e.replace(o,function(e,o,r,i){var a=r.replace(/["']/g,"");return n&&(a=new URL(a,n).href),t.href=a,a=t.href,o+"'"+a+"'"+i})}};e.path=o}),window.HTMLImports.addModule(function(e){var t={async:!0,ok:function(e){return e.status>=200&&e.status<300||304===e.status||0===e.status},load:function(n,o,r){var i=new XMLHttpRequest;return(e.flags.debug||e.flags.bust)&&(n+="?"+Math.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",function(e){if(4===i.readyState){var n=null;try{var a=i.getResponseHeader("Location");a&&(n="/"===a.substr(0,1)?location.origin+a:a)}catch(e){console.error(e.message)}o.call(r,!t.ok(i)&&i,i.response||i.responseText,n)}}),i.send(),i},loadDocument:function(e,t,n){this.load(e,t,n).responseType="document"}};e.xhr=t}),window.HTMLImports.addModule(function(e){var t=e.xhr,n=e.flags,o=function(e,t){this.cache={},this.onload=e,this.oncomplete=t,this.inflight=0,this.pending={}};o.prototype={addNodes:function(e){this.inflight+=e.length;for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)this.require(t);this.checkDone()},addNode:function(e){this.inflight++,this.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nodeUrl=t,this.dedupe(t,e)||this.fetch(t,e)},dedupe:function(e,t){if(this.pending[e])return this.pending[e].push(t),!0;return this.cache[e]?(this.onload(e,t,this.cache[e]),this.tail(),!0):(this.pending[e]=[t],!1)},fetch:function(e,o){if(n.load&&console.log("fetch",e,o),e)if(e.match(/^data:/)){var r=e.split(","),i=r[0],a=r[1];a=i.indexOf(";base64")>-1?atob(a):decodeURIComponent(a),setTimeout(function(){this.receive(e,o,null,a)}.bind(this),0)}else{var s=function(t,n,r){this.receive(e,o,t,n,r)}.bind(this);t.load(e,s)}else setTimeout(function(){this.receive(e,o,{error:"href must be specified"},null)}.bind(this),0)},receive:function(e,t,n,o,r){this.cache[e]=o;for(var i,a=this.pending[e],s=0,c=a.length;c>s&&(i=a[s]);s++)this.onload(e,i,o,n,r),this.tail();this.pending[e]=null},tail:function(){--this.inflight,this.checkDone()},checkDone:function(){this.inflight||this.oncomplete()}},e.Loader=o}),window.HTMLImports.addModule(function(e){var t=function(e){this.addCallback=e,this.mo=new MutationObserver(this.handler.bind(this))};t.prototype={handler:function(e){for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)"childList"===t.type&&t.addedNodes.length&&this.addedNodes(t.addedNodes)},addedNodes:function(e){this.addCallback&&this.addCallback(e);for(var t,n=0,o=e.length;o>n&&(t=e[n]);n++)t.children&&t.children.length&&this.addedNodes(t.children)},observe:function(e){this.mo.observe(e,{childList:!0,subtree:!0})}},e.Observer=t}),window.HTMLImports.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===l}function n(e){var t=o(e);return"data:text/javascript;charset=utf-8,"+encodeURIComponent(t)}function o(e){return e.textContent+r(e)}function r(e){var t=e.ownerDocument;t.__importedScripts=t.__importedScripts||0;var n=e.ownerDocument.baseURI,o=t.__importedScripts?"-"+t.__importedScripts:"";return t.__importedScripts++,"\n//# sourceURL="+n+o+".js\n"}function i(e){var t=e.ownerDocument.createElement("style");return t.textContent=e.textContent,a.resolveUrlsInStyle(t),t}var a=e.path,s=e.rootDocument,c=e.flags,d=e.isIE,l=e.IMPORT_LINK_TYPE,u="link[rel="+l+"]",h={documentSelectors:u,importsSelectors:[u,"link[rel=stylesheet]:not([type])","style:not([type])","script:not([type])",'script[type="application/javascript"]','script[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScript",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextToParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(c.parse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.localName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){this.dynamicElements.push(e),t||this.parseNext()},markParsing:function(e){c.parse&&console.log("parsing",e),this.parsingElement=e},markParsingComplete:function(e){e.__importParsed=!0,this.markDynamicParsingComplete(e),e.__importElement&&(e.__importElement.__importParsed=!0,this.markDynamicParsingComplete(e.__importElement)),this.parsingElement=null,c.parse&&console.log("completed",e)},markDynamicParsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynamicElements.splice(t,1)},parseImport:function(e){if(e["import"]=e.__doc,window.HTMLImports.__importsParsingHook&&window.HTMLImports.__importsParsingHook(e),e["import"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.__resource&&!e.__error?e.dispatchEvent(new CustomEvent("load",{bubbles:!1})):e.dispatchEvent(new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.length;)t=e.__pending.shift(),t&&t({target:e});this.parseNext()},parseLink:function(e){t(e)?this.parseImport(e):(e.href=e.href,this.parseGeneric(e))},parseStyle:function(e){var t=e;e=i(e),t.__appliedElement=e,e.__importElement=t,this.parseGeneric(e)},parseGeneric:function(e){this.trackElement(e),this.addElementToDocument(e)},rootImportForElement:function(e){for(var t=e;t.ownerDocument.__importLink;)t=t.ownerDocument.__importLink;return t},addElementToDocument:function(e){var t=this.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},trackElement:function(e,t){var n=this,o=function(r){e.removeEventListener("load",o),e.removeEventListener("error",o),t&&t(r),n.markParsingComplete(e),n.parseNext()};if(e.addEventListener("load",o),e.addEventListener("error",o),d&&"style"===e.localName){var r=!1;if(-1==e.textContent.indexOf("@import"))r=!0;else if(e.sheet){r=!0;for(var i,a=e.sheet.cssRules,s=a?a.length:0,c=0;s>c&&(i=a[c]);c++)i.type===CSSRule.IMPORT_RULE&&(r=r&&Boolean(i.styleSheet))}r&&setTimeout(function(){e.dispatchEvent(new CustomEvent("load",{bubbles:!1}))})}},parseScript:function(t){var o=document.createElement("script");o.__importElement=t,o.src=t.src?t.src:n(t),e.currentScript=t,this.trackElement(o,function(t){o.parentNode&&o.parentNode.removeChild(o),e.currentScript=null}),this.addElementToDocument(o)},nextToParse:function(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s)||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayParse.indexOf(e)<0){this._mayParse.push(e);for(var o,r=e.querySelectorAll(this.parseSelectorsForNode(e)),i=0,a=r.length;a>i&&(o=r[i]);i++)if(!this.isParsed(o))return this.hasResource(o)?t(o)?this.nextToParseInDoc(o.__doc,o):o:void 0}return n},nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:this.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicParsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:function(e){return!t(e)||void 0!==e.__doc}};e.parser=h,e.IMPORT_SELECTOR=u}),window.HTMLImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){return"link"===e.localName&&e.getAttribute("rel")===t}function o(e){return!!Object.getOwnPropertyDescriptor(e,"baseURI")}function r(e,t){var n=document.implementation.createHTMLDocument(a);n._URL=t;var r=n.createElement("base");r.setAttribute("href",t),n.baseURI||o(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.createElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild(i),n.head.appendChild(r),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemplateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPORT_LINK_TYPE,s=e.IMPORT_SELECTOR,c=e.rootDocument,d=e.Loader,l=e.Observer,u=e.parser,h={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join(","),loadNode:function(e){f.addNode(e)},loadSubtree:function(e){var t=this.marshalNodes(e);f.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(this.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocument||e;return t===c?this.documentPreloadSelectors:this.importsPreloadSelectors},loaded:function(e,n,o,a,s){if(i.load&&console.log("loaded",e,n),n.__resource=o,n.__error=a,t(n)){var c=this.documents[e];void 0===c&&(c=a?null:r(o,s||e),c&&(c.__importLink=n,this.bootDocument(c)),this.documents[e]=c),n.__doc=c}u.parseNext()},bootDocument:function(e){this.loadSubtree(e),this.observer.observe(e),u.parseNext()},loadedAll:function(){u.parseNext()}},f=new d(h.loaded.bind(h),h.loadedAll.bind(h));if(h.observer=new l,!document.baseURI){var p={get:function(){var e=document.querySelector("base");return e?e.href:window.location.href},configurable:!0};Object.defineProperty(document,"baseURI",p),Object.defineProperty(c,"baseURI",p)}e.importer=h,e.importLoader=f}),window.HTMLImports.addModule(function(e){var t=e.parser,n=e.importer,o={added:function(e){for(var o,r,i,a,s=0,c=e.length;c>s&&(a=e[s]);s++)o||(o=a.ownerDocument,r=t.isParsed(o)),i=this.shouldLoadNode(a),i&&n.loadNode(a),this.shouldParseNode(a)&&r&&t.parseDynamic(a,i)},shouldLoadNode:function(e){return 1===e.nodeType&&r.call(e,n.loadSelectorsForNode(e))},shouldParseNode:function(e){return 1===e.nodeType&&r.call(e,t.parseSelectorsForNode(e))}};n.observer.addCallback=o.added.bind(o);var r=HTMLElement.prototype.matches||HTMLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector}),function(e){function t(){window.HTMLImports.importer.bootDocument(o)}var n=e.initializeModules;e.isIE;if(!e.useNative){n();var o=e.rootDocument;"complete"===document.readyState||"interactive"===document.readyState&&!window.attachEvent?t():document.addEventListener("DOMContentLoaded",t)}}(window.HTMLImports),window.CustomElements=window.CustomElements||{flags:{}},function(e){var t=e.flags,n=[],o=function(e){n.push(e)},r=function(){n.forEach(function(t){t(e)})};e.addModule=o,e.initializeModules=r,e.hasNative=Boolean(document.registerElement),e.isIE=/Trident/.test(navigator.userAgent),e.useNative=!t.register&&e.hasNative&&!window.ShadowDOMPolyfill&&(!window.HTMLImports||window.HTMLImports.useNative)}(window.CustomElements),window.CustomElements.addModule(function(e){function t(e,t){n(e,function(e){return t(e)?!0:void o(e,t)}),o(e,t)}function n(e,t,o){var r=e.firstElementChild;if(!r)for(r=e.firstChild;r&&r.nodeType!==Node.ELEMENT_NODE;)r=r.nextSibling;for(;r;)t(r,o)!==!0&&n(r,t,o),r=r.nextElementSibling;return null}function o(e,n){for(var o=e.shadowRoot;o;)t(o,n),o=o.olderShadowRoot}function r(e,t){i(e,t,[])}function i(e,t,n){if(e=window.wrap(e),!(n.indexOf(e)>=0)){n.push(e);for(var o,r=e.querySelectorAll("link[rel="+a+"]"),s=0,c=r.length;c>s&&(o=r[s]);s++)o["import"]&&i(o["import"],t,n);t(e)}}var a=window.HTMLImports?window.HTMLImports.IMPORT_LINK_TYPE:"none";e.forDocumentTree=r,e.forSubtree=t}),window.CustomElements.addModule(function(e){function t(e,t){return n(e,t)||o(e,t)}function n(t,n){return e.upgrade(t,n)?!0:void(n&&a(t))}function o(e,t){g(e,function(e){return n(e,t)?!0:void 0})}function r(e){L.push(e),E||(E=!0,setTimeout(i))}function i(){E=!1;for(var e,t=L,n=0,o=t.length;o>n&&(e=t[n]);n++)e();L=[]}function a(e){y?r(function(){s(e)}):s(e)}function s(e){ | 
| +e.__upgraded__&&!e.__attached&&(e.__attached=!0,e.attachedCallback&&e.attachedCallback())}function c(e){d(e),g(e,function(e){d(e)})}function d(e){y?r(function(){l(e)}):l(e)}function l(e){e.__upgraded__&&e.__attached&&(e.__attached=!1,e.detachedCallback&&e.detachedCallback())}function u(e){for(var t=e,n=window.wrap(document);t;){if(t==n)return!0;t=t.parentNode||t.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&t.host}}function h(e){if(e.shadowRoot&&!e.shadowRoot.__watched){_.dom&&console.log("watching shadow-root for: ",e.localName);for(var t=e.shadowRoot;t;)m(t),t=t.olderShadowRoot}}function f(e,n){if(_.dom){var o=n[0];if(o&&"childList"===o.type&&o.addedNodes&&o.addedNodes){for(var r=o.addedNodes[0];r&&r!==document&&!r.host;)r=r.parentNode;var i=r&&(r.URL||r._URL||r.host&&r.host.localName)||"";i=i.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",n.length,i||"")}var a=u(e);n.forEach(function(e){"childList"===e.type&&(N(e.addedNodes,function(e){e.localName&&t(e,a)}),N(e.removedNodes,function(e){e.localName&&c(e)}))}),_.dom&&console.groupEnd()}function p(e){for(e=window.wrap(e),e||(e=window.wrap(document));e.parentNode;)e=e.parentNode;var t=e.__observer;t&&(f(e,t.takeRecords()),i())}function m(e){if(!e.__observer){var t=new MutationObserver(f.bind(this,e));t.observe(e,{childList:!0,subtree:!0}),e.__observer=t}}function v(e){e=window.wrap(e),_.dom&&console.group("upgradeDocument: ",e.baseURI.split("/").pop());var n=e===window.wrap(document);t(e,n),m(e),_.dom&&console.groupEnd()}function w(e){b(e,v)}var _=e.flags,g=e.forSubtree,b=e.forDocumentTree,y=window.MutationObserver._isPolyfilled&&_["throttle-attached"];e.hasPolyfillMutations=y,e.hasThrottledAttached=y;var E=!1,L=[],N=Array.prototype.forEach.call.bind(Array.prototype.forEach),M=Element.prototype.createShadowRoot;M&&(Element.prototype.createShadowRoot=function(){var e=M.call(this);return window.CustomElements.watchShadow(this),e}),e.watchShadow=h,e.upgradeDocumentTree=w,e.upgradeDocument=v,e.upgradeSubtree=o,e.upgradeAll=t,e.attached=a,e.takeRecords=p}),window.CustomElements.addModule(function(e){function t(t,o){if("template"===t.localName&&window.HTMLTemplateElement&&HTMLTemplateElement.decorate&&HTMLTemplateElement.decorate(t),!t.__upgraded__&&t.nodeType===Node.ELEMENT_NODE){var r=t.getAttribute("is"),i=e.getRegisteredDefinition(t.localName)||e.getRegisteredDefinition(r);if(i&&(r&&i.tag==t.localName||!r&&!i["extends"]))return n(t,i,o)}}function n(t,n,r){return a.upgrade&&console.group("upgrade:",t.localName),n.is&&t.setAttribute("is",n.is),o(t,n),t.__upgraded__=!0,i(t),r&&e.attached(t),e.upgradeSubtree(t,r),a.upgrade&&console.groupEnd(),t}function o(e,t){Object.__proto__?e.__proto__=t.prototype:(r(e,t.prototype,t["native"]),e.__proto__=t.prototype)}function r(e,t,n){for(var o={},r=t;r!==n&&r!==HTMLElement.prototype;){for(var i,a=Object.getOwnPropertyNames(r),s=0;i=a[s];s++)o[i]||(Object.defineProperty(e,i,Object.getOwnPropertyDescriptor(r,i)),o[i]=1);r=Object.getPrototypeOf(r)}}function i(e){e.createdCallback&&e.createdCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPrototype=o}),window.CustomElements.addModule(function(e){function t(t,o){var c=o||{};if(!t)throw new Error("document.registerElement: first argument `name` must not be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(t)+"'.");if(r(t))throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '"+String(t)+"'. The type name is invalid.");if(d(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+"' is already registered");return c.prototype||(c.prototype=Object.create(HTMLElement.prototype)),c.__name=t.toLowerCase(),c["extends"]&&(c["extends"]=c["extends"].toLowerCase()),c.lifecycle=c.lifecycle||{},c.ancestry=i(c["extends"]),a(c),s(c),n(c.prototype),l(c.__name,c),c.ctor=u(c),c.ctor.prototype=c.prototype,c.prototype.constructor=c.ctor,e.ready&&v(document),c.ctor}function n(e){if(!e.setAttribute._polyfilled){var t=e.setAttribute;e.setAttribute=function(e,n){o.call(this,e,n,t)};var n=e.removeAttribute;e.removeAttribute=function(e){o.call(this,e,null,n)},e.setAttribute._polyfilled=!0}}function o(e,t,n){e=e.toLowerCase();var o=this.getAttribute(e);n.apply(this,arguments);var r=this.getAttribute(e);this.attributeChangedCallback&&r!==o&&this.attributeChangedCallback(e,o,r)}function r(e){for(var t=0;t<y.length;t++)if(e===y[t])return!0}function i(e){var t=d(e);return t?i(t["extends"]).concat([t]):[]}function a(e){for(var t,n=e["extends"],o=0;t=e.ancestry[o];o++)n=t.is&&t.tag;e.tag=n||e.__name,n&&(e.is=e.__name)}function s(e){if(!Object.__proto__){var t=HTMLElement.prototype;if(e.is){var n=document.createElement(e.tag);t=Object.getPrototypeOf(n)}for(var o,r=e.prototype,i=!1;r;)r==t&&(i=!0),o=Object.getPrototypeOf(r),o&&(r.__proto__=o),r=o;i||console.warn(e.tag+" prototype not found in prototype chain for "+e.is),e["native"]=t}}function c(e){return _(N(e.tag),e)}function d(e){return e?E[e.toLowerCase()]:void 0}function l(e,t){E[e]=t}function u(e){return function(){return c(e)}}function h(e,t,n){return e===L?f(t,n):M(e,t)}function f(e,t){e&&(e=e.toLowerCase()),t&&(t=t.toLowerCase());var n=d(t||e);if(n){if(e==n.tag&&t==n.is)return new n.ctor;if(!t&&!n.is)return new n.ctor}var o;return t?(o=f(e),o.setAttribute("is",t),o):(o=N(e),e.indexOf("-")>=0&&g(o,HTMLElement),o)}function p(e,t){var n=e[t];e[t]=function(){var e=n.apply(this,arguments);return w(e),e}}var m,v=(e.isIE,e.upgradeDocumentTree),w=e.upgradeAll,_=e.upgradeWithDefinition,g=e.implementPrototype,b=e.useNative,y=["annotation-xml","color-profile","font-face","font-face-src","font-face-uri","font-face-format","font-face-name","missing-glyph"],E={},L="http://www.w3.org/1999/xhtml",N=document.createElement.bind(document),M=document.createElementNS.bind(document);m=Object.__proto__||b?function(e,t){return e instanceof t}:function(e,t){if(e instanceof t)return!0;for(var n=e;n;){if(n===t.prototype)return!0;n=n.__proto__}return!1},p(Node.prototype,"cloneNode"),p(document,"importNode"),document.registerElement=t,document.createElement=f,document.createElementNS=h,e.registry=E,e["instanceof"]=m,e.reservedTagList=y,e.getRegisteredDefinition=d,document.register=document.registerElement}),function(e){function t(){i(window.wrap(document)),window.CustomElements.ready=!0;var e=window.requestAnimationFrame||function(e){setTimeout(e,16)};e(function(){setTimeout(function(){window.CustomElements.readyTime=Date.now(),window.HTMLImports&&(window.CustomElements.elapsed=window.CustomElements.readyTime-window.HTMLImports.readyTime),document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})})}var n=e.useNative,o=e.initializeModules;e.isIE;if(n){var r=function(){};e.watchShadow=r,e.upgrade=r,e.upgradeAll=r,e.upgradeDocumentTree=r,e.upgradeSubtree=r,e.takeRecords=r,e["instanceof"]=function(e,t){return e instanceof t}}else o();var i=e.upgradeDocumentTree,a=e.upgradeDocument;if(window.wrap||(window.ShadowDOMPolyfill?(window.wrap=window.ShadowDOMPolyfill.wrapIfNeeded,window.unwrap=window.ShadowDOMPolyfill.unwrapIfNeeded):window.wrap=window.unwrap=function(e){return e}),window.HTMLImports&&(window.HTMLImports.__importsParsingHook=function(e){e["import"]&&a(wrap(e["import"]))}),"complete"===document.readyState||e.flags.eager)t();else if("interactive"!==document.readyState||window.attachEvent||window.HTMLImports&&!window.HTMLImports.ready){var s=window.HTMLImports&&!window.HTMLImports.ready?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(s,t)}else t()}(window.CustomElements),function(e){var t=document.createElement("style");t.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var n=document.querySelector("head");n.insertBefore(t,n.firstChild)}(window.WebComponents);</script> | 
| +  </head> | 
| + | 
| +<body><div hidden="" by-vulcanize=""><script>(function () { | 
| +function resolve() { | 
| +document.body.removeAttribute('unresolved'); | 
| +} | 
| +if (window.WebComponents) { | 
| +addEventListener('WebComponentsReady', resolve); | 
| +} else { | 
| +if (document.readyState === 'interactive' || document.readyState === 'complete') { | 
| +resolve(); | 
| +} else { | 
| +addEventListener('DOMContentLoaded', resolve); | 
| +} | 
| +} | 
| +}());window.Polymer = { | 
| +Settings: function () { | 
| +var settings = window.Polymer || {}; | 
| +var parts = location.search.slice(1).split('&'); | 
| +for (var i = 0, o; i < parts.length && (o = parts[i]); i++) { | 
| +o = o.split('='); | 
| +o[0] && (settings[o[0]] = o[1] || true); | 
| +} | 
| +settings.wantShadow = settings.dom === 'shadow'; | 
| +settings.hasShadow = Boolean(Element.prototype.createShadowRoot); | 
| +settings.nativeShadow = settings.hasShadow && !window.ShadowDOMPolyfill; | 
| +settings.useShadow = settings.wantShadow && settings.hasShadow; | 
| +settings.hasNativeImports = Boolean('import' in document.createElement('link')); | 
| +settings.useNativeImports = settings.hasNativeImports; | 
| +settings.useNativeCustomElements = !window.CustomElements || window.CustomElements.useNative; | 
| +settings.useNativeShadow = settings.useShadow && settings.nativeShadow; | 
| +settings.usePolyfillProto = !settings.useNativeCustomElements && !Object.__proto__; | 
| +settings.hasNativeCSSProperties = !navigator.userAgent.match('AppleWebKit/601') && window.CSS && CSS.supports && CSS.supports('box-shadow', '0 0 0 var(--foo)'); | 
| +settings.useNativeCSSProperties = settings.hasNativeCSSProperties && settings.lazyRegister && settings.useNativeCSSProperties; | 
| +return settings; | 
| +}() | 
| +};(function () { | 
| +var userPolymer = window.Polymer; | 
| +window.Polymer = function (prototype) { | 
| +if (typeof prototype === 'function') { | 
| +prototype = prototype.prototype; | 
| +} | 
| +if (!prototype) { | 
| +prototype = {}; | 
| +} | 
| +var factory = desugar(prototype); | 
| +prototype = factory.prototype; | 
| +var options = { prototype: prototype }; | 
| +if (prototype.extends) { | 
| +options.extends = prototype.extends; | 
| +} | 
| +Polymer.telemetry._registrate(prototype); | 
| +document.registerElement(prototype.is, options); | 
| +return factory; | 
| +}; | 
| +var desugar = function (prototype) { | 
| +var base = Polymer.Base; | 
| +if (prototype.extends) { | 
| +base = Polymer.Base._getExtendedPrototype(prototype.extends); | 
| +} | 
| +prototype = Polymer.Base.chainObject(prototype, base); | 
| +prototype.registerCallback(); | 
| +return prototype.constructor; | 
| +}; | 
| +if (userPolymer) { | 
| +for (var i in userPolymer) { | 
| +Polymer[i] = userPolymer[i]; | 
| +} | 
| +} | 
| +Polymer.Class = desugar; | 
| +}()); | 
| +Polymer.telemetry = { | 
| +registrations: [], | 
| +_regLog: function (prototype) { | 
| +console.log('[' + prototype.is + ']: registered'); | 
| +}, | 
| +_registrate: function (prototype) { | 
| +this.registrations.push(prototype); | 
| +Polymer.log && this._regLog(prototype); | 
| +}, | 
| +dumpRegistrations: function () { | 
| +this.registrations.forEach(this._regLog); | 
| +} | 
| +};Object.defineProperty(window, 'currentImport', { | 
| +enumerable: true, | 
| +configurable: true, | 
| +get: function () { | 
| +return (document._currentScript || document.currentScript).ownerDocument; | 
| +} | 
| +});Polymer.RenderStatus = { | 
| +_ready: false, | 
| +_callbacks: [], | 
| +whenReady: function (cb) { | 
| +if (this._ready) { | 
| +cb(); | 
| +} else { | 
| +this._callbacks.push(cb); | 
| +} | 
| +}, | 
| +_makeReady: function () { | 
| +this._ready = true; | 
| +for (var i = 0; i < this._callbacks.length; i++) { | 
| +this._callbacks[i](); | 
| +} | 
| +this._callbacks = []; | 
| +}, | 
| +_catchFirstRender: function () { | 
| +requestAnimationFrame(function () { | 
| +Polymer.RenderStatus._makeReady(); | 
| +}); | 
| +}, | 
| +_afterNextRenderQueue: [], | 
| +_waitingNextRender: false, | 
| +afterNextRender: function (element, fn, args) { | 
| +this._watchNextRender(); | 
| +this._afterNextRenderQueue.push([ | 
| +element, | 
| +fn, | 
| +args | 
| +]); | 
| +}, | 
| +hasRendered: function () { | 
| +return this._ready; | 
| +}, | 
| +_watchNextRender: function () { | 
| +if (!this._waitingNextRender) { | 
| +this._waitingNextRender = true; | 
| +var fn = function () { | 
| +Polymer.RenderStatus._flushNextRender(); | 
| +}; | 
| +if (!this._ready) { | 
| +this.whenReady(fn); | 
| +} else { | 
| +requestAnimationFrame(fn); | 
| +} | 
| +} | 
| +}, | 
| +_flushNextRender: function () { | 
| +var self = this; | 
| +setTimeout(function () { | 
| +self._flushRenderCallbacks(self._afterNextRenderQueue); | 
| +self._afterNextRenderQueue = []; | 
| +self._waitingNextRender = false; | 
| +}); | 
| +}, | 
| +_flushRenderCallbacks: function (callbacks) { | 
| +for (var i = 0, h; i < callbacks.length; i++) { | 
| +h = callbacks[i]; | 
| +h[1].apply(h[0], h[2] || Polymer.nar); | 
| +} | 
| +} | 
| +}; | 
| +if (window.HTMLImports) { | 
| +HTMLImports.whenReady(function () { | 
| +Polymer.RenderStatus._catchFirstRender(); | 
| +}); | 
| +} else { | 
| +Polymer.RenderStatus._catchFirstRender(); | 
| +} | 
| +Polymer.ImportStatus = Polymer.RenderStatus; | 
| +Polymer.ImportStatus.whenLoaded = Polymer.ImportStatus.whenReady;(function () { | 
| +'use strict'; | 
| +var settings = Polymer.Settings; | 
| +Polymer.Base = { | 
| +__isPolymerInstance__: true, | 
| +_addFeature: function (feature) { | 
| +this.extend(this, feature); | 
| +}, | 
| +registerCallback: function () { | 
| +this._desugarBehaviors(); | 
| +this._doBehavior('beforeRegister'); | 
| +this._registerFeatures(); | 
| +if (!settings.lazyRegister) { | 
| +this.ensureRegisterFinished(); | 
| +} | 
| +}, | 
| +createdCallback: function () { | 
| +if (!this.__hasRegisterFinished) { | 
| +this._ensureRegisterFinished(this.__proto__); | 
| +} | 
| +Polymer.telemetry.instanceCount++; | 
| +this.root = this; | 
| +this._doBehavior('created'); | 
| +this._initFeatures(); | 
| +}, | 
| +ensureRegisterFinished: function () { | 
| +this._ensureRegisterFinished(this); | 
| +}, | 
| +_ensureRegisterFinished: function (proto) { | 
| +if (proto.__hasRegisterFinished !== proto.is) { | 
| +proto.__hasRegisterFinished = proto.is; | 
| +if (proto._finishRegisterFeatures) { | 
| +proto._finishRegisterFeatures(); | 
| +} | 
| +proto._doBehavior('registered'); | 
| +if (settings.usePolyfillProto && proto !== this) { | 
| +proto.extend(this, proto); | 
| +} | 
| +} | 
| +}, | 
| +attachedCallback: function () { | 
| +var self = this; | 
| +Polymer.RenderStatus.whenReady(function () { | 
| +self.isAttached = true; | 
| +self._doBehavior('attached'); | 
| +}); | 
| +}, | 
| +detachedCallback: function () { | 
| +var self = this; | 
| +Polymer.RenderStatus.whenReady(function () { | 
| +self.isAttached = false; | 
| +self._doBehavior('detached'); | 
| +}); | 
| +}, | 
| +attributeChangedCallback: function (name, oldValue, newValue) { | 
| +this._attributeChangedImpl(name); | 
| +this._doBehavior('attributeChanged', [ | 
| +name, | 
| +oldValue, | 
| +newValue | 
| +]); | 
| +}, | 
| +_attributeChangedImpl: function (name) { | 
| +this._setAttributeToProperty(this, name); | 
| +}, | 
| +extend: function (prototype, api) { | 
| +if (prototype && api) { | 
| +var n$ = Object.getOwnPropertyNames(api); | 
| +for (var i = 0, n; i < n$.length && (n = n$[i]); i++) { | 
| +this.copyOwnProperty(n, api, prototype); | 
| +} | 
| +} | 
| +return prototype || api; | 
| +}, | 
| +mixin: function (target, source) { | 
| +for (var i in source) { | 
| +target[i] = source[i]; | 
| +} | 
| +return target; | 
| +}, | 
| +copyOwnProperty: function (name, source, target) { | 
| +var pd = Object.getOwnPropertyDescriptor(source, name); | 
| +if (pd) { | 
| +Object.defineProperty(target, name, pd); | 
| +} | 
| +}, | 
| +_logger: function (level, args) { | 
| +if (args.length === 1 && Array.isArray(args[0])) { | 
| +args = args[0]; | 
| +} | 
| +switch (level) { | 
| +case 'log': | 
| +case 'warn': | 
| +case 'error': | 
| +console[level].apply(console, args); | 
| +break; | 
| +} | 
| +}, | 
| +_log: function () { | 
| +var args = Array.prototype.slice.call(arguments, 0); | 
| +this._logger('log', args); | 
| +}, | 
| +_warn: function () { | 
| +var args = Array.prototype.slice.call(arguments, 0); | 
| +this._logger('warn', args); | 
| +}, | 
| +_error: function () { | 
| +var args = Array.prototype.slice.call(arguments, 0); | 
| +this._logger('error', args); | 
| +}, | 
| +_logf: function () { | 
| +return this._logPrefix.concat(this.is).concat(Array.prototype.slice.call(arguments, 0)); | 
| +} | 
| +}; | 
| +Polymer.Base._logPrefix = function () { | 
| +var color = window.chrome && !/edge/i.test(navigator.userAgent) || /firefox/i.test(navigator.userAgent); | 
| +return color ? [ | 
| +'%c[%s::%s]:', | 
| +'font-weight: bold; background-color:#EEEE00;' | 
| +] : ['[%s::%s]:']; | 
| +}(); | 
| +Polymer.Base.chainObject = function (object, inherited) { | 
| +if (object && inherited && object !== inherited) { | 
| +if (!Object.__proto__) { | 
| +object = Polymer.Base.extend(Object.create(inherited), object); | 
| +} | 
| +object.__proto__ = inherited; | 
| +} | 
| +return object; | 
| +}; | 
| +Polymer.Base = Polymer.Base.chainObject(Polymer.Base, HTMLElement.prototype); | 
| +if (window.CustomElements) { | 
| +Polymer.instanceof = CustomElements.instanceof; | 
| +} else { | 
| +Polymer.instanceof = function (obj, ctor) { | 
| +return obj instanceof ctor; | 
| +}; | 
| +} | 
| +Polymer.isInstance = function (obj) { | 
| +return Boolean(obj && obj.__isPolymerInstance__); | 
| +}; | 
| +Polymer.telemetry.instanceCount = 0; | 
| +}());(function () { | 
| +var modules = {}; | 
| +var lcModules = {}; | 
| +var findModule = function (id) { | 
| +return modules[id] || lcModules[id.toLowerCase()]; | 
| +}; | 
| +var DomModule = function () { | 
| +return document.createElement('dom-module'); | 
| +}; | 
| +DomModule.prototype = Object.create(HTMLElement.prototype); | 
| +Polymer.Base.extend(DomModule.prototype, { | 
| +constructor: DomModule, | 
| +createdCallback: function () { | 
| +this.register(); | 
| +}, | 
| +register: function (id) { | 
| +id = id || this.id || this.getAttribute('name') || this.getAttribute('is'); | 
| +if (id) { | 
| +this.id = id; | 
| +modules[id] = this; | 
| +lcModules[id.toLowerCase()] = this; | 
| +} | 
| +}, | 
| +import: function (id, selector) { | 
| +if (id) { | 
| +var m = findModule(id); | 
| +if (!m) { | 
| +forceDomModulesUpgrade(); | 
| +m = findModule(id); | 
| +} | 
| +if (m && selector) { | 
| +m = m.querySelector(selector); | 
| +} | 
| +return m; | 
| +} | 
| +} | 
| +}); | 
| +var cePolyfill = window.CustomElements && !CustomElements.useNative; | 
| +document.registerElement('dom-module', DomModule); | 
| +function forceDomModulesUpgrade() { | 
| +if (cePolyfill) { | 
| +var script = document._currentScript || document.currentScript; | 
| +var doc = script && script.ownerDocument || document; | 
| +var modules = doc.querySelectorAll('dom-module'); | 
| +for (var i = modules.length - 1, m; i >= 0 && (m = modules[i]); i--) { | 
| +if (m.__upgraded__) { | 
| +return; | 
| +} else { | 
| +CustomElements.upgrade(m); | 
| +} | 
| +} | 
| +} | 
| +} | 
| +}());Polymer.Base._addFeature({ | 
| +_prepIs: function () { | 
| +if (!this.is) { | 
| +var module = (document._currentScript || document.currentScript).parentNode; | 
| +if (module.localName === 'dom-module') { | 
| +var id = module.id || module.getAttribute('name') || module.getAttribute('is'); | 
| +this.is = id; | 
| +} | 
| +} | 
| +if (this.is) { | 
| +this.is = this.is.toLowerCase(); | 
| +} | 
| +} | 
| +});Polymer.Base._addFeature({ | 
| +behaviors: [], | 
| +_desugarBehaviors: function () { | 
| +if (this.behaviors.length) { | 
| +this.behaviors = this._desugarSomeBehaviors(this.behaviors); | 
| +} | 
| +}, | 
| +_desugarSomeBehaviors: function (behaviors) { | 
| +var behaviorSet = []; | 
| +behaviors = this._flattenBehaviorsList(behaviors); | 
| +for (var i = behaviors.length - 1; i >= 0; i--) { | 
| +var b = behaviors[i]; | 
| +if (behaviorSet.indexOf(b) === -1) { | 
| +this._mixinBehavior(b); | 
| +behaviorSet.unshift(b); | 
| +} | 
| +} | 
| +return behaviorSet; | 
| +}, | 
| +_flattenBehaviorsList: function (behaviors) { | 
| +var flat = []; | 
| +for (var i = 0; i < behaviors.length; i++) { | 
| +var b = behaviors[i]; | 
| +if (b instanceof Array) { | 
| +flat = flat.concat(this._flattenBehaviorsList(b)); | 
| +} else if (b) { | 
| +flat.push(b); | 
| +} else { | 
| +this._warn(this._logf('_flattenBehaviorsList', 'behavior is null, check for missing or 404 import')); | 
| +} | 
| +} | 
| +return flat; | 
| +}, | 
| +_mixinBehavior: function (b) { | 
| +var n$ = Object.getOwnPropertyNames(b); | 
| +for (var i = 0, n; i < n$.length && (n = n$[i]); i++) { | 
| +if (!Polymer.Base._behaviorProperties[n] && !this.hasOwnProperty(n)) { | 
| +this.copyOwnProperty(n, b, this); | 
| +} | 
| +} | 
| +}, | 
| +_prepBehaviors: function () { | 
| +this._prepFlattenedBehaviors(this.behaviors); | 
| +}, | 
| +_prepFlattenedBehaviors: function (behaviors) { | 
| +for (var i = 0, l = behaviors.length; i < l; i++) { | 
| +this._prepBehavior(behaviors[i]); | 
| +} | 
| +this._prepBehavior(this); | 
| +}, | 
| +_doBehavior: function (name, args) { | 
| +for (var i = 0; i < this.behaviors.length; i++) { | 
| +this._invokeBehavior(this.behaviors[i], name, args); | 
| +} | 
| +this._invokeBehavior(this, name, args); | 
| +}, | 
| +_invokeBehavior: function (b, name, args) { | 
| +var fn = b[name]; | 
| +if (fn) { | 
| +fn.apply(this, args || Polymer.nar); | 
| +} | 
| +}, | 
| +_marshalBehaviors: function () { | 
| +for (var i = 0; i < this.behaviors.length; i++) { | 
| +this._marshalBehavior(this.behaviors[i]); | 
| +} | 
| +this._marshalBehavior(this); | 
| +} | 
| +}); | 
| +Polymer.Base._behaviorProperties = { | 
| +hostAttributes: true, | 
| +beforeRegister: true, | 
| +registered: true, | 
| +properties: true, | 
| +observers: true, | 
| +listeners: true, | 
| +created: true, | 
| +attached: true, | 
| +detached: true, | 
| +attributeChanged: true, | 
| +ready: true | 
| +};Polymer.Base._addFeature({ | 
| +_getExtendedPrototype: function (tag) { | 
| +return this._getExtendedNativePrototype(tag); | 
| +}, | 
| +_nativePrototypes: {}, | 
| +_getExtendedNativePrototype: function (tag) { | 
| +var p = this._nativePrototypes[tag]; | 
| +if (!p) { | 
| +var np = this.getNativePrototype(tag); | 
| +p = this.extend(Object.create(np), Polymer.Base); | 
| +this._nativePrototypes[tag] = p; | 
| +} | 
| +return p; | 
| +}, | 
| +getNativePrototype: function (tag) { | 
| +return Object.getPrototypeOf(document.createElement(tag)); | 
| +} | 
| +});Polymer.Base._addFeature({ | 
| +_prepConstructor: function () { | 
| +this._factoryArgs = this.extends ? [ | 
| +this.extends, | 
| +this.is | 
| +] : [this.is]; | 
| +var ctor = function () { | 
| +return this._factory(arguments); | 
| +}; | 
| +if (this.hasOwnProperty('extends')) { | 
| +ctor.extends = this.extends; | 
| +} | 
| +Object.defineProperty(this, 'constructor', { | 
| +value: ctor, | 
| +writable: true, | 
| +configurable: true | 
| +}); | 
| +ctor.prototype = this; | 
| +}, | 
| +_factory: function (args) { | 
| +var elt = document.createElement.apply(document, this._factoryArgs); | 
| +if (this.factoryImpl) { | 
| +this.factoryImpl.apply(elt, args); | 
| +} | 
| +return elt; | 
| +} | 
| +});Polymer.nob = Object.create(null); | 
| +Polymer.Base._addFeature({ | 
| +properties: {}, | 
| +getPropertyInfo: function (property) { | 
| +var info = this._getPropertyInfo(property, this.properties); | 
| +if (!info) { | 
| +for (var i = 0; i < this.behaviors.length; i++) { | 
| +info = this._getPropertyInfo(property, this.behaviors[i].properties); | 
| +if (info) { | 
| +return info; | 
| +} | 
| +} | 
| +} | 
| +return info || Polymer.nob; | 
| +}, | 
| +_getPropertyInfo: function (property, properties) { | 
| +var p = properties && properties[property]; | 
| +if (typeof p === 'function') { | 
| +p = properties[property] = { type: p }; | 
| +} | 
| +if (p) { | 
| +p.defined = true; | 
| +} | 
| +return p; | 
| +}, | 
| +_prepPropertyInfo: function () { | 
| +this._propertyInfo = {}; | 
| +for (var i = 0; i < this.behaviors.length; i++) { | 
| +this._addPropertyInfo(this._propertyInfo, this.behaviors[i].properties); | 
| +} | 
| +this._addPropertyInfo(this._propertyInfo, this.properties); | 
| +this._addPropertyInfo(this._propertyInfo, this._propertyEffects); | 
| +}, | 
| +_addPropertyInfo: function (target, source) { | 
| +if (source) { | 
| +var t, s; | 
| +for (var i in source) { | 
| +t = target[i]; | 
| +s = source[i]; | 
| +if (i[0] === '_' && !s.readOnly) { | 
| +continue; | 
| +} | 
| +if (!target[i]) { | 
| +target[i] = { | 
| +type: typeof s === 'function' ? s : s.type, | 
| +readOnly: s.readOnly, | 
| +attribute: Polymer.CaseMap.camelToDashCase(i) | 
| +}; | 
| +} else { | 
| +if (!t.type) { | 
| +t.type = s.type; | 
| +} | 
| +if (!t.readOnly) { | 
| +t.readOnly = s.readOnly; | 
| +} | 
| +} | 
| +} | 
| +} | 
| +} | 
| +});Polymer.CaseMap = { | 
| +_caseMap: {}, | 
| +_rx: { | 
| +dashToCamel: /-[a-z]/g, | 
| +camelToDash: /([A-Z])/g | 
| +}, | 
| +dashToCamelCase: function (dash) { | 
| +return this._caseMap[dash] || (this._caseMap[dash] = dash.indexOf('-') < 0 ? dash : dash.replace(this._rx.dashToCamel, function (m) { | 
| +return m[1].toUpperCase(); | 
| +})); | 
| +}, | 
| +camelToDashCase: function (camel) { | 
| +return this._caseMap[camel] || (this._caseMap[camel] = camel.replace(this._rx.camelToDash, '-$1').toLowerCase()); | 
| +} | 
| +};Polymer.Base._addFeature({ | 
| +_addHostAttributes: function (attributes) { | 
| +if (!this._aggregatedAttributes) { | 
| +this._aggregatedAttributes = {}; | 
| +} | 
| +if (attributes) { | 
| +this.mixin(this._aggregatedAttributes, attributes); | 
| +} | 
| +}, | 
| +_marshalHostAttributes: function () { | 
| +if (this._aggregatedAttributes) { | 
| +this._applyAttributes(this, this._aggregatedAttributes); | 
| +} | 
| +}, | 
| +_applyAttributes: function (node, attr$) { | 
| +for (var n in attr$) { | 
| +if (!this.hasAttribute(n) && n !== 'class') { | 
| +var v = attr$[n]; | 
| +this.serializeValueToAttribute(v, n, this); | 
| +} | 
| +} | 
| +}, | 
| +_marshalAttributes: function () { | 
| +this._takeAttributesToModel(this); | 
| +}, | 
| +_takeAttributesToModel: function (model) { | 
| +if (this.hasAttributes()) { | 
| +for (var i in this._propertyInfo) { | 
| +var info = this._propertyInfo[i]; | 
| +if (this.hasAttribute(info.attribute)) { | 
| +this._setAttributeToProperty(model, info.attribute, i, info); | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_setAttributeToProperty: function (model, attribute, property, info) { | 
| +if (!this._serializing) { | 
| +property = property || Polymer.CaseMap.dashToCamelCase(attribute); | 
| +info = info || this._propertyInfo && this._propertyInfo[property]; | 
| +if (info && !info.readOnly) { | 
| +var v = this.getAttribute(attribute); | 
| +model[property] = this.deserialize(v, info.type); | 
| +} | 
| +} | 
| +}, | 
| +_serializing: false, | 
| +reflectPropertyToAttribute: function (property, attribute, value) { | 
| +this._serializing = true; | 
| +value = value === undefined ? this[property] : value; | 
| +this.serializeValueToAttribute(value, attribute || Polymer.CaseMap.camelToDashCase(property)); | 
| +this._serializing = false; | 
| +}, | 
| +serializeValueToAttribute: function (value, attribute, node) { | 
| +var str = this.serialize(value); | 
| +node = node || this; | 
| +if (str === undefined) { | 
| +node.removeAttribute(attribute); | 
| +} else { | 
| +node.setAttribute(attribute, str); | 
| +} | 
| +}, | 
| +deserialize: function (value, type) { | 
| +switch (type) { | 
| +case Number: | 
| +value = Number(value); | 
| +break; | 
| +case Boolean: | 
| +value = value != null; | 
| +break; | 
| +case Object: | 
| +try { | 
| +value = JSON.parse(value); | 
| +} catch (x) { | 
| +} | 
| +break; | 
| +case Array: | 
| +try { | 
| +value = JSON.parse(value); | 
| +} catch (x) { | 
| +value = null; | 
| +console.warn('Polymer::Attributes: couldn`t decode Array as JSON'); | 
| +} | 
| +break; | 
| +case Date: | 
| +value = new Date(value); | 
| +break; | 
| +case String: | 
| +default: | 
| +break; | 
| +} | 
| +return value; | 
| +}, | 
| +serialize: function (value) { | 
| +switch (typeof value) { | 
| +case 'boolean': | 
| +return value ? '' : undefined; | 
| +case 'object': | 
| +if (value instanceof Date) { | 
| +return value.toString(); | 
| +} else if (value) { | 
| +try { | 
| +return JSON.stringify(value); | 
| +} catch (x) { | 
| +return ''; | 
| +} | 
| +} | 
| +default: | 
| +return value != null ? value : undefined; | 
| +} | 
| +} | 
| +});Polymer.version = '1.6.0';Polymer.Base._addFeature({ | 
| +_registerFeatures: function () { | 
| +this._prepIs(); | 
| +this._prepBehaviors(); | 
| +this._prepConstructor(); | 
| +this._prepPropertyInfo(); | 
| +}, | 
| +_prepBehavior: function (b) { | 
| +this._addHostAttributes(b.hostAttributes); | 
| +}, | 
| +_marshalBehavior: function (b) { | 
| +}, | 
| +_initFeatures: function () { | 
| +this._marshalHostAttributes(); | 
| +this._marshalBehaviors(); | 
| +} | 
| +});</script> | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| +<script>Polymer.Base._addFeature({ | 
| +_prepTemplate: function () { | 
| +if (this._template === undefined) { | 
| +this._template = Polymer.DomModule.import(this.is, 'template'); | 
| +} | 
| +if (this._template && this._template.hasAttribute('is')) { | 
| +this._warn(this._logf('_prepTemplate', 'top-level Polymer template ' + 'must not be a type-extension, found', this._template, 'Move inside simple <template>.')); | 
| +} | 
| +if (this._template && !this._template.content && window.HTMLTemplateElement && HTMLTemplateElement.decorate) { | 
| +HTMLTemplateElement.decorate(this._template); | 
| +} | 
| +}, | 
| +_stampTemplate: function () { | 
| +if (this._template) { | 
| +this.root = this.instanceTemplate(this._template); | 
| +} | 
| +}, | 
| +instanceTemplate: function (template) { | 
| +var dom = document.importNode(template._content || template.content, true); | 
| +return dom; | 
| +} | 
| +});(function () { | 
| +var baseAttachedCallback = Polymer.Base.attachedCallback; | 
| +Polymer.Base._addFeature({ | 
| +_hostStack: [], | 
| +ready: function () { | 
| +}, | 
| +_registerHost: function (host) { | 
| +this.dataHost = host = host || Polymer.Base._hostStack[Polymer.Base._hostStack.length - 1]; | 
| +if (host && host._clients) { | 
| +host._clients.push(this); | 
| +} | 
| +this._clients = null; | 
| +this._clientsReadied = false; | 
| +}, | 
| +_beginHosting: function () { | 
| +Polymer.Base._hostStack.push(this); | 
| +if (!this._clients) { | 
| +this._clients = []; | 
| +} | 
| +}, | 
| +_endHosting: function () { | 
| +Polymer.Base._hostStack.pop(); | 
| +}, | 
| +_tryReady: function () { | 
| +this._readied = false; | 
| +if (this._canReady()) { | 
| +this._ready(); | 
| +} | 
| +}, | 
| +_canReady: function () { | 
| +return !this.dataHost || this.dataHost._clientsReadied; | 
| +}, | 
| +_ready: function () { | 
| +this._beforeClientsReady(); | 
| +if (this._template) { | 
| +this._setupRoot(); | 
| +this._readyClients(); | 
| +} | 
| +this._clientsReadied = true; | 
| +this._clients = null; | 
| +this._afterClientsReady(); | 
| +this._readySelf(); | 
| +}, | 
| +_readyClients: function () { | 
| +this._beginDistribute(); | 
| +var c$ = this._clients; | 
| +if (c$) { | 
| +for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { | 
| +c._ready(); | 
| +} | 
| +} | 
| +this._finishDistribute(); | 
| +}, | 
| +_readySelf: function () { | 
| +this._doBehavior('ready'); | 
| +this._readied = true; | 
| +if (this._attachedPending) { | 
| +this._attachedPending = false; | 
| +this.attachedCallback(); | 
| +} | 
| +}, | 
| +_beforeClientsReady: function () { | 
| +}, | 
| +_afterClientsReady: function () { | 
| +}, | 
| +_beforeAttached: function () { | 
| +}, | 
| +attachedCallback: function () { | 
| +if (this._readied) { | 
| +this._beforeAttached(); | 
| +baseAttachedCallback.call(this); | 
| +} else { | 
| +this._attachedPending = true; | 
| +} | 
| +} | 
| +}); | 
| +}());Polymer.ArraySplice = function () { | 
| +function newSplice(index, removed, addedCount) { | 
| +return { | 
| +index: index, | 
| +removed: removed, | 
| +addedCount: addedCount | 
| +}; | 
| +} | 
| +var EDIT_LEAVE = 0; | 
| +var EDIT_UPDATE = 1; | 
| +var EDIT_ADD = 2; | 
| +var EDIT_DELETE = 3; | 
| +function ArraySplice() { | 
| +} | 
| +ArraySplice.prototype = { | 
| +calcEditDistances: function (current, currentStart, currentEnd, old, oldStart, oldEnd) { | 
| +var rowCount = oldEnd - oldStart + 1; | 
| +var columnCount = currentEnd - currentStart + 1; | 
| +var distances = new Array(rowCount); | 
| +for (var i = 0; i < rowCount; i++) { | 
| +distances[i] = new Array(columnCount); | 
| +distances[i][0] = i; | 
| +} | 
| +for (var j = 0; j < columnCount; j++) | 
| +distances[0][j] = j; | 
| +for (i = 1; i < rowCount; i++) { | 
| +for (j = 1; j < columnCount; j++) { | 
| +if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) | 
| +distances[i][j] = distances[i - 1][j - 1]; | 
| +else { | 
| +var north = distances[i - 1][j] + 1; | 
| +var west = distances[i][j - 1] + 1; | 
| +distances[i][j] = north < west ? north : west; | 
| +} | 
| +} | 
| +} | 
| +return distances; | 
| +}, | 
| +spliceOperationsFromEditDistances: function (distances) { | 
| +var i = distances.length - 1; | 
| +var j = distances[0].length - 1; | 
| +var current = distances[i][j]; | 
| +var edits = []; | 
| +while (i > 0 || j > 0) { | 
| +if (i == 0) { | 
| +edits.push(EDIT_ADD); | 
| +j--; | 
| +continue; | 
| +} | 
| +if (j == 0) { | 
| +edits.push(EDIT_DELETE); | 
| +i--; | 
| +continue; | 
| +} | 
| +var northWest = distances[i - 1][j - 1]; | 
| +var west = distances[i - 1][j]; | 
| +var north = distances[i][j - 1]; | 
| +var min; | 
| +if (west < north) | 
| +min = west < northWest ? west : northWest; | 
| +else | 
| +min = north < northWest ? north : northWest; | 
| +if (min == northWest) { | 
| +if (northWest == current) { | 
| +edits.push(EDIT_LEAVE); | 
| +} else { | 
| +edits.push(EDIT_UPDATE); | 
| +current = northWest; | 
| +} | 
| +i--; | 
| +j--; | 
| +} else if (min == west) { | 
| +edits.push(EDIT_DELETE); | 
| +i--; | 
| +current = west; | 
| +} else { | 
| +edits.push(EDIT_ADD); | 
| +j--; | 
| +current = north; | 
| +} | 
| +} | 
| +edits.reverse(); | 
| +return edits; | 
| +}, | 
| +calcSplices: function (current, currentStart, currentEnd, old, oldStart, oldEnd) { | 
| +var prefixCount = 0; | 
| +var suffixCount = 0; | 
| +var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart); | 
| +if (currentStart == 0 && oldStart == 0) | 
| +prefixCount = this.sharedPrefix(current, old, minLength); | 
| +if (currentEnd == current.length && oldEnd == old.length) | 
| +suffixCount = this.sharedSuffix(current, old, minLength - prefixCount); | 
| +currentStart += prefixCount; | 
| +oldStart += prefixCount; | 
| +currentEnd -= suffixCount; | 
| +oldEnd -= suffixCount; | 
| +if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) | 
| +return []; | 
| +if (currentStart == currentEnd) { | 
| +var splice = newSplice(currentStart, [], 0); | 
| +while (oldStart < oldEnd) | 
| +splice.removed.push(old[oldStart++]); | 
| +return [splice]; | 
| +} else if (oldStart == oldEnd) | 
| +return [newSplice(currentStart, [], currentEnd - currentStart)]; | 
| +var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd)); | 
| +splice = undefined; | 
| +var splices = []; | 
| +var index = currentStart; | 
| +var oldIndex = oldStart; | 
| +for (var i = 0; i < ops.length; i++) { | 
| +switch (ops[i]) { | 
| +case EDIT_LEAVE: | 
| +if (splice) { | 
| +splices.push(splice); | 
| +splice = undefined; | 
| +} | 
| +index++; | 
| +oldIndex++; | 
| +break; | 
| +case EDIT_UPDATE: | 
| +if (!splice) | 
| +splice = newSplice(index, [], 0); | 
| +splice.addedCount++; | 
| +index++; | 
| +splice.removed.push(old[oldIndex]); | 
| +oldIndex++; | 
| +break; | 
| +case EDIT_ADD: | 
| +if (!splice) | 
| +splice = newSplice(index, [], 0); | 
| +splice.addedCount++; | 
| +index++; | 
| +break; | 
| +case EDIT_DELETE: | 
| +if (!splice) | 
| +splice = newSplice(index, [], 0); | 
| +splice.removed.push(old[oldIndex]); | 
| +oldIndex++; | 
| +break; | 
| +} | 
| +} | 
| +if (splice) { | 
| +splices.push(splice); | 
| +} | 
| +return splices; | 
| +}, | 
| +sharedPrefix: function (current, old, searchLength) { | 
| +for (var i = 0; i < searchLength; i++) | 
| +if (!this.equals(current[i], old[i])) | 
| +return i; | 
| +return searchLength; | 
| +}, | 
| +sharedSuffix: function (current, old, searchLength) { | 
| +var index1 = current.length; | 
| +var index2 = old.length; | 
| +var count = 0; | 
| +while (count < searchLength && this.equals(current[--index1], old[--index2])) | 
| +count++; | 
| +return count; | 
| +}, | 
| +calculateSplices: function (current, previous) { | 
| +return this.calcSplices(current, 0, current.length, previous, 0, previous.length); | 
| +}, | 
| +equals: function (currentValue, previousValue) { | 
| +return currentValue === previousValue; | 
| +} | 
| +}; | 
| +return new ArraySplice(); | 
| +}();Polymer.domInnerHTML = function () { | 
| +var escapeAttrRegExp = /[&\u00A0"]/g; | 
| +var escapeDataRegExp = /[&\u00A0<>]/g; | 
| +function escapeReplace(c) { | 
| +switch (c) { | 
| +case '&': | 
| +return '&'; | 
| +case '<': | 
| +return '<'; | 
| +case '>': | 
| +return '>'; | 
| +case '"': | 
| +return '"'; | 
| +case '\xA0': | 
| +return ' '; | 
| +} | 
| +} | 
| +function escapeAttr(s) { | 
| +return s.replace(escapeAttrRegExp, escapeReplace); | 
| +} | 
| +function escapeData(s) { | 
| +return s.replace(escapeDataRegExp, escapeReplace); | 
| +} | 
| +function makeSet(arr) { | 
| +var set = {}; | 
| +for (var i = 0; i < arr.length; i++) { | 
| +set[arr[i]] = true; | 
| +} | 
| +return set; | 
| +} | 
| +var voidElements = makeSet([ | 
| +'area', | 
| +'base', | 
| +'br', | 
| +'col', | 
| +'command', | 
| +'embed', | 
| +'hr', | 
| +'img', | 
| +'input', | 
| +'keygen', | 
| +'link', | 
| +'meta', | 
| +'param', | 
| +'source', | 
| +'track', | 
| +'wbr' | 
| +]); | 
| +var plaintextParents = makeSet([ | 
| +'style', | 
| +'script', | 
| +'xmp', | 
| +'iframe', | 
| +'noembed', | 
| +'noframes', | 
| +'plaintext', | 
| +'noscript' | 
| +]); | 
| +function getOuterHTML(node, parentNode, composed) { | 
| +switch (node.nodeType) { | 
| +case Node.ELEMENT_NODE: | 
| +var tagName = node.localName; | 
| +var s = '<' + tagName; | 
| +var attrs = node.attributes; | 
| +for (var i = 0, attr; attr = attrs[i]; i++) { | 
| +s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"'; | 
| +} | 
| +s += '>'; | 
| +if (voidElements[tagName]) { | 
| +return s; | 
| +} | 
| +return s + getInnerHTML(node, composed) + '</' + tagName + '>'; | 
| +case Node.TEXT_NODE: | 
| +var data = node.data; | 
| +if (parentNode && plaintextParents[parentNode.localName]) { | 
| +return data; | 
| +} | 
| +return escapeData(data); | 
| +case Node.COMMENT_NODE: | 
| +return '<!--' + node.data + '-->'; | 
| +default: | 
| +console.error(node); | 
| +throw new Error('not implemented'); | 
| +} | 
| +} | 
| +function getInnerHTML(node, composed) { | 
| +if (node instanceof HTMLTemplateElement) | 
| +node = node.content; | 
| +var s = ''; | 
| +var c$ = Polymer.dom(node).childNodes; | 
| +for (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) { | 
| +s += getOuterHTML(child, node, composed); | 
| +} | 
| +return s; | 
| +} | 
| +return { getInnerHTML: getInnerHTML }; | 
| +}();(function () { | 
| +'use strict'; | 
| +var nativeInsertBefore = Element.prototype.insertBefore; | 
| +var nativeAppendChild = Element.prototype.appendChild; | 
| +var nativeRemoveChild = Element.prototype.removeChild; | 
| +Polymer.TreeApi = { | 
| +arrayCopyChildNodes: function (parent) { | 
| +var copy = [], i = 0; | 
| +for (var n = parent.firstChild; n; n = n.nextSibling) { | 
| +copy[i++] = n; | 
| +} | 
| +return copy; | 
| +}, | 
| +arrayCopyChildren: function (parent) { | 
| +var copy = [], i = 0; | 
| +for (var n = parent.firstElementChild; n; n = n.nextElementSibling) { | 
| +copy[i++] = n; | 
| +} | 
| +return copy; | 
| +}, | 
| +arrayCopy: function (a$) { | 
| +var l = a$.length; | 
| +var copy = new Array(l); | 
| +for (var i = 0; i < l; i++) { | 
| +copy[i] = a$[i]; | 
| +} | 
| +return copy; | 
| +} | 
| +}; | 
| +Polymer.TreeApi.Logical = { | 
| +hasParentNode: function (node) { | 
| +return Boolean(node.__dom && node.__dom.parentNode); | 
| +}, | 
| +hasChildNodes: function (node) { | 
| +return Boolean(node.__dom && node.__dom.childNodes !== undefined); | 
| +}, | 
| +getChildNodes: function (node) { | 
| +return this.hasChildNodes(node) ? this._getChildNodes(node) : node.childNodes; | 
| +}, | 
| +_getChildNodes: function (node) { | 
| +if (!node.__dom.childNodes) { | 
| +node.__dom.childNodes = []; | 
| +for (var n = node.__dom.firstChild; n; n = n.__dom.nextSibling) { | 
| +node.__dom.childNodes.push(n); | 
| +} | 
| +} | 
| +return node.__dom.childNodes; | 
| +}, | 
| +getParentNode: function (node) { | 
| +return node.__dom && node.__dom.parentNode !== undefined ? node.__dom.parentNode : node.parentNode; | 
| +}, | 
| +getFirstChild: function (node) { | 
| +return node.__dom && node.__dom.firstChild !== undefined ? node.__dom.firstChild : node.firstChild; | 
| +}, | 
| +getLastChild: function (node) { | 
| +return node.__dom && node.__dom.lastChild !== undefined ? node.__dom.lastChild : node.lastChild; | 
| +}, | 
| +getNextSibling: function (node) { | 
| +return node.__dom && node.__dom.nextSibling !== undefined ? node.__dom.nextSibling : node.nextSibling; | 
| +}, | 
| +getPreviousSibling: function (node) { | 
| +return node.__dom && node.__dom.previousSibling !== undefined ? node.__dom.previousSibling : node.previousSibling; | 
| +}, | 
| +getFirstElementChild: function (node) { | 
| +return node.__dom && node.__dom.firstChild !== undefined ? this._getFirstElementChild(node) : node.firstElementChild; | 
| +}, | 
| +_getFirstElementChild: function (node) { | 
| +var n = node.__dom.firstChild; | 
| +while (n && n.nodeType !== Node.ELEMENT_NODE) { | 
| +n = n.__dom.nextSibling; | 
| +} | 
| +return n; | 
| +}, | 
| +getLastElementChild: function (node) { | 
| +return node.__dom && node.__dom.lastChild !== undefined ? this._getLastElementChild(node) : node.lastElementChild; | 
| +}, | 
| +_getLastElementChild: function (node) { | 
| +var n = node.__dom.lastChild; | 
| +while (n && n.nodeType !== Node.ELEMENT_NODE) { | 
| +n = n.__dom.previousSibling; | 
| +} | 
| +return n; | 
| +}, | 
| +getNextElementSibling: function (node) { | 
| +return node.__dom && node.__dom.nextSibling !== undefined ? this._getNextElementSibling(node) : node.nextElementSibling; | 
| +}, | 
| +_getNextElementSibling: function (node) { | 
| +var n = node.__dom.nextSibling; | 
| +while (n && n.nodeType !== Node.ELEMENT_NODE) { | 
| +n = n.__dom.nextSibling; | 
| +} | 
| +return n; | 
| +}, | 
| +getPreviousElementSibling: function (node) { | 
| +return node.__dom && node.__dom.previousSibling !== undefined ? this._getPreviousElementSibling(node) : node.previousElementSibling; | 
| +}, | 
| +_getPreviousElementSibling: function (node) { | 
| +var n = node.__dom.previousSibling; | 
| +while (n && n.nodeType !== Node.ELEMENT_NODE) { | 
| +n = n.__dom.previousSibling; | 
| +} | 
| +return n; | 
| +}, | 
| +saveChildNodes: function (node) { | 
| +if (!this.hasChildNodes(node)) { | 
| +node.__dom = node.__dom || {}; | 
| +node.__dom.firstChild = node.firstChild; | 
| +node.__dom.lastChild = node.lastChild; | 
| +node.__dom.childNodes = []; | 
| +for (var n = node.firstChild; n; n = n.nextSibling) { | 
| +n.__dom = n.__dom || {}; | 
| +n.__dom.parentNode = node; | 
| +node.__dom.childNodes.push(n); | 
| +n.__dom.nextSibling = n.nextSibling; | 
| +n.__dom.previousSibling = n.previousSibling; | 
| +} | 
| +} | 
| +}, | 
| +recordInsertBefore: function (node, container, ref_node) { | 
| +container.__dom.childNodes = null; | 
| +if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { | 
| +for (var n = node.firstChild; n; n = n.nextSibling) { | 
| +this._linkNode(n, container, ref_node); | 
| +} | 
| +} else { | 
| +this._linkNode(node, container, ref_node); | 
| +} | 
| +}, | 
| +_linkNode: function (node, container, ref_node) { | 
| +node.__dom = node.__dom || {}; | 
| +container.__dom = container.__dom || {}; | 
| +if (ref_node) { | 
| +ref_node.__dom = ref_node.__dom || {}; | 
| +} | 
| +node.__dom.previousSibling = ref_node ? ref_node.__dom.previousSibling : container.__dom.lastChild; | 
| +if (node.__dom.previousSibling) { | 
| +node.__dom.previousSibling.__dom.nextSibling = node; | 
| +} | 
| +node.__dom.nextSibling = ref_node || null; | 
| +if (node.__dom.nextSibling) { | 
| +node.__dom.nextSibling.__dom.previousSibling = node; | 
| +} | 
| +node.__dom.parentNode = container; | 
| +if (ref_node) { | 
| +if (ref_node === container.__dom.firstChild) { | 
| +container.__dom.firstChild = node; | 
| +} | 
| +} else { | 
| +container.__dom.lastChild = node; | 
| +if (!container.__dom.firstChild) { | 
| +container.__dom.firstChild = node; | 
| +} | 
| +} | 
| +container.__dom.childNodes = null; | 
| +}, | 
| +recordRemoveChild: function (node, container) { | 
| +node.__dom = node.__dom || {}; | 
| +container.__dom = container.__dom || {}; | 
| +if (node === container.__dom.firstChild) { | 
| +container.__dom.firstChild = node.__dom.nextSibling; | 
| +} | 
| +if (node === container.__dom.lastChild) { | 
| +container.__dom.lastChild = node.__dom.previousSibling; | 
| +} | 
| +var p = node.__dom.previousSibling; | 
| +var n = node.__dom.nextSibling; | 
| +if (p) { | 
| +p.__dom.nextSibling = n; | 
| +} | 
| +if (n) { | 
| +n.__dom.previousSibling = p; | 
| +} | 
| +node.__dom.parentNode = node.__dom.previousSibling = node.__dom.nextSibling = undefined; | 
| +container.__dom.childNodes = null; | 
| +} | 
| +}; | 
| +Polymer.TreeApi.Composed = { | 
| +getChildNodes: function (node) { | 
| +return Polymer.TreeApi.arrayCopyChildNodes(node); | 
| +}, | 
| +getParentNode: function (node) { | 
| +return node.parentNode; | 
| +}, | 
| +clearChildNodes: function (node) { | 
| +node.textContent = ''; | 
| +}, | 
| +insertBefore: function (parentNode, newChild, refChild) { | 
| +return nativeInsertBefore.call(parentNode, newChild, refChild || null); | 
| +}, | 
| +appendChild: function (parentNode, newChild) { | 
| +return nativeAppendChild.call(parentNode, newChild); | 
| +}, | 
| +removeChild: function (parentNode, node) { | 
| +return nativeRemoveChild.call(parentNode, node); | 
| +} | 
| +}; | 
| +}());Polymer.DomApi = function () { | 
| +'use strict'; | 
| +var Settings = Polymer.Settings; | 
| +var TreeApi = Polymer.TreeApi; | 
| +var DomApi = function (node) { | 
| +this.node = needsToWrap ? DomApi.wrap(node) : node; | 
| +}; | 
| +var needsToWrap = Settings.hasShadow && !Settings.nativeShadow; | 
| +DomApi.wrap = window.wrap ? window.wrap : function (node) { | 
| +return node; | 
| +}; | 
| +DomApi.prototype = { | 
| +flush: function () { | 
| +Polymer.dom.flush(); | 
| +}, | 
| +deepContains: function (node) { | 
| +if (this.node.contains(node)) { | 
| +return true; | 
| +} | 
| +var n = node; | 
| +var doc = node.ownerDocument; | 
| +while (n && n !== doc && n !== this.node) { | 
| +n = Polymer.dom(n).parentNode || n.host; | 
| +} | 
| +return n === this.node; | 
| +}, | 
| +queryDistributedElements: function (selector) { | 
| +var c$ = this.getEffectiveChildNodes(); | 
| +var list = []; | 
| +for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { | 
| +if (c.nodeType === Node.ELEMENT_NODE && DomApi.matchesSelector.call(c, selector)) { | 
| +list.push(c); | 
| +} | 
| +} | 
| +return list; | 
| +}, | 
| +getEffectiveChildNodes: function () { | 
| +var list = []; | 
| +var c$ = this.childNodes; | 
| +for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { | 
| +if (c.localName === CONTENT) { | 
| +var d$ = dom(c).getDistributedNodes(); | 
| +for (var j = 0; j < d$.length; j++) { | 
| +list.push(d$[j]); | 
| +} | 
| +} else { | 
| +list.push(c); | 
| +} | 
| +} | 
| +return list; | 
| +}, | 
| +observeNodes: function (callback) { | 
| +if (callback) { | 
| +if (!this.observer) { | 
| +this.observer = this.node.localName === CONTENT ? new DomApi.DistributedNodesObserver(this) : new DomApi.EffectiveNodesObserver(this); | 
| +} | 
| +return this.observer.addListener(callback); | 
| +} | 
| +}, | 
| +unobserveNodes: function (handle) { | 
| +if (this.observer) { | 
| +this.observer.removeListener(handle); | 
| +} | 
| +}, | 
| +notifyObserver: function () { | 
| +if (this.observer) { | 
| +this.observer.notify(); | 
| +} | 
| +}, | 
| +_query: function (matcher, node, halter) { | 
| +node = node || this.node; | 
| +var list = []; | 
| +this._queryElements(TreeApi.Logical.getChildNodes(node), matcher, halter, list); | 
| +return list; | 
| +}, | 
| +_queryElements: function (elements, matcher, halter, list) { | 
| +for (var i = 0, l = elements.length, c; i < l && (c = elements[i]); i++) { | 
| +if (c.nodeType === Node.ELEMENT_NODE) { | 
| +if (this._queryElement(c, matcher, halter, list)) { | 
| +return true; | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_queryElement: function (node, matcher, halter, list) { | 
| +var result = matcher(node); | 
| +if (result) { | 
| +list.push(node); | 
| +} | 
| +if (halter && halter(result)) { | 
| +return result; | 
| +} | 
| +this._queryElements(TreeApi.Logical.getChildNodes(node), matcher, halter, list); | 
| +} | 
| +}; | 
| +var CONTENT = DomApi.CONTENT = 'content'; | 
| +var dom = DomApi.factory = function (node) { | 
| +node = node || document; | 
| +if (!node.__domApi) { | 
| +node.__domApi = new DomApi.ctor(node); | 
| +} | 
| +return node.__domApi; | 
| +}; | 
| +DomApi.hasApi = function (node) { | 
| +return Boolean(node.__domApi); | 
| +}; | 
| +DomApi.ctor = DomApi; | 
| +Polymer.dom = function (obj, patch) { | 
| +if (obj instanceof Event) { | 
| +return Polymer.EventApi.factory(obj); | 
| +} else { | 
| +return DomApi.factory(obj, patch); | 
| +} | 
| +}; | 
| +var p = Element.prototype; | 
| +DomApi.matchesSelector = p.matches || p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector; | 
| +return DomApi; | 
| +}();(function () { | 
| +'use strict'; | 
| +var Settings = Polymer.Settings; | 
| +var DomApi = Polymer.DomApi; | 
| +var dom = DomApi.factory; | 
| +var TreeApi = Polymer.TreeApi; | 
| +var getInnerHTML = Polymer.domInnerHTML.getInnerHTML; | 
| +var CONTENT = DomApi.CONTENT; | 
| +if (Settings.useShadow) { | 
| +return; | 
| +} | 
| +var nativeCloneNode = Element.prototype.cloneNode; | 
| +var nativeImportNode = Document.prototype.importNode; | 
| +Polymer.Base.extend(DomApi.prototype, { | 
| +_lazyDistribute: function (host) { | 
| +if (host.shadyRoot && host.shadyRoot._distributionClean) { | 
| +host.shadyRoot._distributionClean = false; | 
| +Polymer.dom.addDebouncer(host.debounce('_distribute', host._distributeContent)); | 
| +} | 
| +}, | 
| +appendChild: function (node) { | 
| +return this.insertBefore(node); | 
| +}, | 
| +insertBefore: function (node, ref_node) { | 
| +if (ref_node && TreeApi.Logical.getParentNode(ref_node) !== this.node) { | 
| +throw Error('The ref_node to be inserted before is not a child ' + 'of this node'); | 
| +} | 
| +if (node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) { | 
| +var parent = TreeApi.Logical.getParentNode(node); | 
| +if (parent) { | 
| +if (DomApi.hasApi(parent)) { | 
| +dom(parent).notifyObserver(); | 
| +} | 
| +this._removeNode(node); | 
| +} else { | 
| +this._removeOwnerShadyRoot(node); | 
| +} | 
| +} | 
| +if (!this._addNode(node, ref_node)) { | 
| +if (ref_node) { | 
| +ref_node = ref_node.localName === CONTENT ? this._firstComposedNode(ref_node) : ref_node; | 
| +} | 
| +var container = this.node._isShadyRoot ? this.node.host : this.node; | 
| +if (ref_node) { | 
| +TreeApi.Composed.insertBefore(container, node, ref_node); | 
| +} else { | 
| +TreeApi.Composed.appendChild(container, node); | 
| +} | 
| +} | 
| +this.notifyObserver(); | 
| +return node; | 
| +}, | 
| +_addNode: function (node, ref_node) { | 
| +var root = this.getOwnerRoot(); | 
| +if (root) { | 
| +var ipAdded = this._maybeAddInsertionPoint(node, this.node); | 
| +if (!root._invalidInsertionPoints) { | 
| +root._invalidInsertionPoints = ipAdded; | 
| +} | 
| +this._addNodeToHost(root.host, node); | 
| +} | 
| +if (TreeApi.Logical.hasChildNodes(this.node)) { | 
| +TreeApi.Logical.recordInsertBefore(node, this.node, ref_node); | 
| +} | 
| +var handled = this._maybeDistribute(node) || this.node.shadyRoot; | 
| +if (handled) { | 
| +if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { | 
| +while (node.firstChild) { | 
| +TreeApi.Composed.removeChild(node, node.firstChild); | 
| +} | 
| +} else { | 
| +var parent = TreeApi.Composed.getParentNode(node); | 
| +if (parent) { | 
| +TreeApi.Composed.removeChild(parent, node); | 
| +} | 
| +} | 
| +} | 
| +return handled; | 
| +}, | 
| +removeChild: function (node) { | 
| +if (TreeApi.Logical.getParentNode(node) !== this.node) { | 
| +throw Error('The node to be removed is not a child of this node: ' + node); | 
| +} | 
| +if (!this._removeNode(node)) { | 
| +var container = this.node._isShadyRoot ? this.node.host : this.node; | 
| +var parent = TreeApi.Composed.getParentNode(node); | 
| +if (container === parent) { | 
| +TreeApi.Composed.removeChild(container, node); | 
| +} | 
| +} | 
| +this.notifyObserver(); | 
| +return node; | 
| +}, | 
| +_removeNode: function (node) { | 
| +var logicalParent = TreeApi.Logical.hasParentNode(node) && TreeApi.Logical.getParentNode(node); | 
| +var distributed; | 
| +var root = this._ownerShadyRootForNode(node); | 
| +if (logicalParent) { | 
| +distributed = dom(node)._maybeDistributeParent(); | 
| +TreeApi.Logical.recordRemoveChild(node, logicalParent); | 
| +if (root && this._removeDistributedChildren(root, node)) { | 
| +root._invalidInsertionPoints = true; | 
| +this._lazyDistribute(root.host); | 
| +} | 
| +} | 
| +this._removeOwnerShadyRoot(node); | 
| +if (root) { | 
| +this._removeNodeFromHost(root.host, node); | 
| +} | 
| +return distributed; | 
| +}, | 
| +replaceChild: function (node, ref_node) { | 
| +this.insertBefore(node, ref_node); | 
| +this.removeChild(ref_node); | 
| +return node; | 
| +}, | 
| +_hasCachedOwnerRoot: function (node) { | 
| +return Boolean(node._ownerShadyRoot !== undefined); | 
| +}, | 
| +getOwnerRoot: function () { | 
| +return this._ownerShadyRootForNode(this.node); | 
| +}, | 
| +_ownerShadyRootForNode: function (node) { | 
| +if (!node) { | 
| +return; | 
| +} | 
| +var root = node._ownerShadyRoot; | 
| +if (root === undefined) { | 
| +if (node._isShadyRoot) { | 
| +root = node; | 
| +} else { | 
| +var parent = TreeApi.Logical.getParentNode(node); | 
| +if (parent) { | 
| +root = parent._isShadyRoot ? parent : this._ownerShadyRootForNode(parent); | 
| +} else { | 
| +root = null; | 
| +} | 
| +} | 
| +if (root || document.documentElement.contains(node)) { | 
| +node._ownerShadyRoot = root; | 
| +} | 
| +} | 
| +return root; | 
| +}, | 
| +_maybeDistribute: function (node) { | 
| +var fragContent = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noContent && dom(node).querySelector(CONTENT); | 
| +var wrappedContent = fragContent && TreeApi.Logical.getParentNode(fragContent).nodeType !== Node.DOCUMENT_FRAGMENT_NODE; | 
| +var hasContent = fragContent || node.localName === CONTENT; | 
| +if (hasContent) { | 
| +var root = this.getOwnerRoot(); | 
| +if (root) { | 
| +this._lazyDistribute(root.host); | 
| +} | 
| +} | 
| +var needsDist = this._nodeNeedsDistribution(this.node); | 
| +if (needsDist) { | 
| +this._lazyDistribute(this.node); | 
| +} | 
| +return needsDist || hasContent && !wrappedContent; | 
| +}, | 
| +_maybeAddInsertionPoint: function (node, parent) { | 
| +var added; | 
| +if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noContent) { | 
| +var c$ = dom(node).querySelectorAll(CONTENT); | 
| +for (var i = 0, n, np, na; i < c$.length && (n = c$[i]); i++) { | 
| +np = TreeApi.Logical.getParentNode(n); | 
| +if (np === node) { | 
| +np = parent; | 
| +} | 
| +na = this._maybeAddInsertionPoint(n, np); | 
| +added = added || na; | 
| +} | 
| +} else if (node.localName === CONTENT) { | 
| +TreeApi.Logical.saveChildNodes(parent); | 
| +TreeApi.Logical.saveChildNodes(node); | 
| +added = true; | 
| +} | 
| +return added; | 
| +}, | 
| +_updateInsertionPoints: function (host) { | 
| +var i$ = host.shadyRoot._insertionPoints = dom(host.shadyRoot).querySelectorAll(CONTENT); | 
| +for (var i = 0, c; i < i$.length; i++) { | 
| +c = i$[i]; | 
| +TreeApi.Logical.saveChildNodes(c); | 
| +TreeApi.Logical.saveChildNodes(TreeApi.Logical.getParentNode(c)); | 
| +} | 
| +}, | 
| +_nodeNeedsDistribution: function (node) { | 
| +return node && node.shadyRoot && DomApi.hasInsertionPoint(node.shadyRoot); | 
| +}, | 
| +_addNodeToHost: function (host, node) { | 
| +if (host._elementAdd) { | 
| +host._elementAdd(node); | 
| +} | 
| +}, | 
| +_removeNodeFromHost: function (host, node) { | 
| +if (host._elementRemove) { | 
| +host._elementRemove(node); | 
| +} | 
| +}, | 
| +_removeDistributedChildren: function (root, container) { | 
| +var hostNeedsDist; | 
| +var ip$ = root._insertionPoints; | 
| +for (var i = 0; i < ip$.length; i++) { | 
| +var content = ip$[i]; | 
| +if (this._contains(container, content)) { | 
| +var dc$ = dom(content).getDistributedNodes(); | 
| +for (var j = 0; j < dc$.length; j++) { | 
| +hostNeedsDist = true; | 
| +var node = dc$[j]; | 
| +var parent = TreeApi.Composed.getParentNode(node); | 
| +if (parent) { | 
| +TreeApi.Composed.removeChild(parent, node); | 
| +} | 
| +} | 
| +} | 
| +} | 
| +return hostNeedsDist; | 
| +}, | 
| +_contains: function (container, node) { | 
| +while (node) { | 
| +if (node == container) { | 
| +return true; | 
| +} | 
| +node = TreeApi.Logical.getParentNode(node); | 
| +} | 
| +}, | 
| +_removeOwnerShadyRoot: function (node) { | 
| +if (this._hasCachedOwnerRoot(node)) { | 
| +var c$ = TreeApi.Logical.getChildNodes(node); | 
| +for (var i = 0, l = c$.length, n; i < l && (n = c$[i]); i++) { | 
| +this._removeOwnerShadyRoot(n); | 
| +} | 
| +} | 
| +node._ownerShadyRoot = undefined; | 
| +}, | 
| +_firstComposedNode: function (content) { | 
| +var n$ = dom(content).getDistributedNodes(); | 
| +for (var i = 0, l = n$.length, n, p$; i < l && (n = n$[i]); i++) { | 
| +p$ = dom(n).getDestinationInsertionPoints(); | 
| +if (p$[p$.length - 1] === content) { | 
| +return n; | 
| +} | 
| +} | 
| +}, | 
| +querySelector: function (selector) { | 
| +var result = this._query(function (n) { | 
| +return DomApi.matchesSelector.call(n, selector); | 
| +}, this.node, function (n) { | 
| +return Boolean(n); | 
| +})[0]; | 
| +return result || null; | 
| +}, | 
| +querySelectorAll: function (selector) { | 
| +return this._query(function (n) { | 
| +return DomApi.matchesSelector.call(n, selector); | 
| +}, this.node); | 
| +}, | 
| +getDestinationInsertionPoints: function () { | 
| +return this.node._destinationInsertionPoints || []; | 
| +}, | 
| +getDistributedNodes: function () { | 
| +return this.node._distributedNodes || []; | 
| +}, | 
| +_clear: function () { | 
| +while (this.childNodes.length) { | 
| +this.removeChild(this.childNodes[0]); | 
| +} | 
| +}, | 
| +setAttribute: function (name, value) { | 
| +this.node.setAttribute(name, value); | 
| +this._maybeDistributeParent(); | 
| +}, | 
| +removeAttribute: function (name) { | 
| +this.node.removeAttribute(name); | 
| +this._maybeDistributeParent(); | 
| +}, | 
| +_maybeDistributeParent: function () { | 
| +if (this._nodeNeedsDistribution(this.parentNode)) { | 
| +this._lazyDistribute(this.parentNode); | 
| +return true; | 
| +} | 
| +}, | 
| +cloneNode: function (deep) { | 
| +var n = nativeCloneNode.call(this.node, false); | 
| +if (deep) { | 
| +var c$ = this.childNodes; | 
| +var d = dom(n); | 
| +for (var i = 0, nc; i < c$.length; i++) { | 
| +nc = dom(c$[i]).cloneNode(true); | 
| +d.appendChild(nc); | 
| +} | 
| +} | 
| +return n; | 
| +}, | 
| +importNode: function (externalNode, deep) { | 
| +var doc = this.node instanceof Document ? this.node : this.node.ownerDocument; | 
| +var n = nativeImportNode.call(doc, externalNode, false); | 
| +if (deep) { | 
| +var c$ = TreeApi.Logical.getChildNodes(externalNode); | 
| +var d = dom(n); | 
| +for (var i = 0, nc; i < c$.length; i++) { | 
| +nc = dom(doc).importNode(c$[i], true); | 
| +d.appendChild(nc); | 
| +} | 
| +} | 
| +return n; | 
| +}, | 
| +_getComposedInnerHTML: function () { | 
| +return getInnerHTML(this.node, true); | 
| +} | 
| +}); | 
| +Object.defineProperties(DomApi.prototype, { | 
| +activeElement: { | 
| +get: function () { | 
| +var active = document.activeElement; | 
| +if (!active) { | 
| +return null; | 
| +} | 
| +var isShadyRoot = !!this.node._isShadyRoot; | 
| +if (this.node !== document) { | 
| +if (!isShadyRoot) { | 
| +return null; | 
| +} | 
| +if (this.node.host === active || !this.node.host.contains(active)) { | 
| +return null; | 
| +} | 
| +} | 
| +var activeRoot = dom(active).getOwnerRoot(); | 
| +while (activeRoot && activeRoot !== this.node) { | 
| +active = activeRoot.host; | 
| +activeRoot = dom(active).getOwnerRoot(); | 
| +} | 
| +if (this.node === document) { | 
| +return activeRoot ? null : active; | 
| +} else { | 
| +return activeRoot === this.node ? active : null; | 
| +} | 
| +}, | 
| +configurable: true | 
| +}, | 
| +childNodes: { | 
| +get: function () { | 
| +var c$ = TreeApi.Logical.getChildNodes(this.node); | 
| +return Array.isArray(c$) ? c$ : TreeApi.arrayCopyChildNodes(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +children: { | 
| +get: function () { | 
| +if (TreeApi.Logical.hasChildNodes(this.node)) { | 
| +return Array.prototype.filter.call(this.childNodes, function (n) { | 
| +return n.nodeType === Node.ELEMENT_NODE; | 
| +}); | 
| +} else { | 
| +return TreeApi.arrayCopyChildren(this.node); | 
| +} | 
| +}, | 
| +configurable: true | 
| +}, | 
| +parentNode: { | 
| +get: function () { | 
| +return TreeApi.Logical.getParentNode(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +firstChild: { | 
| +get: function () { | 
| +return TreeApi.Logical.getFirstChild(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +lastChild: { | 
| +get: function () { | 
| +return TreeApi.Logical.getLastChild(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +nextSibling: { | 
| +get: function () { | 
| +return TreeApi.Logical.getNextSibling(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +previousSibling: { | 
| +get: function () { | 
| +return TreeApi.Logical.getPreviousSibling(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +firstElementChild: { | 
| +get: function () { | 
| +return TreeApi.Logical.getFirstElementChild(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +lastElementChild: { | 
| +get: function () { | 
| +return TreeApi.Logical.getLastElementChild(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +nextElementSibling: { | 
| +get: function () { | 
| +return TreeApi.Logical.getNextElementSibling(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +previousElementSibling: { | 
| +get: function () { | 
| +return TreeApi.Logical.getPreviousElementSibling(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +textContent: { | 
| +get: function () { | 
| +var nt = this.node.nodeType; | 
| +if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) { | 
| +return this.node.textContent; | 
| +} else { | 
| +var tc = []; | 
| +for (var i = 0, cn = this.childNodes, c; c = cn[i]; i++) { | 
| +if (c.nodeType !== Node.COMMENT_NODE) { | 
| +tc.push(c.textContent); | 
| +} | 
| +} | 
| +return tc.join(''); | 
| +} | 
| +}, | 
| +set: function (text) { | 
| +var nt = this.node.nodeType; | 
| +if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) { | 
| +this.node.textContent = text; | 
| +} else { | 
| +this._clear(); | 
| +if (text) { | 
| +this.appendChild(document.createTextNode(text)); | 
| +} | 
| +} | 
| +}, | 
| +configurable: true | 
| +}, | 
| +innerHTML: { | 
| +get: function () { | 
| +var nt = this.node.nodeType; | 
| +if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) { | 
| +return null; | 
| +} else { | 
| +return getInnerHTML(this.node); | 
| +} | 
| +}, | 
| +set: function (text) { | 
| +var nt = this.node.nodeType; | 
| +if (nt !== Node.TEXT_NODE || nt !== Node.COMMENT_NODE) { | 
| +this._clear(); | 
| +var d = document.createElement('div'); | 
| +d.innerHTML = text; | 
| +var c$ = TreeApi.arrayCopyChildNodes(d); | 
| +for (var i = 0; i < c$.length; i++) { | 
| +this.appendChild(c$[i]); | 
| +} | 
| +} | 
| +}, | 
| +configurable: true | 
| +} | 
| +}); | 
| +DomApi.hasInsertionPoint = function (root) { | 
| +return Boolean(root && root._insertionPoints.length); | 
| +}; | 
| +}());(function () { | 
| +'use strict'; | 
| +var Settings = Polymer.Settings; | 
| +var TreeApi = Polymer.TreeApi; | 
| +var DomApi = Polymer.DomApi; | 
| +if (!Settings.useShadow) { | 
| +return; | 
| +} | 
| +Polymer.Base.extend(DomApi.prototype, { | 
| +querySelectorAll: function (selector) { | 
| +return TreeApi.arrayCopy(this.node.querySelectorAll(selector)); | 
| +}, | 
| +getOwnerRoot: function () { | 
| +var n = this.node; | 
| +while (n) { | 
| +if (n.nodeType === Node.DOCUMENT_FRAGMENT_NODE && n.host) { | 
| +return n; | 
| +} | 
| +n = n.parentNode; | 
| +} | 
| +}, | 
| +importNode: function (externalNode, deep) { | 
| +var doc = this.node instanceof Document ? this.node : this.node.ownerDocument; | 
| +return doc.importNode(externalNode, deep); | 
| +}, | 
| +getDestinationInsertionPoints: function () { | 
| +var n$ = this.node.getDestinationInsertionPoints && this.node.getDestinationInsertionPoints(); | 
| +return n$ ? TreeApi.arrayCopy(n$) : []; | 
| +}, | 
| +getDistributedNodes: function () { | 
| +var n$ = this.node.getDistributedNodes && this.node.getDistributedNodes(); | 
| +return n$ ? TreeApi.arrayCopy(n$) : []; | 
| +} | 
| +}); | 
| +Object.defineProperties(DomApi.prototype, { | 
| +activeElement: { | 
| +get: function () { | 
| +var node = DomApi.wrap(this.node); | 
| +var activeElement = node.activeElement; | 
| +return node.contains(activeElement) ? activeElement : null; | 
| +}, | 
| +configurable: true | 
| +}, | 
| +childNodes: { | 
| +get: function () { | 
| +return TreeApi.arrayCopyChildNodes(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +children: { | 
| +get: function () { | 
| +return TreeApi.arrayCopyChildren(this.node); | 
| +}, | 
| +configurable: true | 
| +}, | 
| +textContent: { | 
| +get: function () { | 
| +return this.node.textContent; | 
| +}, | 
| +set: function (value) { | 
| +return this.node.textContent = value; | 
| +}, | 
| +configurable: true | 
| +}, | 
| +innerHTML: { | 
| +get: function () { | 
| +return this.node.innerHTML; | 
| +}, | 
| +set: function (value) { | 
| +return this.node.innerHTML = value; | 
| +}, | 
| +configurable: true | 
| +} | 
| +}); | 
| +var forwardMethods = function (m$) { | 
| +for (var i = 0; i < m$.length; i++) { | 
| +forwardMethod(m$[i]); | 
| +} | 
| +}; | 
| +var forwardMethod = function (method) { | 
| +DomApi.prototype[method] = function () { | 
| +return this.node[method].apply(this.node, arguments); | 
| +}; | 
| +}; | 
| +forwardMethods([ | 
| +'cloneNode', | 
| +'appendChild', | 
| +'insertBefore', | 
| +'removeChild', | 
| +'replaceChild', | 
| +'setAttribute', | 
| +'removeAttribute', | 
| +'querySelector' | 
| +]); | 
| +var forwardProperties = function (f$) { | 
| +for (var i = 0; i < f$.length; i++) { | 
| +forwardProperty(f$[i]); | 
| +} | 
| +}; | 
| +var forwardProperty = function (name) { | 
| +Object.defineProperty(DomApi.prototype, name, { | 
| +get: function () { | 
| +return this.node[name]; | 
| +}, | 
| +configurable: true | 
| +}); | 
| +}; | 
| +forwardProperties([ | 
| +'parentNode', | 
| +'firstChild', | 
| +'lastChild', | 
| +'nextSibling', | 
| +'previousSibling', | 
| +'firstElementChild', | 
| +'lastElementChild', | 
| +'nextElementSibling', | 
| +'previousElementSibling' | 
| +]); | 
| +}());Polymer.Base.extend(Polymer.dom, { | 
| +_flushGuard: 0, | 
| +_FLUSH_MAX: 100, | 
| +_needsTakeRecords: !Polymer.Settings.useNativeCustomElements, | 
| +_debouncers: [], | 
| +_staticFlushList: [], | 
| +_finishDebouncer: null, | 
| +flush: function () { | 
| +this._flushGuard = 0; | 
| +this._prepareFlush(); | 
| +while (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) { | 
| +while (this._debouncers.length) { | 
| +this._debouncers.shift().complete(); | 
| +} | 
| +if (this._finishDebouncer) { | 
| +this._finishDebouncer.complete(); | 
| +} | 
| +this._prepareFlush(); | 
| +this._flushGuard++; | 
| +} | 
| +if (this._flushGuard >= this._FLUSH_MAX) { | 
| +console.warn('Polymer.dom.flush aborted. Flush may not be complete.'); | 
| +} | 
| +}, | 
| +_prepareFlush: function () { | 
| +if (this._needsTakeRecords) { | 
| +CustomElements.takeRecords(); | 
| +} | 
| +for (var i = 0; i < this._staticFlushList.length; i++) { | 
| +this._staticFlushList[i](); | 
| +} | 
| +}, | 
| +addStaticFlush: function (fn) { | 
| +this._staticFlushList.push(fn); | 
| +}, | 
| +removeStaticFlush: function (fn) { | 
| +var i = this._staticFlushList.indexOf(fn); | 
| +if (i >= 0) { | 
| +this._staticFlushList.splice(i, 1); | 
| +} | 
| +}, | 
| +addDebouncer: function (debouncer) { | 
| +this._debouncers.push(debouncer); | 
| +this._finishDebouncer = Polymer.Debounce(this._finishDebouncer, this._finishFlush); | 
| +}, | 
| +_finishFlush: function () { | 
| +Polymer.dom._debouncers = []; | 
| +} | 
| +});Polymer.EventApi = function () { | 
| +'use strict'; | 
| +var DomApi = Polymer.DomApi.ctor; | 
| +var Settings = Polymer.Settings; | 
| +DomApi.Event = function (event) { | 
| +this.event = event; | 
| +}; | 
| +if (Settings.useShadow) { | 
| +DomApi.Event.prototype = { | 
| +get rootTarget() { | 
| +return this.event.path[0]; | 
| +}, | 
| +get localTarget() { | 
| +return this.event.target; | 
| +}, | 
| +get path() { | 
| +var path = this.event.path; | 
| +if (!Array.isArray(path)) { | 
| +path = Array.prototype.slice.call(path); | 
| +} | 
| +return path; | 
| +} | 
| +}; | 
| +} else { | 
| +DomApi.Event.prototype = { | 
| +get rootTarget() { | 
| +return this.event.target; | 
| +}, | 
| +get localTarget() { | 
| +var current = this.event.currentTarget; | 
| +var currentRoot = current && Polymer.dom(current).getOwnerRoot(); | 
| +var p$ = this.path; | 
| +for (var i = 0; i < p$.length; i++) { | 
| +if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) { | 
| +return p$[i]; | 
| +} | 
| +} | 
| +}, | 
| +get path() { | 
| +if (!this.event._path) { | 
| +var path = []; | 
| +var current = this.rootTarget; | 
| +while (current) { | 
| +path.push(current); | 
| +var insertionPoints = Polymer.dom(current).getDestinationInsertionPoints(); | 
| +if (insertionPoints.length) { | 
| +for (var i = 0; i < insertionPoints.length - 1; i++) { | 
| +path.push(insertionPoints[i]); | 
| +} | 
| +current = insertionPoints[insertionPoints.length - 1]; | 
| +} else { | 
| +current = Polymer.dom(current).parentNode || current.host; | 
| +} | 
| +} | 
| +path.push(window); | 
| +this.event._path = path; | 
| +} | 
| +return this.event._path; | 
| +} | 
| +}; | 
| +} | 
| +var factory = function (event) { | 
| +if (!event.__eventApi) { | 
| +event.__eventApi = new DomApi.Event(event); | 
| +} | 
| +return event.__eventApi; | 
| +}; | 
| +return { factory: factory }; | 
| +}();(function () { | 
| +'use strict'; | 
| +var DomApi = Polymer.DomApi.ctor; | 
| +var useShadow = Polymer.Settings.useShadow; | 
| +Object.defineProperty(DomApi.prototype, 'classList', { | 
| +get: function () { | 
| +if (!this._classList) { | 
| +this._classList = new DomApi.ClassList(this); | 
| +} | 
| +return this._classList; | 
| +}, | 
| +configurable: true | 
| +}); | 
| +DomApi.ClassList = function (host) { | 
| +this.domApi = host; | 
| +this.node = host.node; | 
| +}; | 
| +DomApi.ClassList.prototype = { | 
| +add: function () { | 
| +this.node.classList.add.apply(this.node.classList, arguments); | 
| +this._distributeParent(); | 
| +}, | 
| +remove: function () { | 
| +this.node.classList.remove.apply(this.node.classList, arguments); | 
| +this._distributeParent(); | 
| +}, | 
| +toggle: function () { | 
| +this.node.classList.toggle.apply(this.node.classList, arguments); | 
| +this._distributeParent(); | 
| +}, | 
| +_distributeParent: function () { | 
| +if (!useShadow) { | 
| +this.domApi._maybeDistributeParent(); | 
| +} | 
| +}, | 
| +contains: function () { | 
| +return this.node.classList.contains.apply(this.node.classList, arguments); | 
| +} | 
| +}; | 
| +}());(function () { | 
| +'use strict'; | 
| +var DomApi = Polymer.DomApi.ctor; | 
| +var Settings = Polymer.Settings; | 
| +DomApi.EffectiveNodesObserver = function (domApi) { | 
| +this.domApi = domApi; | 
| +this.node = this.domApi.node; | 
| +this._listeners = []; | 
| +}; | 
| +DomApi.EffectiveNodesObserver.prototype = { | 
| +addListener: function (callback) { | 
| +if (!this._isSetup) { | 
| +this._setup(); | 
| +this._isSetup = true; | 
| +} | 
| +var listener = { | 
| +fn: callback, | 
| +_nodes: [] | 
| +}; | 
| +this._listeners.push(listener); | 
| +this._scheduleNotify(); | 
| +return listener; | 
| +}, | 
| +removeListener: function (handle) { | 
| +var i = this._listeners.indexOf(handle); | 
| +if (i >= 0) { | 
| +this._listeners.splice(i, 1); | 
| +handle._nodes = []; | 
| +} | 
| +if (!this._hasListeners()) { | 
| +this._cleanup(); | 
| +this._isSetup = false; | 
| +} | 
| +}, | 
| +_setup: function () { | 
| +this._observeContentElements(this.domApi.childNodes); | 
| +}, | 
| +_cleanup: function () { | 
| +this._unobserveContentElements(this.domApi.childNodes); | 
| +}, | 
| +_hasListeners: function () { | 
| +return Boolean(this._listeners.length); | 
| +}, | 
| +_scheduleNotify: function () { | 
| +if (this._debouncer) { | 
| +this._debouncer.stop(); | 
| +} | 
| +this._debouncer = Polymer.Debounce(this._debouncer, this._notify); | 
| +this._debouncer.context = this; | 
| +Polymer.dom.addDebouncer(this._debouncer); | 
| +}, | 
| +notify: function () { | 
| +if (this._hasListeners()) { | 
| +this._scheduleNotify(); | 
| +} | 
| +}, | 
| +_notify: function () { | 
| +this._beforeCallListeners(); | 
| +this._callListeners(); | 
| +}, | 
| +_beforeCallListeners: function () { | 
| +this._updateContentElements(); | 
| +}, | 
| +_updateContentElements: function () { | 
| +this._observeContentElements(this.domApi.childNodes); | 
| +}, | 
| +_observeContentElements: function (elements) { | 
| +for (var i = 0, n; i < elements.length && (n = elements[i]); i++) { | 
| +if (this._isContent(n)) { | 
| +n.__observeNodesMap = n.__observeNodesMap || new WeakMap(); | 
| +if (!n.__observeNodesMap.has(this)) { | 
| +n.__observeNodesMap.set(this, this._observeContent(n)); | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_observeContent: function (content) { | 
| +var self = this; | 
| +var h = Polymer.dom(content).observeNodes(function () { | 
| +self._scheduleNotify(); | 
| +}); | 
| +h._avoidChangeCalculation = true; | 
| +return h; | 
| +}, | 
| +_unobserveContentElements: function (elements) { | 
| +for (var i = 0, n, h; i < elements.length && (n = elements[i]); i++) { | 
| +if (this._isContent(n)) { | 
| +h = n.__observeNodesMap.get(this); | 
| +if (h) { | 
| +Polymer.dom(n).unobserveNodes(h); | 
| +n.__observeNodesMap.delete(this); | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_isContent: function (node) { | 
| +return node.localName === 'content'; | 
| +}, | 
| +_callListeners: function () { | 
| +var o$ = this._listeners; | 
| +var nodes = this._getEffectiveNodes(); | 
| +for (var i = 0, o; i < o$.length && (o = o$[i]); i++) { | 
| +var info = this._generateListenerInfo(o, nodes); | 
| +if (info || o._alwaysNotify) { | 
| +this._callListener(o, info); | 
| +} | 
| +} | 
| +}, | 
| +_getEffectiveNodes: function () { | 
| +return this.domApi.getEffectiveChildNodes(); | 
| +}, | 
| +_generateListenerInfo: function (listener, newNodes) { | 
| +if (listener._avoidChangeCalculation) { | 
| +return true; | 
| +} | 
| +var oldNodes = listener._nodes; | 
| +var info = { | 
| +target: this.node, | 
| +addedNodes: [], | 
| +removedNodes: [] | 
| +}; | 
| +var splices = Polymer.ArraySplice.calculateSplices(newNodes, oldNodes); | 
| +for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { | 
| +for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) { | 
| +info.removedNodes.push(n); | 
| +} | 
| +} | 
| +for (i = 0, s; i < splices.length && (s = splices[i]); i++) { | 
| +for (j = s.index; j < s.index + s.addedCount; j++) { | 
| +info.addedNodes.push(newNodes[j]); | 
| +} | 
| +} | 
| +listener._nodes = newNodes; | 
| +if (info.addedNodes.length || info.removedNodes.length) { | 
| +return info; | 
| +} | 
| +}, | 
| +_callListener: function (listener, info) { | 
| +return listener.fn.call(this.node, info); | 
| +}, | 
| +enableShadowAttributeTracking: function () { | 
| +} | 
| +}; | 
| +if (Settings.useShadow) { | 
| +var baseSetup = DomApi.EffectiveNodesObserver.prototype._setup; | 
| +var baseCleanup = DomApi.EffectiveNodesObserver.prototype._cleanup; | 
| +Polymer.Base.extend(DomApi.EffectiveNodesObserver.prototype, { | 
| +_setup: function () { | 
| +if (!this._observer) { | 
| +var self = this; | 
| +this._mutationHandler = function (mxns) { | 
| +if (mxns && mxns.length) { | 
| +self._scheduleNotify(); | 
| +} | 
| +}; | 
| +this._observer = new MutationObserver(this._mutationHandler); | 
| +this._boundFlush = function () { | 
| +self._flush(); | 
| +}; | 
| +Polymer.dom.addStaticFlush(this._boundFlush); | 
| +this._observer.observe(this.node, { childList: true }); | 
| +} | 
| +baseSetup.call(this); | 
| +}, | 
| +_cleanup: function () { | 
| +this._observer.disconnect(); | 
| +this._observer = null; | 
| +this._mutationHandler = null; | 
| +Polymer.dom.removeStaticFlush(this._boundFlush); | 
| +baseCleanup.call(this); | 
| +}, | 
| +_flush: function () { | 
| +if (this._observer) { | 
| +this._mutationHandler(this._observer.takeRecords()); | 
| +} | 
| +}, | 
| +enableShadowAttributeTracking: function () { | 
| +if (this._observer) { | 
| +this._makeContentListenersAlwaysNotify(); | 
| +this._observer.disconnect(); | 
| +this._observer.observe(this.node, { | 
| +childList: true, | 
| +attributes: true, | 
| +subtree: true | 
| +}); | 
| +var root = this.domApi.getOwnerRoot(); | 
| +var host = root && root.host; | 
| +if (host && Polymer.dom(host).observer) { | 
| +Polymer.dom(host).observer.enableShadowAttributeTracking(); | 
| +} | 
| +} | 
| +}, | 
| +_makeContentListenersAlwaysNotify: function () { | 
| +for (var i = 0, h; i < this._listeners.length; i++) { | 
| +h = this._listeners[i]; | 
| +h._alwaysNotify = h._isContentListener; | 
| +} | 
| +} | 
| +}); | 
| +} | 
| +}());(function () { | 
| +'use strict'; | 
| +var DomApi = Polymer.DomApi.ctor; | 
| +var Settings = Polymer.Settings; | 
| +DomApi.DistributedNodesObserver = function (domApi) { | 
| +DomApi.EffectiveNodesObserver.call(this, domApi); | 
| +}; | 
| +DomApi.DistributedNodesObserver.prototype = Object.create(DomApi.EffectiveNodesObserver.prototype); | 
| +Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, { | 
| +_setup: function () { | 
| +}, | 
| +_cleanup: function () { | 
| +}, | 
| +_beforeCallListeners: function () { | 
| +}, | 
| +_getEffectiveNodes: function () { | 
| +return this.domApi.getDistributedNodes(); | 
| +} | 
| +}); | 
| +if (Settings.useShadow) { | 
| +Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, { | 
| +_setup: function () { | 
| +if (!this._observer) { | 
| +var root = this.domApi.getOwnerRoot(); | 
| +var host = root && root.host; | 
| +if (host) { | 
| +var self = this; | 
| +this._observer = Polymer.dom(host).observeNodes(function () { | 
| +self._scheduleNotify(); | 
| +}); | 
| +this._observer._isContentListener = true; | 
| +if (this._hasAttrSelect()) { | 
| +Polymer.dom(host).observer.enableShadowAttributeTracking(); | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_hasAttrSelect: function () { | 
| +var select = this.node.getAttribute('select'); | 
| +return select && select.match(/[[.]+/); | 
| +}, | 
| +_cleanup: function () { | 
| +var root = this.domApi.getOwnerRoot(); | 
| +var host = root && root.host; | 
| +if (host) { | 
| +Polymer.dom(host).unobserveNodes(this._observer); | 
| +} | 
| +this._observer = null; | 
| +} | 
| +}); | 
| +} | 
| +}());(function () { | 
| +var DomApi = Polymer.DomApi; | 
| +var TreeApi = Polymer.TreeApi; | 
| +Polymer.Base._addFeature({ | 
| +_prepShady: function () { | 
| +this._useContent = this._useContent || Boolean(this._template); | 
| +}, | 
| +_setupShady: function () { | 
| +this.shadyRoot = null; | 
| +if (!this.__domApi) { | 
| +this.__domApi = null; | 
| +} | 
| +if (!this.__dom) { | 
| +this.__dom = null; | 
| +} | 
| +if (!this._ownerShadyRoot) { | 
| +this._ownerShadyRoot = undefined; | 
| +} | 
| +}, | 
| +_poolContent: function () { | 
| +if (this._useContent) { | 
| +TreeApi.Logical.saveChildNodes(this); | 
| +} | 
| +}, | 
| +_setupRoot: function () { | 
| +if (this._useContent) { | 
| +this._createLocalRoot(); | 
| +if (!this.dataHost) { | 
| +upgradeLogicalChildren(TreeApi.Logical.getChildNodes(this)); | 
| +} | 
| +} | 
| +}, | 
| +_createLocalRoot: function () { | 
| +this.shadyRoot = this.root; | 
| +this.shadyRoot._distributionClean = false; | 
| +this.shadyRoot._hasDistributed = false; | 
| +this.shadyRoot._isShadyRoot = true; | 
| +this.shadyRoot._dirtyRoots = []; | 
| +var i$ = this.shadyRoot._insertionPoints = !this._notes || this._notes._hasContent ? this.shadyRoot.querySelectorAll('content') : []; | 
| +TreeApi.Logical.saveChildNodes(this.shadyRoot); | 
| +for (var i = 0, c; i < i$.length; i++) { | 
| +c = i$[i]; | 
| +TreeApi.Logical.saveChildNodes(c); | 
| +TreeApi.Logical.saveChildNodes(c.parentNode); | 
| +} | 
| +this.shadyRoot.host = this; | 
| +}, | 
| +get domHost() { | 
| +var root = Polymer.dom(this).getOwnerRoot(); | 
| +return root && root.host; | 
| +}, | 
| +distributeContent: function (updateInsertionPoints) { | 
| +if (this.shadyRoot) { | 
| +this.shadyRoot._invalidInsertionPoints = this.shadyRoot._invalidInsertionPoints || updateInsertionPoints; | 
| +var host = getTopDistributingHost(this); | 
| +Polymer.dom(this)._lazyDistribute(host); | 
| +} | 
| +}, | 
| +_distributeContent: function () { | 
| +if (this._useContent && !this.shadyRoot._distributionClean) { | 
| +if (this.shadyRoot._invalidInsertionPoints) { | 
| +Polymer.dom(this)._updateInsertionPoints(this); | 
| +this.shadyRoot._invalidInsertionPoints = false; | 
| +} | 
| +this._beginDistribute(); | 
| +this._distributeDirtyRoots(); | 
| +this._finishDistribute(); | 
| +} | 
| +}, | 
| +_beginDistribute: function () { | 
| +if (this._useContent && DomApi.hasInsertionPoint(this.shadyRoot)) { | 
| +this._resetDistribution(); | 
| +this._distributePool(this.shadyRoot, this._collectPool()); | 
| +} | 
| +}, | 
| +_distributeDirtyRoots: function () { | 
| +var c$ = this.shadyRoot._dirtyRoots; | 
| +for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { | 
| +c._distributeContent(); | 
| +} | 
| +this.shadyRoot._dirtyRoots = []; | 
| +}, | 
| +_finishDistribute: function () { | 
| +if (this._useContent) { | 
| +this.shadyRoot._distributionClean = true; | 
| +if (DomApi.hasInsertionPoint(this.shadyRoot)) { | 
| +this._composeTree(); | 
| +notifyContentObservers(this.shadyRoot); | 
| +} else { | 
| +if (!this.shadyRoot._hasDistributed) { | 
| +TreeApi.Composed.clearChildNodes(this); | 
| +this.appendChild(this.shadyRoot); | 
| +} else { | 
| +var children = this._composeNode(this); | 
| +this._updateChildNodes(this, children); | 
| +} | 
| +} | 
| +if (!this.shadyRoot._hasDistributed) { | 
| +notifyInitialDistribution(this); | 
| +} | 
| +this.shadyRoot._hasDistributed = true; | 
| +} | 
| +}, | 
| +elementMatches: function (selector, node) { | 
| +node = node || this; | 
| +return DomApi.matchesSelector.call(node, selector); | 
| +}, | 
| +_resetDistribution: function () { | 
| +var children = TreeApi.Logical.getChildNodes(this); | 
| +for (var i = 0; i < children.length; i++) { | 
| +var child = children[i]; | 
| +if (child._destinationInsertionPoints) { | 
| +child._destinationInsertionPoints = undefined; | 
| +} | 
| +if (isInsertionPoint(child)) { | 
| +clearDistributedDestinationInsertionPoints(child); | 
| +} | 
| +} | 
| +var root = this.shadyRoot; | 
| +var p$ = root._insertionPoints; | 
| +for (var j = 0; j < p$.length; j++) { | 
| +p$[j]._distributedNodes = []; | 
| +} | 
| +}, | 
| +_collectPool: function () { | 
| +var pool = []; | 
| +var children = TreeApi.Logical.getChildNodes(this); | 
| +for (var i = 0; i < children.length; i++) { | 
| +var child = children[i]; | 
| +if (isInsertionPoint(child)) { | 
| +pool.push.apply(pool, child._distributedNodes); | 
| +} else { | 
| +pool.push(child); | 
| +} | 
| +} | 
| +return pool; | 
| +}, | 
| +_distributePool: function (node, pool) { | 
| +var p$ = node._insertionPoints; | 
| +for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) { | 
| +this._distributeInsertionPoint(p, pool); | 
| +maybeRedistributeParent(p, this); | 
| +} | 
| +}, | 
| +_distributeInsertionPoint: function (content, pool) { | 
| +var anyDistributed = false; | 
| +for (var i = 0, l = pool.length, node; i < l; i++) { | 
| +node = pool[i]; | 
| +if (!node) { | 
| +continue; | 
| +} | 
| +if (this._matchesContentSelect(node, content)) { | 
| +distributeNodeInto(node, content); | 
| +pool[i] = undefined; | 
| +anyDistributed = true; | 
| +} | 
| +} | 
| +if (!anyDistributed) { | 
| +var children = TreeApi.Logical.getChildNodes(content); | 
| +for (var j = 0; j < children.length; j++) { | 
| +distributeNodeInto(children[j], content); | 
| +} | 
| +} | 
| +}, | 
| +_composeTree: function () { | 
| +this._updateChildNodes(this, this._composeNode(this)); | 
| +var p$ = this.shadyRoot._insertionPoints; | 
| +for (var i = 0, l = p$.length, p, parent; i < l && (p = p$[i]); i++) { | 
| +parent = TreeApi.Logical.getParentNode(p); | 
| +if (!parent._useContent && parent !== this && parent !== this.shadyRoot) { | 
| +this._updateChildNodes(parent, this._composeNode(parent)); | 
| +} | 
| +} | 
| +}, | 
| +_composeNode: function (node) { | 
| +var children = []; | 
| +var c$ = TreeApi.Logical.getChildNodes(node.shadyRoot || node); | 
| +for (var i = 0; i < c$.length; i++) { | 
| +var child = c$[i]; | 
| +if (isInsertionPoint(child)) { | 
| +var distributedNodes = child._distributedNodes; | 
| +for (var j = 0; j < distributedNodes.length; j++) { | 
| +var distributedNode = distributedNodes[j]; | 
| +if (isFinalDestination(child, distributedNode)) { | 
| +children.push(distributedNode); | 
| +} | 
| +} | 
| +} else { | 
| +children.push(child); | 
| +} | 
| +} | 
| +return children; | 
| +}, | 
| +_updateChildNodes: function (container, children) { | 
| +var composed = TreeApi.Composed.getChildNodes(container); | 
| +var splices = Polymer.ArraySplice.calculateSplices(children, composed); | 
| +for (var i = 0, d = 0, s; i < splices.length && (s = splices[i]); i++) { | 
| +for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) { | 
| +if (TreeApi.Composed.getParentNode(n) === container) { | 
| +TreeApi.Composed.removeChild(container, n); | 
| +} | 
| +composed.splice(s.index + d, 1); | 
| +} | 
| +d -= s.addedCount; | 
| +} | 
| +for (var i = 0, s, next; i < splices.length && (s = splices[i]); i++) { | 
| +next = composed[s.index]; | 
| +for (j = s.index, n; j < s.index + s.addedCount; j++) { | 
| +n = children[j]; | 
| +TreeApi.Composed.insertBefore(container, n, next); | 
| +composed.splice(j, 0, n); | 
| +} | 
| +} | 
| +}, | 
| +_matchesContentSelect: function (node, contentElement) { | 
| +var select = contentElement.getAttribute('select'); | 
| +if (!select) { | 
| +return true; | 
| +} | 
| +select = select.trim(); | 
| +if (!select) { | 
| +return true; | 
| +} | 
| +if (!(node instanceof Element)) { | 
| +return false; | 
| +} | 
| +var validSelectors = /^(:not\()?[*.#[a-zA-Z_|]/; | 
| +if (!validSelectors.test(select)) { | 
| +return false; | 
| +} | 
| +return this.elementMatches(select, node); | 
| +}, | 
| +_elementAdd: function () { | 
| +}, | 
| +_elementRemove: function () { | 
| +} | 
| +}); | 
| +function distributeNodeInto(child, insertionPoint) { | 
| +insertionPoint._distributedNodes.push(child); | 
| +var points = child._destinationInsertionPoints; | 
| +if (!points) { | 
| +child._destinationInsertionPoints = [insertionPoint]; | 
| +} else { | 
| +points.push(insertionPoint); | 
| +} | 
| +} | 
| +function clearDistributedDestinationInsertionPoints(content) { | 
| +var e$ = content._distributedNodes; | 
| +if (e$) { | 
| +for (var i = 0; i < e$.length; i++) { | 
| +var d = e$[i]._destinationInsertionPoints; | 
| +if (d) { | 
| +d.splice(d.indexOf(content) + 1, d.length); | 
| +} | 
| +} | 
| +} | 
| +} | 
| +function maybeRedistributeParent(content, host) { | 
| +var parent = TreeApi.Logical.getParentNode(content); | 
| +if (parent && parent.shadyRoot && DomApi.hasInsertionPoint(parent.shadyRoot) && parent.shadyRoot._distributionClean) { | 
| +parent.shadyRoot._distributionClean = false; | 
| +host.shadyRoot._dirtyRoots.push(parent); | 
| +} | 
| +} | 
| +function isFinalDestination(insertionPoint, node) { | 
| +var points = node._destinationInsertionPoints; | 
| +return points && points[points.length - 1] === insertionPoint; | 
| +} | 
| +function isInsertionPoint(node) { | 
| +return node.localName == 'content'; | 
| +} | 
| +function getTopDistributingHost(host) { | 
| +while (host && hostNeedsRedistribution(host)) { | 
| +host = host.domHost; | 
| +} | 
| +return host; | 
| +} | 
| +function hostNeedsRedistribution(host) { | 
| +var c$ = TreeApi.Logical.getChildNodes(host); | 
| +for (var i = 0, c; i < c$.length; i++) { | 
| +c = c$[i]; | 
| +if (c.localName && c.localName === 'content') { | 
| +return host.domHost; | 
| +} | 
| +} | 
| +} | 
| +function notifyContentObservers(root) { | 
| +for (var i = 0, c; i < root._insertionPoints.length; i++) { | 
| +c = root._insertionPoints[i]; | 
| +if (DomApi.hasApi(c)) { | 
| +Polymer.dom(c).notifyObserver(); | 
| +} | 
| +} | 
| +} | 
| +function notifyInitialDistribution(host) { | 
| +if (DomApi.hasApi(host)) { | 
| +Polymer.dom(host).notifyObserver(); | 
| +} | 
| +} | 
| +var needsUpgrade = window.CustomElements && !CustomElements.useNative; | 
| +function upgradeLogicalChildren(children) { | 
| +if (needsUpgrade && children) { | 
| +for (var i = 0; i < children.length; i++) { | 
| +CustomElements.upgrade(children[i]); | 
| +} | 
| +} | 
| +} | 
| +}());if (Polymer.Settings.useShadow) { | 
| +Polymer.Base._addFeature({ | 
| +_poolContent: function () { | 
| +}, | 
| +_beginDistribute: function () { | 
| +}, | 
| +distributeContent: function () { | 
| +}, | 
| +_distributeContent: function () { | 
| +}, | 
| +_finishDistribute: function () { | 
| +}, | 
| +_createLocalRoot: function () { | 
| +this.createShadowRoot(); | 
| +this.shadowRoot.appendChild(this.root); | 
| +this.root = this.shadowRoot; | 
| +} | 
| +}); | 
| +}Polymer.Async = { | 
| +_currVal: 0, | 
| +_lastVal: 0, | 
| +_callbacks: [], | 
| +_twiddleContent: 0, | 
| +_twiddle: document.createTextNode(''), | 
| +run: function (callback, waitTime) { | 
| +if (waitTime > 0) { | 
| +return ~setTimeout(callback, waitTime); | 
| +} else { | 
| +this._twiddle.textContent = this._twiddleContent++; | 
| +this._callbacks.push(callback); | 
| +return this._currVal++; | 
| +} | 
| +}, | 
| +cancel: function (handle) { | 
| +if (handle < 0) { | 
| +clearTimeout(~handle); | 
| +} else { | 
| +var idx = handle - this._lastVal; | 
| +if (idx >= 0) { | 
| +if (!this._callbacks[idx]) { | 
| +throw 'invalid async handle: ' + handle; | 
| +} | 
| +this._callbacks[idx] = null; | 
| +} | 
| +} | 
| +}, | 
| +_atEndOfMicrotask: function () { | 
| +var len = this._callbacks.length; | 
| +for (var i = 0; i < len; i++) { | 
| +var cb = this._callbacks[i]; | 
| +if (cb) { | 
| +try { | 
| +cb(); | 
| +} catch (e) { | 
| +i++; | 
| +this._callbacks.splice(0, i); | 
| +this._lastVal += i; | 
| +this._twiddle.textContent = this._twiddleContent++; | 
| +throw e; | 
| +} | 
| +} | 
| +} | 
| +this._callbacks.splice(0, len); | 
| +this._lastVal += len; | 
| +} | 
| +}; | 
| +new window.MutationObserver(function () { | 
| +Polymer.Async._atEndOfMicrotask(); | 
| +}).observe(Polymer.Async._twiddle, { characterData: true });Polymer.Debounce = function () { | 
| +var Async = Polymer.Async; | 
| +var Debouncer = function (context) { | 
| +this.context = context; | 
| +var self = this; | 
| +this.boundComplete = function () { | 
| +self.complete(); | 
| +}; | 
| +}; | 
| +Debouncer.prototype = { | 
| +go: function (callback, wait) { | 
| +var h; | 
| +this.finish = function () { | 
| +Async.cancel(h); | 
| +}; | 
| +h = Async.run(this.boundComplete, wait); | 
| +this.callback = callback; | 
| +}, | 
| +stop: function () { | 
| +if (this.finish) { | 
| +this.finish(); | 
| +this.finish = null; | 
| +this.callback = null; | 
| +} | 
| +}, | 
| +complete: function () { | 
| +if (this.finish) { | 
| +var callback = this.callback; | 
| +this.stop(); | 
| +callback.call(this.context); | 
| +} | 
| +} | 
| +}; | 
| +function debounce(debouncer, callback, wait) { | 
| +if (debouncer) { | 
| +debouncer.stop(); | 
| +} else { | 
| +debouncer = new Debouncer(this); | 
| +} | 
| +debouncer.go(callback, wait); | 
| +return debouncer; | 
| +} | 
| +return debounce; | 
| +}();Polymer.Base._addFeature({ | 
| +_setupDebouncers: function () { | 
| +this._debouncers = {}; | 
| +}, | 
| +debounce: function (jobName, callback, wait) { | 
| +return this._debouncers[jobName] = Polymer.Debounce.call(this, this._debouncers[jobName], callback, wait); | 
| +}, | 
| +isDebouncerActive: function (jobName) { | 
| +var debouncer = this._debouncers[jobName]; | 
| +return !!(debouncer && debouncer.finish); | 
| +}, | 
| +flushDebouncer: function (jobName) { | 
| +var debouncer = this._debouncers[jobName]; | 
| +if (debouncer) { | 
| +debouncer.complete(); | 
| +} | 
| +}, | 
| +cancelDebouncer: function (jobName) { | 
| +var debouncer = this._debouncers[jobName]; | 
| +if (debouncer) { | 
| +debouncer.stop(); | 
| +} | 
| +} | 
| +});Polymer.DomModule = document.createElement('dom-module'); | 
| +Polymer.Base._addFeature({ | 
| +_registerFeatures: function () { | 
| +this._prepIs(); | 
| +this._prepBehaviors(); | 
| +this._prepConstructor(); | 
| +this._prepTemplate(); | 
| +this._prepShady(); | 
| +this._prepPropertyInfo(); | 
| +}, | 
| +_prepBehavior: function (b) { | 
| +this._addHostAttributes(b.hostAttributes); | 
| +}, | 
| +_initFeatures: function () { | 
| +this._registerHost(); | 
| +if (this._template) { | 
| +this._poolContent(); | 
| +this._beginHosting(); | 
| +this._stampTemplate(); | 
| +this._endHosting(); | 
| +} | 
| +this._marshalHostAttributes(); | 
| +this._setupDebouncers(); | 
| +this._marshalBehaviors(); | 
| +this._tryReady(); | 
| +}, | 
| +_marshalBehavior: function (b) { | 
| +} | 
| +});</script> | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| +<script>Polymer.nar = []; | 
| +Polymer.Annotations = { | 
| +parseAnnotations: function (template) { | 
| +var list = []; | 
| +var content = template._content || template.content; | 
| +this._parseNodeAnnotations(content, list, template.hasAttribute('strip-whitespace')); | 
| +return list; | 
| +}, | 
| +_parseNodeAnnotations: function (node, list, stripWhiteSpace) { | 
| +return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, list) : this._parseElementAnnotations(node, list, stripWhiteSpace); | 
| +}, | 
| +_bindingRegex: function () { | 
| +var IDENT = '(?:' + '[a-zA-Z_$][\\w.:$\\-*]*' + ')'; | 
| +var NUMBER = '(?:' + '[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?' + ')'; | 
| +var SQUOTE_STRING = '(?:' + '\'(?:[^\'\\\\]|\\\\.)*\'' + ')'; | 
| +var DQUOTE_STRING = '(?:' + '"(?:[^"\\\\]|\\\\.)*"' + ')'; | 
| +var STRING = '(?:' + SQUOTE_STRING + '|' + DQUOTE_STRING + ')'; | 
| +var ARGUMENT = '(?:' + IDENT + '|' + NUMBER + '|' + STRING + '\\s*' + ')'; | 
| +var ARGUMENTS = '(?:' + ARGUMENT + '(?:,\\s*' + ARGUMENT + ')*' + ')'; | 
| +var ARGUMENT_LIST = '(?:' + '\\(\\s*' + '(?:' + ARGUMENTS + '?' + ')' + '\\)\\s*' + ')'; | 
| +var BINDING = '(' + IDENT + '\\s*' + ARGUMENT_LIST + '?' + ')'; | 
| +var OPEN_BRACKET = '(\\[\\[|{{)' + '\\s*'; | 
| +var CLOSE_BRACKET = '(?:]]|}})'; | 
| +var NEGATE = '(?:(!)\\s*)?'; | 
| +var EXPRESSION = OPEN_BRACKET + NEGATE + BINDING + CLOSE_BRACKET; | 
| +return new RegExp(EXPRESSION, 'g'); | 
| +}(), | 
| +_parseBindings: function (text) { | 
| +var re = this._bindingRegex; | 
| +var parts = []; | 
| +var lastIndex = 0; | 
| +var m; | 
| +while ((m = re.exec(text)) !== null) { | 
| +if (m.index > lastIndex) { | 
| +parts.push({ literal: text.slice(lastIndex, m.index) }); | 
| +} | 
| +var mode = m[1][0]; | 
| +var negate = Boolean(m[2]); | 
| +var value = m[3].trim(); | 
| +var customEvent, notifyEvent, colon; | 
| +if (mode == '{' && (colon = value.indexOf('::')) > 0) { | 
| +notifyEvent = value.substring(colon + 2); | 
| +value = value.substring(0, colon); | 
| +customEvent = true; | 
| +} | 
| +parts.push({ | 
| +compoundIndex: parts.length, | 
| +value: value, | 
| +mode: mode, | 
| +negate: negate, | 
| +event: notifyEvent, | 
| +customEvent: customEvent | 
| +}); | 
| +lastIndex = re.lastIndex; | 
| +} | 
| +if (lastIndex && lastIndex < text.length) { | 
| +var literal = text.substring(lastIndex); | 
| +if (literal) { | 
| +parts.push({ literal: literal }); | 
| +} | 
| +} | 
| +if (parts.length) { | 
| +return parts; | 
| +} | 
| +}, | 
| +_literalFromParts: function (parts) { | 
| +var s = ''; | 
| +for (var i = 0; i < parts.length; i++) { | 
| +var literal = parts[i].literal; | 
| +s += literal || ''; | 
| +} | 
| +return s; | 
| +}, | 
| +_parseTextNodeAnnotation: function (node, list) { | 
| +var parts = this._parseBindings(node.textContent); | 
| +if (parts) { | 
| +node.textContent = this._literalFromParts(parts) || ' '; | 
| +var annote = { | 
| +bindings: [{ | 
| +kind: 'text', | 
| +name: 'textContent', | 
| +parts: parts, | 
| +isCompound: parts.length !== 1 | 
| +}] | 
| +}; | 
| +list.push(annote); | 
| +return annote; | 
| +} | 
| +}, | 
| +_parseElementAnnotations: function (element, list, stripWhiteSpace) { | 
| +var annote = { | 
| +bindings: [], | 
| +events: [] | 
| +}; | 
| +if (element.localName === 'content') { | 
| +list._hasContent = true; | 
| +} | 
| +this._parseChildNodesAnnotations(element, annote, list, stripWhiteSpace); | 
| +if (element.attributes) { | 
| +this._parseNodeAttributeAnnotations(element, annote, list); | 
| +if (this.prepElement) { | 
| +this.prepElement(element); | 
| +} | 
| +} | 
| +if (annote.bindings.length || annote.events.length || annote.id) { | 
| +list.push(annote); | 
| +} | 
| +return annote; | 
| +}, | 
| +_parseChildNodesAnnotations: function (root, annote, list, stripWhiteSpace) { | 
| +if (root.firstChild) { | 
| +var node = root.firstChild; | 
| +var i = 0; | 
| +while (node) { | 
| +var next = node.nextSibling; | 
| +if (node.localName === 'template' && !node.hasAttribute('preserve-content')) { | 
| +this._parseTemplate(node, i, list, annote); | 
| +} | 
| +if (node.nodeType === Node.TEXT_NODE) { | 
| +var n = next; | 
| +while (n && n.nodeType === Node.TEXT_NODE) { | 
| +node.textContent += n.textContent; | 
| +next = n.nextSibling; | 
| +root.removeChild(n); | 
| +n = next; | 
| +} | 
| +if (stripWhiteSpace && !node.textContent.trim()) { | 
| +root.removeChild(node); | 
| +i--; | 
| +} | 
| +} | 
| +if (node.parentNode) { | 
| +var childAnnotation = this._parseNodeAnnotations(node, list, stripWhiteSpace); | 
| +if (childAnnotation) { | 
| +childAnnotation.parent = annote; | 
| +childAnnotation.index = i; | 
| +} | 
| +} | 
| +node = next; | 
| +i++; | 
| +} | 
| +} | 
| +}, | 
| +_parseTemplate: function (node, index, list, parent) { | 
| +var content = document.createDocumentFragment(); | 
| +content._notes = this.parseAnnotations(node); | 
| +content.appendChild(node.content); | 
| +list.push({ | 
| +bindings: Polymer.nar, | 
| +events: Polymer.nar, | 
| +templateContent: content, | 
| +parent: parent, | 
| +index: index | 
| +}); | 
| +}, | 
| +_parseNodeAttributeAnnotations: function (node, annotation) { | 
| +var attrs = Array.prototype.slice.call(node.attributes); | 
| +for (var i = attrs.length - 1, a; a = attrs[i]; i--) { | 
| +var n = a.name; | 
| +var v = a.value; | 
| +var b; | 
| +if (n.slice(0, 3) === 'on-') { | 
| +node.removeAttribute(n); | 
| +annotation.events.push({ | 
| +name: n.slice(3), | 
| +value: v | 
| +}); | 
| +} else if (b = this._parseNodeAttributeAnnotation(node, n, v)) { | 
| +annotation.bindings.push(b); | 
| +} else if (n === 'id') { | 
| +annotation.id = v; | 
| +} | 
| +} | 
| +}, | 
| +_parseNodeAttributeAnnotation: function (node, name, value) { | 
| +var parts = this._parseBindings(value); | 
| +if (parts) { | 
| +var origName = name; | 
| +var kind = 'property'; | 
| +if (name[name.length - 1] == '$') { | 
| +name = name.slice(0, -1); | 
| +kind = 'attribute'; | 
| +} | 
| +var literal = this._literalFromParts(parts); | 
| +if (literal && kind == 'attribute') { | 
| +node.setAttribute(name, literal); | 
| +} | 
| +if (node.localName === 'input' && origName === 'value') { | 
| +node.setAttribute(origName, ''); | 
| +} | 
| +node.removeAttribute(origName); | 
| +var propertyName = Polymer.CaseMap.dashToCamelCase(name); | 
| +if (kind === 'property') { | 
| +name = propertyName; | 
| +} | 
| +return { | 
| +kind: kind, | 
| +name: name, | 
| +propertyName: propertyName, | 
| +parts: parts, | 
| +literal: literal, | 
| +isCompound: parts.length !== 1 | 
| +}; | 
| +} | 
| +}, | 
| +findAnnotatedNode: function (root, annote) { | 
| +var parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote.parent); | 
| +if (parent) { | 
| +for (var n = parent.firstChild, i = 0; n; n = n.nextSibling) { | 
| +if (annote.index === i++) { | 
| +return n; | 
| +} | 
| +} | 
| +} else { | 
| +return root; | 
| +} | 
| +} | 
| +};(function () { | 
| +function resolveCss(cssText, ownerDocument) { | 
| +return cssText.replace(CSS_URL_RX, function (m, pre, url, post) { | 
| +return pre + '\'' + resolve(url.replace(/["']/g, ''), ownerDocument) + '\'' + post; | 
| +}); | 
| +} | 
| +function resolveAttrs(element, ownerDocument) { | 
| +for (var name in URL_ATTRS) { | 
| +var a$ = URL_ATTRS[name]; | 
| +for (var i = 0, l = a$.length, a, at, v; i < l && (a = a$[i]); i++) { | 
| +if (name === '*' || element.localName === name) { | 
| +at = element.attributes[a]; | 
| +v = at && at.value; | 
| +if (v && v.search(BINDING_RX) < 0) { | 
| +at.value = a === 'style' ? resolveCss(v, ownerDocument) : resolve(v, ownerDocument); | 
| +} | 
| +} | 
| +} | 
| +} | 
| +} | 
| +function resolve(url, ownerDocument) { | 
| +if (url && url[0] === '#') { | 
| +return url; | 
| +} | 
| +var resolver = getUrlResolver(ownerDocument); | 
| +resolver.href = url; | 
| +return resolver.href || url; | 
| +} | 
| +var tempDoc; | 
| +var tempDocBase; | 
| +function resolveUrl(url, baseUri) { | 
| +if (!tempDoc) { | 
| +tempDoc = document.implementation.createHTMLDocument('temp'); | 
| +tempDocBase = tempDoc.createElement('base'); | 
| +tempDoc.head.appendChild(tempDocBase); | 
| +} | 
| +tempDocBase.href = baseUri; | 
| +return resolve(url, tempDoc); | 
| +} | 
| +function getUrlResolver(ownerDocument) { | 
| +return ownerDocument.__urlResolver || (ownerDocument.__urlResolver = ownerDocument.createElement('a')); | 
| +} | 
| +var CSS_URL_RX = /(url\()([^)]*)(\))/g; | 
| +var URL_ATTRS = { | 
| +'*': [ | 
| +'href', | 
| +'src', | 
| +'style', | 
| +'url' | 
| +], | 
| +form: ['action'] | 
| +}; | 
| +var BINDING_RX = /\{\{|\[\[/; | 
| +Polymer.ResolveUrl = { | 
| +resolveCss: resolveCss, | 
| +resolveAttrs: resolveAttrs, | 
| +resolveUrl: resolveUrl | 
| +}; | 
| +}());Polymer.Base._addFeature({ | 
| +_prepAnnotations: function () { | 
| +if (!this._template) { | 
| +this._notes = []; | 
| +} else { | 
| +var self = this; | 
| +Polymer.Annotations.prepElement = function (element) { | 
| +self._prepElement(element); | 
| +}; | 
| +if (this._template._content && this._template._content._notes) { | 
| +this._notes = this._template._content._notes; | 
| +} else { | 
| +this._notes = Polymer.Annotations.parseAnnotations(this._template); | 
| +this._processAnnotations(this._notes); | 
| +} | 
| +Polymer.Annotations.prepElement = null; | 
| +} | 
| +}, | 
| +_processAnnotations: function (notes) { | 
| +for (var i = 0; i < notes.length; i++) { | 
| +var note = notes[i]; | 
| +for (var j = 0; j < note.bindings.length; j++) { | 
| +var b = note.bindings[j]; | 
| +for (var k = 0; k < b.parts.length; k++) { | 
| +var p = b.parts[k]; | 
| +if (!p.literal) { | 
| +var signature = this._parseMethod(p.value); | 
| +if (signature) { | 
| +p.signature = signature; | 
| +} else { | 
| +p.model = this._modelForPath(p.value); | 
| +} | 
| +} | 
| +} | 
| +} | 
| +if (note.templateContent) { | 
| +this._processAnnotations(note.templateContent._notes); | 
| +var pp = note.templateContent._parentProps = this._discoverTemplateParentProps(note.templateContent._notes); | 
| +var bindings = []; | 
| +for (var prop in pp) { | 
| +var name = '_parent_' + prop; | 
| +bindings.push({ | 
| +index: note.index, | 
| +kind: 'property', | 
| +name: name, | 
| +propertyName: name, | 
| +parts: [{ | 
| +mode: '{', | 
| +model: prop, | 
| +value: prop | 
| +}] | 
| +}); | 
| +} | 
| +note.bindings = note.bindings.concat(bindings); | 
| +} | 
| +} | 
| +}, | 
| +_discoverTemplateParentProps: function (notes) { | 
| +var pp = {}; | 
| +for (var i = 0, n; i < notes.length && (n = notes[i]); i++) { | 
| +for (var j = 0, b$ = n.bindings, b; j < b$.length && (b = b$[j]); j++) { | 
| +for (var k = 0, p$ = b.parts, p; k < p$.length && (p = p$[k]); k++) { | 
| +if (p.signature) { | 
| +var args = p.signature.args; | 
| +for (var kk = 0; kk < args.length; kk++) { | 
| +var model = args[kk].model; | 
| +if (model) { | 
| +pp[model] = true; | 
| +} | 
| +} | 
| +if (p.signature.dynamicFn) { | 
| +pp[p.signature.method] = true; | 
| +} | 
| +} else { | 
| +if (p.model) { | 
| +pp[p.model] = true; | 
| +} | 
| +} | 
| +} | 
| +} | 
| +if (n.templateContent) { | 
| +var tpp = n.templateContent._parentProps; | 
| +Polymer.Base.mixin(pp, tpp); | 
| +} | 
| +} | 
| +return pp; | 
| +}, | 
| +_prepElement: function (element) { | 
| +Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument); | 
| +}, | 
| +_findAnnotatedNode: Polymer.Annotations.findAnnotatedNode, | 
| +_marshalAnnotationReferences: function () { | 
| +if (this._template) { | 
| +this._marshalIdNodes(); | 
| +this._marshalAnnotatedNodes(); | 
| +this._marshalAnnotatedListeners(); | 
| +} | 
| +}, | 
| +_configureAnnotationReferences: function () { | 
| +var notes = this._notes; | 
| +var nodes = this._nodes; | 
| +for (var i = 0; i < notes.length; i++) { | 
| +var note = notes[i]; | 
| +var node = nodes[i]; | 
| +this._configureTemplateContent(note, node); | 
| +this._configureCompoundBindings(note, node); | 
| +} | 
| +}, | 
| +_configureTemplateContent: function (note, node) { | 
| +if (note.templateContent) { | 
| +node._content = note.templateContent; | 
| +} | 
| +}, | 
| +_configureCompoundBindings: function (note, node) { | 
| +var bindings = note.bindings; | 
| +for (var i = 0; i < bindings.length; i++) { | 
| +var binding = bindings[i]; | 
| +if (binding.isCompound) { | 
| +var storage = node.__compoundStorage__ || (node.__compoundStorage__ = {}); | 
| +var parts = binding.parts; | 
| +var literals = new Array(parts.length); | 
| +for (var j = 0; j < parts.length; j++) { | 
| +literals[j] = parts[j].literal; | 
| +} | 
| +var name = binding.name; | 
| +storage[name] = literals; | 
| +if (binding.literal && binding.kind == 'property') { | 
| +if (node._configValue) { | 
| +node._configValue(name, binding.literal); | 
| +} else { | 
| +node[name] = binding.literal; | 
| +} | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_marshalIdNodes: function () { | 
| +this.$ = {}; | 
| +for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) { | 
| +if (a.id) { | 
| +this.$[a.id] = this._findAnnotatedNode(this.root, a); | 
| +} | 
| +} | 
| +}, | 
| +_marshalAnnotatedNodes: function () { | 
| +if (this._notes && this._notes.length) { | 
| +var r = new Array(this._notes.length); | 
| +for (var i = 0; i < this._notes.length; i++) { | 
| +r[i] = this._findAnnotatedNode(this.root, this._notes[i]); | 
| +} | 
| +this._nodes = r; | 
| +} | 
| +}, | 
| +_marshalAnnotatedListeners: function () { | 
| +for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) { | 
| +if (a.events && a.events.length) { | 
| +var node = this._findAnnotatedNode(this.root, a); | 
| +for (var j = 0, e$ = a.events, e; j < e$.length && (e = e$[j]); j++) { | 
| +this.listen(node, e.name, e.value); | 
| +} | 
| +} | 
| +} | 
| +} | 
| +});Polymer.Base._addFeature({ | 
| +listeners: {}, | 
| +_listenListeners: function (listeners) { | 
| +var node, name, eventName; | 
| +for (eventName in listeners) { | 
| +if (eventName.indexOf('.') < 0) { | 
| +node = this; | 
| +name = eventName; | 
| +} else { | 
| +name = eventName.split('.'); | 
| +node = this.$[name[0]]; | 
| +name = name[1]; | 
| +} | 
| +this.listen(node, name, listeners[eventName]); | 
| +} | 
| +}, | 
| +listen: function (node, eventName, methodName) { | 
| +var handler = this._recallEventHandler(this, eventName, node, methodName); | 
| +if (!handler) { | 
| +handler = this._createEventHandler(node, eventName, methodName); | 
| +} | 
| +if (handler._listening) { | 
| +return; | 
| +} | 
| +this._listen(node, eventName, handler); | 
| +handler._listening = true; | 
| +}, | 
| +_boundListenerKey: function (eventName, methodName) { | 
| +return eventName + ':' + methodName; | 
| +}, | 
| +_recordEventHandler: function (host, eventName, target, methodName, handler) { | 
| +var hbl = host.__boundListeners; | 
| +if (!hbl) { | 
| +hbl = host.__boundListeners = new WeakMap(); | 
| +} | 
| +var bl = hbl.get(target); | 
| +if (!bl) { | 
| +bl = {}; | 
| +hbl.set(target, bl); | 
| +} | 
| +var key = this._boundListenerKey(eventName, methodName); | 
| +bl[key] = handler; | 
| +}, | 
| +_recallEventHandler: function (host, eventName, target, methodName) { | 
| +var hbl = host.__boundListeners; | 
| +if (!hbl) { | 
| +return; | 
| +} | 
| +var bl = hbl.get(target); | 
| +if (!bl) { | 
| +return; | 
| +} | 
| +var key = this._boundListenerKey(eventName, methodName); | 
| +return bl[key]; | 
| +}, | 
| +_createEventHandler: function (node, eventName, methodName) { | 
| +var host = this; | 
| +var handler = function (e) { | 
| +if (host[methodName]) { | 
| +host[methodName](e, e.detail); | 
| +} else { | 
| +host._warn(host._logf('_createEventHandler', 'listener method `' + methodName + '` not defined')); | 
| +} | 
| +}; | 
| +handler._listening = false; | 
| +this._recordEventHandler(host, eventName, node, methodName, handler); | 
| +return handler; | 
| +}, | 
| +unlisten: function (node, eventName, methodName) { | 
| +var handler = this._recallEventHandler(this, eventName, node, methodName); | 
| +if (handler) { | 
| +this._unlisten(node, eventName, handler); | 
| +handler._listening = false; | 
| +} | 
| +}, | 
| +_listen: function (node, eventName, handler) { | 
| +node.addEventListener(eventName, handler); | 
| +}, | 
| +_unlisten: function (node, eventName, handler) { | 
| +node.removeEventListener(eventName, handler); | 
| +} | 
| +});(function () { | 
| +'use strict'; | 
| +var wrap = Polymer.DomApi.wrap; | 
| +var HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string'; | 
| +var GESTURE_KEY = '__polymerGestures'; | 
| +var HANDLED_OBJ = '__polymerGesturesHandled'; | 
| +var TOUCH_ACTION = '__polymerGesturesTouchAction'; | 
| +var TAP_DISTANCE = 25; | 
| +var TRACK_DISTANCE = 5; | 
| +var TRACK_LENGTH = 2; | 
| +var MOUSE_TIMEOUT = 2500; | 
| +var MOUSE_EVENTS = [ | 
| +'mousedown', | 
| +'mousemove', | 
| +'mouseup', | 
| +'click' | 
| +]; | 
| +var MOUSE_WHICH_TO_BUTTONS = [ | 
| +0, | 
| +1, | 
| +4, | 
| +2 | 
| +]; | 
| +var MOUSE_HAS_BUTTONS = function () { | 
| +try { | 
| +return new MouseEvent('test', { buttons: 1 }).buttons === 1; | 
| +} catch (e) { | 
| +return false; | 
| +} | 
| +}(); | 
| +var IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/); | 
| +var mouseCanceller = function (mouseEvent) { | 
| +mouseEvent[HANDLED_OBJ] = { skip: true }; | 
| +if (mouseEvent.type === 'click') { | 
| +var path = Polymer.dom(mouseEvent).path; | 
| +for (var i = 0; i < path.length; i++) { | 
| +if (path[i] === POINTERSTATE.mouse.target) { | 
| +return; | 
| +} | 
| +} | 
| +mouseEvent.preventDefault(); | 
| +mouseEvent.stopPropagation(); | 
| +} | 
| +}; | 
| +function setupTeardownMouseCanceller(setup) { | 
| +for (var i = 0, en; i < MOUSE_EVENTS.length; i++) { | 
| +en = MOUSE_EVENTS[i]; | 
| +if (setup) { | 
| +document.addEventListener(en, mouseCanceller, true); | 
| +} else { | 
| +document.removeEventListener(en, mouseCanceller, true); | 
| +} | 
| +} | 
| +} | 
| +function ignoreMouse() { | 
| +if (IS_TOUCH_ONLY) { | 
| +return; | 
| +} | 
| +if (!POINTERSTATE.mouse.mouseIgnoreJob) { | 
| +setupTeardownMouseCanceller(true); | 
| +} | 
| +var unset = function () { | 
| +setupTeardownMouseCanceller(); | 
| +POINTERSTATE.mouse.target = null; | 
| +POINTERSTATE.mouse.mouseIgnoreJob = null; | 
| +}; | 
| +POINTERSTATE.mouse.mouseIgnoreJob = Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob, unset, MOUSE_TIMEOUT); | 
| +} | 
| +function hasLeftMouseButton(ev) { | 
| +var type = ev.type; | 
| +if (MOUSE_EVENTS.indexOf(type) === -1) { | 
| +return false; | 
| +} | 
| +if (type === 'mousemove') { | 
| +var buttons = ev.buttons === undefined ? 1 : ev.buttons; | 
| +if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) { | 
| +buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0; | 
| +} | 
| +return Boolean(buttons & 1); | 
| +} else { | 
| +var button = ev.button === undefined ? 0 : ev.button; | 
| +return button === 0; | 
| +} | 
| +} | 
| +function isSyntheticClick(ev) { | 
| +if (ev.type === 'click') { | 
| +if (ev.detail === 0) { | 
| +return true; | 
| +} | 
| +var t = Gestures.findOriginalTarget(ev); | 
| +var bcr = t.getBoundingClientRect(); | 
| +var x = ev.pageX, y = ev.pageY; | 
| +return !(x >= bcr.left && x <= bcr.right && (y >= bcr.top && y <= bcr.bottom)); | 
| +} | 
| +return false; | 
| +} | 
| +var POINTERSTATE = { | 
| +mouse: { | 
| +target: null, | 
| +mouseIgnoreJob: null | 
| +}, | 
| +touch: { | 
| +x: 0, | 
| +y: 0, | 
| +id: -1, | 
| +scrollDecided: false | 
| +} | 
| +}; | 
| +function firstTouchAction(ev) { | 
| +var path = Polymer.dom(ev).path; | 
| +var ta = 'auto'; | 
| +for (var i = 0, n; i < path.length; i++) { | 
| +n = path[i]; | 
| +if (n[TOUCH_ACTION]) { | 
| +ta = n[TOUCH_ACTION]; | 
| +break; | 
| +} | 
| +} | 
| +return ta; | 
| +} | 
| +function trackDocument(stateObj, movefn, upfn) { | 
| +stateObj.movefn = movefn; | 
| +stateObj.upfn = upfn; | 
| +document.addEventListener('mousemove', movefn); | 
| +document.addEventListener('mouseup', upfn); | 
| +} | 
| +function untrackDocument(stateObj) { | 
| +document.removeEventListener('mousemove', stateObj.movefn); | 
| +document.removeEventListener('mouseup', stateObj.upfn); | 
| +stateObj.movefn = null; | 
| +stateObj.upfn = null; | 
| +} | 
| +var Gestures = { | 
| +gestures: {}, | 
| +recognizers: [], | 
| +deepTargetFind: function (x, y) { | 
| +var node = document.elementFromPoint(x, y); | 
| +var next = node; | 
| +while (next && next.shadowRoot) { | 
| +next = next.shadowRoot.elementFromPoint(x, y); | 
| +if (next) { | 
| +node = next; | 
| +} | 
| +} | 
| +return node; | 
| +}, | 
| +findOriginalTarget: function (ev) { | 
| +if (ev.path) { | 
| +return ev.path[0]; | 
| +} | 
| +return ev.target; | 
| +}, | 
| +handleNative: function (ev) { | 
| +var handled; | 
| +var type = ev.type; | 
| +var node = wrap(ev.currentTarget); | 
| +var gobj = node[GESTURE_KEY]; | 
| +if (!gobj) { | 
| +return; | 
| +} | 
| +var gs = gobj[type]; | 
| +if (!gs) { | 
| +return; | 
| +} | 
| +if (!ev[HANDLED_OBJ]) { | 
| +ev[HANDLED_OBJ] = {}; | 
| +if (type.slice(0, 5) === 'touch') { | 
| +var t = ev.changedTouches[0]; | 
| +if (type === 'touchstart') { | 
| +if (ev.touches.length === 1) { | 
| +POINTERSTATE.touch.id = t.identifier; | 
| +} | 
| +} | 
| +if (POINTERSTATE.touch.id !== t.identifier) { | 
| +return; | 
| +} | 
| +if (!HAS_NATIVE_TA) { | 
| +if (type === 'touchstart' || type === 'touchmove') { | 
| +Gestures.handleTouchAction(ev); | 
| +} | 
| +} | 
| +if (type === 'touchend') { | 
| +POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget; | 
| +ignoreMouse(); | 
| +} | 
| +} | 
| +} | 
| +handled = ev[HANDLED_OBJ]; | 
| +if (handled.skip) { | 
| +return; | 
| +} | 
| +var recognizers = Gestures.recognizers; | 
| +for (var i = 0, r; i < recognizers.length; i++) { | 
| +r = recognizers[i]; | 
| +if (gs[r.name] && !handled[r.name]) { | 
| +if (r.flow && r.flow.start.indexOf(ev.type) > -1 && r.reset) { | 
| +r.reset(); | 
| +} | 
| +} | 
| +} | 
| +for (i = 0, r; i < recognizers.length; i++) { | 
| +r = recognizers[i]; | 
| +if (gs[r.name] && !handled[r.name]) { | 
| +handled[r.name] = true; | 
| +r[type](ev); | 
| +} | 
| +} | 
| +}, | 
| +handleTouchAction: function (ev) { | 
| +var t = ev.changedTouches[0]; | 
| +var type = ev.type; | 
| +if (type === 'touchstart') { | 
| +POINTERSTATE.touch.x = t.clientX; | 
| +POINTERSTATE.touch.y = t.clientY; | 
| +POINTERSTATE.touch.scrollDecided = false; | 
| +} else if (type === 'touchmove') { | 
| +if (POINTERSTATE.touch.scrollDecided) { | 
| +return; | 
| +} | 
| +POINTERSTATE.touch.scrollDecided = true; | 
| +var ta = firstTouchAction(ev); | 
| +var prevent = false; | 
| +var dx = Math.abs(POINTERSTATE.touch.x - t.clientX); | 
| +var dy = Math.abs(POINTERSTATE.touch.y - t.clientY); | 
| +if (!ev.cancelable) { | 
| +} else if (ta === 'none') { | 
| +prevent = true; | 
| +} else if (ta === 'pan-x') { | 
| +prevent = dy > dx; | 
| +} else if (ta === 'pan-y') { | 
| +prevent = dx > dy; | 
| +} | 
| +if (prevent) { | 
| +ev.preventDefault(); | 
| +} else { | 
| +Gestures.prevent('track'); | 
| +} | 
| +} | 
| +}, | 
| +add: function (node, evType, handler) { | 
| +node = wrap(node); | 
| +var recognizer = this.gestures[evType]; | 
| +var deps = recognizer.deps; | 
| +var name = recognizer.name; | 
| +var gobj = node[GESTURE_KEY]; | 
| +if (!gobj) { | 
| +node[GESTURE_KEY] = gobj = {}; | 
| +} | 
| +for (var i = 0, dep, gd; i < deps.length; i++) { | 
| +dep = deps[i]; | 
| +if (IS_TOUCH_ONLY && MOUSE_EVENTS.indexOf(dep) > -1) { | 
| +continue; | 
| +} | 
| +gd = gobj[dep]; | 
| +if (!gd) { | 
| +gobj[dep] = gd = { _count: 0 }; | 
| +} | 
| +if (gd._count === 0) { | 
| +node.addEventListener(dep, this.handleNative); | 
| +} | 
| +gd[name] = (gd[name] || 0) + 1; | 
| +gd._count = (gd._count || 0) + 1; | 
| +} | 
| +node.addEventListener(evType, handler); | 
| +if (recognizer.touchAction) { | 
| +this.setTouchAction(node, recognizer.touchAction); | 
| +} | 
| +}, | 
| +remove: function (node, evType, handler) { | 
| +node = wrap(node); | 
| +var recognizer = this.gestures[evType]; | 
| +var deps = recognizer.deps; | 
| +var name = recognizer.name; | 
| +var gobj = node[GESTURE_KEY]; | 
| +if (gobj) { | 
| +for (var i = 0, dep, gd; i < deps.length; i++) { | 
| +dep = deps[i]; | 
| +gd = gobj[dep]; | 
| +if (gd && gd[name]) { | 
| +gd[name] = (gd[name] || 1) - 1; | 
| +gd._count = (gd._count || 1) - 1; | 
| +if (gd._count === 0) { | 
| +node.removeEventListener(dep, this.handleNative); | 
| +} | 
| +} | 
| +} | 
| +} | 
| +node.removeEventListener(evType, handler); | 
| +}, | 
| +register: function (recog) { | 
| +this.recognizers.push(recog); | 
| +for (var i = 0; i < recog.emits.length; i++) { | 
| +this.gestures[recog.emits[i]] = recog; | 
| +} | 
| +}, | 
| +findRecognizerByEvent: function (evName) { | 
| +for (var i = 0, r; i < this.recognizers.length; i++) { | 
| +r = this.recognizers[i]; | 
| +for (var j = 0, n; j < r.emits.length; j++) { | 
| +n = r.emits[j]; | 
| +if (n === evName) { | 
| +return r; | 
| +} | 
| +} | 
| +} | 
| +return null; | 
| +}, | 
| +setTouchAction: function (node, value) { | 
| +if (HAS_NATIVE_TA) { | 
| +node.style.touchAction = value; | 
| +} | 
| +node[TOUCH_ACTION] = value; | 
| +}, | 
| +fire: function (target, type, detail) { | 
| +var ev = Polymer.Base.fire(type, detail, { | 
| +node: target, | 
| +bubbles: true, | 
| +cancelable: true | 
| +}); | 
| +if (ev.defaultPrevented) { | 
| +var preventer = detail.preventer || detail.sourceEvent; | 
| +if (preventer && preventer.preventDefault) { | 
| +preventer.preventDefault(); | 
| +} | 
| +} | 
| +}, | 
| +prevent: function (evName) { | 
| +var recognizer = this.findRecognizerByEvent(evName); | 
| +if (recognizer.info) { | 
| +recognizer.info.prevent = true; | 
| +} | 
| +}, | 
| +resetMouseCanceller: function () { | 
| +if (POINTERSTATE.mouse.mouseIgnoreJob) { | 
| +POINTERSTATE.mouse.mouseIgnoreJob.complete(); | 
| +} | 
| +} | 
| +}; | 
| +Gestures.register({ | 
| +name: 'downup', | 
| +deps: [ | 
| +'mousedown', | 
| +'touchstart', | 
| +'touchend' | 
| +], | 
| +flow: { | 
| +start: [ | 
| +'mousedown', | 
| +'touchstart' | 
| +], | 
| +end: [ | 
| +'mouseup', | 
| +'touchend' | 
| +] | 
| +}, | 
| +emits: [ | 
| +'down', | 
| +'up' | 
| +], | 
| +info: { | 
| +movefn: null, | 
| +upfn: null | 
| +}, | 
| +reset: function () { | 
| +untrackDocument(this.info); | 
| +}, | 
| +mousedown: function (e) { | 
| +if (!hasLeftMouseButton(e)) { | 
| +return; | 
| +} | 
| +var t = Gestures.findOriginalTarget(e); | 
| +var self = this; | 
| +var movefn = function movefn(e) { | 
| +if (!hasLeftMouseButton(e)) { | 
| +self.fire('up', t, e); | 
| +untrackDocument(self.info); | 
| +} | 
| +}; | 
| +var upfn = function upfn(e) { | 
| +if (hasLeftMouseButton(e)) { | 
| +self.fire('up', t, e); | 
| +} | 
| +untrackDocument(self.info); | 
| +}; | 
| +trackDocument(this.info, movefn, upfn); | 
| +this.fire('down', t, e); | 
| +}, | 
| +touchstart: function (e) { | 
| +this.fire('down', Gestures.findOriginalTarget(e), e.changedTouches[0], e); | 
| +}, | 
| +touchend: function (e) { | 
| +this.fire('up', Gestures.findOriginalTarget(e), e.changedTouches[0], e); | 
| +}, | 
| +fire: function (type, target, event, preventer) { | 
| +Gestures.fire(target, type, { | 
| +x: event.clientX, | 
| +y: event.clientY, | 
| +sourceEvent: event, | 
| +preventer: preventer, | 
| +prevent: function (e) { | 
| +return Gestures.prevent(e); | 
| +} | 
| +}); | 
| +} | 
| +}); | 
| +Gestures.register({ | 
| +name: 'track', | 
| +touchAction: 'none', | 
| +deps: [ | 
| +'mousedown', | 
| +'touchstart', | 
| +'touchmove', | 
| +'touchend' | 
| +], | 
| +flow: { | 
| +start: [ | 
| +'mousedown', | 
| +'touchstart' | 
| +], | 
| +end: [ | 
| +'mouseup', | 
| +'touchend' | 
| +] | 
| +}, | 
| +emits: ['track'], | 
| +info: { | 
| +x: 0, | 
| +y: 0, | 
| +state: 'start', | 
| +started: false, | 
| +moves: [], | 
| +addMove: function (move) { | 
| +if (this.moves.length > TRACK_LENGTH) { | 
| +this.moves.shift(); | 
| +} | 
| +this.moves.push(move); | 
| +}, | 
| +movefn: null, | 
| +upfn: null, | 
| +prevent: false | 
| +}, | 
| +reset: function () { | 
| +this.info.state = 'start'; | 
| +this.info.started = false; | 
| +this.info.moves = []; | 
| +this.info.x = 0; | 
| +this.info.y = 0; | 
| +this.info.prevent = false; | 
| +untrackDocument(this.info); | 
| +}, | 
| +hasMovedEnough: function (x, y) { | 
| +if (this.info.prevent) { | 
| +return false; | 
| +} | 
| +if (this.info.started) { | 
| +return true; | 
| +} | 
| +var dx = Math.abs(this.info.x - x); | 
| +var dy = Math.abs(this.info.y - y); | 
| +return dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE; | 
| +}, | 
| +mousedown: function (e) { | 
| +if (!hasLeftMouseButton(e)) { | 
| +return; | 
| +} | 
| +var t = Gestures.findOriginalTarget(e); | 
| +var self = this; | 
| +var movefn = function movefn(e) { | 
| +var x = e.clientX, y = e.clientY; | 
| +if (self.hasMovedEnough(x, y)) { | 
| +self.info.state = self.info.started ? e.type === 'mouseup' ? 'end' : 'track' : 'start'; | 
| +if (self.info.state === 'start') { | 
| +Gestures.prevent('tap'); | 
| +} | 
| +self.info.addMove({ | 
| +x: x, | 
| +y: y | 
| +}); | 
| +if (!hasLeftMouseButton(e)) { | 
| +self.info.state = 'end'; | 
| +untrackDocument(self.info); | 
| +} | 
| +self.fire(t, e); | 
| +self.info.started = true; | 
| +} | 
| +}; | 
| +var upfn = function upfn(e) { | 
| +if (self.info.started) { | 
| +movefn(e); | 
| +} | 
| +untrackDocument(self.info); | 
| +}; | 
| +trackDocument(this.info, movefn, upfn); | 
| +this.info.x = e.clientX; | 
| +this.info.y = e.clientY; | 
| +}, | 
| +touchstart: function (e) { | 
| +var ct = e.changedTouches[0]; | 
| +this.info.x = ct.clientX; | 
| +this.info.y = ct.clientY; | 
| +}, | 
| +touchmove: function (e) { | 
| +var t = Gestures.findOriginalTarget(e); | 
| +var ct = e.changedTouches[0]; | 
| +var x = ct.clientX, y = ct.clientY; | 
| +if (this.hasMovedEnough(x, y)) { | 
| +if (this.info.state === 'start') { | 
| +Gestures.prevent('tap'); | 
| +} | 
| +this.info.addMove({ | 
| +x: x, | 
| +y: y | 
| +}); | 
| +this.fire(t, ct); | 
| +this.info.state = 'track'; | 
| +this.info.started = true; | 
| +} | 
| +}, | 
| +touchend: function (e) { | 
| +var t = Gestures.findOriginalTarget(e); | 
| +var ct = e.changedTouches[0]; | 
| +if (this.info.started) { | 
| +this.info.state = 'end'; | 
| +this.info.addMove({ | 
| +x: ct.clientX, | 
| +y: ct.clientY | 
| +}); | 
| +this.fire(t, ct, e); | 
| +} | 
| +}, | 
| +fire: function (target, touch, preventer) { | 
| +var secondlast = this.info.moves[this.info.moves.length - 2]; | 
| +var lastmove = this.info.moves[this.info.moves.length - 1]; | 
| +var dx = lastmove.x - this.info.x; | 
| +var dy = lastmove.y - this.info.y; | 
| +var ddx, ddy = 0; | 
| +if (secondlast) { | 
| +ddx = lastmove.x - secondlast.x; | 
| +ddy = lastmove.y - secondlast.y; | 
| +} | 
| +return Gestures.fire(target, 'track', { | 
| +state: this.info.state, | 
| +x: touch.clientX, | 
| +y: touch.clientY, | 
| +dx: dx, | 
| +dy: dy, | 
| +ddx: ddx, | 
| +ddy: ddy, | 
| +sourceEvent: touch, | 
| +preventer: preventer, | 
| +hover: function () { | 
| +return Gestures.deepTargetFind(touch.clientX, touch.clientY); | 
| +} | 
| +}); | 
| +} | 
| +}); | 
| +Gestures.register({ | 
| +name: 'tap', | 
| +deps: [ | 
| +'mousedown', | 
| +'click', | 
| +'touchstart', | 
| +'touchend' | 
| +], | 
| +flow: { | 
| +start: [ | 
| +'mousedown', | 
| +'touchstart' | 
| +], | 
| +end: [ | 
| +'click', | 
| +'touchend' | 
| +] | 
| +}, | 
| +emits: ['tap'], | 
| +info: { | 
| +x: NaN, | 
| +y: NaN, | 
| +prevent: false | 
| +}, | 
| +reset: function () { | 
| +this.info.x = NaN; | 
| +this.info.y = NaN; | 
| +this.info.prevent = false; | 
| +}, | 
| +save: function (e) { | 
| +this.info.x = e.clientX; | 
| +this.info.y = e.clientY; | 
| +}, | 
| +mousedown: function (e) { | 
| +if (hasLeftMouseButton(e)) { | 
| +this.save(e); | 
| +} | 
| +}, | 
| +click: function (e) { | 
| +if (hasLeftMouseButton(e)) { | 
| +this.forward(e); | 
| +} | 
| +}, | 
| +touchstart: function (e) { | 
| +this.save(e.changedTouches[0], e); | 
| +}, | 
| +touchend: function (e) { | 
| +this.forward(e.changedTouches[0], e); | 
| +}, | 
| +forward: function (e, preventer) { | 
| +var dx = Math.abs(e.clientX - this.info.x); | 
| +var dy = Math.abs(e.clientY - this.info.y); | 
| +var t = Gestures.findOriginalTarget(e); | 
| +if (isNaN(dx) || isNaN(dy) || dx <= TAP_DISTANCE && dy <= TAP_DISTANCE || isSyntheticClick(e)) { | 
| +if (!this.info.prevent) { | 
| +Gestures.fire(t, 'tap', { | 
| +x: e.clientX, | 
| +y: e.clientY, | 
| +sourceEvent: e, | 
| +preventer: preventer | 
| +}); | 
| +} | 
| +} | 
| +} | 
| +}); | 
| +var DIRECTION_MAP = { | 
| +x: 'pan-x', | 
| +y: 'pan-y', | 
| +none: 'none', | 
| +all: 'auto' | 
| +}; | 
| +Polymer.Base._addFeature({ | 
| +_setupGestures: function () { | 
| +this.__polymerGestures = null; | 
| +}, | 
| +_listen: function (node, eventName, handler) { | 
| +if (Gestures.gestures[eventName]) { | 
| +Gestures.add(node, eventName, handler); | 
| +} else { | 
| +node.addEventListener(eventName, handler); | 
| +} | 
| +}, | 
| +_unlisten: function (node, eventName, handler) { | 
| +if (Gestures.gestures[eventName]) { | 
| +Gestures.remove(node, eventName, handler); | 
| +} else { | 
| +node.removeEventListener(eventName, handler); | 
| +} | 
| +}, | 
| +setScrollDirection: function (direction, node) { | 
| +node = node || this; | 
| +Gestures.setTouchAction(node, DIRECTION_MAP[direction] || 'auto'); | 
| +} | 
| +}); | 
| +Polymer.Gestures = Gestures; | 
| +}());(function () { | 
| +'use strict'; | 
| +Polymer.Base._addFeature({ | 
| +$$: function (slctr) { | 
| +return Polymer.dom(this.root).querySelector(slctr); | 
| +}, | 
| +toggleClass: function (name, bool, node) { | 
| +node = node || this; | 
| +if (arguments.length == 1) { | 
| +bool = !node.classList.contains(name); | 
| +} | 
| +if (bool) { | 
| +Polymer.dom(node).classList.add(name); | 
| +} else { | 
| +Polymer.dom(node).classList.remove(name); | 
| +} | 
| +}, | 
| +toggleAttribute: function (name, bool, node) { | 
| +node = node || this; | 
| +if (arguments.length == 1) { | 
| +bool = !node.hasAttribute(name); | 
| +} | 
| +if (bool) { | 
| +Polymer.dom(node).setAttribute(name, ''); | 
| +} else { | 
| +Polymer.dom(node).removeAttribute(name); | 
| +} | 
| +}, | 
| +classFollows: function (name, toElement, fromElement) { | 
| +if (fromElement) { | 
| +Polymer.dom(fromElement).classList.remove(name); | 
| +} | 
| +if (toElement) { | 
| +Polymer.dom(toElement).classList.add(name); | 
| +} | 
| +}, | 
| +attributeFollows: function (name, toElement, fromElement) { | 
| +if (fromElement) { | 
| +Polymer.dom(fromElement).removeAttribute(name); | 
| +} | 
| +if (toElement) { | 
| +Polymer.dom(toElement).setAttribute(name, ''); | 
| +} | 
| +}, | 
| +getEffectiveChildNodes: function () { | 
| +return Polymer.dom(this).getEffectiveChildNodes(); | 
| +}, | 
| +getEffectiveChildren: function () { | 
| +var list = Polymer.dom(this).getEffectiveChildNodes(); | 
| +return list.filter(function (n) { | 
| +return n.nodeType === Node.ELEMENT_NODE; | 
| +}); | 
| +}, | 
| +getEffectiveTextContent: function () { | 
| +var cn = this.getEffectiveChildNodes(); | 
| +var tc = []; | 
| +for (var i = 0, c; c = cn[i]; i++) { | 
| +if (c.nodeType !== Node.COMMENT_NODE) { | 
| +tc.push(Polymer.dom(c).textContent); | 
| +} | 
| +} | 
| +return tc.join(''); | 
| +}, | 
| +queryEffectiveChildren: function (slctr) { | 
| +var e$ = Polymer.dom(this).queryDistributedElements(slctr); | 
| +return e$ && e$[0]; | 
| +}, | 
| +queryAllEffectiveChildren: function (slctr) { | 
| +return Polymer.dom(this).queryDistributedElements(slctr); | 
| +}, | 
| +getContentChildNodes: function (slctr) { | 
| +var content = Polymer.dom(this.root).querySelector(slctr || 'content'); | 
| +return content ? Polymer.dom(content).getDistributedNodes() : []; | 
| +}, | 
| +getContentChildren: function (slctr) { | 
| +return this.getContentChildNodes(slctr).filter(function (n) { | 
| +return n.nodeType === Node.ELEMENT_NODE; | 
| +}); | 
| +}, | 
| +fire: function (type, detail, options) { | 
| +options = options || Polymer.nob; | 
| +var node = options.node || this; | 
| +detail = detail === null || detail === undefined ? {} : detail; | 
| +var bubbles = options.bubbles === undefined ? true : options.bubbles; | 
| +var cancelable = Boolean(options.cancelable); | 
| +var useCache = options._useCache; | 
| +var event = this._getEvent(type, bubbles, cancelable, useCache); | 
| +event.detail = detail; | 
| +if (useCache) { | 
| +this.__eventCache[type] = null; | 
| +} | 
| +node.dispatchEvent(event); | 
| +if (useCache) { | 
| +this.__eventCache[type] = event; | 
| +} | 
| +return event; | 
| +}, | 
| +__eventCache: {}, | 
| +_getEvent: function (type, bubbles, cancelable, useCache) { | 
| +var event = useCache && this.__eventCache[type]; | 
| +if (!event || (event.bubbles != bubbles || event.cancelable != cancelable)) { | 
| +event = new Event(type, { | 
| +bubbles: Boolean(bubbles), | 
| +cancelable: cancelable | 
| +}); | 
| +} | 
| +return event; | 
| +}, | 
| +async: function (callback, waitTime) { | 
| +var self = this; | 
| +return Polymer.Async.run(function () { | 
| +callback.call(self); | 
| +}, waitTime); | 
| +}, | 
| +cancelAsync: function (handle) { | 
| +Polymer.Async.cancel(handle); | 
| +}, | 
| +arrayDelete: function (path, item) { | 
| +var index; | 
| +if (Array.isArray(path)) { | 
| +index = path.indexOf(item); | 
| +if (index >= 0) { | 
| +return path.splice(index, 1); | 
| +} | 
| +} else { | 
| +var arr = this._get(path); | 
| +index = arr.indexOf(item); | 
| +if (index >= 0) { | 
| +return this.splice(path, index, 1); | 
| +} | 
| +} | 
| +}, | 
| +transform: function (transform, node) { | 
| +node = node || this; | 
| +node.style.webkitTransform = transform; | 
| +node.style.transform = transform; | 
| +}, | 
| +translate3d: function (x, y, z, node) { | 
| +node = node || this; | 
| +this.transform('translate3d(' + x + ',' + y + ',' + z + ')', node); | 
| +}, | 
| +importHref: function (href, onload, onerror, optAsync) { | 
| +var link = document.createElement('link'); | 
| +link.rel = 'import'; | 
| +link.href = href; | 
| +var list = Polymer.Base.importHref.imported = Polymer.Base.importHref.imported || {}; | 
| +var cached = list[link.href]; | 
| +var imprt = cached || link; | 
| +var self = this; | 
| +if (onload) { | 
| +var loadListener = function (e) { | 
| +e.target.__firedLoad = true; | 
| +e.target.removeEventListener('load', loadListener); | 
| +return onload.call(self, e); | 
| +}; | 
| +imprt.addEventListener('load', loadListener); | 
| +} | 
| +if (onerror) { | 
| +var errorListener = function (e) { | 
| +e.target.__firedError = true; | 
| +e.target.removeEventListener('error', errorListener); | 
| +return onerror.call(self, e); | 
| +}; | 
| +imprt.addEventListener('error', errorListener); | 
| +} | 
| +if (cached) { | 
| +if (cached.__firedLoad) { | 
| +cached.dispatchEvent(new Event('load')); | 
| +} | 
| +if (cached.__firedError) { | 
| +cached.dispatchEvent(new Event('error')); | 
| +} | 
| +} else { | 
| +list[link.href] = link; | 
| +optAsync = Boolean(optAsync); | 
| +if (optAsync) { | 
| +link.setAttribute('async', ''); | 
| +} | 
| +document.head.appendChild(link); | 
| +} | 
| +return imprt; | 
| +}, | 
| +create: function (tag, props) { | 
| +var elt = document.createElement(tag); | 
| +if (props) { | 
| +for (var n in props) { | 
| +elt[n] = props[n]; | 
| +} | 
| +} | 
| +return elt; | 
| +}, | 
| +isLightDescendant: function (node) { | 
| +return this !== node && this.contains(node) && Polymer.dom(this).getOwnerRoot() === Polymer.dom(node).getOwnerRoot(); | 
| +}, | 
| +isLocalDescendant: function (node) { | 
| +return this.root === Polymer.dom(node).getOwnerRoot(); | 
| +} | 
| +}); | 
| +if (!Polymer.Settings.useNativeCustomElements) { | 
| +var importHref = Polymer.Base.importHref; | 
| +Polymer.Base.importHref = function (href, onload, onerror, optAsync) { | 
| +CustomElements.ready = false; | 
| +var loadFn = function (e) { | 
| +CustomElements.upgradeDocumentTree(document); | 
| +CustomElements.ready = true; | 
| +if (onload) { | 
| +return onload.call(this, e); | 
| +} | 
| +}; | 
| +return importHref.call(this, href, loadFn, onerror, optAsync); | 
| +}; | 
| +} | 
| +}());Polymer.Bind = { | 
| +prepareModel: function (model) { | 
| +Polymer.Base.mixin(model, this._modelApi); | 
| +}, | 
| +_modelApi: { | 
| +_notifyChange: function (source, event, value) { | 
| +value = value === undefined ? this[source] : value; | 
| +event = event || Polymer.CaseMap.camelToDashCase(source) + '-changed'; | 
| +this.fire(event, { value: value }, { | 
| +bubbles: false, | 
| +cancelable: false, | 
| +_useCache: true | 
| +}); | 
| +}, | 
| +_propertySetter: function (property, value, effects, fromAbove) { | 
| +var old = this.__data__[property]; | 
| +if (old !== value && (old === old || value === value)) { | 
| +this.__data__[property] = value; | 
| +if (typeof value == 'object') { | 
| +this._clearPath(property); | 
| +} | 
| +if (this._propertyChanged) { | 
| +this._propertyChanged(property, value, old); | 
| +} | 
| +if (effects) { | 
| +this._effectEffects(property, value, effects, old, fromAbove); | 
| +} | 
| +} | 
| +return old; | 
| +}, | 
| +__setProperty: function (property, value, quiet, node) { | 
| +node = node || this; | 
| +var effects = node._propertyEffects && node._propertyEffects[property]; | 
| +if (effects) { | 
| +node._propertySetter(property, value, effects, quiet); | 
| +} else { | 
| +node[property] = value; | 
| +} | 
| +}, | 
| +_effectEffects: function (property, value, effects, old, fromAbove) { | 
| +for (var i = 0, l = effects.length, fx; i < l && (fx = effects[i]); i++) { | 
| +fx.fn.call(this, property, this[property], fx.effect, old, fromAbove); | 
| +} | 
| +}, | 
| +_clearPath: function (path) { | 
| +for (var prop in this.__data__) { | 
| +if (prop.indexOf(path + '.') === 0) { | 
| +this.__data__[prop] = undefined; | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +ensurePropertyEffects: function (model, property) { | 
| +if (!model._propertyEffects) { | 
| +model._propertyEffects = {}; | 
| +} | 
| +var fx = model._propertyEffects[property]; | 
| +if (!fx) { | 
| +fx = model._propertyEffects[property] = []; | 
| +} | 
| +return fx; | 
| +}, | 
| +addPropertyEffect: function (model, property, kind, effect) { | 
| +var fx = this.ensurePropertyEffects(model, property); | 
| +var propEffect = { | 
| +kind: kind, | 
| +effect: effect, | 
| +fn: Polymer.Bind['_' + kind + 'Effect'] | 
| +}; | 
| +fx.push(propEffect); | 
| +return propEffect; | 
| +}, | 
| +createBindings: function (model) { | 
| +var fx$ = model._propertyEffects; | 
| +if (fx$) { | 
| +for (var n in fx$) { | 
| +var fx = fx$[n]; | 
| +fx.sort(this._sortPropertyEffects); | 
| +this._createAccessors(model, n, fx); | 
| +} | 
| +} | 
| +}, | 
| +_sortPropertyEffects: function () { | 
| +var EFFECT_ORDER = { | 
| +'compute': 0, | 
| +'annotation': 1, | 
| +'annotatedComputation': 2, | 
| +'reflect': 3, | 
| +'notify': 4, | 
| +'observer': 5, | 
| +'complexObserver': 6, | 
| +'function': 7 | 
| +}; | 
| +return function (a, b) { | 
| +return EFFECT_ORDER[a.kind] - EFFECT_ORDER[b.kind]; | 
| +}; | 
| +}(), | 
| +_createAccessors: function (model, property, effects) { | 
| +var defun = { | 
| +get: function () { | 
| +return this.__data__[property]; | 
| +} | 
| +}; | 
| +var setter = function (value) { | 
| +this._propertySetter(property, value, effects); | 
| +}; | 
| +var info = model.getPropertyInfo && model.getPropertyInfo(property); | 
| +if (info && info.readOnly) { | 
| +if (!info.computed) { | 
| +model['_set' + this.upper(property)] = setter; | 
| +} | 
| +} else { | 
| +defun.set = setter; | 
| +} | 
| +Object.defineProperty(model, property, defun); | 
| +}, | 
| +upper: function (name) { | 
| +return name[0].toUpperCase() + name.substring(1); | 
| +}, | 
| +_addAnnotatedListener: function (model, index, property, path, event, negated) { | 
| +if (!model._bindListeners) { | 
| +model._bindListeners = []; | 
| +} | 
| +var fn = this._notedListenerFactory(property, path, this._isStructured(path), negated); | 
| +var eventName = event || Polymer.CaseMap.camelToDashCase(property) + '-changed'; | 
| +model._bindListeners.push({ | 
| +index: index, | 
| +property: property, | 
| +path: path, | 
| +changedFn: fn, | 
| +event: eventName | 
| +}); | 
| +}, | 
| +_isStructured: function (path) { | 
| +return path.indexOf('.') > 0; | 
| +}, | 
| +_isEventBogus: function (e, target) { | 
| +return e.path && e.path[0] !== target; | 
| +}, | 
| +_notedListenerFactory: function (property, path, isStructured, negated) { | 
| +return function (target, value, targetPath) { | 
| +if (targetPath) { | 
| +this._notifyPath(this._fixPath(path, property, targetPath), value); | 
| +} else { | 
| +value = target[property]; | 
| +if (negated) { | 
| +value = !value; | 
| +} | 
| +if (!isStructured) { | 
| +this[path] = value; | 
| +} else { | 
| +if (this.__data__[path] != value) { | 
| +this.set(path, value); | 
| +} | 
| +} | 
| +} | 
| +}; | 
| +}, | 
| +prepareInstance: function (inst) { | 
| +inst.__data__ = Object.create(null); | 
| +}, | 
| +setupBindListeners: function (inst) { | 
| +var b$ = inst._bindListeners; | 
| +for (var i = 0, l = b$.length, info; i < l && (info = b$[i]); i++) { | 
| +var node = inst._nodes[info.index]; | 
| +this._addNotifyListener(node, inst, info.event, info.changedFn); | 
| +} | 
| +}, | 
| +_addNotifyListener: function (element, context, event, changedFn) { | 
| +element.addEventListener(event, function (e) { | 
| +return context._notifyListener(changedFn, e); | 
| +}); | 
| +} | 
| +};Polymer.Base.extend(Polymer.Bind, { | 
| +_shouldAddListener: function (effect) { | 
| +return effect.name && effect.kind != 'attribute' && effect.kind != 'text' && !effect.isCompound && effect.parts[0].mode === '{'; | 
| +}, | 
| +_annotationEffect: function (source, value, effect) { | 
| +if (source != effect.value) { | 
| +value = this._get(effect.value); | 
| +this.__data__[effect.value] = value; | 
| +} | 
| +this._applyEffectValue(effect, value); | 
| +}, | 
| +_reflectEffect: function (source, value, effect) { | 
| +this.reflectPropertyToAttribute(source, effect.attribute, value); | 
| +}, | 
| +_notifyEffect: function (source, value, effect, old, fromAbove) { | 
| +if (!fromAbove) { | 
| +this._notifyChange(source, effect.event, value); | 
| +} | 
| +}, | 
| +_functionEffect: function (source, value, fn, old, fromAbove) { | 
| +fn.call(this, source, value, old, fromAbove); | 
| +}, | 
| +_observerEffect: function (source, value, effect, old) { | 
| +var fn = this[effect.method]; | 
| +if (fn) { | 
| +fn.call(this, value, old); | 
| +} else { | 
| +this._warn(this._logf('_observerEffect', 'observer method `' + effect.method + '` not defined')); | 
| +} | 
| +}, | 
| +_complexObserverEffect: function (source, value, effect) { | 
| +var fn = this[effect.method]; | 
| +if (fn) { | 
| +var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); | 
| +if (args) { | 
| +fn.apply(this, args); | 
| +} | 
| +} else if (effect.dynamicFn) { | 
| +} else { | 
| +this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.method + '` not defined')); | 
| +} | 
| +}, | 
| +_computeEffect: function (source, value, effect) { | 
| +var fn = this[effect.method]; | 
| +if (fn) { | 
| +var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); | 
| +if (args) { | 
| +var computedvalue = fn.apply(this, args); | 
| +this.__setProperty(effect.name, computedvalue); | 
| +} | 
| +} else if (effect.dynamicFn) { | 
| +} else { | 
| +this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined')); | 
| +} | 
| +}, | 
| +_annotatedComputationEffect: function (source, value, effect) { | 
| +var computedHost = this._rootDataHost || this; | 
| +var fn = computedHost[effect.method]; | 
| +if (fn) { | 
| +var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value); | 
| +if (args) { | 
| +var computedvalue = fn.apply(computedHost, args); | 
| +this._applyEffectValue(effect, computedvalue); | 
| +} | 
| +} else if (effect.dynamicFn) { | 
| +} else { | 
| +computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute method `' + effect.method + '` not defined')); | 
| +} | 
| +}, | 
| +_marshalArgs: function (model, effect, path, value) { | 
| +var values = []; | 
| +var args = effect.args; | 
| +var bailoutEarly = args.length > 1 || effect.dynamicFn; | 
| +for (var i = 0, l = args.length; i < l; i++) { | 
| +var arg = args[i]; | 
| +var name = arg.name; | 
| +var v; | 
| +if (arg.literal) { | 
| +v = arg.value; | 
| +} else if (path === name) { | 
| +v = value; | 
| +} else { | 
| +v = model[name]; | 
| +if (v === undefined && arg.structured) { | 
| +v = Polymer.Base._get(name, model); | 
| +} | 
| +} | 
| +if (bailoutEarly && v === undefined) { | 
| +return; | 
| +} | 
| +if (arg.wildcard) { | 
| +var matches = path.indexOf(name + '.') === 0; | 
| +values[i] = { | 
| +path: matches ? path : name, | 
| +value: matches ? value : v, | 
| +base: v | 
| +}; | 
| +} else { | 
| +values[i] = v; | 
| +} | 
| +} | 
| +return values; | 
| +} | 
| +});Polymer.Base._addFeature({ | 
| +_addPropertyEffect: function (property, kind, effect) { | 
| +var prop = Polymer.Bind.addPropertyEffect(this, property, kind, effect); | 
| +prop.pathFn = this['_' + prop.kind + 'PathEffect']; | 
| +}, | 
| +_prepEffects: function () { | 
| +Polymer.Bind.prepareModel(this); | 
| +this._addAnnotationEffects(this._notes); | 
| +}, | 
| +_prepBindings: function () { | 
| +Polymer.Bind.createBindings(this); | 
| +}, | 
| +_addPropertyEffects: function (properties) { | 
| +if (properties) { | 
| +for (var p in properties) { | 
| +var prop = properties[p]; | 
| +if (prop.observer) { | 
| +this._addObserverEffect(p, prop.observer); | 
| +} | 
| +if (prop.computed) { | 
| +prop.readOnly = true; | 
| +this._addComputedEffect(p, prop.computed); | 
| +} | 
| +if (prop.notify) { | 
| +this._addPropertyEffect(p, 'notify', { event: Polymer.CaseMap.camelToDashCase(p) + '-changed' }); | 
| +} | 
| +if (prop.reflectToAttribute) { | 
| +var attr = Polymer.CaseMap.camelToDashCase(p); | 
| +if (attr[0] === '-') { | 
| +this._warn(this._logf('_addPropertyEffects', 'Property ' + p + ' cannot be reflected to attribute ' + attr + ' because "-" is not a valid starting attribute name. Use a lowercase first letter for the property instead.')); | 
| +} else { | 
| +this._addPropertyEffect(p, 'reflect', { attribute: attr }); | 
| +} | 
| +} | 
| +if (prop.readOnly) { | 
| +Polymer.Bind.ensurePropertyEffects(this, p); | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_addComputedEffect: function (name, expression) { | 
| +var sig = this._parseMethod(expression); | 
| +var dynamicFn = sig.dynamicFn; | 
| +for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) { | 
| +this._addPropertyEffect(arg.model, 'compute', { | 
| +method: sig.method, | 
| +args: sig.args, | 
| +trigger: arg, | 
| +name: name, | 
| +dynamicFn: dynamicFn | 
| +}); | 
| +} | 
| +if (dynamicFn) { | 
| +this._addPropertyEffect(sig.method, 'compute', { | 
| +method: sig.method, | 
| +args: sig.args, | 
| +trigger: null, | 
| +name: name, | 
| +dynamicFn: dynamicFn | 
| +}); | 
| +} | 
| +}, | 
| +_addObserverEffect: function (property, observer) { | 
| +this._addPropertyEffect(property, 'observer', { | 
| +method: observer, | 
| +property: property | 
| +}); | 
| +}, | 
| +_addComplexObserverEffects: function (observers) { | 
| +if (observers) { | 
| +for (var i = 0, o; i < observers.length && (o = observers[i]); i++) { | 
| +this._addComplexObserverEffect(o); | 
| +} | 
| +} | 
| +}, | 
| +_addComplexObserverEffect: function (observer) { | 
| +var sig = this._parseMethod(observer); | 
| +if (!sig) { | 
| +throw new Error('Malformed observer expression \'' + observer + '\''); | 
| +} | 
| +var dynamicFn = sig.dynamicFn; | 
| +for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) { | 
| +this._addPropertyEffect(arg.model, 'complexObserver', { | 
| +method: sig.method, | 
| +args: sig.args, | 
| +trigger: arg, | 
| +dynamicFn: dynamicFn | 
| +}); | 
| +} | 
| +if (dynamicFn) { | 
| +this._addPropertyEffect(sig.method, 'complexObserver', { | 
| +method: sig.method, | 
| +args: sig.args, | 
| +trigger: null, | 
| +dynamicFn: dynamicFn | 
| +}); | 
| +} | 
| +}, | 
| +_addAnnotationEffects: function (notes) { | 
| +for (var i = 0, note; i < notes.length && (note = notes[i]); i++) { | 
| +var b$ = note.bindings; | 
| +for (var j = 0, binding; j < b$.length && (binding = b$[j]); j++) { | 
| +this._addAnnotationEffect(binding, i); | 
| +} | 
| +} | 
| +}, | 
| +_addAnnotationEffect: function (note, index) { | 
| +if (Polymer.Bind._shouldAddListener(note)) { | 
| +Polymer.Bind._addAnnotatedListener(this, index, note.name, note.parts[0].value, note.parts[0].event, note.parts[0].negate); | 
| +} | 
| +for (var i = 0; i < note.parts.length; i++) { | 
| +var part = note.parts[i]; | 
| +if (part.signature) { | 
| +this._addAnnotatedComputationEffect(note, part, index); | 
| +} else if (!part.literal) { | 
| +if (note.kind === 'attribute' && note.name[0] === '-') { | 
| +this._warn(this._logf('_addAnnotationEffect', 'Cannot set attribute ' + note.name + ' because "-" is not a valid attribute starting character')); | 
| +} else { | 
| +this._addPropertyEffect(part.model, 'annotation', { | 
| +kind: note.kind, | 
| +index: index, | 
| +name: note.name, | 
| +propertyName: note.propertyName, | 
| +value: part.value, | 
| +isCompound: note.isCompound, | 
| +compoundIndex: part.compoundIndex, | 
| +event: part.event, | 
| +customEvent: part.customEvent, | 
| +negate: part.negate | 
| +}); | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_addAnnotatedComputationEffect: function (note, part, index) { | 
| +var sig = part.signature; | 
| +if (sig.static) { | 
| +this.__addAnnotatedComputationEffect('__static__', index, note, part, null); | 
| +} else { | 
| +for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) { | 
| +if (!arg.literal) { | 
| +this.__addAnnotatedComputationEffect(arg.model, index, note, part, arg); | 
| +} | 
| +} | 
| +if (sig.dynamicFn) { | 
| +this.__addAnnotatedComputationEffect(sig.method, index, note, part, null); | 
| +} | 
| +} | 
| +}, | 
| +__addAnnotatedComputationEffect: function (property, index, note, part, trigger) { | 
| +this._addPropertyEffect(property, 'annotatedComputation', { | 
| +index: index, | 
| +isCompound: note.isCompound, | 
| +compoundIndex: part.compoundIndex, | 
| +kind: note.kind, | 
| +name: note.name, | 
| +negate: part.negate, | 
| +method: part.signature.method, | 
| +args: part.signature.args, | 
| +trigger: trigger, | 
| +dynamicFn: part.signature.dynamicFn | 
| +}); | 
| +}, | 
| +_parseMethod: function (expression) { | 
| +var m = expression.match(/([^\s]+?)\(([\s\S]*)\)/); | 
| +if (m) { | 
| +var sig = { | 
| +method: m[1], | 
| +static: true | 
| +}; | 
| +if (this.getPropertyInfo(sig.method) !== Polymer.nob) { | 
| +sig.static = false; | 
| +sig.dynamicFn = true; | 
| +} | 
| +if (m[2].trim()) { | 
| +var args = m[2].replace(/\\,/g, ',').split(','); | 
| +return this._parseArgs(args, sig); | 
| +} else { | 
| +sig.args = Polymer.nar; | 
| +return sig; | 
| +} | 
| +} | 
| +}, | 
| +_parseArgs: function (argList, sig) { | 
| +sig.args = argList.map(function (rawArg) { | 
| +var arg = this._parseArg(rawArg); | 
| +if (!arg.literal) { | 
| +sig.static = false; | 
| +} | 
| +return arg; | 
| +}, this); | 
| +return sig; | 
| +}, | 
| +_parseArg: function (rawArg) { | 
| +var arg = rawArg.trim().replace(/,/g, ',').replace(/\\(.)/g, '$1'); | 
| +var a = { name: arg }; | 
| +var fc = arg[0]; | 
| +if (fc === '-') { | 
| +fc = arg[1]; | 
| +} | 
| +if (fc >= '0' && fc <= '9') { | 
| +fc = '#'; | 
| +} | 
| +switch (fc) { | 
| +case '\'': | 
| +case '"': | 
| +a.value = arg.slice(1, -1); | 
| +a.literal = true; | 
| +break; | 
| +case '#': | 
| +a.value = Number(arg); | 
| +a.literal = true; | 
| +break; | 
| +} | 
| +if (!a.literal) { | 
| +a.model = this._modelForPath(arg); | 
| +a.structured = arg.indexOf('.') > 0; | 
| +if (a.structured) { | 
| +a.wildcard = arg.slice(-2) == '.*'; | 
| +if (a.wildcard) { | 
| +a.name = arg.slice(0, -2); | 
| +} | 
| +} | 
| +} | 
| +return a; | 
| +}, | 
| +_marshalInstanceEffects: function () { | 
| +Polymer.Bind.prepareInstance(this); | 
| +if (this._bindListeners) { | 
| +Polymer.Bind.setupBindListeners(this); | 
| +} | 
| +}, | 
| +_applyEffectValue: function (info, value) { | 
| +var node = this._nodes[info.index]; | 
| +var property = info.name; | 
| +value = this._computeFinalAnnotationValue(node, property, value, info); | 
| +if (info.customEvent && node[property] === value) { | 
| +return; | 
| +} | 
| +if (info.kind == 'attribute') { | 
| +this.serializeValueToAttribute(value, property, node); | 
| +} else { | 
| +var pinfo = node._propertyInfo && node._propertyInfo[property]; | 
| +if (pinfo && pinfo.readOnly) { | 
| +return; | 
| +} | 
| +this.__setProperty(property, value, false, node); | 
| +} | 
| +}, | 
| +_computeFinalAnnotationValue: function (node, property, value, info) { | 
| +if (info.negate) { | 
| +value = !value; | 
| +} | 
| +if (info.isCompound) { | 
| +var storage = node.__compoundStorage__[property]; | 
| +storage[info.compoundIndex] = value; | 
| +value = storage.join(''); | 
| +} | 
| +if (info.kind !== 'attribute') { | 
| +if (property === 'className') { | 
| +value = this._scopeElementClass(node, value); | 
| +} | 
| +if (property === 'textContent' || node.localName == 'input' && property == 'value') { | 
| +value = value == undefined ? '' : value; | 
| +} | 
| +} | 
| +return value; | 
| +}, | 
| +_executeStaticEffects: function () { | 
| +if (this._propertyEffects && this._propertyEffects.__static__) { | 
| +this._effectEffects('__static__', null, this._propertyEffects.__static__); | 
| +} | 
| +} | 
| +});(function () { | 
| +var usePolyfillProto = Polymer.Settings.usePolyfillProto; | 
| +Polymer.Base._addFeature({ | 
| +_setupConfigure: function (initialConfig) { | 
| +this._config = {}; | 
| +this._handlers = []; | 
| +this._aboveConfig = null; | 
| +if (initialConfig) { | 
| +for (var i in initialConfig) { | 
| +if (initialConfig[i] !== undefined) { | 
| +this._config[i] = initialConfig[i]; | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_marshalAttributes: function () { | 
| +this._takeAttributesToModel(this._config); | 
| +}, | 
| +_attributeChangedImpl: function (name) { | 
| +var model = this._clientsReadied ? this : this._config; | 
| +this._setAttributeToProperty(model, name); | 
| +}, | 
| +_configValue: function (name, value) { | 
| +var info = this._propertyInfo[name]; | 
| +if (!info || !info.readOnly) { | 
| +this._config[name] = value; | 
| +} | 
| +}, | 
| +_beforeClientsReady: function () { | 
| +this._configure(); | 
| +}, | 
| +_configure: function () { | 
| +this._configureAnnotationReferences(); | 
| +this._aboveConfig = this.mixin({}, this._config); | 
| +var config = {}; | 
| +for (var i = 0; i < this.behaviors.length; i++) { | 
| +this._configureProperties(this.behaviors[i].properties, config); | 
| +} | 
| +this._configureProperties(this.properties, config); | 
| +this.mixin(config, this._aboveConfig); | 
| +this._config = config; | 
| +if (this._clients && this._clients.length) { | 
| +this._distributeConfig(this._config); | 
| +} | 
| +}, | 
| +_configureProperties: function (properties, config) { | 
| +for (var i in properties) { | 
| +var c = properties[i]; | 
| +if (!usePolyfillProto && this.hasOwnProperty(i) && this._propertyEffects && this._propertyEffects[i]) { | 
| +config[i] = this[i]; | 
| +delete this[i]; | 
| +} else if (c.value !== undefined) { | 
| +var value = c.value; | 
| +if (typeof value == 'function') { | 
| +value = value.call(this, this._config); | 
| +} | 
| +config[i] = value; | 
| +} | 
| +} | 
| +}, | 
| +_distributeConfig: function (config) { | 
| +var fx$ = this._propertyEffects; | 
| +if (fx$) { | 
| +for (var p in config) { | 
| +var fx = fx$[p]; | 
| +if (fx) { | 
| +for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) { | 
| +if (x.kind === 'annotation') { | 
| +var node = this._nodes[x.effect.index]; | 
| +var name = x.effect.propertyName; | 
| +var isAttr = x.effect.kind == 'attribute'; | 
| +var hasEffect = node._propertyEffects && node._propertyEffects[name]; | 
| +if (node._configValue && (hasEffect || !isAttr)) { | 
| +var value = p === x.effect.value ? config[p] : this._get(x.effect.value, config); | 
| +value = this._computeFinalAnnotationValue(node, name, value, x.effect); | 
| +if (isAttr) { | 
| +value = node.deserialize(this.serialize(value), node._propertyInfo[name].type); | 
| +} | 
| +node._configValue(name, value); | 
| +} | 
| +} | 
| +} | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_afterClientsReady: function () { | 
| +this._executeStaticEffects(); | 
| +this._applyConfig(this._config, this._aboveConfig); | 
| +this._flushHandlers(); | 
| +}, | 
| +_applyConfig: function (config, aboveConfig) { | 
| +for (var n in config) { | 
| +if (this[n] === undefined) { | 
| +this.__setProperty(n, config[n], n in aboveConfig); | 
| +} | 
| +} | 
| +}, | 
| +_notifyListener: function (fn, e) { | 
| +if (!Polymer.Bind._isEventBogus(e, e.target)) { | 
| +var value, path; | 
| +if (e.detail) { | 
| +value = e.detail.value; | 
| +path = e.detail.path; | 
| +} | 
| +if (!this._clientsReadied) { | 
| +this._queueHandler([ | 
| +fn, | 
| +e.target, | 
| +value, | 
| +path | 
| +]); | 
| +} else { | 
| +return fn.call(this, e.target, value, path); | 
| +} | 
| +} | 
| +}, | 
| +_queueHandler: function (args) { | 
| +this._handlers.push(args); | 
| +}, | 
| +_flushHandlers: function () { | 
| +var h$ = this._handlers; | 
| +for (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) { | 
| +h[0].call(this, h[1], h[2], h[3]); | 
| +} | 
| +this._handlers = []; | 
| +} | 
| +}); | 
| +}());(function () { | 
| +'use strict'; | 
| +Polymer.Base._addFeature({ | 
| +notifyPath: function (path, value, fromAbove) { | 
| +var info = {}; | 
| +var v = this._get(path, this, info); | 
| +if (arguments.length === 1) { | 
| +value = v; | 
| +} | 
| +if (info.path) { | 
| +this._notifyPath(info.path, value, fromAbove); | 
| +} | 
| +}, | 
| +_notifyPath: function (path, value, fromAbove) { | 
| +var old = this._propertySetter(path, value); | 
| +if (old !== value && (old === old || value === value)) { | 
| +this._pathEffector(path, value); | 
| +if (!fromAbove) { | 
| +this._notifyPathUp(path, value); | 
| +} | 
| +return true; | 
| +} | 
| +}, | 
| +_getPathParts: function (path) { | 
| +if (Array.isArray(path)) { | 
| +var parts = []; | 
| +for (var i = 0; i < path.length; i++) { | 
| +var args = path[i].toString().split('.'); | 
| +for (var j = 0; j < args.length; j++) { | 
| +parts.push(args[j]); | 
| +} | 
| +} | 
| +return parts; | 
| +} else { | 
| +return path.toString().split('.'); | 
| +} | 
| +}, | 
| +set: function (path, value, root) { | 
| +var prop = root || this; | 
| +var parts = this._getPathParts(path); | 
| +var array; | 
| +var last = parts[parts.length - 1]; | 
| +if (parts.length > 1) { | 
| +for (var i = 0; i < parts.length - 1; i++) { | 
| +var part = parts[i]; | 
| +if (array && part[0] == '#') { | 
| +prop = Polymer.Collection.get(array).getItem(part); | 
| +} else { | 
| +prop = prop[part]; | 
| +if (array && parseInt(part, 10) == part) { | 
| +parts[i] = Polymer.Collection.get(array).getKey(prop); | 
| +} | 
| +} | 
| +if (!prop) { | 
| +return; | 
| +} | 
| +array = Array.isArray(prop) ? prop : null; | 
| +} | 
| +if (array) { | 
| +var coll = Polymer.Collection.get(array); | 
| +var old, key; | 
| +if (last[0] == '#') { | 
| +key = last; | 
| +old = coll.getItem(key); | 
| +last = array.indexOf(old); | 
| +coll.setItem(key, value); | 
| +} else if (parseInt(last, 10) == last) { | 
| +old = prop[last]; | 
| +key = coll.getKey(old); | 
| +parts[i] = key; | 
| +coll.setItem(key, value); | 
| +} | 
| +} | 
| +prop[last] = value; | 
| +if (!root) { | 
| +this._notifyPath(parts.join('.'), value); | 
| +} | 
| +} else { | 
| +prop[path] = value; | 
| +} | 
| +}, | 
| +get: function (path, root) { | 
| +return this._get(path, root); | 
| +}, | 
| +_get: function (path, root, info) { | 
| +var prop = root || this; | 
| +var parts = this._getPathParts(path); | 
| +var array; | 
| +for (var i = 0; i < parts.length; i++) { | 
| +if (!prop) { | 
| +return; | 
| +} | 
| +var part = parts[i]; | 
| +if (array && part[0] == '#') { | 
| +prop = Polymer.Collection.get(array).getItem(part); | 
| +} else { | 
| +prop = prop[part]; | 
| +if (info && array && parseInt(part, 10) == part) { | 
| +parts[i] = Polymer.Collection.get(array).getKey(prop); | 
| +} | 
| +} | 
| +array = Array.isArray(prop) ? prop : null; | 
| +} | 
| +if (info) { | 
| +info.path = parts.join('.'); | 
| +} | 
| +return prop; | 
| +}, | 
| +_pathEffector: function (path, value) { | 
| +var model = this._modelForPath(path); | 
| +var fx$ = this._propertyEffects && this._propertyEffects[model]; | 
| +if (fx$) { | 
| +for (var i = 0, fx; i < fx$.length && (fx = fx$[i]); i++) { | 
| +var fxFn = fx.pathFn; | 
| +if (fxFn) { | 
| +fxFn.call(this, path, value, fx.effect); | 
| +} | 
| +} | 
| +} | 
| +if (this._boundPaths) { | 
| +this._notifyBoundPaths(path, value); | 
| +} | 
| +}, | 
| +_annotationPathEffect: function (path, value, effect) { | 
| +if (effect.value === path || effect.value.indexOf(path + '.') === 0) { | 
| +Polymer.Bind._annotationEffect.call(this, path, value, effect); | 
| +} else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) { | 
| +var node = this._nodes[effect.index]; | 
| +if (node && node._notifyPath) { | 
| +var p = this._fixPath(effect.name, effect.value, path); | 
| +node._notifyPath(p, value, true); | 
| +} | 
| +} | 
| +}, | 
| +_complexObserverPathEffect: function (path, value, effect) { | 
| +if (this._pathMatchesEffect(path, effect)) { | 
| +Polymer.Bind._complexObserverEffect.call(this, path, value, effect); | 
| +} | 
| +}, | 
| +_computePathEffect: function (path, value, effect) { | 
| +if (this._pathMatchesEffect(path, effect)) { | 
| +Polymer.Bind._computeEffect.call(this, path, value, effect); | 
| +} | 
| +}, | 
| +_annotatedComputationPathEffect: function (path, value, effect) { | 
| +if (this._pathMatchesEffect(path, effect)) { | 
| +Polymer.Bind._annotatedComputationEffect.call(this, path, value, effect); | 
| +} | 
| +}, | 
| +_pathMatchesEffect: function (path, effect) { | 
| +var effectArg = effect.trigger.name; | 
| +return effectArg == path || effectArg.indexOf(path + '.') === 0 || effect.trigger.wildcard && path.indexOf(effectArg + '.') === 0; | 
| +}, | 
| +linkPaths: function (to, from) { | 
| +this._boundPaths = this._boundPaths || {}; | 
| +if (from) { | 
| +this._boundPaths[to] = from; | 
| +} else { | 
| +this.unlinkPaths(to); | 
| +} | 
| +}, | 
| +unlinkPaths: function (path) { | 
| +if (this._boundPaths) { | 
| +delete this._boundPaths[path]; | 
| +} | 
| +}, | 
| +_notifyBoundPaths: function (path, value) { | 
| +for (var a in this._boundPaths) { | 
| +var b = this._boundPaths[a]; | 
| +if (path.indexOf(a + '.') == 0) { | 
| +this._notifyPath(this._fixPath(b, a, path), value); | 
| +} else if (path.indexOf(b + '.') == 0) { | 
| +this._notifyPath(this._fixPath(a, b, path), value); | 
| +} | 
| +} | 
| +}, | 
| +_fixPath: function (property, root, path) { | 
| +return property + path.slice(root.length); | 
| +}, | 
| +_notifyPathUp: function (path, value) { | 
| +var rootName = this._modelForPath(path); | 
| +var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName); | 
| +var eventName = dashCaseName + this._EVENT_CHANGED; | 
| +this.fire(eventName, { | 
| +path: path, | 
| +value: value | 
| +}, { | 
| +bubbles: false, | 
| +_useCache: true | 
| +}); | 
| +}, | 
| +_modelForPath: function (path) { | 
| +var dot = path.indexOf('.'); | 
| +return dot < 0 ? path : path.slice(0, dot); | 
| +}, | 
| +_EVENT_CHANGED: '-changed', | 
| +notifySplices: function (path, splices) { | 
| +var info = {}; | 
| +var array = this._get(path, this, info); | 
| +this._notifySplices(array, info.path, splices); | 
| +}, | 
| +_notifySplices: function (array, path, splices) { | 
| +var change = { | 
| +keySplices: Polymer.Collection.applySplices(array, splices), | 
| +indexSplices: splices | 
| +}; | 
| +var splicesPath = path + '.splices'; | 
| +this._notifyPath(splicesPath, change); | 
| +this._notifyPath(path + '.length', array.length); | 
| +this.__data__[splicesPath] = { | 
| +keySplices: null, | 
| +indexSplices: null | 
| +}; | 
| +}, | 
| +_notifySplice: function (array, path, index, added, removed) { | 
| +this._notifySplices(array, path, [{ | 
| +index: index, | 
| +addedCount: added, | 
| +removed: removed, | 
| +object: array, | 
| +type: 'splice' | 
| +}]); | 
| +}, | 
| +push: function (path) { | 
| +var info = {}; | 
| +var array = this._get(path, this, info); | 
| +var args = Array.prototype.slice.call(arguments, 1); | 
| +var len = array.length; | 
| +var ret = array.push.apply(array, args); | 
| +if (args.length) { | 
| +this._notifySplice(array, info.path, len, args.length, []); | 
| +} | 
| +return ret; | 
| +}, | 
| +pop: function (path) { | 
| +var info = {}; | 
| +var array = this._get(path, this, info); | 
| +var hadLength = Boolean(array.length); | 
| +var args = Array.prototype.slice.call(arguments, 1); | 
| +var ret = array.pop.apply(array, args); | 
| +if (hadLength) { | 
| +this._notifySplice(array, info.path, array.length, 0, [ret]); | 
| +} | 
| +return ret; | 
| +}, | 
| +splice: function (path, start) { | 
| +var info = {}; | 
| +var array = this._get(path, this, info); | 
| +if (start < 0) { | 
| +start = array.length - Math.floor(-start); | 
| +} else { | 
| +start = Math.floor(start); | 
| +} | 
| +if (!start) { | 
| +start = 0; | 
| +} | 
| +var args = Array.prototype.slice.call(arguments, 1); | 
| +var ret = array.splice.apply(array, args); | 
| +var addedCount = Math.max(args.length - 2, 0); | 
| +if (addedCount || ret.length) { | 
| +this._notifySplice(array, info.path, start, addedCount, ret); | 
| +} | 
| +return ret; | 
| +}, | 
| +shift: function (path) { | 
| +var info = {}; | 
| +var array = this._get(path, this, info); | 
| +var hadLength = Boolean(array.length); | 
| +var args = Array.prototype.slice.call(arguments, 1); | 
| +var ret = array.shift.apply(array, args); | 
| +if (hadLength) { | 
| +this._notifySplice(array, info.path, 0, 0, [ret]); | 
| +} | 
| +return ret; | 
| +}, | 
| +unshift: function (path) { | 
| +var info = {}; | 
| +var array = this._get(path, this, info); | 
| +var args = Array.prototype.slice.call(arguments, 1); | 
| +var ret = array.unshift.apply(array, args); | 
| +if (args.length) { | 
| +this._notifySplice(array, info.path, 0, args.length, []); | 
| +} | 
| +return ret; | 
| +}, | 
| +prepareModelNotifyPath: function (model) { | 
| +this.mixin(model, { | 
| +fire: Polymer.Base.fire, | 
| +_getEvent: Polymer.Base._getEvent, | 
| +__eventCache: Polymer.Base.__eventCache, | 
| +notifyPath: Polymer.Base.notifyPath, | 
| +_get: Polymer.Base._get, | 
| +_EVENT_CHANGED: Polymer.Base._EVENT_CHANGED, | 
| +_notifyPath: Polymer.Base._notifyPath, | 
| +_notifyPathUp: Polymer.Base._notifyPathUp, | 
| +_pathEffector: Polymer.Base._pathEffector, | 
| +_annotationPathEffect: Polymer.Base._annotationPathEffect, | 
| +_complexObserverPathEffect: Polymer.Base._complexObserverPathEffect, | 
| +_annotatedComputationPathEffect: Polymer.Base._annotatedComputationPathEffect, | 
| +_computePathEffect: Polymer.Base._computePathEffect, | 
| +_modelForPath: Polymer.Base._modelForPath, | 
| +_pathMatchesEffect: Polymer.Base._pathMatchesEffect, | 
| +_notifyBoundPaths: Polymer.Base._notifyBoundPaths, | 
| +_getPathParts: Polymer.Base._getPathParts | 
| +}); | 
| +} | 
| +}); | 
| +}());Polymer.Base._addFeature({ | 
| +resolveUrl: function (url) { | 
| +var module = Polymer.DomModule.import(this.is); | 
| +var root = ''; | 
| +if (module) { | 
| +var assetPath = module.getAttribute('assetpath') || ''; | 
| +root = Polymer.ResolveUrl.resolveUrl(assetPath, module.ownerDocument.baseURI); | 
| +} | 
| +return Polymer.ResolveUrl.resolveUrl(url, root); | 
| +} | 
| +});Polymer.CssParse = function () { | 
| +return { | 
| +parse: function (text) { | 
| +text = this._clean(text); | 
| +return this._parseCss(this._lex(text), text); | 
| +}, | 
| +_clean: function (cssText) { | 
| +return cssText.replace(this._rx.comments, '').replace(this._rx.port, ''); | 
| +}, | 
| +_lex: function (text) { | 
| +var root = { | 
| +start: 0, | 
| +end: text.length | 
| +}; | 
| +var n = root; | 
| +for (var i = 0, l = text.length; i < l; i++) { | 
| +switch (text[i]) { | 
| +case this.OPEN_BRACE: | 
| +if (!n.rules) { | 
| +n.rules = []; | 
| +} | 
| +var p = n; | 
| +var previous = p.rules[p.rules.length - 1]; | 
| +n = { | 
| +start: i + 1, | 
| +parent: p, | 
| +previous: previous | 
| +}; | 
| +p.rules.push(n); | 
| +break; | 
| +case this.CLOSE_BRACE: | 
| +n.end = i + 1; | 
| +n = n.parent || root; | 
| +break; | 
| +} | 
| +} | 
| +return root; | 
| +}, | 
| +_parseCss: function (node, text) { | 
| +var t = text.substring(node.start, node.end - 1); | 
| +node.parsedCssText = node.cssText = t.trim(); | 
| +if (node.parent) { | 
| +var ss = node.previous ? node.previous.end : node.parent.start; | 
| +t = text.substring(ss, node.start - 1); | 
| +t = this._expandUnicodeEscapes(t); | 
| +t = t.replace(this._rx.multipleSpaces, ' '); | 
| +t = t.substring(t.lastIndexOf(';') + 1); | 
| +var s = node.parsedSelector = node.selector = t.trim(); | 
| +node.atRule = s.indexOf(this.AT_START) === 0; | 
| +if (node.atRule) { | 
| +if (s.indexOf(this.MEDIA_START) === 0) { | 
| +node.type = this.types.MEDIA_RULE; | 
| +} else if (s.match(this._rx.keyframesRule)) { | 
| +node.type = this.types.KEYFRAMES_RULE; | 
| +node.keyframesName = node.selector.split(this._rx.multipleSpaces).pop(); | 
| +} | 
| +} else { | 
| +if (s.indexOf(this.VAR_START) === 0) { | 
| +node.type = this.types.MIXIN_RULE; | 
| +} else { | 
| +node.type = this.types.STYLE_RULE; | 
| +} | 
| +} | 
| +} | 
| +var r$ = node.rules; | 
| +if (r$) { | 
| +for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) { | 
| +this._parseCss(r, text); | 
| +} | 
| +} | 
| +return node; | 
| +}, | 
| +_expandUnicodeEscapes: function (s) { | 
| +return s.replace(/\\([0-9a-f]{1,6})\s/gi, function () { | 
| +var code = arguments[1], repeat = 6 - code.length; | 
| +while (repeat--) { | 
| +code = '0' + code; | 
| +} | 
| +return '\\' + code; | 
| +}); | 
| +}, | 
| +stringify: function (node, preserveProperties, text) { | 
| +text = text || ''; | 
| +var cssText = ''; | 
| +if (node.cssText || node.rules) { | 
| +var r$ = node.rules; | 
| +if (r$ && !this._hasMixinRules(r$)) { | 
| +for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) { | 
| +cssText = this.stringify(r, preserveProperties, cssText); | 
| +} | 
| +} else { | 
| +cssText = preserveProperties ? node.cssText : this.removeCustomProps(node.cssText); | 
| +cssText = cssText.trim(); | 
| +if (cssText) { | 
| +cssText = '  ' + cssText + '\n'; | 
| +} | 
| +} | 
| +} | 
| +if (cssText) { | 
| +if (node.selector) { | 
| +text += node.selector + ' ' + this.OPEN_BRACE + '\n'; | 
| +} | 
| +text += cssText; | 
| +if (node.selector) { | 
| +text += this.CLOSE_BRACE + '\n\n'; | 
| +} | 
| +} | 
| +return text; | 
| +}, | 
| +_hasMixinRules: function (rules) { | 
| +return rules[0].selector.indexOf(this.VAR_START) === 0; | 
| +}, | 
| +removeCustomProps: function (cssText) { | 
| +cssText = this.removeCustomPropAssignment(cssText); | 
| +return this.removeCustomPropApply(cssText); | 
| +}, | 
| +removeCustomPropAssignment: function (cssText) { | 
| +return cssText.replace(this._rx.customProp, '').replace(this._rx.mixinProp, ''); | 
| +}, | 
| +removeCustomPropApply: function (cssText) { | 
| +return cssText.replace(this._rx.mixinApply, '').replace(this._rx.varApply, ''); | 
| +}, | 
| +types: { | 
| +STYLE_RULE: 1, | 
| +KEYFRAMES_RULE: 7, | 
| +MEDIA_RULE: 4, | 
| +MIXIN_RULE: 1000 | 
| +}, | 
| +OPEN_BRACE: '{', | 
| +CLOSE_BRACE: '}', | 
| +_rx: { | 
| +comments: /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim, | 
| +port: /@import[^;]*;/gim, | 
| +customProp: /(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\n]|$)/gim, | 
| +mixinProp: /(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\n]|$)?/gim, | 
| +mixinApply: /@apply\s*\(?[^);]*\)?\s*(?:[;\n]|$)?/gim, | 
| +varApply: /[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim, | 
| +keyframesRule: /^@[^\s]*keyframes/, | 
| +multipleSpaces: /\s+/g | 
| +}, | 
| +VAR_START: '--', | 
| +MEDIA_START: '@media', | 
| +AT_START: '@' | 
| +}; | 
| +}();Polymer.StyleUtil = function () { | 
| +var settings = Polymer.Settings; | 
| +return { | 
| +NATIVE_VARIABLES: Polymer.Settings.useNativeCSSProperties, | 
| +MODULE_STYLES_SELECTOR: 'style, link[rel=import][type~=css], template', | 
| +INCLUDE_ATTR: 'include', | 
| +toCssText: function (rules, callback) { | 
| +if (typeof rules === 'string') { | 
| +rules = this.parser.parse(rules); | 
| +} | 
| +if (callback) { | 
| +this.forEachRule(rules, callback); | 
| +} | 
| +return this.parser.stringify(rules, this.NATIVE_VARIABLES); | 
| +}, | 
| +forRulesInStyles: function (styles, styleRuleCallback, keyframesRuleCallback) { | 
| +if (styles) { | 
| +for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) { | 
| +this.forEachRuleInStyle(s, styleRuleCallback, keyframesRuleCallback); | 
| +} | 
| +} | 
| +}, | 
| +forActiveRulesInStyles: function (styles, styleRuleCallback, keyframesRuleCallback) { | 
| +if (styles) { | 
| +for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) { | 
| +this.forEachRuleInStyle(s, styleRuleCallback, keyframesRuleCallback, true); | 
| +} | 
| +} | 
| +}, | 
| +rulesForStyle: function (style) { | 
| +if (!style.__cssRules && style.textContent) { | 
| +style.__cssRules = this.parser.parse(style.textContent); | 
| +} | 
| +return style.__cssRules; | 
| +}, | 
| +isKeyframesSelector: function (rule) { | 
| +return rule.parent && rule.parent.type === this.ruleTypes.KEYFRAMES_RULE; | 
| +}, | 
| +forEachRuleInStyle: function (style, styleRuleCallback, keyframesRuleCallback, onlyActiveRules) { | 
| +var rules = this.rulesForStyle(style); | 
| +var styleCallback, keyframeCallback; | 
| +if (styleRuleCallback) { | 
| +styleCallback = function (rule) { | 
| +styleRuleCallback(rule, style); | 
| +}; | 
| +} | 
| +if (keyframesRuleCallback) { | 
| +keyframeCallback = function (rule) { | 
| +keyframesRuleCallback(rule, style); | 
| +}; | 
| +} | 
| +this.forEachRule(rules, styleCallback, keyframeCallback, onlyActiveRules); | 
| +}, | 
| +forEachRule: function (node, styleRuleCallback, keyframesRuleCallback, onlyActiveRules) { | 
| +if (!node) { | 
| +return; | 
| +} | 
| +var skipRules = false; | 
| +if (onlyActiveRules) { | 
| +if (node.type === this.ruleTypes.MEDIA_RULE) { | 
| +var matchMedia = node.selector.match(this.rx.MEDIA_MATCH); | 
| +if (matchMedia) { | 
| +if (!window.matchMedia(matchMedia[1]).matches) { | 
| +skipRules = true; | 
| +} | 
| +} | 
| +} | 
| +} | 
| +if (node.type === this.ruleTypes.STYLE_RULE) { | 
| +styleRuleCallback(node); | 
| +} else if (keyframesRuleCallback && node.type === this.ruleTypes.KEYFRAMES_RULE) { | 
| +keyframesRuleCallback(node); | 
| +} else if (node.type === this.ruleTypes.MIXIN_RULE) { | 
| +skipRules = true; | 
| +} | 
| +var r$ = node.rules; | 
| +if (r$ && !skipRules) { | 
| +for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) { | 
| +this.forEachRule(r, styleRuleCallback, keyframesRuleCallback, onlyActiveRules); | 
| +} | 
| +} | 
| +}, | 
| +applyCss: function (cssText, moniker, target, contextNode) { | 
| +var style = this.createScopeStyle(cssText, moniker); | 
| +return this.applyStyle(style, target, contextNode); | 
| +}, | 
| +applyStyle: function (style, target, contextNode) { | 
| +target = target || document.head; | 
| +var after = contextNode && contextNode.nextSibling || target.firstChild; | 
| +this.__lastHeadApplyNode = style; | 
| +return target.insertBefore(style, after); | 
| +}, | 
| +createScopeStyle: function (cssText, moniker) { | 
| +var style = document.createElement('style'); | 
| +if (moniker) { | 
| +style.setAttribute('scope', moniker); | 
| +} | 
| +style.textContent = cssText; | 
| +return style; | 
| +}, | 
| +__lastHeadApplyNode: null, | 
| +applyStylePlaceHolder: function (moniker) { | 
| +var placeHolder = document.createComment(' Shady DOM styles for ' + moniker + ' '); | 
| +var after = this.__lastHeadApplyNode ? this.__lastHeadApplyNode.nextSibling : null; | 
| +var scope = document.head; | 
| +scope.insertBefore(placeHolder, after || scope.firstChild); | 
| +this.__lastHeadApplyNode = placeHolder; | 
| +return placeHolder; | 
| +}, | 
| +cssFromModules: function (moduleIds, warnIfNotFound) { | 
| +var modules = moduleIds.trim().split(' '); | 
| +var cssText = ''; | 
| +for (var i = 0; i < modules.length; i++) { | 
| +cssText += this.cssFromModule(modules[i], warnIfNotFound); | 
| +} | 
| +return cssText; | 
| +}, | 
| +cssFromModule: function (moduleId, warnIfNotFound) { | 
| +var m = Polymer.DomModule.import(moduleId); | 
| +if (m && !m._cssText) { | 
| +m._cssText = this.cssFromElement(m); | 
| +} | 
| +if (!m && warnIfNotFound) { | 
| +console.warn('Could not find style data in module named', moduleId); | 
| +} | 
| +return m && m._cssText || ''; | 
| +}, | 
| +cssFromElement: function (element) { | 
| +var cssText = ''; | 
| +var content = element.content || element; | 
| +var e$ = Polymer.TreeApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR)); | 
| +for (var i = 0, e; i < e$.length; i++) { | 
| +e = e$[i]; | 
| +if (e.localName === 'template') { | 
| +cssText += this.cssFromElement(e); | 
| +} else { | 
| +if (e.localName === 'style') { | 
| +var include = e.getAttribute(this.INCLUDE_ATTR); | 
| +if (include) { | 
| +cssText += this.cssFromModules(include, true); | 
| +} | 
| +e = e.__appliedElement || e; | 
| +e.parentNode.removeChild(e); | 
| +cssText += this.resolveCss(e.textContent, element.ownerDocument); | 
| +} else if (e.import && e.import.body) { | 
| +cssText += this.resolveCss(e.import.body.textContent, e.import); | 
| +} | 
| +} | 
| +} | 
| +return cssText; | 
| +}, | 
| +isTargetedBuild: function (buildType) { | 
| +return settings.useNativeShadow ? buildType === 'shadow' : buildType === 'shady'; | 
| +}, | 
| +cssBuildTypeForModule: function (module) { | 
| +var dm = Polymer.DomModule.import(module); | 
| +if (dm) { | 
| +return this.getCssBuildType(dm); | 
| +} | 
| +}, | 
| +getCssBuildType: function (element) { | 
| +return element.getAttribute('css-build'); | 
| +}, | 
| +rx: { | 
| +VAR_ASSIGN: /(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi, | 
| +MIXIN_MATCH: /(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi, | 
| +VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,()]*)|(?:[^;()]*\([^;)]*\)+))[\s]*?\)/gi, | 
| +VAR_CONSUMED: /(--[\w-]+)\s*([:,;)]|$)/gi, | 
| +ANIMATION_MATCH: /(animation\s*:)|(animation-name\s*:)/, | 
| +MEDIA_MATCH: /@media[^(]*(\([^)]*\))/, | 
| +IS_VAR: /^--/, | 
| +BRACKETED: /\{[^}]*\}/g, | 
| +HOST_PREFIX: '(?:^|[^.#[:])', | 
| +HOST_SUFFIX: '($|[.:[\\s>+~])' | 
| +}, | 
| +resolveCss: Polymer.ResolveUrl.resolveCss, | 
| +parser: Polymer.CssParse, | 
| +ruleTypes: Polymer.CssParse.types | 
| +}; | 
| +}();Polymer.StyleTransformer = function () { | 
| +var styleUtil = Polymer.StyleUtil; | 
| +var settings = Polymer.Settings; | 
| +var api = { | 
| +dom: function (node, scope, useAttr, shouldRemoveScope) { | 
| +this._transformDom(node, scope || '', useAttr, shouldRemoveScope); | 
| +}, | 
| +_transformDom: function (node, selector, useAttr, shouldRemoveScope) { | 
| +if (node.setAttribute) { | 
| +this.element(node, selector, useAttr, shouldRemoveScope); | 
| +} | 
| +var c$ = Polymer.dom(node).childNodes; | 
| +for (var i = 0; i < c$.length; i++) { | 
| +this._transformDom(c$[i], selector, useAttr, shouldRemoveScope); | 
| +} | 
| +}, | 
| +element: function (element, scope, useAttr, shouldRemoveScope) { | 
| +if (useAttr) { | 
| +if (shouldRemoveScope) { | 
| +element.removeAttribute(SCOPE_NAME); | 
| +} else { | 
| +element.setAttribute(SCOPE_NAME, scope); | 
| +} | 
| +} else { | 
| +if (scope) { | 
| +if (element.classList) { | 
| +if (shouldRemoveScope) { | 
| +element.classList.remove(SCOPE_NAME); | 
| +element.classList.remove(scope); | 
| +} else { | 
| +element.classList.add(SCOPE_NAME); | 
| +element.classList.add(scope); | 
| +} | 
| +} else if (element.getAttribute) { | 
| +var c = element.getAttribute(CLASS); | 
| +if (shouldRemoveScope) { | 
| +if (c) { | 
| +element.setAttribute(CLASS, c.replace(SCOPE_NAME, '').replace(scope, '')); | 
| +} | 
| +} else { | 
| +element.setAttribute(CLASS, (c ? c + ' ' : '') + SCOPE_NAME + ' ' + scope); | 
| +} | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +elementStyles: function (element, callback) { | 
| +var styles = element._styles; | 
| +var cssText = ''; | 
| +var cssBuildType = element.__cssBuild; | 
| +for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) { | 
| +var rules = styleUtil.rulesForStyle(s); | 
| +cssText += settings.useNativeShadow || cssBuildType === 'shady' ? styleUtil.toCssText(rules, callback) : this.css(rules, element.is, element.extends, callback, element._scopeCssViaAttr) + '\n\n'; | 
| +} | 
| +return cssText.trim(); | 
| +}, | 
| +css: function (rules, scope, ext, callback, useAttr) { | 
| +var hostScope = this._calcHostScope(scope, ext); | 
| +scope = this._calcElementScope(scope, useAttr); | 
| +var self = this; | 
| +return styleUtil.toCssText(rules, function (rule) { | 
| +if (!rule.isScoped) { | 
| +self.rule(rule, scope, hostScope); | 
| +rule.isScoped = true; | 
| +} | 
| +if (callback) { | 
| +callback(rule, scope, hostScope); | 
| +} | 
| +}); | 
| +}, | 
| +_calcElementScope: function (scope, useAttr) { | 
| +if (scope) { | 
| +return useAttr ? CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX : CSS_CLASS_PREFIX + scope; | 
| +} else { | 
| +return ''; | 
| +} | 
| +}, | 
| +_calcHostScope: function (scope, ext) { | 
| +return ext ? '[is=' + scope + ']' : scope; | 
| +}, | 
| +rule: function (rule, scope, hostScope) { | 
| +this._transformRule(rule, this._transformComplexSelector, scope, hostScope); | 
| +}, | 
| +_transformRule: function (rule, transformer, scope, hostScope) { | 
| +rule.selector = rule.transformedSelector = this._transformRuleCss(rule, transformer, scope, hostScope); | 
| +}, | 
| +_transformRuleCss: function (rule, transformer, scope, hostScope) { | 
| +var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP); | 
| +if (!styleUtil.isKeyframesSelector(rule)) { | 
| +for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) { | 
| +p$[i] = transformer.call(this, p, scope, hostScope); | 
| +} | 
| +} | 
| +return p$.join(COMPLEX_SELECTOR_SEP); | 
| +}, | 
| +_transformComplexSelector: function (selector, scope, hostScope) { | 
| +var stop = false; | 
| +var hostContext = false; | 
| +var self = this; | 
| +selector = selector.trim(); | 
| +selector = selector.replace(CONTENT_START, HOST + ' $1'); | 
| +selector = selector.replace(SIMPLE_SELECTOR_SEP, function (m, c, s) { | 
| +if (!stop) { | 
| +var info = self._transformCompoundSelector(s, c, scope, hostScope); | 
| +stop = stop || info.stop; | 
| +hostContext = hostContext || info.hostContext; | 
| +c = info.combinator; | 
| +s = info.value; | 
| +} else { | 
| +s = s.replace(SCOPE_JUMP, ' '); | 
| +} | 
| +return c + s; | 
| +}); | 
| +if (hostContext) { | 
| +selector = selector.replace(HOST_CONTEXT_PAREN, function (m, pre, paren, post) { | 
| +return pre + paren + ' ' + hostScope + post + COMPLEX_SELECTOR_SEP + ' ' + pre + hostScope + paren + post; | 
| +}); | 
| +} | 
| +return selector; | 
| +}, | 
| +_transformCompoundSelector: function (selector, combinator, scope, hostScope) { | 
| +var jumpIndex = selector.search(SCOPE_JUMP); | 
| +var hostContext = false; | 
| +if (selector.indexOf(HOST_CONTEXT) >= 0) { | 
| +hostContext = true; | 
| +} else if (selector.indexOf(HOST) >= 0) { | 
| +selector = this._transformHostSelector(selector, hostScope); | 
| +} else if (jumpIndex !== 0) { | 
| +selector = scope ? this._transformSimpleSelector(selector, scope) : selector; | 
| +} | 
| +if (selector.indexOf(CONTENT) >= 0) { | 
| +combinator = ''; | 
| +} | 
| +var stop; | 
| +if (jumpIndex >= 0) { | 
| +selector = selector.replace(SCOPE_JUMP, ' '); | 
| +stop = true; | 
| +} | 
| +return { | 
| +value: selector, | 
| +combinator: combinator, | 
| +stop: stop, | 
| +hostContext: hostContext | 
| +}; | 
| +}, | 
| +_transformSimpleSelector: function (selector, scope) { | 
| +var p$ = selector.split(PSEUDO_PREFIX); | 
| +p$[0] += scope; | 
| +return p$.join(PSEUDO_PREFIX); | 
| +}, | 
| +_transformHostSelector: function (selector, hostScope) { | 
| +var m = selector.match(HOST_PAREN); | 
| +var paren = m && m[2].trim() || ''; | 
| +if (paren) { | 
| +if (!paren[0].match(SIMPLE_SELECTOR_PREFIX)) { | 
| +var typeSelector = paren.split(SIMPLE_SELECTOR_PREFIX)[0]; | 
| +if (typeSelector === hostScope) { | 
| +return paren; | 
| +} else { | 
| +return SELECTOR_NO_MATCH; | 
| +} | 
| +} else { | 
| +return selector.replace(HOST_PAREN, function (m, host, paren) { | 
| +return hostScope + paren; | 
| +}); | 
| +} | 
| +} else { | 
| +return selector.replace(HOST, hostScope); | 
| +} | 
| +}, | 
| +documentRule: function (rule) { | 
| +rule.selector = rule.parsedSelector; | 
| +this.normalizeRootSelector(rule); | 
| +if (!settings.useNativeShadow) { | 
| +this._transformRule(rule, this._transformDocumentSelector); | 
| +} | 
| +}, | 
| +normalizeRootSelector: function (rule) { | 
| +if (rule.selector === ROOT) { | 
| +rule.selector = 'html'; | 
| +} | 
| +}, | 
| +_transformDocumentSelector: function (selector) { | 
| +return selector.match(SCOPE_JUMP) ? this._transformComplexSelector(selector, SCOPE_DOC_SELECTOR) : this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELECTOR); | 
| +}, | 
| +SCOPE_NAME: 'style-scope' | 
| +}; | 
| +var SCOPE_NAME = api.SCOPE_NAME; | 
| +var SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' + ':not(.' + SCOPE_NAME + ')'; | 
| +var COMPLEX_SELECTOR_SEP = ','; | 
| +var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)((?:\[.+?\]|[^\s>+~=\[])+)/g; | 
| +var SIMPLE_SELECTOR_PREFIX = /[[.:#*]/; | 
| +var HOST = ':host'; | 
| +var ROOT = ':root'; | 
| +var HOST_PAREN = /(:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/; | 
| +var HOST_CONTEXT = ':host-context'; | 
| +var HOST_CONTEXT_PAREN = /(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/; | 
| +var CONTENT = '::content'; | 
| +var SCOPE_JUMP = /::content|::shadow|\/deep\//; | 
| +var CSS_CLASS_PREFIX = '.'; | 
| +var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~='; | 
| +var CSS_ATTR_SUFFIX = ']'; | 
| +var PSEUDO_PREFIX = ':'; | 
| +var CLASS = 'class'; | 
| +var CONTENT_START = new RegExp('^(' + CONTENT + ')'); | 
| +var SELECTOR_NO_MATCH = 'should_not_match'; | 
| +return api; | 
| +}();Polymer.StyleExtends = function () { | 
| +var styleUtil = Polymer.StyleUtil; | 
| +return { | 
| +hasExtends: function (cssText) { | 
| +return Boolean(cssText.match(this.rx.EXTEND)); | 
| +}, | 
| +transform: function (style) { | 
| +var rules = styleUtil.rulesForStyle(style); | 
| +var self = this; | 
| +styleUtil.forEachRule(rules, function (rule) { | 
| +self._mapRuleOntoParent(rule); | 
| +if (rule.parent) { | 
| +var m; | 
| +while (m = self.rx.EXTEND.exec(rule.cssText)) { | 
| +var extend = m[1]; | 
| +var extendor = self._findExtendor(extend, rule); | 
| +if (extendor) { | 
| +self._extendRule(rule, extendor); | 
| +} | 
| +} | 
| +} | 
| +rule.cssText = rule.cssText.replace(self.rx.EXTEND, ''); | 
| +}); | 
| +return styleUtil.toCssText(rules, function (rule) { | 
| +if (rule.selector.match(self.rx.STRIP)) { | 
| +rule.cssText = ''; | 
| +} | 
| +}, true); | 
| +}, | 
| +_mapRuleOntoParent: function (rule) { | 
| +if (rule.parent) { | 
| +var map = rule.parent.map || (rule.parent.map = {}); | 
| +var parts = rule.selector.split(','); | 
| +for (var i = 0, p; i < parts.length; i++) { | 
| +p = parts[i]; | 
| +map[p.trim()] = rule; | 
| +} | 
| +return map; | 
| +} | 
| +}, | 
| +_findExtendor: function (extend, rule) { | 
| +return rule.parent && rule.parent.map && rule.parent.map[extend] || this._findExtendor(extend, rule.parent); | 
| +}, | 
| +_extendRule: function (target, source) { | 
| +if (target.parent !== source.parent) { | 
| +this._cloneAndAddRuleToParent(source, target.parent); | 
| +} | 
| +target.extends = target.extends || []; | 
| +target.extends.push(source); | 
| +source.selector = source.selector.replace(this.rx.STRIP, ''); | 
| +source.selector = (source.selector && source.selector + ',\n') + target.selector; | 
| +if (source.extends) { | 
| +source.extends.forEach(function (e) { | 
| +this._extendRule(target, e); | 
| +}, this); | 
| +} | 
| +}, | 
| +_cloneAndAddRuleToParent: function (rule, parent) { | 
| +rule = Object.create(rule); | 
| +rule.parent = parent; | 
| +if (rule.extends) { | 
| +rule.extends = rule.extends.slice(); | 
| +} | 
| +parent.rules.push(rule); | 
| +}, | 
| +rx: { | 
| +EXTEND: /@extends\(([^)]*)\)\s*?;/gim, | 
| +STRIP: /%[^,]*$/ | 
| +} | 
| +}; | 
| +}();Polymer.ApplyShim = function () { | 
| +'use strict'; | 
| +var styleUtil = Polymer.StyleUtil; | 
| +var MIXIN_MATCH = styleUtil.rx.MIXIN_MATCH; | 
| +var VAR_ASSIGN = styleUtil.rx.VAR_ASSIGN; | 
| +var VAR_MATCH = styleUtil.rx.VAR_MATCH; | 
| +var APPLY_NAME_CLEAN = /;\s*/m; | 
| +var MIXIN_VAR_SEP = '_-_'; | 
| +var mixinMap = {}; | 
| +function mapSet(name, prop) { | 
| +name = name.trim(); | 
| +mixinMap[name] = prop; | 
| +} | 
| +function mapGet(name) { | 
| +name = name.trim(); | 
| +return mixinMap[name]; | 
| +} | 
| +function cssTextToMap(text) { | 
| +var props = text.split(';'); | 
| +var out = {}; | 
| +for (var i = 0, p, sp; i < props.length; i++) { | 
| +p = props[i]; | 
| +if (p) { | 
| +sp = p.split(':'); | 
| +if (sp.length > 1) { | 
| +out[sp[0].trim()] = sp.slice(1).join(':'); | 
| +} | 
| +} | 
| +} | 
| +return out; | 
| +} | 
| +function produceCssProperties(matchText, propertyName, valueProperty, valueMixin) { | 
| +if (valueProperty) { | 
| +VAR_MATCH.lastIndex = 0; | 
| +var m = VAR_MATCH.exec(valueProperty); | 
| +if (m) { | 
| +var value = m[2]; | 
| +if (mapGet(value)) { | 
| +valueMixin = '@apply ' + value + ';'; | 
| +} | 
| +} | 
| +} | 
| +if (!valueMixin) { | 
| +return matchText; | 
| +} | 
| +var mixinAsProperties = consumeCssProperties(valueMixin); | 
| +var prefix = matchText.slice(0, matchText.indexOf('--')); | 
| +var mixinValues = cssTextToMap(mixinAsProperties); | 
| +var oldProperties = mapGet(propertyName); | 
| +var combinedProps = mixinValues; | 
| +if (oldProperties) { | 
| +combinedProps = Polymer.Base.mixin(oldProperties, mixinValues); | 
| +} else { | 
| +mapSet(propertyName, combinedProps); | 
| +} | 
| +var out = []; | 
| +var p, v; | 
| +for (p in combinedProps) { | 
| +v = mixinValues[p]; | 
| +if (v === undefined) { | 
| +v = 'initial'; | 
| +} | 
| +out.push(propertyName + MIXIN_VAR_SEP + p + ': ' + v); | 
| +} | 
| +return prefix + out.join('; ') + ';'; | 
| +} | 
| +function fixVars(matchText, prefix, value, fallback) { | 
| +if (!fallback || fallback.indexOf('--') !== 0) { | 
| +return matchText; | 
| +} | 
| +return [ | 
| +prefix, | 
| +'var(', | 
| +value, | 
| +', var(', | 
| +fallback, | 
| +'));' | 
| +].join(''); | 
| +} | 
| +function atApplyToCssProperties(mixinName, fallbacks) { | 
| +mixinName = mixinName.replace(APPLY_NAME_CLEAN, ''); | 
| +var vars = []; | 
| +var mixinProperties = mapGet(mixinName); | 
| +if (mixinProperties) { | 
| +var p, parts, f; | 
| +for (p in mixinProperties) { | 
| +f = fallbacks && fallbacks[p]; | 
| +parts = [ | 
| +p, | 
| +': var(', | 
| +mixinName, | 
| +MIXIN_VAR_SEP, | 
| +p | 
| +]; | 
| +if (f) { | 
| +parts.push(',', f); | 
| +} | 
| +parts.push(')'); | 
| +vars.push(parts.join('')); | 
| +} | 
| +} | 
| +return vars.join('; '); | 
| +} | 
| +function consumeCssProperties(text) { | 
| +var m; | 
| +while (m = MIXIN_MATCH.exec(text)) { | 
| +var matchText = m[0]; | 
| +var mixinName = m[1]; | 
| +var idx = m.index; | 
| +var applyPos = idx + matchText.indexOf('@apply'); | 
| +var afterApplyPos = idx + matchText.length; | 
| +var textBeforeApply = text.slice(0, applyPos); | 
| +var textAfterApply = text.slice(afterApplyPos); | 
| +var defaults = cssTextToMap(textBeforeApply); | 
| +var replacement = atApplyToCssProperties(mixinName, defaults); | 
| +text = [ | 
| +textBeforeApply, | 
| +replacement, | 
| +textAfterApply | 
| +].join(''); | 
| +MIXIN_MATCH.lastIndex = idx + replacement.length; | 
| +} | 
| +return text; | 
| +} | 
| +var ApplyShim = { | 
| +_map: mixinMap, | 
| +_separator: MIXIN_VAR_SEP, | 
| +transform: function (styles) { | 
| +styleUtil.forRulesInStyles(styles, this._boundTransformRule); | 
| +}, | 
| +transformRule: function (rule) { | 
| +rule.cssText = this.transformCssText(rule.parsedCssText); | 
| +if (rule.selector === ':root') { | 
| +rule.selector = ':host > *'; | 
| +} | 
| +}, | 
| +transformCssText: function (cssText) { | 
| +cssText = cssText.replace(VAR_MATCH, fixVars); | 
| +cssText = cssText.replace(VAR_ASSIGN, produceCssProperties); | 
| +return consumeCssProperties(cssText); | 
| +} | 
| +}; | 
| +ApplyShim._boundTransformRule = ApplyShim.transformRule.bind(ApplyShim); | 
| +return ApplyShim; | 
| +}();(function () { | 
| +var prepElement = Polymer.Base._prepElement; | 
| +var nativeShadow = Polymer.Settings.useNativeShadow; | 
| +var styleUtil = Polymer.StyleUtil; | 
| +var styleTransformer = Polymer.StyleTransformer; | 
| +var styleExtends = Polymer.StyleExtends; | 
| +var applyShim = Polymer.ApplyShim; | 
| +var settings = Polymer.Settings; | 
| +Polymer.Base._addFeature({ | 
| +_prepElement: function (element) { | 
| +if (this._encapsulateStyle && this.__cssBuild !== 'shady') { | 
| +styleTransformer.element(element, this.is, this._scopeCssViaAttr); | 
| +} | 
| +prepElement.call(this, element); | 
| +}, | 
| +_prepStyles: function () { | 
| +if (this._encapsulateStyle === undefined) { | 
| +this._encapsulateStyle = !nativeShadow; | 
| +} | 
| +if (!nativeShadow) { | 
| +this._scopeStyle = styleUtil.applyStylePlaceHolder(this.is); | 
| +} | 
| +this.__cssBuild = styleUtil.cssBuildTypeForModule(this.is); | 
| +}, | 
| +_prepShimStyles: function () { | 
| +if (this._template) { | 
| +var hasTargetedCssBuild = styleUtil.isTargetedBuild(this.__cssBuild); | 
| +if (settings.useNativeCSSProperties && this.__cssBuild === 'shadow' && hasTargetedCssBuild) { | 
| +return; | 
| +} | 
| +this._styles = this._styles || this._collectStyles(); | 
| +if (settings.useNativeCSSProperties && !this.__cssBuild) { | 
| +applyShim.transform(this._styles); | 
| +} | 
| +var cssText = settings.useNativeCSSProperties && hasTargetedCssBuild ? this._styles.length && this._styles[0].textContent.trim() : styleTransformer.elementStyles(this); | 
| +this._prepStyleProperties(); | 
| +if (!this._needsStyleProperties() && cssText) { | 
| +styleUtil.applyCss(cssText, this.is, nativeShadow ? this._template.content : null, this._scopeStyle); | 
| +} | 
| +} else { | 
| +this._styles = []; | 
| +} | 
| +}, | 
| +_collectStyles: function () { | 
| +var styles = []; | 
| +var cssText = '', m$ = this.styleModules; | 
| +if (m$) { | 
| +for (var i = 0, l = m$.length, m; i < l && (m = m$[i]); i++) { | 
| +cssText += styleUtil.cssFromModule(m); | 
| +} | 
| +} | 
| +cssText += styleUtil.cssFromModule(this.is); | 
| +var p = this._template && this._template.parentNode; | 
| +if (this._template && (!p || p.id.toLowerCase() !== this.is)) { | 
| +cssText += styleUtil.cssFromElement(this._template); | 
| +} | 
| +if (cssText) { | 
| +var style = document.createElement('style'); | 
| +style.textContent = cssText; | 
| +if (styleExtends.hasExtends(style.textContent)) { | 
| +cssText = styleExtends.transform(style); | 
| +} | 
| +styles.push(style); | 
| +} | 
| +return styles; | 
| +}, | 
| +_elementAdd: function (node) { | 
| +if (this._encapsulateStyle) { | 
| +if (node.__styleScoped) { | 
| +node.__styleScoped = false; | 
| +} else { | 
| +styleTransformer.dom(node, this.is, this._scopeCssViaAttr); | 
| +} | 
| +} | 
| +}, | 
| +_elementRemove: function (node) { | 
| +if (this._encapsulateStyle) { | 
| +styleTransformer.dom(node, this.is, this._scopeCssViaAttr, true); | 
| +} | 
| +}, | 
| +scopeSubtree: function (container, shouldObserve) { | 
| +if (nativeShadow) { | 
| +return; | 
| +} | 
| +var self = this; | 
| +var scopify = function (node) { | 
| +if (node.nodeType === Node.ELEMENT_NODE) { | 
| +var className = node.getAttribute('class'); | 
| +node.setAttribute('class', self._scopeElementClass(node, className)); | 
| +var n$ = node.querySelectorAll('*'); | 
| +for (var i = 0, n; i < n$.length && (n = n$[i]); i++) { | 
| +className = n.getAttribute('class'); | 
| +n.setAttribute('class', self._scopeElementClass(n, className)); | 
| +} | 
| +} | 
| +}; | 
| +scopify(container); | 
| +if (shouldObserve) { | 
| +var mo = new MutationObserver(function (mxns) { | 
| +for (var i = 0, m; i < mxns.length && (m = mxns[i]); i++) { | 
| +if (m.addedNodes) { | 
| +for (var j = 0; j < m.addedNodes.length; j++) { | 
| +scopify(m.addedNodes[j]); | 
| +} | 
| +} | 
| +} | 
| +}); | 
| +mo.observe(container, { | 
| +childList: true, | 
| +subtree: true | 
| +}); | 
| +return mo; | 
| +} | 
| +} | 
| +}); | 
| +}());Polymer.StyleProperties = function () { | 
| +'use strict'; | 
| +var matchesSelector = Polymer.DomApi.matchesSelector; | 
| +var styleUtil = Polymer.StyleUtil; | 
| +var styleTransformer = Polymer.StyleTransformer; | 
| +var settings = Polymer.Settings; | 
| +return { | 
| +decorateStyles: function (styles, scope) { | 
| +var self = this, props = {}, keyframes = [], ruleIndex = 0; | 
| +var scopeSelector = styleTransformer._calcHostScope(scope.is, scope.extends); | 
| +styleUtil.forRulesInStyles(styles, function (rule, style) { | 
| +self.decorateRule(rule); | 
| +rule.index = ruleIndex++; | 
| +self.whenHostOrRootRule(scope, rule, style, function (info) { | 
| +if (rule.parent.type === styleUtil.ruleTypes.MEDIA_RULE) { | 
| +scope.__notStyleScopeCacheable = true; | 
| +} | 
| +if (info.isHost) { | 
| +var hostContextOrFunction = info.selector.split(' ').some(function (s) { | 
| +return s.indexOf(scopeSelector) === 0 && s.length !== scopeSelector.length; | 
| +}); | 
| +scope.__notStyleScopeCacheable = scope.__notStyleScopeCacheable || hostContextOrFunction; | 
| +} | 
| +}); | 
| +self.collectPropertiesInCssText(rule.propertyInfo.cssText, props); | 
| +}, function onKeyframesRule(rule) { | 
| +keyframes.push(rule); | 
| +}); | 
| +styles._keyframes = keyframes; | 
| +var names = []; | 
| +for (var i in props) { | 
| +names.push(i); | 
| +} | 
| +return names; | 
| +}, | 
| +decorateRule: function (rule) { | 
| +if (rule.propertyInfo) { | 
| +return rule.propertyInfo; | 
| +} | 
| +var info = {}, properties = {}; | 
| +var hasProperties = this.collectProperties(rule, properties); | 
| +if (hasProperties) { | 
| +info.properties = properties; | 
| +rule.rules = null; | 
| +} | 
| +info.cssText = this.collectCssText(rule); | 
| +rule.propertyInfo = info; | 
| +return info; | 
| +}, | 
| +collectProperties: function (rule, properties) { | 
| +var info = rule.propertyInfo; | 
| +if (info) { | 
| +if (info.properties) { | 
| +Polymer.Base.mixin(properties, info.properties); | 
| +return true; | 
| +} | 
| +} else { | 
| +var m, rx = this.rx.VAR_ASSIGN; | 
| +var cssText = rule.parsedCssText; | 
| +var any; | 
| +while (m = rx.exec(cssText)) { | 
| +properties[m[1].trim()] = (m[2] || m[3]).trim(); | 
| +any = true; | 
| +} | 
| +return any; | 
| +} | 
| +}, | 
| +collectCssText: function (rule) { | 
| +return this.collectConsumingCssText(rule.parsedCssText); | 
| +}, | 
| +collectConsumingCssText: function (cssText) { | 
| +return cssText.replace(this.rx.BRACKETED, '').replace(this.rx.VAR_ASSIGN, ''); | 
| +}, | 
| +collectPropertiesInCssText: function (cssText, props) { | 
| +var m; | 
| +while (m = this.rx.VAR_CONSUMED.exec(cssText)) { | 
| +var name = m[1]; | 
| +if (m[2] !== ':') { | 
| +props[name] = true; | 
| +} | 
| +} | 
| +}, | 
| +reify: function (props) { | 
| +var names = Object.getOwnPropertyNames(props); | 
| +for (var i = 0, n; i < names.length; i++) { | 
| +n = names[i]; | 
| +props[n] = this.valueForProperty(props[n], props); | 
| +} | 
| +}, | 
| +valueForProperty: function (property, props) { | 
| +if (property) { | 
| +if (property.indexOf(';') >= 0) { | 
| +property = this.valueForProperties(property, props); | 
| +} else { | 
| +var self = this; | 
| +var fn = function (all, prefix, value, fallback) { | 
| +var propertyValue = self.valueForProperty(props[value], props) || self.valueForProperty(props[fallback] || fallback, props) || fallback; | 
| +return prefix + (propertyValue || ''); | 
| +}; | 
| +property = property.replace(this.rx.VAR_MATCH, fn); | 
| +} | 
| +} | 
| +return property && property.trim() || ''; | 
| +}, | 
| +valueForProperties: function (property, props) { | 
| +var parts = property.split(';'); | 
| +for (var i = 0, p, m; i < parts.length; i++) { | 
| +if (p = parts[i]) { | 
| +this.rx.MIXIN_MATCH.lastIndex = 0; | 
| +m = this.rx.MIXIN_MATCH.exec(p); | 
| +if (m) { | 
| +p = this.valueForProperty(props[m[1]], props); | 
| +} else { | 
| +var colon = p.indexOf(':'); | 
| +if (colon !== -1) { | 
| +var pp = p.substring(colon); | 
| +pp = pp.trim(); | 
| +pp = this.valueForProperty(pp, props) || pp; | 
| +p = p.substring(0, colon) + pp; | 
| +} | 
| +} | 
| +parts[i] = p && p.lastIndexOf(';') === p.length - 1 ? p.slice(0, -1) : p || ''; | 
| +} | 
| +} | 
| +return parts.join(';'); | 
| +}, | 
| +applyProperties: function (rule, props) { | 
| +var output = ''; | 
| +if (!rule.propertyInfo) { | 
| +this.decorateRule(rule); | 
| +} | 
| +if (rule.propertyInfo.cssText) { | 
| +output = this.valueForProperties(rule.propertyInfo.cssText, props); | 
| +} | 
| +rule.cssText = output; | 
| +}, | 
| +applyKeyframeTransforms: function (rule, keyframeTransforms) { | 
| +var input = rule.cssText; | 
| +var output = rule.cssText; | 
| +if (rule.hasAnimations == null) { | 
| +rule.hasAnimations = this.rx.ANIMATION_MATCH.test(input); | 
| +} | 
| +if (rule.hasAnimations) { | 
| +var transform; | 
| +if (rule.keyframeNamesToTransform == null) { | 
| +rule.keyframeNamesToTransform = []; | 
| +for (var keyframe in keyframeTransforms) { | 
| +transform = keyframeTransforms[keyframe]; | 
| +output = transform(input); | 
| +if (input !== output) { | 
| +input = output; | 
| +rule.keyframeNamesToTransform.push(keyframe); | 
| +} | 
| +} | 
| +} else { | 
| +for (var i = 0; i < rule.keyframeNamesToTransform.length; ++i) { | 
| +transform = keyframeTransforms[rule.keyframeNamesToTransform[i]]; | 
| +input = transform(input); | 
| +} | 
| +output = input; | 
| +} | 
| +} | 
| +rule.cssText = output; | 
| +}, | 
| +propertyDataFromStyles: function (styles, element) { | 
| +var props = {}, self = this; | 
| +var o = []; | 
| +styleUtil.forActiveRulesInStyles(styles, function (rule) { | 
| +if (!rule.propertyInfo) { | 
| +self.decorateRule(rule); | 
| +} | 
| +var selectorToMatch = rule.transformedSelector || rule.parsedSelector; | 
| +if (element && rule.propertyInfo.properties && selectorToMatch) { | 
| +if (matchesSelector.call(element, selectorToMatch)) { | 
| +self.collectProperties(rule, props); | 
| +addToBitMask(rule.index, o); | 
| +} | 
| +} | 
| +}); | 
| +return { | 
| +properties: props, | 
| +key: o | 
| +}; | 
| +}, | 
| +whenHostOrRootRule: function (scope, rule, style, callback) { | 
| +if (!rule.propertyInfo) { | 
| +self.decorateRule(rule); | 
| +} | 
| +if (!rule.propertyInfo.properties) { | 
| +return; | 
| +} | 
| +var hostScope = scope.is ? styleTransformer._calcHostScope(scope.is, scope.extends) : 'html'; | 
| +var parsedSelector = rule.parsedSelector; | 
| +var isRoot = parsedSelector === ':root'; | 
| +var isHost = parsedSelector.indexOf(':host') === 0; | 
| +var cssBuild = scope.__cssBuild || style.__cssBuild; | 
| +if (cssBuild === 'shady') { | 
| +isRoot = parsedSelector === hostScope + '> *.' + hostScope || parsedSelector.indexOf('html') !== -1; | 
| +isHost = !isRoot && parsedSelector.indexOf(hostScope) === 0; | 
| +} | 
| +if (cssBuild === 'shadow') { | 
| +isRoot = parsedSelector === ':host > *' || parsedSelector === 'html'; | 
| +isHost = isHost && !isRoot; | 
| +} | 
| +if (!isRoot && !isHost) { | 
| +return; | 
| +} | 
| +var selectorToMatch = hostScope; | 
| +if (isHost) { | 
| +if (settings.useNativeShadow && !rule.transformedSelector) { | 
| +rule.transformedSelector = styleTransformer._transformRuleCss(rule, styleTransformer._transformComplexSelector, scope.is, hostScope); | 
| +} | 
| +selectorToMatch = rule.transformedSelector || hostScope; | 
| +} | 
| +callback({ | 
| +selector: selectorToMatch, | 
| +isHost: isHost, | 
| +isRoot: isRoot | 
| +}); | 
| +}, | 
| +hostAndRootPropertiesForScope: function (scope) { | 
| +var hostProps = {}, rootProps = {}, self = this; | 
| +styleUtil.forActiveRulesInStyles(scope._styles, function (rule, style) { | 
| +self.whenHostOrRootRule(scope, rule, style, function (info) { | 
| +var element = scope._element || scope; | 
| +if (matchesSelector.call(element, info.selector)) { | 
| +if (info.isHost) { | 
| +self.collectProperties(rule, hostProps); | 
| +} else { | 
| +self.collectProperties(rule, rootProps); | 
| +} | 
| +} | 
| +}); | 
| +}); | 
| +return { | 
| +rootProps: rootProps, | 
| +hostProps: hostProps | 
| +}; | 
| +}, | 
| +transformStyles: function (element, properties, scopeSelector) { | 
| +var self = this; | 
| +var hostSelector = styleTransformer._calcHostScope(element.is, element.extends); | 
| +var rxHostSelector = element.extends ? '\\' + hostSelector.slice(0, -1) + '\\]' : hostSelector; | 
| +var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector + this.rx.HOST_SUFFIX); | 
| +var keyframeTransforms = this._elementKeyframeTransforms(element, scopeSelector); | 
| +return styleTransformer.elementStyles(element, function (rule) { | 
| +self.applyProperties(rule, properties); | 
| +if (!settings.useNativeShadow && !Polymer.StyleUtil.isKeyframesSelector(rule) && rule.cssText) { | 
| +self.applyKeyframeTransforms(rule, keyframeTransforms); | 
| +self._scopeSelector(rule, hostRx, hostSelector, element._scopeCssViaAttr, scopeSelector); | 
| +} | 
| +}); | 
| +}, | 
| +_elementKeyframeTransforms: function (element, scopeSelector) { | 
| +var keyframesRules = element._styles._keyframes; | 
| +var keyframeTransforms = {}; | 
| +if (!settings.useNativeShadow && keyframesRules) { | 
| +for (var i = 0, keyframesRule = keyframesRules[i]; i < keyframesRules.length; keyframesRule = keyframesRules[++i]) { | 
| +this._scopeKeyframes(keyframesRule, scopeSelector); | 
| +keyframeTransforms[keyframesRule.keyframesName] = this._keyframesRuleTransformer(keyframesRule); | 
| +} | 
| +} | 
| +return keyframeTransforms; | 
| +}, | 
| +_keyframesRuleTransformer: function (keyframesRule) { | 
| +return function (cssText) { | 
| +return cssText.replace(keyframesRule.keyframesNameRx, keyframesRule.transformedKeyframesName); | 
| +}; | 
| +}, | 
| +_scopeKeyframes: function (rule, scopeId) { | 
| +rule.keyframesNameRx = new RegExp(rule.keyframesName, 'g'); | 
| +rule.transformedKeyframesName = rule.keyframesName + '-' + scopeId; | 
| +rule.transformedSelector = rule.transformedSelector || rule.selector; | 
| +rule.selector = rule.transformedSelector.replace(rule.keyframesName, rule.transformedKeyframesName); | 
| +}, | 
| +_scopeSelector: function (rule, hostRx, hostSelector, viaAttr, scopeId) { | 
| +rule.transformedSelector = rule.transformedSelector || rule.selector; | 
| +var selector = rule.transformedSelector; | 
| +var scope = viaAttr ? '[' + styleTransformer.SCOPE_NAME + '~=' + scopeId + ']' : '.' + scopeId; | 
| +var parts = selector.split(','); | 
| +for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) { | 
| +parts[i] = p.match(hostRx) ? p.replace(hostSelector, scope) : scope + ' ' + p; | 
| +} | 
| +rule.selector = parts.join(','); | 
| +}, | 
| +applyElementScopeSelector: function (element, selector, old, viaAttr) { | 
| +var c = viaAttr ? element.getAttribute(styleTransformer.SCOPE_NAME) : element.getAttribute('class') || ''; | 
| +var v = old ? c.replace(old, selector) : (c ? c + ' ' : '') + this.XSCOPE_NAME + ' ' + selector; | 
| +if (c !== v) { | 
| +if (viaAttr) { | 
| +element.setAttribute(styleTransformer.SCOPE_NAME, v); | 
| +} else { | 
| +element.setAttribute('class', v); | 
| +} | 
| +} | 
| +}, | 
| +applyElementStyle: function (element, properties, selector, style) { | 
| +var cssText = style ? style.textContent || '' : this.transformStyles(element, properties, selector); | 
| +var s = element._customStyle; | 
| +if (s && !settings.useNativeShadow && s !== style) { | 
| +s._useCount--; | 
| +if (s._useCount <= 0 && s.parentNode) { | 
| +s.parentNode.removeChild(s); | 
| +} | 
| +} | 
| +if (settings.useNativeShadow) { | 
| +if (element._customStyle) { | 
| +element._customStyle.textContent = cssText; | 
| +style = element._customStyle; | 
| +} else if (cssText) { | 
| +style = styleUtil.applyCss(cssText, selector, element.root, element._scopeStyle); | 
| +} | 
| +} else { | 
| +if (!style) { | 
| +if (cssText) { | 
| +style = styleUtil.applyCss(cssText, selector, null, element._scopeStyle); | 
| +} | 
| +} else if (!style.parentNode) { | 
| +styleUtil.applyStyle(style, null, element._scopeStyle); | 
| +} | 
| +} | 
| +if (style) { | 
| +style._useCount = style._useCount || 0; | 
| +if (element._customStyle != style) { | 
| +style._useCount++; | 
| +} | 
| +element._customStyle = style; | 
| +} | 
| +return style; | 
| +}, | 
| +mixinCustomStyle: function (props, customStyle) { | 
| +var v; | 
| +for (var i in customStyle) { | 
| +v = customStyle[i]; | 
| +if (v || v === 0) { | 
| +props[i] = v; | 
| +} | 
| +} | 
| +}, | 
| +updateNativeStyleProperties: function (element, properties) { | 
| +for (var i = 0; i < element.style.length; i++) { | 
| +element.style.removeProperty(element.style[i]); | 
| +} | 
| +for (var p in properties) { | 
| +if (properties[p] !== null) { | 
| +element.style.setProperty(p, properties[p]); | 
| +} | 
| +} | 
| +}, | 
| +rx: styleUtil.rx, | 
| +XSCOPE_NAME: 'x-scope' | 
| +}; | 
| +function addToBitMask(n, bits) { | 
| +var o = parseInt(n / 32); | 
| +var v = 1 << n % 32; | 
| +bits[o] = (bits[o] || 0) | v; | 
| +} | 
| +}();(function () { | 
| +Polymer.StyleCache = function () { | 
| +this.cache = {}; | 
| +}; | 
| +Polymer.StyleCache.prototype = { | 
| +MAX: 100, | 
| +store: function (is, data, keyValues, keyStyles) { | 
| +data.keyValues = keyValues; | 
| +data.styles = keyStyles; | 
| +var s$ = this.cache[is] = this.cache[is] || []; | 
| +s$.push(data); | 
| +if (s$.length > this.MAX) { | 
| +s$.shift(); | 
| +} | 
| +}, | 
| +retrieve: function (is, keyValues, keyStyles) { | 
| +var cache = this.cache[is]; | 
| +if (cache) { | 
| +for (var i = cache.length - 1, data; i >= 0; i--) { | 
| +data = cache[i]; | 
| +if (keyStyles === data.styles && this._objectsEqual(keyValues, data.keyValues)) { | 
| +return data; | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +clear: function () { | 
| +this.cache = {}; | 
| +}, | 
| +_objectsEqual: function (target, source) { | 
| +var t, s; | 
| +for (var i in target) { | 
| +t = target[i], s = source[i]; | 
| +if (!(typeof t === 'object' && t ? this._objectsStrictlyEqual(t, s) : t === s)) { | 
| +return false; | 
| +} | 
| +} | 
| +if (Array.isArray(target)) { | 
| +return target.length === source.length; | 
| +} | 
| +return true; | 
| +}, | 
| +_objectsStrictlyEqual: function (target, source) { | 
| +return this._objectsEqual(target, source) && this._objectsEqual(source, target); | 
| +} | 
| +}; | 
| +}());Polymer.StyleDefaults = function () { | 
| +var styleProperties = Polymer.StyleProperties; | 
| +var StyleCache = Polymer.StyleCache; | 
| +var nativeVariables = Polymer.Settings.useNativeCSSProperties; | 
| +var api = { | 
| +_styles: [], | 
| +_properties: null, | 
| +customStyle: {}, | 
| +_styleCache: new StyleCache(), | 
| +_element: Polymer.DomApi.wrap(document.documentElement), | 
| +addStyle: function (style) { | 
| +this._styles.push(style); | 
| +this._properties = null; | 
| +}, | 
| +get _styleProperties() { | 
| +if (!this._properties) { | 
| +styleProperties.decorateStyles(this._styles, this); | 
| +this._styles._scopeStyleProperties = null; | 
| +this._properties = styleProperties.hostAndRootPropertiesForScope(this).rootProps; | 
| +styleProperties.mixinCustomStyle(this._properties, this.customStyle); | 
| +styleProperties.reify(this._properties); | 
| +} | 
| +return this._properties; | 
| +}, | 
| +hasStyleProperties: function () { | 
| +return Boolean(this._properties); | 
| +}, | 
| +_needsStyleProperties: function () { | 
| +}, | 
| +_computeStyleProperties: function () { | 
| +return this._styleProperties; | 
| +}, | 
| +updateStyles: function (properties) { | 
| +this._properties = null; | 
| +if (properties) { | 
| +Polymer.Base.mixin(this.customStyle, properties); | 
| +} | 
| +this._styleCache.clear(); | 
| +for (var i = 0, s; i < this._styles.length; i++) { | 
| +s = this._styles[i]; | 
| +s = s.__importElement || s; | 
| +s._apply(); | 
| +} | 
| +if (nativeVariables) { | 
| +styleProperties.updateNativeStyleProperties(document.documentElement, this.customStyle); | 
| +} | 
| +} | 
| +}; | 
| +return api; | 
| +}();(function () { | 
| +'use strict'; | 
| +var serializeValueToAttribute = Polymer.Base.serializeValueToAttribute; | 
| +var propertyUtils = Polymer.StyleProperties; | 
| +var styleTransformer = Polymer.StyleTransformer; | 
| +var styleDefaults = Polymer.StyleDefaults; | 
| +var nativeShadow = Polymer.Settings.useNativeShadow; | 
| +var nativeVariables = Polymer.Settings.useNativeCSSProperties; | 
| +Polymer.Base._addFeature({ | 
| +_prepStyleProperties: function () { | 
| +if (!nativeVariables) { | 
| +this._ownStylePropertyNames = this._styles && this._styles.length ? propertyUtils.decorateStyles(this._styles, this) : null; | 
| +} | 
| +}, | 
| +customStyle: null, | 
| +getComputedStyleValue: function (property) { | 
| +return !nativeVariables && this._styleProperties && this._styleProperties[property] || getComputedStyle(this).getPropertyValue(property); | 
| +}, | 
| +_setupStyleProperties: function () { | 
| +this.customStyle = {}; | 
| +this._styleCache = null; | 
| +this._styleProperties = null; | 
| +this._scopeSelector = null; | 
| +this._ownStyleProperties = null; | 
| +this._customStyle = null; | 
| +}, | 
| +_needsStyleProperties: function () { | 
| +return Boolean(!nativeVariables && this._ownStylePropertyNames && this._ownStylePropertyNames.length); | 
| +}, | 
| +_beforeAttached: function () { | 
| +if ((!this._scopeSelector || this.__stylePropertiesInvalid) && this._needsStyleProperties()) { | 
| +this.__stylePropertiesInvalid = false; | 
| +this._updateStyleProperties(); | 
| +} | 
| +}, | 
| +_findStyleHost: function () { | 
| +var e = this, root; | 
| +while (root = Polymer.dom(e).getOwnerRoot()) { | 
| +if (Polymer.isInstance(root.host)) { | 
| +return root.host; | 
| +} | 
| +e = root.host; | 
| +} | 
| +return styleDefaults; | 
| +}, | 
| +_updateStyleProperties: function () { | 
| +var info, scope = this._findStyleHost(); | 
| +if (!scope._styleCache) { | 
| +scope._styleCache = new Polymer.StyleCache(); | 
| +} | 
| +var scopeData = propertyUtils.propertyDataFromStyles(scope._styles, this); | 
| +var scopeCacheable = !this.__notStyleScopeCacheable; | 
| +if (scopeCacheable) { | 
| +scopeData.key.customStyle = this.customStyle; | 
| +info = scope._styleCache.retrieve(this.is, scopeData.key, this._styles); | 
| +} | 
| +var scopeCached = Boolean(info); | 
| +if (scopeCached) { | 
| +this._styleProperties = info._styleProperties; | 
| +} else { | 
| +this._computeStyleProperties(scopeData.properties); | 
| +} | 
| +this._computeOwnStyleProperties(); | 
| +if (!scopeCached) { | 
| +info = styleCache.retrieve(this.is, this._ownStyleProperties, this._styles); | 
| +} | 
| +var globalCached = Boolean(info) && !scopeCached; | 
| +var style = this._applyStyleProperties(info); | 
| +if (!scopeCached) { | 
| +style = style && nativeShadow ? style.cloneNode(true) : style; | 
| +info = { | 
| +style: style, | 
| +_scopeSelector: this._scopeSelector, | 
| +_styleProperties: this._styleProperties | 
| +}; | 
| +if (scopeCacheable) { | 
| +scopeData.key.customStyle = {}; | 
| +this.mixin(scopeData.key.customStyle, this.customStyle); | 
| +scope._styleCache.store(this.is, info, scopeData.key, this._styles); | 
| +} | 
| +if (!globalCached) { | 
| +styleCache.store(this.is, Object.create(info), this._ownStyleProperties, this._styles); | 
| +} | 
| +} | 
| +}, | 
| +_computeStyleProperties: function (scopeProps) { | 
| +var scope = this._findStyleHost(); | 
| +if (!scope._styleProperties) { | 
| +scope._computeStyleProperties(); | 
| +} | 
| +var props = Object.create(scope._styleProperties); | 
| +var hostAndRootProps = propertyUtils.hostAndRootPropertiesForScope(this); | 
| +this.mixin(props, hostAndRootProps.hostProps); | 
| +scopeProps = scopeProps || propertyUtils.propertyDataFromStyles(scope._styles, this).properties; | 
| +this.mixin(props, scopeProps); | 
| +this.mixin(props, hostAndRootProps.rootProps); | 
| +propertyUtils.mixinCustomStyle(props, this.customStyle); | 
| +propertyUtils.reify(props); | 
| +this._styleProperties = props; | 
| +}, | 
| +_computeOwnStyleProperties: function () { | 
| +var props = {}; | 
| +for (var i = 0, n; i < this._ownStylePropertyNames.length; i++) { | 
| +n = this._ownStylePropertyNames[i]; | 
| +props[n] = this._styleProperties[n]; | 
| +} | 
| +this._ownStyleProperties = props; | 
| +}, | 
| +_scopeCount: 0, | 
| +_applyStyleProperties: function (info) { | 
| +var oldScopeSelector = this._scopeSelector; | 
| +this._scopeSelector = info ? info._scopeSelector : this.is + '-' + this.__proto__._scopeCount++; | 
| +var style = propertyUtils.applyElementStyle(this, this._styleProperties, this._scopeSelector, info && info.style); | 
| +if (!nativeShadow) { | 
| +propertyUtils.applyElementScopeSelector(this, this._scopeSelector, oldScopeSelector, this._scopeCssViaAttr); | 
| +} | 
| +return style; | 
| +}, | 
| +serializeValueToAttribute: function (value, attribute, node) { | 
| +node = node || this; | 
| +if (attribute === 'class' && !nativeShadow) { | 
| +var host = node === this ? this.domHost || this.dataHost : this; | 
| +if (host) { | 
| +value = host._scopeElementClass(node, value); | 
| +} | 
| +} | 
| +node = this.shadyRoot && this.shadyRoot._hasDistributed ? Polymer.dom(node) : node; | 
| +serializeValueToAttribute.call(this, value, attribute, node); | 
| +}, | 
| +_scopeElementClass: function (element, selector) { | 
| +if (!nativeShadow && !this._scopeCssViaAttr) { | 
| +selector = (selector ? selector + ' ' : '') + SCOPE_NAME + ' ' + this.is + (element._scopeSelector ? ' ' + XSCOPE_NAME + ' ' + element._scopeSelector : ''); | 
| +} | 
| +return selector; | 
| +}, | 
| +updateStyles: function (properties) { | 
| +if (properties) { | 
| +this.mixin(this.customStyle, properties); | 
| +} | 
| +if (nativeVariables) { | 
| +propertyUtils.updateNativeStyleProperties(this, this.customStyle); | 
| +} else { | 
| +if (this.isAttached) { | 
| +if (this._needsStyleProperties()) { | 
| +this._updateStyleProperties(); | 
| +} else { | 
| +this._styleProperties = null; | 
| +} | 
| +} else { | 
| +this.__stylePropertiesInvalid = true; | 
| +} | 
| +if (this._styleCache) { | 
| +this._styleCache.clear(); | 
| +} | 
| +this._updateRootStyles(); | 
| +} | 
| +}, | 
| +_updateRootStyles: function (root) { | 
| +root = root || this.root; | 
| +var c$ = Polymer.dom(root)._query(function (e) { | 
| +return e.shadyRoot || e.shadowRoot; | 
| +}); | 
| +for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) { | 
| +if (c.updateStyles) { | 
| +c.updateStyles(); | 
| +} | 
| +} | 
| +} | 
| +}); | 
| +Polymer.updateStyles = function (properties) { | 
| +styleDefaults.updateStyles(properties); | 
| +Polymer.Base._updateRootStyles(document); | 
| +}; | 
| +var styleCache = new Polymer.StyleCache(); | 
| +Polymer.customStyleCache = styleCache; | 
| +var SCOPE_NAME = styleTransformer.SCOPE_NAME; | 
| +var XSCOPE_NAME = propertyUtils.XSCOPE_NAME; | 
| +}());Polymer.Base._addFeature({ | 
| +_registerFeatures: function () { | 
| +this._prepIs(); | 
| +this._prepConstructor(); | 
| +this._prepStyles(); | 
| +}, | 
| +_finishRegisterFeatures: function () { | 
| +this._prepTemplate(); | 
| +this._prepShimStyles(); | 
| +this._prepAnnotations(); | 
| +this._prepEffects(); | 
| +this._prepBehaviors(); | 
| +this._prepPropertyInfo(); | 
| +this._prepBindings(); | 
| +this._prepShady(); | 
| +}, | 
| +_prepBehavior: function (b) { | 
| +this._addPropertyEffects(b.properties); | 
| +this._addComplexObserverEffects(b.observers); | 
| +this._addHostAttributes(b.hostAttributes); | 
| +}, | 
| +_initFeatures: function () { | 
| +this._setupGestures(); | 
| +this._setupConfigure(); | 
| +this._setupStyleProperties(); | 
| +this._setupDebouncers(); | 
| +this._setupShady(); | 
| +this._registerHost(); | 
| +if (this._template) { | 
| +this._poolContent(); | 
| +this._beginHosting(); | 
| +this._stampTemplate(); | 
| +this._endHosting(); | 
| +this._marshalAnnotationReferences(); | 
| +} | 
| +this._marshalInstanceEffects(); | 
| +this._marshalBehaviors(); | 
| +this._marshalHostAttributes(); | 
| +this._marshalAttributes(); | 
| +this._tryReady(); | 
| +}, | 
| +_marshalBehavior: function (b) { | 
| +if (b.listeners) { | 
| +this._listenListeners(b.listeners); | 
| +} | 
| +} | 
| +});(function () { | 
| +var propertyUtils = Polymer.StyleProperties; | 
| +var styleUtil = Polymer.StyleUtil; | 
| +var cssParse = Polymer.CssParse; | 
| +var styleDefaults = Polymer.StyleDefaults; | 
| +var styleTransformer = Polymer.StyleTransformer; | 
| +var applyShim = Polymer.ApplyShim; | 
| +var debounce = Polymer.Debounce; | 
| +var settings = Polymer.Settings; | 
| +var updateDebouncer; | 
| +Polymer({ | 
| +is: 'custom-style', | 
| +extends: 'style', | 
| +_template: null, | 
| +properties: { include: String }, | 
| +ready: function () { | 
| +this.__appliedElement = this.__appliedElement || this; | 
| +this.__cssBuild = styleUtil.getCssBuildType(this); | 
| +if (this.__appliedElement !== this) { | 
| +this.__appliedElement.__cssBuild = this.__cssBuild; | 
| +} | 
| +this._tryApply(); | 
| +}, | 
| +attached: function () { | 
| +this._tryApply(); | 
| +}, | 
| +_tryApply: function () { | 
| +if (!this._appliesToDocument) { | 
| +if (this.parentNode && this.parentNode.localName !== 'dom-module') { | 
| +this._appliesToDocument = true; | 
| +var e = this.__appliedElement; | 
| +if (!settings.useNativeCSSProperties) { | 
| +this.__needsUpdateStyles = styleDefaults.hasStyleProperties(); | 
| +styleDefaults.addStyle(e); | 
| +} | 
| +if (e.textContent || this.include) { | 
| +this._apply(true); | 
| +} else { | 
| +var self = this; | 
| +var observer = new MutationObserver(function () { | 
| +observer.disconnect(); | 
| +self._apply(true); | 
| +}); | 
| +observer.observe(e, { childList: true }); | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_updateStyles: function () { | 
| +Polymer.updateStyles(); | 
| +}, | 
| +_apply: function (initialApply) { | 
| +var e = this.__appliedElement; | 
| +if (this.include) { | 
| +e.textContent = styleUtil.cssFromModules(this.include, true) + e.textContent; | 
| +} | 
| +if (!e.textContent) { | 
| +return; | 
| +} | 
| +var buildType = this.__cssBuild; | 
| +var targetedBuild = styleUtil.isTargetedBuild(buildType); | 
| +if (settings.useNativeCSSProperties && targetedBuild) { | 
| +return; | 
| +} | 
| +var styleRules = styleUtil.rulesForStyle(e); | 
| +if (!targetedBuild) { | 
| +styleUtil.forEachRule(styleRules, function (rule) { | 
| +styleTransformer.documentRule(rule); | 
| +if (settings.useNativeCSSProperties && !buildType) { | 
| +applyShim.transformRule(rule); | 
| +} | 
| +}); | 
| +} | 
| +if (settings.useNativeCSSProperties) { | 
| +e.textContent = styleUtil.toCssText(styleRules); | 
| +} else { | 
| +var self = this; | 
| +var fn = function fn() { | 
| +self._flushCustomProperties(); | 
| +}; | 
| +if (initialApply) { | 
| +Polymer.RenderStatus.whenReady(fn); | 
| +} else { | 
| +fn(); | 
| +} | 
| +} | 
| +}, | 
| +_flushCustomProperties: function () { | 
| +if (this.__needsUpdateStyles) { | 
| +this.__needsUpdateStyles = false; | 
| +updateDebouncer = debounce(updateDebouncer, this._updateStyles); | 
| +} else { | 
| +this._applyCustomProperties(); | 
| +} | 
| +}, | 
| +_applyCustomProperties: function () { | 
| +var element = this.__appliedElement; | 
| +this._computeStyleProperties(); | 
| +var props = this._styleProperties; | 
| +var rules = styleUtil.rulesForStyle(element); | 
| +if (!rules) { | 
| +return; | 
| +} | 
| +element.textContent = styleUtil.toCssText(rules, function (rule) { | 
| +var css = rule.cssText = rule.parsedCssText; | 
| +if (rule.propertyInfo && rule.propertyInfo.cssText) { | 
| +css = cssParse.removeCustomPropAssignment(css); | 
| +rule.cssText = propertyUtils.valueForProperties(css, props); | 
| +} | 
| +}); | 
| +} | 
| +}); | 
| +}());Polymer.Templatizer = { | 
| +properties: { __hideTemplateChildren__: { observer: '_showHideChildren' } }, | 
| +_instanceProps: Polymer.nob, | 
| +_parentPropPrefix: '_parent_', | 
| +templatize: function (template) { | 
| +this._templatized = template; | 
| +if (!template._content) { | 
| +template._content = template.content; | 
| +} | 
| +if (template._content._ctor) { | 
| +this.ctor = template._content._ctor; | 
| +this._prepParentProperties(this.ctor.prototype, template); | 
| +return; | 
| +} | 
| +var archetype = Object.create(Polymer.Base); | 
| +this._customPrepAnnotations(archetype, template); | 
| +this._prepParentProperties(archetype, template); | 
| +archetype._prepEffects(); | 
| +this._customPrepEffects(archetype); | 
| +archetype._prepBehaviors(); | 
| +archetype._prepPropertyInfo(); | 
| +archetype._prepBindings(); | 
| +archetype._notifyPathUp = this._notifyPathUpImpl; | 
| +archetype._scopeElementClass = this._scopeElementClassImpl; | 
| +archetype.listen = this._listenImpl; | 
| +archetype._showHideChildren = this._showHideChildrenImpl; | 
| +archetype.__setPropertyOrig = this.__setProperty; | 
| +archetype.__setProperty = this.__setPropertyImpl; | 
| +var _constructor = this._constructorImpl; | 
| +var ctor = function TemplateInstance(model, host) { | 
| +_constructor.call(this, model, host); | 
| +}; | 
| +ctor.prototype = archetype; | 
| +archetype.constructor = ctor; | 
| +template._content._ctor = ctor; | 
| +this.ctor = ctor; | 
| +}, | 
| +_getRootDataHost: function () { | 
| +return this.dataHost && this.dataHost._rootDataHost || this.dataHost; | 
| +}, | 
| +_showHideChildrenImpl: function (hide) { | 
| +var c = this._children; | 
| +for (var i = 0; i < c.length; i++) { | 
| +var n = c[i]; | 
| +if (Boolean(hide) != Boolean(n.__hideTemplateChildren__)) { | 
| +if (n.nodeType === Node.TEXT_NODE) { | 
| +if (hide) { | 
| +n.__polymerTextContent__ = n.textContent; | 
| +n.textContent = ''; | 
| +} else { | 
| +n.textContent = n.__polymerTextContent__; | 
| +} | 
| +} else if (n.style) { | 
| +if (hide) { | 
| +n.__polymerDisplay__ = n.style.display; | 
| +n.style.display = 'none'; | 
| +} else { | 
| +n.style.display = n.__polymerDisplay__; | 
| +} | 
| +} | 
| +} | 
| +n.__hideTemplateChildren__ = hide; | 
| +} | 
| +}, | 
| +__setPropertyImpl: function (property, value, fromAbove, node) { | 
| +if (node && node.__hideTemplateChildren__ && property == 'textContent') { | 
| +property = '__polymerTextContent__'; | 
| +} | 
| +this.__setPropertyOrig(property, value, fromAbove, node); | 
| +}, | 
| +_debounceTemplate: function (fn) { | 
| +Polymer.dom.addDebouncer(this.debounce('_debounceTemplate', fn)); | 
| +}, | 
| +_flushTemplates: function () { | 
| +Polymer.dom.flush(); | 
| +}, | 
| +_customPrepEffects: function (archetype) { | 
| +var parentProps = archetype._parentProps; | 
| +for (var prop in parentProps) { | 
| +archetype._addPropertyEffect(prop, 'function', this._createHostPropEffector(prop)); | 
| +} | 
| +for (prop in this._instanceProps) { | 
| +archetype._addPropertyEffect(prop, 'function', this._createInstancePropEffector(prop)); | 
| +} | 
| +}, | 
| +_customPrepAnnotations: function (archetype, template) { | 
| +archetype._template = template; | 
| +var c = template._content; | 
| +if (!c._notes) { | 
| +var rootDataHost = archetype._rootDataHost; | 
| +if (rootDataHost) { | 
| +Polymer.Annotations.prepElement = function () { | 
| +rootDataHost._prepElement(); | 
| +}; | 
| +} | 
| +c._notes = Polymer.Annotations.parseAnnotations(template); | 
| +Polymer.Annotations.prepElement = null; | 
| +this._processAnnotations(c._notes); | 
| +} | 
| +archetype._notes = c._notes; | 
| +archetype._parentProps = c._parentProps; | 
| +}, | 
| +_prepParentProperties: function (archetype, template) { | 
| +var parentProps = this._parentProps = archetype._parentProps; | 
| +if (this._forwardParentProp && parentProps) { | 
| +var proto = archetype._parentPropProto; | 
| +var prop; | 
| +if (!proto) { | 
| +for (prop in this._instanceProps) { | 
| +delete parentProps[prop]; | 
| +} | 
| +proto = archetype._parentPropProto = Object.create(null); | 
| +if (template != this) { | 
| +Polymer.Bind.prepareModel(proto); | 
| +Polymer.Base.prepareModelNotifyPath(proto); | 
| +} | 
| +for (prop in parentProps) { | 
| +var parentProp = this._parentPropPrefix + prop; | 
| +var effects = [ | 
| +{ | 
| +kind: 'function', | 
| +effect: this._createForwardPropEffector(prop), | 
| +fn: Polymer.Bind._functionEffect | 
| +}, | 
| +{ | 
| +kind: 'notify', | 
| +fn: Polymer.Bind._notifyEffect, | 
| +effect: { event: Polymer.CaseMap.camelToDashCase(parentProp) + '-changed' } | 
| +} | 
| +]; | 
| +Polymer.Bind._createAccessors(proto, parentProp, effects); | 
| +} | 
| +} | 
| +var self = this; | 
| +if (template != this) { | 
| +Polymer.Bind.prepareInstance(template); | 
| +template._forwardParentProp = function (source, value) { | 
| +self._forwardParentProp(source, value); | 
| +}; | 
| +} | 
| +this._extendTemplate(template, proto); | 
| +template._pathEffector = function (path, value, fromAbove) { | 
| +return self._pathEffectorImpl(path, value, fromAbove); | 
| +}; | 
| +} | 
| +}, | 
| +_createForwardPropEffector: function (prop) { | 
| +return function (source, value) { | 
| +this._forwardParentProp(prop, value); | 
| +}; | 
| +}, | 
| +_createHostPropEffector: function (prop) { | 
| +var prefix = this._parentPropPrefix; | 
| +return function (source, value) { | 
| +this.dataHost._templatized[prefix + prop] = value; | 
| +}; | 
| +}, | 
| +_createInstancePropEffector: function (prop) { | 
| +return function (source, value, old, fromAbove) { | 
| +if (!fromAbove) { | 
| +this.dataHost._forwardInstanceProp(this, prop, value); | 
| +} | 
| +}; | 
| +}, | 
| +_extendTemplate: function (template, proto) { | 
| +var n$ = Object.getOwnPropertyNames(proto); | 
| +if (proto._propertySetter) { | 
| +template._propertySetter = proto._propertySetter; | 
| +} | 
| +for (var i = 0, n; i < n$.length && (n = n$[i]); i++) { | 
| +var val = template[n]; | 
| +var pd = Object.getOwnPropertyDescriptor(proto, n); | 
| +Object.defineProperty(template, n, pd); | 
| +if (val !== undefined) { | 
| +template._propertySetter(n, val); | 
| +} | 
| +} | 
| +}, | 
| +_showHideChildren: function (hidden) { | 
| +}, | 
| +_forwardInstancePath: function (inst, path, value) { | 
| +}, | 
| +_forwardInstanceProp: function (inst, prop, value) { | 
| +}, | 
| +_notifyPathUpImpl: function (path, value) { | 
| +var dataHost = this.dataHost; | 
| +var dot = path.indexOf('.'); | 
| +var root = dot < 0 ? path : path.slice(0, dot); | 
| +dataHost._forwardInstancePath.call(dataHost, this, path, value); | 
| +if (root in dataHost._parentProps) { | 
| +dataHost._templatized._notifyPath(dataHost._parentPropPrefix + path, value); | 
| +} | 
| +}, | 
| +_pathEffectorImpl: function (path, value, fromAbove) { | 
| +if (this._forwardParentPath) { | 
| +if (path.indexOf(this._parentPropPrefix) === 0) { | 
| +var subPath = path.substring(this._parentPropPrefix.length); | 
| +var model = this._modelForPath(subPath); | 
| +if (model in this._parentProps) { | 
| +this._forwardParentPath(subPath, value); | 
| +} | 
| +} | 
| +} | 
| +Polymer.Base._pathEffector.call(this._templatized, path, value, fromAbove); | 
| +}, | 
| +_constructorImpl: function (model, host) { | 
| +this._rootDataHost = host._getRootDataHost(); | 
| +this._setupConfigure(model); | 
| +this._registerHost(host); | 
| +this._beginHosting(); | 
| +this.root = this.instanceTemplate(this._template); | 
| +this.root.__noContent = !this._notes._hasContent; | 
| +this.root.__styleScoped = true; | 
| +this._endHosting(); | 
| +this._marshalAnnotatedNodes(); | 
| +this._marshalInstanceEffects(); | 
| +this._marshalAnnotatedListeners(); | 
| +var children = []; | 
| +for (var n = this.root.firstChild; n; n = n.nextSibling) { | 
| +children.push(n); | 
| +n._templateInstance = this; | 
| +} | 
| +this._children = children; | 
| +if (host.__hideTemplateChildren__) { | 
| +this._showHideChildren(true); | 
| +} | 
| +this._tryReady(); | 
| +}, | 
| +_listenImpl: function (node, eventName, methodName) { | 
| +var model = this; | 
| +var host = this._rootDataHost; | 
| +var handler = host._createEventHandler(node, eventName, methodName); | 
| +var decorated = function (e) { | 
| +e.model = model; | 
| +handler(e); | 
| +}; | 
| +host._listen(node, eventName, decorated); | 
| +}, | 
| +_scopeElementClassImpl: function (node, value) { | 
| +var host = this._rootDataHost; | 
| +if (host) { | 
| +return host._scopeElementClass(node, value); | 
| +} | 
| +return value; | 
| +}, | 
| +stamp: function (model) { | 
| +model = model || {}; | 
| +if (this._parentProps) { | 
| +var templatized = this._templatized; | 
| +for (var prop in this._parentProps) { | 
| +if (model[prop] === undefined) { | 
| +model[prop] = templatized[this._parentPropPrefix + prop]; | 
| +} | 
| +} | 
| +} | 
| +return new this.ctor(model, this); | 
| +}, | 
| +modelForElement: function (el) { | 
| +var model; | 
| +while (el) { | 
| +if (model = el._templateInstance) { | 
| +if (model.dataHost != this) { | 
| +el = model.dataHost; | 
| +} else { | 
| +return model; | 
| +} | 
| +} else { | 
| +el = el.parentNode; | 
| +} | 
| +} | 
| +} | 
| +};Polymer({ | 
| +is: 'dom-template', | 
| +extends: 'template', | 
| +_template: null, | 
| +behaviors: [Polymer.Templatizer], | 
| +ready: function () { | 
| +this.templatize(this); | 
| +} | 
| +});Polymer._collections = new WeakMap(); | 
| +Polymer.Collection = function (userArray) { | 
| +Polymer._collections.set(userArray, this); | 
| +this.userArray = userArray; | 
| +this.store = userArray.slice(); | 
| +this.initMap(); | 
| +}; | 
| +Polymer.Collection.prototype = { | 
| +constructor: Polymer.Collection, | 
| +initMap: function () { | 
| +var omap = this.omap = new WeakMap(); | 
| +var pmap = this.pmap = {}; | 
| +var s = this.store; | 
| +for (var i = 0; i < s.length; i++) { | 
| +var item = s[i]; | 
| +if (item && typeof item == 'object') { | 
| +omap.set(item, i); | 
| +} else { | 
| +pmap[item] = i; | 
| +} | 
| +} | 
| +}, | 
| +add: function (item) { | 
| +var key = this.store.push(item) - 1; | 
| +if (item && typeof item == 'object') { | 
| +this.omap.set(item, key); | 
| +} else { | 
| +this.pmap[item] = key; | 
| +} | 
| +return '#' + key; | 
| +}, | 
| +removeKey: function (key) { | 
| +if (key = this._parseKey(key)) { | 
| +this._removeFromMap(this.store[key]); | 
| +delete this.store[key]; | 
| +} | 
| +}, | 
| +_removeFromMap: function (item) { | 
| +if (item && typeof item == 'object') { | 
| +this.omap.delete(item); | 
| +} else { | 
| +delete this.pmap[item]; | 
| +} | 
| +}, | 
| +remove: function (item) { | 
| +var key = this.getKey(item); | 
| +this.removeKey(key); | 
| +return key; | 
| +}, | 
| +getKey: function (item) { | 
| +var key; | 
| +if (item && typeof item == 'object') { | 
| +key = this.omap.get(item); | 
| +} else { | 
| +key = this.pmap[item]; | 
| +} | 
| +if (key != undefined) { | 
| +return '#' + key; | 
| +} | 
| +}, | 
| +getKeys: function () { | 
| +return Object.keys(this.store).map(function (key) { | 
| +return '#' + key; | 
| +}); | 
| +}, | 
| +_parseKey: function (key) { | 
| +if (key && key[0] == '#') { | 
| +return key.slice(1); | 
| +} | 
| +}, | 
| +setItem: function (key, item) { | 
| +if (key = this._parseKey(key)) { | 
| +var old = this.store[key]; | 
| +if (old) { | 
| +this._removeFromMap(old); | 
| +} | 
| +if (item && typeof item == 'object') { | 
| +this.omap.set(item, key); | 
| +} else { | 
| +this.pmap[item] = key; | 
| +} | 
| +this.store[key] = item; | 
| +} | 
| +}, | 
| +getItem: function (key) { | 
| +if (key = this._parseKey(key)) { | 
| +return this.store[key]; | 
| +} | 
| +}, | 
| +getItems: function () { | 
| +var items = [], store = this.store; | 
| +for (var key in store) { | 
| +items.push(store[key]); | 
| +} | 
| +return items; | 
| +}, | 
| +_applySplices: function (splices) { | 
| +var keyMap = {}, key; | 
| +for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { | 
| +s.addedKeys = []; | 
| +for (var j = 0; j < s.removed.length; j++) { | 
| +key = this.getKey(s.removed[j]); | 
| +keyMap[key] = keyMap[key] ? null : -1; | 
| +} | 
| +for (j = 0; j < s.addedCount; j++) { | 
| +var item = this.userArray[s.index + j]; | 
| +key = this.getKey(item); | 
| +key = key === undefined ? this.add(item) : key; | 
| +keyMap[key] = keyMap[key] ? null : 1; | 
| +s.addedKeys.push(key); | 
| +} | 
| +} | 
| +var removed = []; | 
| +var added = []; | 
| +for (key in keyMap) { | 
| +if (keyMap[key] < 0) { | 
| +this.removeKey(key); | 
| +removed.push(key); | 
| +} | 
| +if (keyMap[key] > 0) { | 
| +added.push(key); | 
| +} | 
| +} | 
| +return [{ | 
| +removed: removed, | 
| +added: added | 
| +}]; | 
| +} | 
| +}; | 
| +Polymer.Collection.get = function (userArray) { | 
| +return Polymer._collections.get(userArray) || new Polymer.Collection(userArray); | 
| +}; | 
| +Polymer.Collection.applySplices = function (userArray, splices) { | 
| +var coll = Polymer._collections.get(userArray); | 
| +return coll ? coll._applySplices(splices) : null; | 
| +};Polymer({ | 
| +is: 'dom-repeat', | 
| +extends: 'template', | 
| +_template: null, | 
| +properties: { | 
| +items: { type: Array }, | 
| +as: { | 
| +type: String, | 
| +value: 'item' | 
| +}, | 
| +indexAs: { | 
| +type: String, | 
| +value: 'index' | 
| +}, | 
| +sort: { | 
| +type: Function, | 
| +observer: '_sortChanged' | 
| +}, | 
| +filter: { | 
| +type: Function, | 
| +observer: '_filterChanged' | 
| +}, | 
| +observe: { | 
| +type: String, | 
| +observer: '_observeChanged' | 
| +}, | 
| +delay: Number, | 
| +renderedItemCount: { | 
| +type: Number, | 
| +notify: true, | 
| +readOnly: true | 
| +}, | 
| +initialCount: { | 
| +type: Number, | 
| +observer: '_initializeChunking' | 
| +}, | 
| +targetFramerate: { | 
| +type: Number, | 
| +value: 20 | 
| +}, | 
| +_targetFrameTime: { | 
| +type: Number, | 
| +computed: '_computeFrameTime(targetFramerate)' | 
| +} | 
| +}, | 
| +behaviors: [Polymer.Templatizer], | 
| +observers: ['_itemsChanged(items.*)'], | 
| +created: function () { | 
| +this._instances = []; | 
| +this._pool = []; | 
| +this._limit = Infinity; | 
| +var self = this; | 
| +this._boundRenderChunk = function () { | 
| +self._renderChunk(); | 
| +}; | 
| +}, | 
| +detached: function () { | 
| +this.__isDetached = true; | 
| +for (var i = 0; i < this._instances.length; i++) { | 
| +this._detachInstance(i); | 
| +} | 
| +}, | 
| +attached: function () { | 
| +if (this.__isDetached) { | 
| +this.__isDetached = false; | 
| +var parent = Polymer.dom(Polymer.dom(this).parentNode); | 
| +for (var i = 0; i < this._instances.length; i++) { | 
| +this._attachInstance(i, parent); | 
| +} | 
| +} | 
| +}, | 
| +ready: function () { | 
| +this._instanceProps = { __key__: true }; | 
| +this._instanceProps[this.as] = true; | 
| +this._instanceProps[this.indexAs] = true; | 
| +if (!this.ctor) { | 
| +this.templatize(this); | 
| +} | 
| +}, | 
| +_sortChanged: function (sort) { | 
| +var dataHost = this._getRootDataHost(); | 
| +this._sortFn = sort && (typeof sort == 'function' ? sort : function () { | 
| +return dataHost[sort].apply(dataHost, arguments); | 
| +}); | 
| +this._needFullRefresh = true; | 
| +if (this.items) { | 
| +this._debounceTemplate(this._render); | 
| +} | 
| +}, | 
| +_filterChanged: function (filter) { | 
| +var dataHost = this._getRootDataHost(); | 
| +this._filterFn = filter && (typeof filter == 'function' ? filter : function () { | 
| +return dataHost[filter].apply(dataHost, arguments); | 
| +}); | 
| +this._needFullRefresh = true; | 
| +if (this.items) { | 
| +this._debounceTemplate(this._render); | 
| +} | 
| +}, | 
| +_computeFrameTime: function (rate) { | 
| +return Math.ceil(1000 / rate); | 
| +}, | 
| +_initializeChunking: function () { | 
| +if (this.initialCount) { | 
| +this._limit = this.initialCount; | 
| +this._chunkCount = this.initialCount; | 
| +this._lastChunkTime = performance.now(); | 
| +} | 
| +}, | 
| +_tryRenderChunk: function () { | 
| +if (this.items && this._limit < this.items.length) { | 
| +this.debounce('renderChunk', this._requestRenderChunk); | 
| +} | 
| +}, | 
| +_requestRenderChunk: function () { | 
| +requestAnimationFrame(this._boundRenderChunk); | 
| +}, | 
| +_renderChunk: function () { | 
| +var currChunkTime = performance.now(); | 
| +var ratio = this._targetFrameTime / (currChunkTime - this._lastChunkTime); | 
| +this._chunkCount = Math.round(this._chunkCount * ratio) || 1; | 
| +this._limit += this._chunkCount; | 
| +this._lastChunkTime = currChunkTime; | 
| +this._debounceTemplate(this._render); | 
| +}, | 
| +_observeChanged: function () { | 
| +this._observePaths = this.observe && this.observe.replace('.*', '.').split(' '); | 
| +}, | 
| +_itemsChanged: function (change) { | 
| +if (change.path == 'items') { | 
| +if (Array.isArray(this.items)) { | 
| +this.collection = Polymer.Collection.get(this.items); | 
| +} else if (!this.items) { | 
| +this.collection = null; | 
| +} else { | 
| +this._error(this._logf('dom-repeat', 'expected array for `items`,' + ' found', this.items)); | 
| +} | 
| +this._keySplices = []; | 
| +this._indexSplices = []; | 
| +this._needFullRefresh = true; | 
| +this._initializeChunking(); | 
| +this._debounceTemplate(this._render); | 
| +} else if (change.path == 'items.splices') { | 
| +this._keySplices = this._keySplices.concat(change.value.keySplices); | 
| +this._indexSplices = this._indexSplices.concat(change.value.indexSplices); | 
| +this._debounceTemplate(this._render); | 
| +} else { | 
| +var subpath = change.path.slice(6); | 
| +this._forwardItemPath(subpath, change.value); | 
| +this._checkObservedPaths(subpath); | 
| +} | 
| +}, | 
| +_checkObservedPaths: function (path) { | 
| +if (this._observePaths) { | 
| +path = path.substring(path.indexOf('.') + 1); | 
| +var paths = this._observePaths; | 
| +for (var i = 0; i < paths.length; i++) { | 
| +if (path.indexOf(paths[i]) === 0) { | 
| +this._needFullRefresh = true; | 
| +if (this.delay) { | 
| +this.debounce('render', this._render, this.delay); | 
| +} else { | 
| +this._debounceTemplate(this._render); | 
| +} | 
| +return; | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +render: function () { | 
| +this._needFullRefresh = true; | 
| +this._debounceTemplate(this._render); | 
| +this._flushTemplates(); | 
| +}, | 
| +_render: function () { | 
| +if (this._needFullRefresh) { | 
| +this._applyFullRefresh(); | 
| +this._needFullRefresh = false; | 
| +} else if (this._keySplices.length) { | 
| +if (this._sortFn) { | 
| +this._applySplicesUserSort(this._keySplices); | 
| +} else { | 
| +if (this._filterFn) { | 
| +this._applyFullRefresh(); | 
| +} else { | 
| +this._applySplicesArrayOrder(this._indexSplices); | 
| +} | 
| +} | 
| +} else { | 
| +} | 
| +this._keySplices = []; | 
| +this._indexSplices = []; | 
| +var keyToIdx = this._keyToInstIdx = {}; | 
| +for (var i = this._instances.length - 1; i >= 0; i--) { | 
| +var inst = this._instances[i]; | 
| +if (inst.isPlaceholder && i < this._limit) { | 
| +inst = this._insertInstance(i, inst.__key__); | 
| +} else if (!inst.isPlaceholder && i >= this._limit) { | 
| +inst = this._downgradeInstance(i, inst.__key__); | 
| +} | 
| +keyToIdx[inst.__key__] = i; | 
| +if (!inst.isPlaceholder) { | 
| +inst.__setProperty(this.indexAs, i, true); | 
| +} | 
| +} | 
| +this._pool.length = 0; | 
| +this._setRenderedItemCount(this._instances.length); | 
| +this.fire('dom-change'); | 
| +this._tryRenderChunk(); | 
| +}, | 
| +_applyFullRefresh: function () { | 
| +var c = this.collection; | 
| +var keys; | 
| +if (this._sortFn) { | 
| +keys = c ? c.getKeys() : []; | 
| +} else { | 
| +keys = []; | 
| +var items = this.items; | 
| +if (items) { | 
| +for (var i = 0; i < items.length; i++) { | 
| +keys.push(c.getKey(items[i])); | 
| +} | 
| +} | 
| +} | 
| +var self = this; | 
| +if (this._filterFn) { | 
| +keys = keys.filter(function (a) { | 
| +return self._filterFn(c.getItem(a)); | 
| +}); | 
| +} | 
| +if (this._sortFn) { | 
| +keys.sort(function (a, b) { | 
| +return self._sortFn(c.getItem(a), c.getItem(b)); | 
| +}); | 
| +} | 
| +for (i = 0; i < keys.length; i++) { | 
| +var key = keys[i]; | 
| +var inst = this._instances[i]; | 
| +if (inst) { | 
| +inst.__key__ = key; | 
| +if (!inst.isPlaceholder && i < this._limit) { | 
| +inst.__setProperty(this.as, c.getItem(key), true); | 
| +} | 
| +} else if (i < this._limit) { | 
| +this._insertInstance(i, key); | 
| +} else { | 
| +this._insertPlaceholder(i, key); | 
| +} | 
| +} | 
| +for (var j = this._instances.length - 1; j >= i; j--) { | 
| +this._detachAndRemoveInstance(j); | 
| +} | 
| +}, | 
| +_numericSort: function (a, b) { | 
| +return a - b; | 
| +}, | 
| +_applySplicesUserSort: function (splices) { | 
| +var c = this.collection; | 
| +var keyMap = {}; | 
| +var key; | 
| +for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { | 
| +for (var j = 0; j < s.removed.length; j++) { | 
| +key = s.removed[j]; | 
| +keyMap[key] = keyMap[key] ? null : -1; | 
| +} | 
| +for (j = 0; j < s.added.length; j++) { | 
| +key = s.added[j]; | 
| +keyMap[key] = keyMap[key] ? null : 1; | 
| +} | 
| +} | 
| +var removedIdxs = []; | 
| +var addedKeys = []; | 
| +for (key in keyMap) { | 
| +if (keyMap[key] === -1) { | 
| +removedIdxs.push(this._keyToInstIdx[key]); | 
| +} | 
| +if (keyMap[key] === 1) { | 
| +addedKeys.push(key); | 
| +} | 
| +} | 
| +if (removedIdxs.length) { | 
| +removedIdxs.sort(this._numericSort); | 
| +for (i = removedIdxs.length - 1; i >= 0; i--) { | 
| +var idx = removedIdxs[i]; | 
| +if (idx !== undefined) { | 
| +this._detachAndRemoveInstance(idx); | 
| +} | 
| +} | 
| +} | 
| +var self = this; | 
| +if (addedKeys.length) { | 
| +if (this._filterFn) { | 
| +addedKeys = addedKeys.filter(function (a) { | 
| +return self._filterFn(c.getItem(a)); | 
| +}); | 
| +} | 
| +addedKeys.sort(function (a, b) { | 
| +return self._sortFn(c.getItem(a), c.getItem(b)); | 
| +}); | 
| +var start = 0; | 
| +for (i = 0; i < addedKeys.length; i++) { | 
| +start = this._insertRowUserSort(start, addedKeys[i]); | 
| +} | 
| +} | 
| +}, | 
| +_insertRowUserSort: function (start, key) { | 
| +var c = this.collection; | 
| +var item = c.getItem(key); | 
| +var end = this._instances.length - 1; | 
| +var idx = -1; | 
| +while (start <= end) { | 
| +var mid = start + end >> 1; | 
| +var midKey = this._instances[mid].__key__; | 
| +var cmp = this._sortFn(c.getItem(midKey), item); | 
| +if (cmp < 0) { | 
| +start = mid + 1; | 
| +} else if (cmp > 0) { | 
| +end = mid - 1; | 
| +} else { | 
| +idx = mid; | 
| +break; | 
| +} | 
| +} | 
| +if (idx < 0) { | 
| +idx = end + 1; | 
| +} | 
| +this._insertPlaceholder(idx, key); | 
| +return idx; | 
| +}, | 
| +_applySplicesArrayOrder: function (splices) { | 
| +for (var i = 0, s; i < splices.length && (s = splices[i]); i++) { | 
| +for (var j = 0; j < s.removed.length; j++) { | 
| +this._detachAndRemoveInstance(s.index); | 
| +} | 
| +for (j = 0; j < s.addedKeys.length; j++) { | 
| +this._insertPlaceholder(s.index + j, s.addedKeys[j]); | 
| +} | 
| +} | 
| +}, | 
| +_detachInstance: function (idx) { | 
| +var inst = this._instances[idx]; | 
| +if (!inst.isPlaceholder) { | 
| +for (var i = 0; i < inst._children.length; i++) { | 
| +var el = inst._children[i]; | 
| +Polymer.dom(inst.root).appendChild(el); | 
| +} | 
| +return inst; | 
| +} | 
| +}, | 
| +_attachInstance: function (idx, parent) { | 
| +var inst = this._instances[idx]; | 
| +if (!inst.isPlaceholder) { | 
| +parent.insertBefore(inst.root, this); | 
| +} | 
| +}, | 
| +_detachAndRemoveInstance: function (idx) { | 
| +var inst = this._detachInstance(idx); | 
| +if (inst) { | 
| +this._pool.push(inst); | 
| +} | 
| +this._instances.splice(idx, 1); | 
| +}, | 
| +_insertPlaceholder: function (idx, key) { | 
| +this._instances.splice(idx, 0, { | 
| +isPlaceholder: true, | 
| +__key__: key | 
| +}); | 
| +}, | 
| +_stampInstance: function (idx, key) { | 
| +var model = { __key__: key }; | 
| +model[this.as] = this.collection.getItem(key); | 
| +model[this.indexAs] = idx; | 
| +return this.stamp(model); | 
| +}, | 
| +_insertInstance: function (idx, key) { | 
| +var inst = this._pool.pop(); | 
| +if (inst) { | 
| +inst.__setProperty(this.as, this.collection.getItem(key), true); | 
| +inst.__setProperty('__key__', key, true); | 
| +} else { | 
| +inst = this._stampInstance(idx, key); | 
| +} | 
| +var beforeRow = this._instances[idx + 1]; | 
| +var beforeNode = beforeRow && !beforeRow.isPlaceholder ? beforeRow._children[0] : this; | 
| +var parentNode = Polymer.dom(this).parentNode; | 
| +Polymer.dom(parentNode).insertBefore(inst.root, beforeNode); | 
| +this._instances[idx] = inst; | 
| +return inst; | 
| +}, | 
| +_downgradeInstance: function (idx, key) { | 
| +var inst = this._detachInstance(idx); | 
| +if (inst) { | 
| +this._pool.push(inst); | 
| +} | 
| +inst = { | 
| +isPlaceholder: true, | 
| +__key__: key | 
| +}; | 
| +this._instances[idx] = inst; | 
| +return inst; | 
| +}, | 
| +_showHideChildren: function (hidden) { | 
| +for (var i = 0; i < this._instances.length; i++) { | 
| +this._instances[i]._showHideChildren(hidden); | 
| +} | 
| +}, | 
| +_forwardInstanceProp: function (inst, prop, value) { | 
| +if (prop == this.as) { | 
| +var idx; | 
| +if (this._sortFn || this._filterFn) { | 
| +idx = this.items.indexOf(this.collection.getItem(inst.__key__)); | 
| +} else { | 
| +idx = inst[this.indexAs]; | 
| +} | 
| +this.set('items.' + idx, value); | 
| +} | 
| +}, | 
| +_forwardInstancePath: function (inst, path, value) { | 
| +if (path.indexOf(this.as + '.') === 0) { | 
| +this._notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value); | 
| +} | 
| +}, | 
| +_forwardParentProp: function (prop, value) { | 
| +var i$ = this._instances; | 
| +for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) { | 
| +if (!inst.isPlaceholder) { | 
| +inst.__setProperty(prop, value, true); | 
| +} | 
| +} | 
| +}, | 
| +_forwardParentPath: function (path, value) { | 
| +var i$ = this._instances; | 
| +for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) { | 
| +if (!inst.isPlaceholder) { | 
| +inst._notifyPath(path, value, true); | 
| +} | 
| +} | 
| +}, | 
| +_forwardItemPath: function (path, value) { | 
| +if (this._keyToInstIdx) { | 
| +var dot = path.indexOf('.'); | 
| +var key = path.substring(0, dot < 0 ? path.length : dot); | 
| +var idx = this._keyToInstIdx[key]; | 
| +var inst = this._instances[idx]; | 
| +if (inst && !inst.isPlaceholder) { | 
| +if (dot >= 0) { | 
| +path = this.as + '.' + path.substring(dot + 1); | 
| +inst._notifyPath(path, value, true); | 
| +} else { | 
| +inst.__setProperty(this.as, value, true); | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +itemForElement: function (el) { | 
| +var instance = this.modelForElement(el); | 
| +return instance && instance[this.as]; | 
| +}, | 
| +keyForElement: function (el) { | 
| +var instance = this.modelForElement(el); | 
| +return instance && instance.__key__; | 
| +}, | 
| +indexForElement: function (el) { | 
| +var instance = this.modelForElement(el); | 
| +return instance && instance[this.indexAs]; | 
| +} | 
| +});Polymer({ | 
| +is: 'array-selector', | 
| +_template: null, | 
| +properties: { | 
| +items: { | 
| +type: Array, | 
| +observer: 'clearSelection' | 
| +}, | 
| +multi: { | 
| +type: Boolean, | 
| +value: false, | 
| +observer: 'clearSelection' | 
| +}, | 
| +selected: { | 
| +type: Object, | 
| +notify: true | 
| +}, | 
| +selectedItem: { | 
| +type: Object, | 
| +notify: true | 
| +}, | 
| +toggle: { | 
| +type: Boolean, | 
| +value: false | 
| +} | 
| +}, | 
| +clearSelection: function () { | 
| +if (Array.isArray(this.selected)) { | 
| +for (var i = 0; i < this.selected.length; i++) { | 
| +this.unlinkPaths('selected.' + i); | 
| +} | 
| +} else { | 
| +this.unlinkPaths('selected'); | 
| +this.unlinkPaths('selectedItem'); | 
| +} | 
| +if (this.multi) { | 
| +if (!this.selected || this.selected.length) { | 
| +this.selected = []; | 
| +this._selectedColl = Polymer.Collection.get(this.selected); | 
| +} | 
| +} else { | 
| +this.selected = null; | 
| +this._selectedColl = null; | 
| +} | 
| +this.selectedItem = null; | 
| +}, | 
| +isSelected: function (item) { | 
| +if (this.multi) { | 
| +return this._selectedColl.getKey(item) !== undefined; | 
| +} else { | 
| +return this.selected == item; | 
| +} | 
| +}, | 
| +deselect: function (item) { | 
| +if (this.multi) { | 
| +if (this.isSelected(item)) { | 
| +var skey = this._selectedColl.getKey(item); | 
| +this.arrayDelete('selected', item); | 
| +this.unlinkPaths('selected.' + skey); | 
| +} | 
| +} else { | 
| +this.selected = null; | 
| +this.selectedItem = null; | 
| +this.unlinkPaths('selected'); | 
| +this.unlinkPaths('selectedItem'); | 
| +} | 
| +}, | 
| +select: function (item) { | 
| +var icol = Polymer.Collection.get(this.items); | 
| +var key = icol.getKey(item); | 
| +if (this.multi) { | 
| +if (this.isSelected(item)) { | 
| +if (this.toggle) { | 
| +this.deselect(item); | 
| +} | 
| +} else { | 
| +this.push('selected', item); | 
| +var skey = this._selectedColl.getKey(item); | 
| +this.linkPaths('selected.' + skey, 'items.' + key); | 
| +} | 
| +} else { | 
| +if (this.toggle && item == this.selected) { | 
| +this.deselect(); | 
| +} else { | 
| +this.selected = item; | 
| +this.selectedItem = item; | 
| +this.linkPaths('selected', 'items.' + key); | 
| +this.linkPaths('selectedItem', 'items.' + key); | 
| +} | 
| +} | 
| +} | 
| +});Polymer({ | 
| +is: 'dom-if', | 
| +extends: 'template', | 
| +_template: null, | 
| +properties: { | 
| +'if': { | 
| +type: Boolean, | 
| +value: false, | 
| +observer: '_queueRender' | 
| +}, | 
| +restamp: { | 
| +type: Boolean, | 
| +value: false, | 
| +observer: '_queueRender' | 
| +} | 
| +}, | 
| +behaviors: [Polymer.Templatizer], | 
| +_queueRender: function () { | 
| +this._debounceTemplate(this._render); | 
| +}, | 
| +detached: function () { | 
| +if (!this.parentNode || this.parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE && (!Polymer.Settings.hasShadow || !(this.parentNode instanceof ShadowRoot))) { | 
| +this._teardownInstance(); | 
| +} | 
| +}, | 
| +attached: function () { | 
| +if (this.if && this.ctor) { | 
| +this.async(this._ensureInstance); | 
| +} | 
| +}, | 
| +render: function () { | 
| +this._flushTemplates(); | 
| +}, | 
| +_render: function () { | 
| +if (this.if) { | 
| +if (!this.ctor) { | 
| +this.templatize(this); | 
| +} | 
| +this._ensureInstance(); | 
| +this._showHideChildren(); | 
| +} else if (this.restamp) { | 
| +this._teardownInstance(); | 
| +} | 
| +if (!this.restamp && this._instance) { | 
| +this._showHideChildren(); | 
| +} | 
| +if (this.if != this._lastIf) { | 
| +this.fire('dom-change'); | 
| +this._lastIf = this.if; | 
| +} | 
| +}, | 
| +_ensureInstance: function () { | 
| +var parentNode = Polymer.dom(this).parentNode; | 
| +if (parentNode) { | 
| +var parent = Polymer.dom(parentNode); | 
| +if (!this._instance) { | 
| +this._instance = this.stamp(); | 
| +var root = this._instance.root; | 
| +parent.insertBefore(root, this); | 
| +} else { | 
| +var c$ = this._instance._children; | 
| +if (c$ && c$.length) { | 
| +var lastChild = Polymer.dom(this).previousSibling; | 
| +if (lastChild !== c$[c$.length - 1]) { | 
| +for (var i = 0, n; i < c$.length && (n = c$[i]); i++) { | 
| +parent.insertBefore(n, this); | 
| +} | 
| +} | 
| +} | 
| +} | 
| +} | 
| +}, | 
| +_teardownInstance: function () { | 
| +if (this._instance) { | 
| +var c$ = this._instance._children; | 
| +if (c$ && c$.length) { | 
| +var parent = Polymer.dom(Polymer.dom(c$[0]).parentNode); | 
| +for (var i = 0, n; i < c$.length && (n = c$[i]); i++) { | 
| +parent.removeChild(n); | 
| +} | 
| +} | 
| +this._instance = null; | 
| +} | 
| +}, | 
| +_showHideChildren: function () { | 
| +var hidden = this.__hideTemplateChildren__ || !this.if; | 
| +if (this._instance) { | 
| +this._instance._showHideChildren(hidden); | 
| +} | 
| +}, | 
| +_forwardParentProp: function (prop, value) { | 
| +if (this._instance) { | 
| +this._instance[prop] = value; | 
| +} | 
| +}, | 
| +_forwardParentPath: function (path, value) { | 
| +if (this._instance) { | 
| +this._instance._notifyPath(path, value, true); | 
| +} | 
| +} | 
| +});Polymer({ | 
| +is: 'dom-bind', | 
| +extends: 'template', | 
| +_template: null, | 
| +created: function () { | 
| +var self = this; | 
| +Polymer.RenderStatus.whenReady(function () { | 
| +if (document.readyState == 'loading') { | 
| +document.addEventListener('DOMContentLoaded', function () { | 
| +self._markImportsReady(); | 
| +}); | 
| +} else { | 
| +self._markImportsReady(); | 
| +} | 
| +}); | 
| +}, | 
| +_ensureReady: function () { | 
| +if (!this._readied) { | 
| +this._readySelf(); | 
| +} | 
| +}, | 
| +_markImportsReady: function () { | 
| +this._importsReady = true; | 
| +this._ensureReady(); | 
| +}, | 
| +_registerFeatures: function () { | 
| +this._prepConstructor(); | 
| +}, | 
| +_insertChildren: function () { | 
| +var parentDom = Polymer.dom(Polymer.dom(this).parentNode); | 
| +parentDom.insertBefore(this.root, this); | 
| +}, | 
| +_removeChildren: function () { | 
| +if (this._children) { | 
| +for (var i = 0; i < this._children.length; i++) { | 
| +this.root.appendChild(this._children[i]); | 
| +} | 
| +} | 
| +}, | 
| +_initFeatures: function () { | 
| +}, | 
| +_scopeElementClass: function (element, selector) { | 
| +if (this.dataHost) { | 
| +return this.dataHost._scopeElementClass(element, selector); | 
| +} else { | 
| +return selector; | 
| +} | 
| +}, | 
| +_prepConfigure: function () { | 
| +var config = {}; | 
| +for (var prop in this._propertyEffects) { | 
| +config[prop] = this[prop]; | 
| +} | 
| +var setupConfigure = this._setupConfigure; | 
| +this._setupConfigure = function () { | 
| +setupConfigure.call(this, config); | 
| +}; | 
| +}, | 
| +attached: function () { | 
| +if (this._importsReady) { | 
| +this.render(); | 
| +} | 
| +}, | 
| +detached: function () { | 
| +this._removeChildren(); | 
| +}, | 
| +render: function () { | 
| +this._ensureReady(); | 
| +if (!this._children) { | 
| +this._template = this; | 
| +this._prepAnnotations(); | 
| +this._prepEffects(); | 
| +this._prepBehaviors(); | 
| +this._prepConfigure(); | 
| +this._prepBindings(); | 
| +this._prepPropertyInfo(); | 
| +Polymer.Base._initFeatures.call(this); | 
| +this._children = Polymer.TreeApi.arrayCopyChildNodes(this.root); | 
| +} | 
| +this._insertChildren(); | 
| +this.fire('dom-change'); | 
| +} | 
| +});</script> | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| + | 
| +<script>function MakePromise (asap) { | 
| +  function Promise(fn) { | 
| +		if (typeof this !== 'object' || typeof fn !== 'function') throw new TypeError(); | 
| +		this._state = null; | 
| +		this._value = null; | 
| +		this._deferreds = [] | 
| + | 
| +		doResolve(fn, resolve.bind(this), reject.bind(this)); | 
| +	} | 
| + | 
| +	function handle(deferred) { | 
| +		var me = this; | 
| +		if (this._state === null) { | 
| +			this._deferreds.push(deferred); | 
| +			return | 
| +		} | 
| +		asap(function() { | 
| +			var cb = me._state ? deferred.onFulfilled : deferred.onRejected | 
| +			if (typeof cb !== 'function') { | 
| +				(me._state ? deferred.resolve : deferred.reject)(me._value); | 
| +				return; | 
| +			} | 
| +			var ret; | 
| +			try { | 
| +				ret = cb(me._value); | 
| +			} | 
| +			catch (e) { | 
| +				deferred.reject(e); | 
| +				return; | 
| +			} | 
| +			deferred.resolve(ret); | 
| +		}) | 
| +	} | 
| + | 
| +	function resolve(newValue) { | 
| +		try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure | 
| +			if (newValue === this) throw new TypeError(); | 
| +			if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { | 
| +				var then = newValue.then; | 
| +				if (typeof then === 'function') { | 
| +					doResolve(then.bind(newValue), resolve.bind(this), reject.bind(this)); | 
| +					return; | 
| +				} | 
| +			} | 
| +			this._state = true; | 
| +			this._value = newValue; | 
| +			finale.call(this); | 
| +		} catch (e) { reject.call(this, e); } | 
| +	} | 
| + | 
| +	function reject(newValue) { | 
| +		this._state = false; | 
| +		this._value = newValue; | 
| +		finale.call(this); | 
| +	} | 
| + | 
| +	function finale() { | 
| +		for (var i = 0, len = this._deferreds.length; i < len; i++) { | 
| +			handle.call(this, this._deferreds[i]); | 
| +		} | 
| +		this._deferreds = null; | 
| +	} | 
| + | 
| +	/** | 
| +	 * Take a potentially misbehaving resolver function and make sure | 
| +	 * onFulfilled and onRejected are only called once. | 
| +	 * | 
| +	 * Makes no guarantees about asynchrony. | 
| +	 */ | 
| +	function doResolve(fn, onFulfilled, onRejected) { | 
| +		var done = false; | 
| +		try { | 
| +			fn(function (value) { | 
| +				if (done) return; | 
| +				done = true; | 
| +				onFulfilled(value); | 
| +			}, function (reason) { | 
| +				if (done) return; | 
| +				done = true; | 
| +				onRejected(reason); | 
| +			}) | 
| +		} catch (ex) { | 
| +			if (done) return; | 
| +			done = true; | 
| +			onRejected(ex); | 
| +		} | 
| +	} | 
| + | 
| +	Promise.prototype['catch'] = function (onRejected) { | 
| +		return this.then(null, onRejected); | 
| +	}; | 
| + | 
| +	Promise.prototype.then = function(onFulfilled, onRejected) { | 
| +		var me = this; | 
| +		return new Promise(function(resolve, reject) { | 
| +      handle.call(me, { | 
| +        onFulfilled: onFulfilled, | 
| +        onRejected: onRejected, | 
| +        resolve: resolve, | 
| +        reject: reject | 
| +      }); | 
| +		}) | 
| +	}; | 
| + | 
| +	Promise.resolve = function (value) { | 
| +		if (value && typeof value === 'object' && value.constructor === Promise) { | 
| +			return value; | 
| +		} | 
| + | 
| +		return new Promise(function (resolve) { | 
| +			resolve(value); | 
| +		}); | 
| +	}; | 
| + | 
| +	Promise.reject = function (value) { | 
| +		return new Promise(function (resolve, reject) { | 
| +			reject(value); | 
| +		}); | 
| +	}; | 
| + | 
| + | 
| +  return Promise; | 
| +} | 
| + | 
| +if (typeof module !== 'undefined') { | 
| +  module.exports = MakePromise; | 
| +} | 
| + | 
| +</script> | 
| +<script> | 
| +if (!window.Promise) { | 
| +  window.Promise = MakePromise(Polymer.Base.async); | 
| +} | 
| +</script> | 
| +<script> | 
| +  'use strict'; | 
| + | 
| +  Polymer({ | 
| +    is: 'iron-request', | 
| + | 
| +    hostAttributes: { | 
| +      hidden: true | 
| +    }, | 
| + | 
| +    properties: { | 
| + | 
| +      /** | 
| +       * A reference to the XMLHttpRequest instance used to generate the | 
| +       * network request. | 
| +       * | 
| +       * @type {XMLHttpRequest} | 
| +       */ | 
| +      xhr: { | 
| +        type: Object, | 
| +        notify: true, | 
| +        readOnly: true, | 
| +        value: function() { | 
| +          return new XMLHttpRequest(); | 
| +        } | 
| +      }, | 
| + | 
| +      /** | 
| +       * A reference to the parsed response body, if the `xhr` has completely | 
| +       * resolved. | 
| +       * | 
| +       * @type {*} | 
| +       * @default null | 
| +       */ | 
| +      response: { | 
| +        type: Object, | 
| +        notify: true, | 
| +        readOnly: true, | 
| +        value: function() { | 
| +          return null; | 
| +        } | 
| +      }, | 
| + | 
| +      /** | 
| +       * A reference to the status code, if the `xhr` has completely resolved. | 
| +       */ | 
| +      status: { | 
| +        type: Number, | 
| +        notify: true, | 
| +        readOnly: true, | 
| +        value: 0 | 
| +      }, | 
| + | 
| +      /** | 
| +       * A reference to the status text, if the `xhr` has completely resolved. | 
| +       */ | 
| +      statusText: { | 
| +        type: String, | 
| +        notify: true, | 
| +        readOnly: true, | 
| +        value: '' | 
| +      }, | 
| + | 
| +      /** | 
| +       * A promise that resolves when the `xhr` response comes back, or rejects | 
| +       * if there is an error before the `xhr` completes. | 
| +       * | 
| +       * @type {Promise} | 
| +       */ | 
| +      completes: { | 
| +        type: Object, | 
| +        readOnly: true, | 
| +        notify: true, | 
| +        value: function() { | 
| +          return new Promise(function (resolve, reject) { | 
| +            this.resolveCompletes = resolve; | 
| +            this.rejectCompletes = reject; | 
| +          }.bind(this)); | 
| +        } | 
| +      }, | 
| + | 
| +      /** | 
| +       * An object that contains progress information emitted by the XHR if | 
| +       * available. | 
| +       * | 
| +       * @default {} | 
| +       */ | 
| +      progress: { | 
| +        type: Object, | 
| +        notify: true, | 
| +        readOnly: true, | 
| +        value: function() { | 
| +          return {}; | 
| +        } | 
| +      }, | 
| + | 
| +      /** | 
| +       * Aborted will be true if an abort of the request is attempted. | 
| +       */ | 
| +      aborted: { | 
| +        type: Boolean, | 
| +        notify: true, | 
| +        readOnly: true, | 
| +        value: false, | 
| +      }, | 
| + | 
| +      /** | 
| +       * Errored will be true if the browser fired an error event from the | 
| +       * XHR object (mainly network errors). | 
| +       */ | 
| +      errored: { | 
| +        type: Boolean, | 
| +        notify: true, | 
| +        readOnly: true, | 
| +        value: false | 
| +      }, | 
| + | 
| +      /** | 
| +       * TimedOut will be true if the XHR threw a timeout event. | 
| +       */ | 
| +      timedOut: { | 
| +        type: Boolean, | 
| +        notify: true, | 
| +        readOnly: true, | 
| +        value: false | 
| +      } | 
| +    }, | 
| + | 
| +    /** | 
| +     * Succeeded is true if the request succeeded. The request succeeded if it | 
| +     * loaded without error, wasn't aborted, and the status code is ≥ 200, and | 
| +     * < 300, or if the status code is 0. | 
| +     * | 
| +     * The status code 0 is accepted as a success because some schemes - e.g. | 
| +     * file:// - don't provide status codes. | 
| +     * | 
| +     * @return {boolean} | 
| +     */ | 
| +    get succeeded() { | 
| +      if (this.errored || this.aborted || this.timedOut) { | 
| +        return false; | 
| +      } | 
| +      var status = this.xhr.status || 0; | 
| + | 
| +      // Note: if we are using the file:// protocol, the status code will be 0 | 
| +      // for all outcomes (successful or otherwise). | 
| +      return status === 0 || | 
| +        (status >= 200 && status < 300); | 
| +    }, | 
| + | 
| +    /** | 
| +     * Sends an HTTP request to the server and returns the XHR object. | 
| +     * | 
| +     * The handling of the `body` parameter will vary based on the Content-Type | 
| +     * header. See the docs for iron-ajax's `body` param for details. | 
| +     * | 
| +     * @param {{ | 
| +     *   url: string, | 
| +     *   method: (string|undefined), | 
| +     *   async: (boolean|undefined), | 
| +     *   body: (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|undefined|Object), | 
| +     *   headers: (Object|undefined), | 
| +     *   handleAs: (string|undefined), | 
| +     *   jsonPrefix: (string|undefined), | 
| +     *   withCredentials: (boolean|undefined)}} options - | 
| +     *     url The url to which the request is sent. | 
| +     *     method The HTTP method to use, default is GET. | 
| +     *     async By default, all requests are sent asynchronously. To send synchronous requests, | 
| +     *         set to false. | 
| +     *     body The content for the request body for POST method. | 
| +     *     headers HTTP request headers. | 
| +     *     handleAs The response type. Default is 'text'. | 
| +     *     withCredentials Whether or not to send credentials on the request. Default is false. | 
| +     *   timeout: (Number|undefined) | 
| +     * @return {Promise} | 
| +     */ | 
| +    send: function (options) { | 
| +      var xhr = this.xhr; | 
| + | 
| +      if (xhr.readyState > 0) { | 
| +        return null; | 
| +      } | 
| + | 
| +      xhr.addEventListener('progress', function (progress) { | 
| +        this._setProgress({ | 
| +          lengthComputable: progress.lengthComputable, | 
| +          loaded: progress.loaded, | 
| +          total: progress.total | 
| +        }); | 
| +      }.bind(this)) | 
| + | 
| +      xhr.addEventListener('error', function (error) { | 
| +        this._setErrored(true); | 
| +        this._updateStatus(); | 
| +        this.rejectCompletes(error); | 
| +      }.bind(this)); | 
| + | 
| +      xhr.addEventListener('timeout', function (error) { | 
| +        this._setTimedOut(true); | 
| +        this._updateStatus(); | 
| +        this.rejectCompletes(error); | 
| +      }.bind(this)); | 
| + | 
| +      xhr.addEventListener('abort', function () { | 
| +        this._updateStatus(); | 
| +        this.rejectCompletes(new Error('Request aborted.')); | 
| +      }.bind(this)); | 
| + | 
| +      // Called after all of the above. | 
| +      xhr.addEventListener('loadend', function () { | 
| +        this._updateStatus(); | 
| +        this._setResponse(this.parseResponse()); | 
| + | 
| +        if (!this.succeeded) { | 
| +          this.rejectCompletes(new Error('The request failed with status code: ' + this.xhr.status)); | 
| +          return; | 
| +        } | 
| + | 
| +        this.resolveCompletes(this); | 
| +      }.bind(this)); | 
| + | 
| +      this.url = options.url; | 
| +      xhr.open( | 
| +        options.method || 'GET', | 
| +        options.url, | 
| +        options.async !== false | 
| +      ); | 
| + | 
| +      var acceptType = { | 
| +        'json': 'application/json', | 
| +        'text': 'text/plain', | 
| +        'html': 'text/html', | 
| +        'xml': 'application/xml', | 
| +        'arraybuffer': 'application/octet-stream' | 
| +      }[options.handleAs]; | 
| +      var headers = options.headers || Object.create(null); | 
| +      var newHeaders = Object.create(null); | 
| +      for (var key in headers) { | 
| +        newHeaders[key.toLowerCase()] = headers[key]; | 
| +      } | 
| +      headers = newHeaders; | 
| + | 
| +      if (acceptType && !headers['accept']) { | 
| +        headers['accept'] = acceptType; | 
| +      } | 
| +      Object.keys(headers).forEach(function (requestHeader) { | 
| +        if (/[A-Z]/.test(requestHeader)) { | 
| +          Polymer.Base._error('Headers must be lower case, got', requestHeader); | 
| +        } | 
| +        xhr.setRequestHeader( | 
| +          requestHeader, | 
| +          headers[requestHeader] | 
| +        ); | 
| +      }, this); | 
| + | 
| +      if (options.async !== false) { | 
| +        if (options.async) { | 
| +          xhr.timeout = options.timeout; | 
| +        } | 
| + | 
| +        var handleAs = options.handleAs; | 
| + | 
| +        // If a JSON prefix is present, the responseType must be 'text' or the | 
| +        // browser won’t be able to parse the response. | 
| +        if (!!options.jsonPrefix || !handleAs) { | 
| +          handleAs = 'text'; | 
| +        } | 
| + | 
| +        // In IE, `xhr.responseType` is an empty string when the response | 
| +        // returns. Hence, caching it as `xhr._responseType`. | 
| +        xhr.responseType = xhr._responseType = handleAs; | 
| + | 
| +        // Cache the JSON prefix, if it exists. | 
| +        if (!!options.jsonPrefix) { | 
| +          xhr._jsonPrefix = options.jsonPrefix; | 
| +        } | 
| +      } | 
| + | 
| +      xhr.withCredentials = !!options.withCredentials; | 
| + | 
| + | 
| +      var body = this._encodeBodyObject(options.body, headers['content-type']); | 
| + | 
| +      xhr.send( | 
| +        /** @type {ArrayBuffer|ArrayBufferView|Blob|Document|FormData| | 
| +                   null|string|undefined} */ | 
| +        (body)); | 
| + | 
| +      return this.completes; | 
| +    }, | 
| + | 
| +    /** | 
| +     * Attempts to parse the response body of the XHR. If parsing succeeds, | 
| +     * the value returned will be deserialized based on the `responseType` | 
| +     * set on the XHR. | 
| +     * | 
| +     * @return {*} The parsed response, | 
| +     * or undefined if there was an empty response or parsing failed. | 
| +     */ | 
| +    parseResponse: function () { | 
| +      var xhr = this.xhr; | 
| +      var responseType = xhr.responseType || xhr._responseType; | 
| +      var preferResponseText = !this.xhr.responseType; | 
| +      var prefixLen = (xhr._jsonPrefix && xhr._jsonPrefix.length) || 0; | 
| + | 
| +      try { | 
| +        switch (responseType) { | 
| +          case 'json': | 
| +            // If the xhr object doesn't have a natural `xhr.responseType`, | 
| +            // we can assume that the browser hasn't parsed the response for us, | 
| +            // and so parsing is our responsibility. Likewise if response is | 
| +            // undefined, as there's no way to encode undefined in JSON. | 
| +            if (preferResponseText || xhr.response === undefined) { | 
| +              // Try to emulate the JSON section of the response body section of | 
| +              // the spec: https://xhr.spec.whatwg.org/#response-body | 
| +              // That is to say, we try to parse as JSON, but if anything goes | 
| +              // wrong return null. | 
| +              try { | 
| +                return JSON.parse(xhr.responseText); | 
| +              } catch (_) { | 
| +                return null; | 
| +              } | 
| +            } | 
| + | 
| +            return xhr.response; | 
| +          case 'xml': | 
| +            return xhr.responseXML; | 
| +          case 'blob': | 
| +          case 'document': | 
| +          case 'arraybuffer': | 
| +            return xhr.response; | 
| +          case 'text': | 
| +          default: { | 
| +            // If `prefixLen` is set, it implies the response should be parsed | 
| +            // as JSON once the prefix of length `prefixLen` is stripped from | 
| +            // it. Emulate the behavior above where null is returned on failure | 
| +            // to parse. | 
| +            if (prefixLen) { | 
| +              try { | 
| +                return JSON.parse(xhr.responseText.substring(prefixLen)); | 
| +              } catch (_) { | 
| +                return null; | 
| +              } | 
| +            } | 
| +            return xhr.responseText; | 
| +          } | 
| +        } | 
| +      } catch (e) { | 
| +        this.rejectCompletes(new Error('Could not parse response. ' + e.message)); | 
| +      } | 
| +    }, | 
| + | 
| +    /** | 
| +     * Aborts the request. | 
| +     */ | 
| +    abort: function () { | 
| +      this._setAborted(true); | 
| +      this.xhr.abort(); | 
| +    }, | 
| + | 
| +    /** | 
| +     * @param {*} body The given body of the request to try and encode. | 
| +     * @param {?string} contentType The given content type, to infer an encoding | 
| +     *     from. | 
| +     * @return {*} Either the encoded body as a string, if successful, | 
| +     *     or the unaltered body object if no encoding could be inferred. | 
| +     */ | 
| +    _encodeBodyObject: function(body, contentType) { | 
| +      if (typeof body == 'string') { | 
| +        return body;  // Already encoded. | 
| +      } | 
| +      var bodyObj = /** @type {Object} */ (body); | 
| +      switch(contentType) { | 
| +        case('application/json'): | 
| +          return JSON.stringify(bodyObj); | 
| +        case('application/x-www-form-urlencoded'): | 
| +          return this._wwwFormUrlEncode(bodyObj); | 
| +      } | 
| +      return body; | 
| +    }, | 
| + | 
| +    /** | 
| +     * @param {Object} object The object to encode as x-www-form-urlencoded. | 
| +     * @return {string} . | 
| +     */ | 
| +    _wwwFormUrlEncode: function(object) { | 
| +      if (!object) { | 
| +        return ''; | 
| +      } | 
| +      var pieces = []; | 
| +      Object.keys(object).forEach(function(key) { | 
| +        // TODO(rictic): handle array values here, in a consistent way with | 
| +        //   iron-ajax params. | 
| +        pieces.push( | 
| +            this._wwwFormUrlEncodePiece(key) + '=' + | 
| +            this._wwwFormUrlEncodePiece(object[key])); | 
| +      }, this); | 
| +      return pieces.join('&'); | 
| +    }, | 
| + | 
| +    /** | 
| +     * @param {*} str A key or value to encode as x-www-form-urlencoded. | 
| +     * @return {string} . | 
| +     */ | 
| +    _wwwFormUrlEncodePiece: function(str) { | 
| +      // Spec says to normalize newlines to \r\n and replace %20 spaces with +. | 
| +      // jQuery does this as well, so this is likely to be widely compatible. | 
| +      if (str === null) { | 
| +        return ''; | 
| +      } | 
| +      return encodeURIComponent(str.toString().replace(/\r?\n/g, '\r\n')) | 
| +          .replace(/%20/g, '+'); | 
| +    }, | 
| + | 
| +    /** | 
| +     * Updates the status code and status text. | 
| +     */ | 
| +    _updateStatus: function() { | 
| +      this._setStatus(this.xhr.status); | 
| +      this._setStatusText((this.xhr.statusText === undefined) ? '' : this.xhr.statusText); | 
| +    } | 
| +  }); | 
| +</script> | 
| + | 
| +<script> | 
| +  'use strict'; | 
| + | 
| +  Polymer({ | 
| + | 
| +    is: 'iron-ajax', | 
| + | 
| +    /** | 
| +     * Fired when a request is sent. | 
| +     * | 
| +     * @event request | 
| +     * @event iron-ajax-request | 
| +     */ | 
| + | 
| +    /** | 
| +     * Fired when a response is received. | 
| +     * | 
| +     * @event response | 
| +     * @event iron-ajax-response | 
| +     */ | 
| + | 
| +    /** | 
| +     * Fired when an error is received. | 
| +     * | 
| +     * @event error | 
| +     * @event iron-ajax-error | 
| +     */ | 
| + | 
| +    hostAttributes: { | 
| +      hidden: true | 
| +    }, | 
| + | 
| +    properties: { | 
| +      /** | 
| +       * The URL target of the request. | 
| +       */ | 
| +      url: { | 
| +        type: String | 
| +      }, | 
| + | 
| +      /** | 
| +       * An object that contains query parameters to be appended to the | 
| +       * specified `url` when generating a request. If you wish to set the body | 
| +       * content when making a POST request, you should use the `body` property | 
| +       * instead. | 
| +       */ | 
| +      params: { | 
| +        type: Object, | 
| +        value: function() { | 
| +          return {}; | 
| +        } | 
| +      }, | 
| + | 
| +      /** | 
| +       * The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'. | 
| +       * Default is 'GET'. | 
| +       */ | 
| +      method: { | 
| +        type: String, | 
| +        value: 'GET' | 
| +      }, | 
| + | 
| +      /** | 
| +       * HTTP request headers to send. | 
| +       * | 
| +       * Example: | 
| +       * | 
| +       *     <iron-ajax | 
| +       *         auto | 
| +       *         url="http://somesite.com" | 
| +       *         headers='{"X-Requested-With": "XMLHttpRequest"}' | 
| +       *         handle-as="json"></iron-ajax> | 
| +       * | 
| +       * Note: setting a `Content-Type` header here will override the value | 
| +       * specified by the `contentType` property of this element. | 
| +       */ | 
| +      headers: { | 
| +        type: Object, | 
| +        value: function() { | 
| +          return {}; | 
| +        } | 
| +      }, | 
| + | 
| +      /** | 
| +       * Content type to use when sending data. If the `contentType` property | 
| +       * is set and a `Content-Type` header is specified in the `headers` | 
| +       * property, the `headers` property value will take precedence. | 
| +       * | 
| +       * Varies the handling of the `body` param. | 
| +       */ | 
| +      contentType: { | 
| +        type: String, | 
| +        value: null | 
| +      }, | 
| + | 
| +      /** | 
| +       * Body content to send with the request, typically used with "POST" | 
| +       * requests. | 
| +       * | 
| +       * If body is a string it will be sent unmodified. | 
| +       * | 
| +       * If Content-Type is set to a value listed below, then | 
| +       * the body will be encoded accordingly. | 
| +       * | 
| +       *    * `content-type="application/json"` | 
| +       *      * body is encoded like `{"foo":"bar baz","x":1}` | 
| +       *    * `content-type="application/x-www-form-urlencoded"` | 
| +       *      * body is encoded like `foo=bar+baz&x=1` | 
| +       * | 
| +       * Otherwise the body will be passed to the browser unmodified, and it | 
| +       * will handle any encoding (e.g. for FormData, Blob, ArrayBuffer). | 
| +       * | 
| +       * @type (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|undefined|Object) | 
| +       */ | 
| +      body: { | 
| +        type: Object, | 
| +        value: null | 
| +      }, | 
| + | 
| +      /** | 
| +       * Toggle whether XHR is synchronous or asynchronous. Don't change this | 
| +       * to true unless You Know What You Are Doing™. | 
| +       */ | 
| +      sync: { | 
| +        type: Boolean, | 
| +        value: false | 
| +      }, | 
| + | 
| +      /** | 
| +       * Specifies what data to store in the `response` property, and | 
| +       * to deliver as `event.detail.response` in `response` events. | 
| +       * | 
| +       * One of: | 
| +       * | 
| +       *    `text`: uses `XHR.responseText`. | 
| +       * | 
| +       *    `xml`: uses `XHR.responseXML`. | 
| +       * | 
| +       *    `json`: uses `XHR.responseText` parsed as JSON. | 
| +       * | 
| +       *    `arraybuffer`: uses `XHR.response`. | 
| +       * | 
| +       *    `blob`: uses `XHR.response`. | 
| +       * | 
| +       *    `document`: uses `XHR.response`. | 
| +       */ | 
| +      handleAs: { | 
| +        type: String, | 
| +        value: 'json' | 
| +      }, | 
| + | 
| +      /** | 
| +       * Set the withCredentials flag on the request. | 
| +       */ | 
| +      withCredentials: { | 
| +        type: Boolean, | 
| +        value: false | 
| +      }, | 
| + | 
| +      /** | 
| +       * Set the timeout flag on the request. | 
| +       */ | 
| +      timeout: { | 
| +        type: Number, | 
| +        value: 0 | 
| +      }, | 
| + | 
| +      /** | 
| +       * If true, automatically performs an Ajax request when either `url` or | 
| +       * `params` changes. | 
| +       */ | 
| +      auto: { | 
| +        type: Boolean, | 
| +        value: false | 
| +      }, | 
| + | 
| +      /** | 
| +       * If true, error messages will automatically be logged to the console. | 
| +       */ | 
| +      verbose: { | 
| +        type: Boolean, | 
| +        value: false | 
| +      }, | 
| + | 
| +      /** | 
| +       * The most recent request made by this iron-ajax element. | 
| +       */ | 
| +      lastRequest: { | 
| +        type: Object, | 
| +        notify: true, | 
| +        readOnly: true | 
| +      }, | 
| + | 
| +      /** | 
| +       * True while lastRequest is in flight. | 
| +       */ | 
| +      loading: { | 
| +        type: Boolean, | 
| +        notify: true, | 
| +        readOnly: true | 
| +      }, | 
| + | 
| +      /** | 
| +       * lastRequest's response. | 
| +       * | 
| +       * Note that lastResponse and lastError are set when lastRequest finishes, | 
| +       * so if loading is true, then lastResponse and lastError will correspond | 
| +       * to the result of the previous request. | 
| +       * | 
| +       * The type of the response is determined by the value of `handleAs` at | 
| +       * the time that the request was generated. | 
| +       * | 
| +       * @type {Object} | 
| +       */ | 
| +      lastResponse: { | 
| +        type: Object, | 
| +        notify: true, | 
| +        readOnly: true | 
| +      }, | 
| + | 
| +      /** | 
| +       * lastRequest's error, if any. | 
| +       * | 
| +       * @type {Object} | 
| +       */ | 
| +      lastError: { | 
| +        type: Object, | 
| +        notify: true, | 
| +        readOnly: true | 
| +      }, | 
| + | 
| +      /** | 
| +       * An Array of all in-flight requests originating from this iron-ajax | 
| +       * element. | 
| +       */ | 
| +      activeRequests: { | 
| +        type: Array, | 
| +        notify: true, | 
| +        readOnly: true, | 
| +        value: function() { | 
| +          return []; | 
| +        } | 
| +      }, | 
| + | 
| +      /** | 
| +       * Length of time in milliseconds to debounce multiple automatically generated requests. | 
| +       */ | 
| +      debounceDuration: { | 
| +        type: Number, | 
| +        value: 0, | 
| +        notify: true | 
| +      }, | 
| + | 
| +      /** | 
| +       * Prefix to be stripped from a JSON response before parsing it. | 
| +       * | 
| +       * In order to prevent an attack using CSRF with Array responses | 
| +       * (http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/) | 
| +       * many backends will mitigate this by prefixing all JSON response bodies | 
| +       * with a string that would be nonsensical to a JavaScript parser. | 
| +       * | 
| +       */ | 
| +      jsonPrefix: { | 
| +        type: String, | 
| +        value: '' | 
| +      }, | 
| + | 
| +      /** | 
| +       * By default, iron-ajax's events do not bubble. Setting this attribute will cause its | 
| +       * request and response events as well as its iron-ajax-request, -response,  and -error | 
| +       * events to bubble to the window object. The vanilla error event never bubbles when | 
| +       * using shadow dom even if this.bubbles is true because a scoped flag is not passed with | 
| +       * it (first link) and because the shadow dom spec did not used to allow certain events, | 
| +       * including events named error, to leak outside of shadow trees (second link). | 
| +       * https://www.w3.org/TR/shadow-dom/#scoped-flag | 
| +       * https://www.w3.org/TR/2015/WD-shadow-dom-20151215/#events-that-are-not-leaked-into-ancestor-trees | 
| +       */ | 
| +      bubbles: { | 
| +        type: Boolean, | 
| +        value: false | 
| +      }, | 
| + | 
| +      _boundHandleResponse: { | 
| +        type: Function, | 
| +        value: function() { | 
| +          return this._handleResponse.bind(this); | 
| +        } | 
| +      } | 
| +    }, | 
| + | 
| +    observers: [ | 
| +      '_requestOptionsChanged(url, method, params.*, headers, contentType, ' + | 
| +          'body, sync, handleAs, jsonPrefix, withCredentials, timeout, auto)' | 
| +    ], | 
| + | 
| +    /** | 
| +     * The query string that should be appended to the `url`, serialized from | 
| +     * the current value of `params`. | 
| +     * | 
| +     * @return {string} | 
| +     */ | 
| +    get queryString () { | 
| +      var queryParts = []; | 
| +      var param; | 
| +      var value; | 
| + | 
| +      for (param in this.params) { | 
| +        value = this.params[param]; | 
| +        param = window.encodeURIComponent(param); | 
| + | 
| +        if (Array.isArray(value)) { | 
| +          for (var i = 0; i < value.length; i++) { | 
| +            queryParts.push(param + '=' + window.encodeURIComponent(value[i])); | 
| +          } | 
| +        } else if (value !== null) { | 
| +          queryParts.push(param + '=' + window.encodeURIComponent(value)); | 
| +        } else { | 
| +          queryParts.push(param); | 
| +        } | 
| +      } | 
| + | 
| +      return queryParts.join('&'); | 
| +    }, | 
| + | 
| +    /** | 
| +     * The `url` with query string (if `params` are specified), suitable for | 
| +     * providing to an `iron-request` instance. | 
| +     * | 
| +     * @return {string} | 
| +     */ | 
| +    get requestUrl() { | 
| +      var queryString = this.queryString; | 
| +      var url = this.url || ''; | 
| + | 
| +      if (queryString) { | 
| +        var bindingChar = url.indexOf('?') >= 0 ? '&' : '?'; | 
| +        return url + bindingChar + queryString; | 
| +      } | 
| + | 
| +      return url; | 
| +    }, | 
| + | 
| +    /** | 
| +     * An object that maps header names to header values, first applying the | 
| +     * the value of `Content-Type` and then overlaying the headers specified | 
| +     * in the `headers` property. | 
| +     * | 
| +     * @return {Object} | 
| +     */ | 
| +    get requestHeaders() { | 
| +      var headers = {}; | 
| +      var contentType = this.contentType; | 
| +      if (contentType == null && (typeof this.body === 'string')) { | 
| +        contentType = 'application/x-www-form-urlencoded'; | 
| +      } | 
| +      if (contentType) { | 
| +        headers['content-type'] = contentType; | 
| +      } | 
| +      var header; | 
| + | 
| +      if (this.headers instanceof Object) { | 
| +        for (header in this.headers) { | 
| +          headers[header] = this.headers[header].toString(); | 
| +        } | 
| +      } | 
| + | 
| +      return headers; | 
| +    }, | 
| + | 
| +    /** | 
| +     * Request options suitable for generating an `iron-request` instance based | 
| +     * on the current state of the `iron-ajax` instance's properties. | 
| +     * | 
| +     * @return {{ | 
| +     *   url: string, | 
| +     *   method: (string|undefined), | 
| +     *   async: (boolean|undefined), | 
| +     *   body: (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|undefined|Object), | 
| +     *   headers: (Object|undefined), | 
| +     *   handleAs: (string|undefined), | 
| +     *   jsonPrefix: (string|undefined), | 
| +     *   withCredentials: (boolean|undefined)}} | 
| +     */ | 
| +    toRequestOptions: function() { | 
| +      return { | 
| +        url: this.requestUrl || '', | 
| +        method: this.method, | 
| +        headers: this.requestHeaders, | 
| +        body: this.body, | 
| +        async: !this.sync, | 
| +        handleAs: this.handleAs, | 
| +        jsonPrefix: this.jsonPrefix, | 
| +        withCredentials: this.withCredentials, | 
| +        timeout: this.timeout | 
| +      }; | 
| +    }, | 
| + | 
| +    /** | 
| +     * Performs an AJAX request to the specified URL. | 
| +     * | 
| +     * @return {!IronRequestElement} | 
| +     */ | 
| +    generateRequest: function() { | 
| +      var request = /** @type {!IronRequestElement} */ (document.createElement('iron-request')); | 
| +      var requestOptions = this.toRequestOptions(); | 
| + | 
| +      this.push('activeRequests', request); | 
| + | 
| +      request.completes.then( | 
| +        this._boundHandleResponse | 
| +      ).catch( | 
| +        this._handleError.bind(this, request) | 
| +      ).then( | 
| +        this._discardRequest.bind(this, request) | 
| +      ); | 
| + | 
| +      request.send(requestOptions); | 
| + | 
| +      this._setLastRequest(request); | 
| +      this._setLoading(true); | 
| + | 
| +      this.fire('request', { | 
| +        request: request, | 
| +        options: requestOptions | 
| +      }, {bubbles: this.bubbles}); | 
| + | 
| +      this.fire('iron-ajax-request', { | 
| +        request: request, | 
| +        options: requestOptions | 
| +      }, {bubbles: this.bubbles}); | 
| + | 
| +      return request; | 
| +    }, | 
| + | 
| +    _handleResponse: function(request) { | 
| +      if (request === this.lastRequest) { | 
| +        this._setLastResponse(request.response); | 
| +        this._setLastError(null); | 
| +        this._setLoading(false); | 
| +      } | 
| +      this.fire('response', request, {bubbles: this.bubbles}); | 
| +      this.fire('iron-ajax-response', request, {bubbles: this.bubbles}); | 
| +    }, | 
| + | 
| +    _handleError: function(request, error) { | 
| +      if (this.verbose) { | 
| +        Polymer.Base._error(error); | 
| +      } | 
| + | 
| +      if (request === this.lastRequest) { | 
| +        this._setLastError({ | 
| +          request: request, | 
| +          error: error, | 
| +          status: request.xhr.status, | 
| +          statusText: request.xhr.statusText, | 
| +          response: request.xhr.response | 
| +        }); | 
| +        this._setLastResponse(null); | 
| +        this._setLoading(false); | 
| +      } | 
| + | 
| +      // Tests fail if this goes after the normal this.fire('error', ...) | 
| +      this.fire('iron-ajax-error', { | 
| +        request: request, | 
| +        error: error | 
| +      }, {bubbles: this.bubbles}); | 
| + | 
| +      this.fire('error', { | 
| +        request: request, | 
| +        error: error | 
| +      }, {bubbles: this.bubbles}); | 
| +    }, | 
| + | 
| +    _discardRequest: function(request) { | 
| +      var requestIndex = this.activeRequests.indexOf(request); | 
| + | 
| +      if (requestIndex > -1) { | 
| +        this.splice('activeRequests', requestIndex, 1); | 
| +      } | 
| +    }, | 
| + | 
| +    _requestOptionsChanged: function() { | 
| +      this.debounce('generate-request', function() { | 
| +        if (this.url == null) { | 
| +          return; | 
| +        } | 
| + | 
| +        if (this.auto) { | 
| +          this.generateRequest(); | 
| +        } | 
| +      }, this.debounceDuration); | 
| +    }, | 
| + | 
| +  }); | 
| +</script> | 
| + | 
| + | 
| +<script> | 
| +(function() { | 
| +  "use strict"; | 
| +  /** | 
| +    `Polymer.IronJsonpLibraryBehavior` loads a jsonp library. | 
| +    Multiple components can request same library, only one copy will load. | 
| + | 
| +    Some libraries require a specific global function be defined. | 
| +    If this is the case, specify the `callbackName` property. | 
| + | 
| +    You should use an HTML Import to load library dependencies | 
| +    when possible instead of using this element. | 
| + | 
| +    @hero hero.svg | 
| +    @demo demo/index.html | 
| +    @polymerBehavior | 
| +   */ | 
| +  Polymer.IronJsonpLibraryBehavior = { | 
| + | 
| +    properties: { | 
| +      /** | 
| +       * True if library has been successfully loaded | 
| +       */ | 
| +      libraryLoaded: { | 
| +        type: Boolean, | 
| +        value: false, | 
| +        notify: true, | 
| +        readOnly: true | 
| +      }, | 
| +      /** | 
| +       * Not null if library has failed to load | 
| +       */ | 
| +      libraryErrorMessage: { | 
| +        type: String, | 
| +        value: null, | 
| +        notify: true, | 
| +        readOnly: true | 
| +      } | 
| +      // Following properties are to be set by behavior users | 
| +      /** | 
| +       * Library url. Must contain string `%%callback%%`. | 
| +       * | 
| +       * `%%callback%%` is a placeholder for jsonp wrapper function name | 
| +       * | 
| +       * Ex: https://maps.googleapis.com/maps/api/js?callback=%%callback%% | 
| +       * @property libraryUrl | 
| +       */ | 
| +      /** | 
| +       * Set if library requires specific callback name. | 
| +       * Name will be automatically generated if not set. | 
| +       * @property callbackName | 
| +       */ | 
| +      /** | 
| +       * name of event to be emitted when library loads. Standard is `api-load` | 
| +       * @property notifyEvent | 
| +       */ | 
| +      /** | 
| +       * event with name specified in `notifyEvent` attribute | 
| +       * will fire upon successful load2 | 
| +       * @event `notifyEvent` | 
| +       */ | 
| +    }, | 
| + | 
| +    observers: [ | 
| +      '_libraryUrlChanged(libraryUrl)' | 
| +    ], | 
| + | 
| +    _libraryUrlChanged: function(libraryUrl) { | 
| +      // can't load before ready because notifyEvent might not be set | 
| +      if (this._isReady && this.libraryUrl) | 
| +        this._loadLibrary(); | 
| +    }, | 
| + | 
| +    _libraryLoadCallback: function(err, result) { | 
| +      if (err) { | 
| +        console.warn("Library load failed:", err.message); | 
| +        this._setLibraryErrorMessage(err.message); | 
| +      } | 
| +      else { | 
| +        this._setLibraryErrorMessage(null); | 
| +        this._setLibraryLoaded(true); | 
| +        if (this.notifyEvent) | 
| +          this.fire(this.notifyEvent, result); | 
| +      } | 
| +    }, | 
| + | 
| +    /** loads the library, and fires this.notifyEvent upon completion */ | 
| +    _loadLibrary: function() { | 
| +      LoaderMap.require( | 
| +        this.libraryUrl, | 
| +        this._libraryLoadCallback.bind(this), | 
| +        this.callbackName | 
| +      ); | 
| +    }, | 
| + | 
| +    ready: function() { | 
| +      this._isReady = true; | 
| +      if (this.libraryUrl) | 
| +        this._loadLibrary(); | 
| +    } | 
| +  }; | 
| + | 
| +  /** | 
| +   * LoaderMap keeps track of all Loaders | 
| +   */ | 
| +  var LoaderMap = { | 
| +    apiMap: {}, // { hash -> Loader } | 
| + | 
| +    /** | 
| +     * @param {Function} notifyCallback loaded callback fn(result) | 
| +     * @param {string} jsonpCallbackName name of jsonpcallback. If API does not provide it, leave empty. Optional. | 
| +     */ | 
| +    require: function(url, notifyCallback, jsonpCallbackName) { | 
| + | 
| +      // make hashable string form url | 
| +      var name = this.nameFromUrl(url); | 
| + | 
| +      // create a loader as needed | 
| +      if (!this.apiMap[name]) | 
| +        this.apiMap[name] = new Loader(name, url, jsonpCallbackName); | 
| + | 
| +      // ask for notification | 
| +      this.apiMap[name].requestNotify(notifyCallback); | 
| +    }, | 
| + | 
| +    nameFromUrl: function(url) { | 
| +      return url.replace(/[\:\/\%\?\&\.\=\-\,]/g, '_') + '_api'; | 
| +    } | 
| +  }; | 
| + | 
| +  /** @constructor */ | 
| +  var Loader = function(name, url, callbackName) { | 
| +    this.notifiers = [];  // array of notifyFn [ notifyFn* ] | 
| + | 
| +    // callback is specified either as callback name | 
| +    // or computed dynamically if url has callbackMacro in it | 
| +    if (!callbackName) { | 
| +      if (url.indexOf(this.callbackMacro) >= 0) { | 
| +        callbackName = name + '_loaded'; | 
| +        url = url.replace(this.callbackMacro, callbackName); | 
| +      } else { | 
| +        this.error = new Error('IronJsonpLibraryBehavior a %%callback%% parameter is required in libraryUrl'); | 
| +        // TODO(sjmiles): we should probably fallback to listening to script.load | 
| +        return; | 
| +      } | 
| +    } | 
| +    this.callbackName = callbackName; | 
| +    window[this.callbackName] = this.success.bind(this); | 
| +    this.addScript(url); | 
| +  }; | 
| + | 
| +  Loader.prototype = { | 
| + | 
| +    callbackMacro: '%%callback%%', | 
| +    loaded: false, | 
| + | 
| +    addScript: function(src) { | 
| +      var script = document.createElement('script'); | 
| +      script.src = src; | 
| +      script.onerror = this.handleError.bind(this); | 
| +      var s = document.querySelector('script') || document.body; | 
| +      s.parentNode.insertBefore(script, s); | 
| +      this.script = script; | 
| +    }, | 
| + | 
| +    removeScript: function() { | 
| +      if (this.script.parentNode) { | 
| +        this.script.parentNode.removeChild(this.script); | 
| +      } | 
| +      this.script = null; | 
| +    }, | 
| + | 
| +    handleError: function(ev) { | 
| +      this.error = new Error("Library failed to load"); | 
| +      this.notifyAll(); | 
| +      this.cleanup(); | 
| +    }, | 
| + | 
| +    success: function() { | 
| +      this.loaded = true; | 
| +      this.result = Array.prototype.slice.call(arguments); | 
| +      this.notifyAll(); | 
| +      this.cleanup(); | 
| +    }, | 
| + | 
| +    cleanup: function() { | 
| +      delete window[this.callbackName]; | 
| +    }, | 
| + | 
| +    notifyAll: function() { | 
| +      this.notifiers.forEach( function(notifyCallback) { | 
| +        notifyCallback(this.error, this.result); | 
| +      }.bind(this)); | 
| +      this.notifiers = []; | 
| +    }, | 
| + | 
| +    requestNotify: function(notifyCallback) { | 
| +      if (this.loaded || this.error) { | 
| +        notifyCallback( this.error, this.result); | 
| +      } else { | 
| +        this.notifiers.push(notifyCallback); | 
| +      } | 
| +    } | 
| +  }; | 
| +})(); | 
| +</script> | 
| + | 
| + | 
| +<script> | 
| +  Polymer({ | 
| + | 
| +    is: 'iron-jsonp-library', | 
| + | 
| +    behaviors: [ Polymer.IronJsonpLibraryBehavior ], | 
| + | 
| +    properties: { | 
| +      /** | 
| +       * Library url. Must contain string `%%callback%%`. | 
| +       * | 
| +       * `%%callback%%` is a placeholder for jsonp wrapper function name | 
| +       * | 
| +       * Ex: https://maps.googleapis.com/maps/api/js?callback=%%callback%% | 
| +       */ | 
| +      libraryUrl: String, | 
| +      /** | 
| +       * Set if library requires specific callback name. | 
| +       * Name will be automatically generated if not set. | 
| +       */ | 
| +      callbackName: String, | 
| +      /** | 
| +       * event with name specified in 'notifyEvent' attribute | 
| +       * will fire upon successful load | 
| +       */ | 
| +      notifyEvent: String | 
| +      /** | 
| +       * event with name specified in 'notifyEvent' attribute | 
| +       * will fire upon successful load | 
| +       * @event `notifyEvent` | 
| +       */ | 
| + | 
| +    } | 
| +  }); | 
| + | 
| +</script> | 
| +<script> | 
| +  Polymer({ | 
| + | 
| +    is: 'google-js-api', | 
| + | 
| +    behaviors: [ | 
| +      Polymer.IronJsonpLibraryBehavior | 
| +    ], | 
| + | 
| +    properties: { | 
| + | 
| +      /** @private */ | 
| +      libraryUrl: { | 
| +        type: String, | 
| +        value: 'https://apis.google.com/js/api.js?onload=%%callback%%' | 
| +      }, | 
| + | 
| +      /** | 
| +       * Fired when the API library is loaded and available. | 
| +       * @event js-api-load | 
| +       */ | 
| +      /** | 
| +       * Name of event fired when library is loaded and available. | 
| +       */ | 
| +      notifyEvent: { | 
| +        type: String, | 
| +        value: 'js-api-load' | 
| +      }, | 
| +    }, | 
| + | 
| +    get api() { | 
| +      return gapi; | 
| +    } | 
| + | 
| +  }); | 
| +</script> | 
| + | 
| +<script> | 
| +  (function() { | 
| + | 
| +    /** | 
| +     * Enum of attributes to be passed through to the login API call. | 
| +     * @readonly | 
| +     * @enum {string} | 
| +     */ | 
| +    var ProxyLoginAttributes = { | 
| +      'appPackageName': 'apppackagename', | 
| +      'clientId': 'clientid', | 
| +      'cookiePolicy': 'cookiepolicy', | 
| +      'hostedDomain': 'hostedDomain', | 
| +      'openidPrompt': 'prompt', | 
| +      'requestVisibleActions': 'requestvisibleactions' | 
| +    }; | 
| + | 
| +    /** | 
| +     * AuthEngine does all interactions with gapi.auth2 | 
| +     * | 
| +     * It is tightly coupled with <google-signin-aware> element | 
| +     * The elements configure AuthEngine. | 
| +     * AuthEngine propagates all authentication events to all google-signin-aware elements | 
| +     * | 
| +     * API used: https://developers.google.com/identity/sign-in/web/reference | 
| +     * | 
| +     */ | 
| +    var AuthEngine = { | 
| + | 
| +      /** | 
| +       * oauth2 argument, set by google-signin-aware | 
| +       */ | 
| +      _clientId: null, | 
| + | 
| +      get clientId() { | 
| +        return this._clientId; | 
| +      }, | 
| + | 
| +      set clientId(val) { | 
| +        if (this._clientId && val && val != this._clientId) { | 
| +          throw new Error('clientId cannot change. Values do not match. New: ' + val + ' Old:' + this._clientId); | 
| +        } | 
| +        if (val && val != this._clientId) { | 
| +          this._clientId = val; | 
| +          this.initAuth2(); | 
| +        } | 
| +      }, | 
| + | 
| +      /** | 
| +       * oauth2 argument, set by google-signin-aware | 
| +       */ | 
| +      _cookiePolicy: 'single_host_origin', | 
| + | 
| +      get cookiePolicy() { | 
| +        return this._cookiePolicy; | 
| +      }, | 
| + | 
| +      set cookiePolicy(val) { | 
| +        if (val) { | 
| +          this._cookiePolicy = val; | 
| +        } | 
| +      }, | 
| + | 
| +      /** | 
| +       * oauth2 argument, set by google-signin-aware | 
| +       */ | 
| +      _appPackageName: '', | 
| + | 
| +      get appPackageName() { | 
| +        return this._appPackageName; | 
| +      }, | 
| + | 
| +      set appPackageName(val) { | 
| +        if (this._appPackageName && val && val != this._appPackageName) { | 
| +          throw new Error('appPackageName cannot change. Values do not match. New: ' + val + ' Old: ' + this._appPackageName); | 
| +        } | 
| +        if (val) { | 
| +          this._appPackageName = val; | 
| +        } | 
| +      }, | 
| + | 
| +     /** | 
| +       * oauth2 argument, set by google-signin-aware | 
| +       */ | 
| +      _requestVisibleActions: '', | 
| + | 
| +      get requestVisibleactions() { | 
| +        return this._requestVisibleActions; | 
| +      }, | 
| + | 
| +      set requestVisibleactions(val) { | 
| +        if (this._requestVisibleActions && val && val != this._requestVisibleActions) { | 
| +          throw new Error('requestVisibleactions cannot change. Values do not match. New: ' + val + ' Old: ' + this._requestVisibleActions); | 
| +        } | 
| +        if (val) | 
| +          this._requestVisibleActions = val; | 
| +      }, | 
| + | 
| +     /** | 
| +       * oauth2 argument, set by google-signin-aware | 
| +       */ | 
| +      _hostedDomain: '', | 
| + | 
| +      get hostedDomain() { | 
| +        return this._hostedDomain; | 
| +      }, | 
| + | 
| +      set hostedDomain(val) { | 
| +        if (this._hostedDomain && val && val != this._hostedDomain) { | 
| +          throw new Error('hostedDomain cannot change. Values do not match. New: ' + val + ' Old: ' + this._hostedDomain); | 
| +        } | 
| +        if (val) | 
| +          this._hostedDomain = val; | 
| +      }, | 
| + | 
| +     /** | 
| +       * oauth2 argument, set by google-signin-aware | 
| +       */ | 
| +      _openidPrompt: '', | 
| + | 
| +      get openidPrompt() { | 
| +        return this._openidPrompt; | 
| +      }, | 
| + | 
| +      set openidPrompt(val) { | 
| +        if (typeof val !== 'string') { | 
| +          throw new Error( | 
| +              'openidPrompt must be a string. Received ' + typeof val); | 
| +        } | 
| +        if (val) { | 
| +          var values = val.split(' '); | 
| +          values = values.map(function(v) { | 
| +            return v.trim(); | 
| +          }); | 
| +          values = values.filter(function(v) { | 
| +            return v; | 
| +          }); | 
| +          var validValues = {none: 0, login: 0, consent: 0, select_account: 0}; | 
| +          values.forEach(function(v) { | 
| +            if (v == 'none' && values.length > 1) { | 
| +              throw new Error( | 
| +                  'none cannot be combined with other openidPrompt values'); | 
| +            } | 
| +            if (!(v in validValues)) { | 
| +              throw new Error( | 
| +                  'invalid openidPrompt value ' + v + | 
| +                  '. Valid values: ' + Object.keys(validValues).join(', ')); | 
| +            } | 
| +          }); | 
| +        } | 
| +        this._openidPrompt = val; | 
| +      }, | 
| + | 
| +      /** Is offline access currently enabled in the google-signin-aware element? */ | 
| +      _offline: false, | 
| + | 
| +      get offline() { | 
| +        return this._offline; | 
| +      }, | 
| + | 
| +      set offline(val) { | 
| +        this._offline = val; | 
| +        this.updateAdditionalAuth(); | 
| +      }, | 
| + | 
| +      /** Should we force a re-prompt for offline access? */ | 
| +      _offlineAlwaysPrompt: false, | 
| + | 
| +      get offlineAlwaysPrompt() { | 
| +        return this._offlineAlwaysPrompt; | 
| +      }, | 
| + | 
| +      set offlineAlwaysPrompt(val) { | 
| +        this._offlineAlwaysPrompt = val; | 
| +        this.updateAdditionalAuth(); | 
| +      }, | 
| + | 
| +      /** Have we already gotten offline access from Google during this session? */ | 
| +      offlineGranted: false, | 
| + | 
| +      /** <google-js-api> */ | 
| +      _apiLoader: null, | 
| + | 
| +      /** an array of wanted scopes. oauth2 argument */ | 
| +      _requestedScopeArray: [], | 
| + | 
| +      /** _requestedScopeArray as string */ | 
| +      get requestedScopes() { | 
| +        return this._requestedScopeArray.join(' '); | 
| +      }, | 
| + | 
| +      /** Is user signed in? */ | 
| +      _signedIn: false, | 
| + | 
| +      /** Currently granted scopes */ | 
| +      _grantedScopeArray: [], | 
| + | 
| +      /** True if additional authorization is required */ | 
| +      _needAdditionalAuth: true, | 
| + | 
| +      /** True if have google+ scopes */ | 
| +      _hasPlusScopes: false, | 
| + | 
| +      /** | 
| +       * array of <google-signin-aware> | 
| +       * state changes are broadcast to them | 
| +       */ | 
| +      signinAwares: [], | 
| + | 
| +      init: function() { | 
| +        this._apiLoader = document.createElement('google-js-api'); | 
| +        this._apiLoader.addEventListener('js-api-load', this.loadAuth2.bind(this)); | 
| +      }, | 
| + | 
| +      loadAuth2: function() { | 
| +        gapi.load('auth2', this.initAuth2.bind(this)); | 
| +      }, | 
| + | 
| +      initAuth2: function() { | 
| +        if (!('gapi' in window) || !('auth2' in window.gapi) || !this.clientId) { | 
| +          return; | 
| +        } | 
| +        var auth = gapi.auth2.init({ | 
| +          'client_id': this.clientId, | 
| +          'cookie_policy': this.cookiePolicy, | 
| +          'scope': this.requestedScopes, | 
| +          'hosted_domain': this.hostedDomain | 
| +        }); | 
| + | 
| +        auth['currentUser'].listen(this.handleUserUpdate.bind(this)); | 
| + | 
| +        auth.then( | 
| +          function onFulfilled() { | 
| +          // Let the current user listener trigger the changes. | 
| +          }, | 
| +          function onRejected(error) { | 
| +            console.error(error); | 
| +          } | 
| +        ); | 
| +      }, | 
| + | 
| +      handleUserUpdate: function(newPrimaryUser) { | 
| +        // update and broadcast currentUser | 
| +        var isSignedIn = newPrimaryUser.isSignedIn(); | 
| +        if (isSignedIn != this._signedIn) { | 
| +          this._signedIn = isSignedIn; | 
| +          for (var i=0; i<this.signinAwares.length; i++) { | 
| +            this.signinAwares[i]._setSignedIn(isSignedIn); | 
| +          } | 
| +        } | 
| + | 
| +        // update granted scopes | 
| +        this._grantedScopeArray = this.strToScopeArray( | 
| +          newPrimaryUser.getGrantedScopes()); | 
| +        // console.log(this._grantedScopeArray); | 
| +        this.updateAdditionalAuth(); | 
| + | 
| +        var response = newPrimaryUser.getAuthResponse(); | 
| +        for (var i=0; i<this.signinAwares.length; i++) { | 
| +          this.signinAwares[i]._updateScopeStatus(response); | 
| +        } | 
| +      }, | 
| + | 
| +      setOfflineCode: function(code) { | 
| +        for (var i=0; i<this.signinAwares.length; i++) { | 
| +          this.signinAwares[i]._updateOfflineCode(code); | 
| +        } | 
| +      }, | 
| + | 
| +      /** convert scope string to scope array */ | 
| +      strToScopeArray: function(str) { | 
| +        if (!str) { | 
| +          return []; | 
| +        } | 
| +        // remove extra spaces, then split | 
| +        var scopes = str.replace(/\ +/g, ' ').trim().split(' '); | 
| +        for (var i=0; i<scopes.length; i++) { | 
| +          scopes[i] = scopes[i].toLowerCase(); | 
| +           // Handle scopes that will be deprecated but are still returned with their old value | 
| +          if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.profile') { | 
| +            scopes[i] = 'profile'; | 
| +          } | 
| +          if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.email') { | 
| +            scopes[i] = 'email'; | 
| +          } | 
| +        } | 
| +        // return with duplicates filtered out | 
| +        return scopes.filter( function(value, index, self) { | 
| +          return self.indexOf(value) === index; | 
| +        }); | 
| +      }, | 
| + | 
| +      /** true if scopes have google+ scopes */ | 
| +      isPlusScope: function(scope) { | 
| +        return (scope.indexOf('/auth/games') > -1) | 
| +            || (scope.indexOf('auth/plus.') > -1 && scope.indexOf('auth/plus.me') < 0); | 
| +      }, | 
| + | 
| +      /** true if scopes have been granted */ | 
| +      hasGrantedScopes: function(scopeStr) { | 
| +        var scopes = this.strToScopeArray(scopeStr); | 
| +        for (var i=0; i< scopes.length; i++) { | 
| +          if (this._grantedScopeArray.indexOf(scopes[i]) === -1) | 
| +            return false; | 
| +        } | 
| +        return true; | 
| +      }, | 
| + | 
| +      /** request additional scopes */ | 
| +      requestScopes: function(newScopeStr) { | 
| +        var newScopes = this.strToScopeArray(newScopeStr); | 
| +        var scopesUpdated = false; | 
| +        for (var i=0; i<newScopes.length; i++) { | 
| +          if (this._requestedScopeArray.indexOf(newScopes[i]) === -1) { | 
| +            this._requestedScopeArray.push(newScopes[i]); | 
| +            scopesUpdated = true; | 
| +          } | 
| +        } | 
| +        if (scopesUpdated) { | 
| +          this.updateAdditionalAuth(); | 
| +          this.updatePlusScopes(); | 
| +        } | 
| +      }, | 
| + | 
| +      /** update status of _needAdditionalAuth */ | 
| +      updateAdditionalAuth: function() { | 
| +        var needMoreAuth = false; | 
| +        if ((this.offlineAlwaysPrompt || this.offline ) && !this.offlineGranted) { | 
| +          needMoreAuth = true; | 
| +        } else { | 
| +          for (var i=0; i<this._requestedScopeArray.length; i++) { | 
| +            if (this._grantedScopeArray.indexOf(this._requestedScopeArray[i]) === -1) { | 
| +              needMoreAuth = true; | 
| +              break; | 
| +            } | 
| +          } | 
| +        } | 
| +        if (this._needAdditionalAuth != needMoreAuth) { | 
| +          this._needAdditionalAuth = needMoreAuth; | 
| +          // broadcast new value | 
| +          for (var i=0; i<this.signinAwares.length; i++) { | 
| +            this.signinAwares[i]._setNeedAdditionalAuth(needMoreAuth); | 
| +          } | 
| +        } | 
| +      }, | 
| + | 
| +      updatePlusScopes: function() { | 
| +        var hasPlusScopes = false; | 
| +        for (var i = 0; i < this._requestedScopeArray.length; i++) { | 
| +          if (this.isPlusScope(this._requestedScopeArray[i])) { | 
| +            hasPlusScopes = true; | 
| +            break; | 
| +          } | 
| +        } | 
| +        if (this._hasPlusScopes != hasPlusScopes) { | 
| +          this._hasPlusScopes = hasPlusScopes; | 
| +          for (var i=0; i<this.signinAwares.length; i++) { | 
| +            this.signinAwares[i]._setHasPlusScopes(hasPlusScopes); | 
| +          } | 
| +        } | 
| +      }, | 
| +      /** | 
| +       * attached <google-signin-aware> | 
| +       * @param {!GoogleSigninAwareElement} aware element to add | 
| +       */ | 
| +      attachSigninAware: function(aware) { | 
| +        if (this.signinAwares.indexOf(aware) == -1) { | 
| +          this.signinAwares.push(aware); | 
| +          // Initialize aware properties | 
| +          aware._setNeedAdditionalAuth(this._needAdditionalAuth); | 
| +          aware._setSignedIn(this._signedIn); | 
| +          aware._setHasPlusScopes(this._hasPlusScopes); | 
| +        } else { | 
| +          console.warn('signinAware attached more than once', aware); | 
| +        } | 
| +      }, | 
| + | 
| +      detachSigninAware: function(aware) { | 
| +        var index = this.signinAwares.indexOf(aware); | 
| +        if (index != -1) { | 
| +          this.signinAwares.splice(index, 1); | 
| +        } else { | 
| +          console.warn('Trying to detach unattached signin-aware'); | 
| +        } | 
| +      }, | 
| + | 
| +      /** returns scopes not granted */ | 
| +      getMissingScopes: function() { | 
| +        return this._requestedScopeArray.filter( function(scope) { | 
| +          return this._grantedScopeArray.indexOf(scope) === -1; | 
| +        }.bind(this)).join(' '); | 
| +      }, | 
| + | 
| +      assertAuthInitialized: function() { | 
| +        if (!this.clientId) { | 
| +          throw new Error("AuthEngine not initialized. clientId has not been configured."); | 
| +        } | 
| +        if (!('gapi' in window)) { | 
| +          throw new Error("AuthEngine not initialized. gapi has not loaded."); | 
| +        } | 
| +        if (!('auth2' in window.gapi)) { | 
| +          throw new Error("AuthEngine not initialized. auth2 not loaded."); | 
| +        } | 
| +      }, | 
| + | 
| +      /** pops up sign-in dialog */ | 
| +      signIn: function() { | 
| +        this.assertAuthInitialized(); | 
| +        var params = { | 
| +          'scope': this.getMissingScopes() | 
| +        }; | 
| + | 
| +        // Proxy specific attributes through to the signIn options. | 
| +        Object.keys(ProxyLoginAttributes).forEach(function(key) { | 
| +          if (this[key] && this[key] !== '') { | 
| +            params[ProxyLoginAttributes[key]] = this[key]; | 
| +          } | 
| +        }, this); | 
| + | 
| +        var promise; | 
| +        var user = gapi.auth2.getAuthInstance()['currentUser'].get(); | 
| +        if (!(this.offline || this.offlineAlwaysPrompt)) { | 
| +          if (user.getGrantedScopes()) { | 
| +            // additional auth, skip multiple account dialog | 
| +            promise = user.grant(params); | 
| +          } else { | 
| +            // initial signin | 
| +            promise = gapi.auth2.getAuthInstance().signIn(params); | 
| +          } | 
| +        } else { | 
| +          params.redirect_uri = 'postmessage'; | 
| +          if (this.offlineAlwaysPrompt) { | 
| +            params.approval_prompt = 'force'; | 
| +          } | 
| + | 
| +          // Despite being documented at https://goo.gl/tiO0Bk | 
| +          // It doesn't seem like user.grantOfflineAccess() actually exists in | 
| +          // the current version of the Google Sign-In JS client we're using | 
| +          // through GoogleWebComponents. So in the offline case, we will not | 
| +          // distinguish between a first auth and an additional one. | 
| +          promise = gapi.auth2.getAuthInstance().grantOfflineAccess(params); | 
| +        } | 
| +        promise.then( | 
| +          function onFulfilled(response) { | 
| +            // If login was offline, response contains one string "code" | 
| +            // Otherwise it contains the user object already | 
| +            var newUser; | 
| +            if (response.code) { | 
| +              AuthEngine.offlineGranted = true; | 
| +              newUser = gapi.auth2.getAuthInstance()['currentUser'].get(); | 
| +              AuthEngine.setOfflineCode(response.code); | 
| +            } else { | 
| +              newUser = response; | 
| +            } | 
| + | 
| +            var authResponse = newUser.getAuthResponse(); | 
| +            // Let the current user listener trigger the changes. | 
| +          }, | 
| +          function onRejected(error) { | 
| +            // Access denied is not an error, user hit cancel | 
| +            if ("Access denied." !== error.reason) { | 
| +              this.signinAwares.forEach(function(awareInstance) { | 
| +                awareInstance.errorNotify(error); | 
| +              }); | 
| +            } | 
| +          }.bind(this) | 
| +        ); | 
| +      }, | 
| + | 
| +      /** signs user out */ | 
| +      signOut: function() { | 
| +        this.assertAuthInitialized(); | 
| +        gapi.auth2.getAuthInstance().signOut().then( | 
| +          function onFulfilled() { | 
| +          // Let the current user listener trigger the changes. | 
| +          }, | 
| +          function onRejected(error) { | 
| +            console.error(error); | 
| +          } | 
| +        ); | 
| +      } | 
| +    }; | 
| + | 
| +    AuthEngine.init(); | 
| + | 
| +/** | 
| +`google-signin-aware` is used to enable authentication in custom elements by | 
| +interacting with a google-signin element that needs to be present somewhere | 
| +on the page. | 
| + | 
| +The `scopes` attribute allows you to specify which scope permissions are required | 
| +(e.g do you want to allow interaction with the Google Drive API). | 
| + | 
| +The `google-signin-aware-success` event is triggered when a user successfully | 
| +authenticates. If either `offline` or `offlineAlwaysPrompt` is set to true, successful | 
| +authentication will also trigger the `google-signin-offline-success`event. | 
| +The `google-signin-aware-signed-out` event is triggered when a user explicitly | 
| +signs out via the google-signin element. | 
| + | 
| +You can bind to `isAuthorized` property to monitor authorization state. | 
| +##### Example | 
| + | 
| +    <google-signin-aware scopes="https://www.googleapis.com/auth/drive"></google-signin-aware> | 
| + | 
| + | 
| +##### Example with offline | 
| +    <template id="awareness" is="dom-bind"> | 
| +      <google-signin-aware | 
| +          scopes="https://www.googleapis.com/auth/drive" | 
| +          offline | 
| +          on-google-signin-aware-success="handleSignin" | 
| +          on-google-signin-offline-success="handleOffline"></google-signin-aware> | 
| +    <\/template> | 
| +    <script> | 
| +      var aware = document.querySelector('#awareness'); | 
| +      aware.handleSignin = function(response) { | 
| +        var user = gapi.auth2.getAuthInstance()['currentUser'].get(); | 
| +        console.log('User name: ' + user.getBasicProfile().getName()); | 
| +      }; | 
| +      aware.handleOffline = function(response) { | 
| +        console.log('Offline code received: ' + response.detail.code); | 
| +        // Here you would POST response.detail.code to your webserver, which can | 
| +        // exchange the authorization code for an access token. More info at: | 
| +        // https://developers.google.com/identity/protocols/OAuth2WebServer | 
| +      }; | 
| +    <\/script> | 
| +*/ | 
| +    Polymer({ | 
| + | 
| +      is: 'google-signin-aware', | 
| + | 
| +      /** | 
| +       * Fired when this scope has been authorized | 
| +       * @param {Object} result Authorization result. | 
| +       * @event google-signin-aware-success | 
| +       */ | 
| + | 
| +      /** | 
| +       * Fired when an offline authorization is successful. | 
| +       * @param {{code: string}} detail - | 
| +       *     code: The one-time authorization code from Google. | 
| +       *         Your application can exchange this for an `access_token` and `refresh_token` | 
| +       * @event google-signin-offline-success | 
| +       */ | 
| + | 
| +      /** | 
| +       * Fired when this scope is not authorized | 
| +       * @event google-signin-aware-signed-out | 
| +       */ | 
| + | 
| +      /** | 
| +       * Fired when there is an error during the signin flow. | 
| +       * @param {Object} detail The error object returned from the OAuth 2 flow. | 
| +       * @event google-signin-aware-error | 
| +       */ | 
| + | 
| +      /** | 
| +       * This block is needed so the previous @param is not assigned to the next property. | 
| +       */ | 
| + | 
| +      properties: { | 
| +        /** | 
| +         * App package name for android over-the-air installs. | 
| +         * See the relevant [docs](https://developers.google.com/+/web/signin/android-app-installs) | 
| +         */ | 
| +        appPackageName: { | 
| +          type: String, | 
| +          observer: '_appPackageNameChanged' | 
| +        }, | 
| + | 
| +        /** | 
| +         * a Google Developers clientId reference | 
| +         */ | 
| +        clientId: { | 
| +          type: String, | 
| +          observer: '_clientIdChanged' | 
| +        }, | 
| + | 
| +        /** | 
| +         * The cookie policy defines what URIs have access to the session cookie | 
| +         * remembering the user's sign-in state. | 
| +         * See the relevant [docs](https://developers.google.com/+/web/signin/reference#determining_a_value_for_cookie_policy) for more information. | 
| +         * @default 'single_host_origin' | 
| +         */ | 
| +        cookiePolicy: { | 
| +          type: String, | 
| +          observer: '_cookiePolicyChanged' | 
| +        }, | 
| + | 
| +        /** | 
| +         * The app activity types you want to write on behalf of the user | 
| +         * (e.g http://schemas.google.com/AddActivity) | 
| +         * | 
| +         */ | 
| +        requestVisibleActions: { | 
| +          type: String, | 
| +          observer: '_requestVisibleActionsChanged' | 
| +        }, | 
| + | 
| +        /** | 
| +         * The Google Apps domain to which users must belong to sign in. | 
| +         * See the relevant [docs](https://developers.google.com/identity/sign-in/web/reference) for more information. | 
| +         */ | 
| +        hostedDomain: { | 
| +          type: String, | 
| +          observer: '_hostedDomainChanged' | 
| +        }, | 
| + | 
| +       /** | 
| +         * Allows for offline `access_token` retrieval during the signin process. | 
| +         * See also `offlineAlwaysPrompt`. You only need to set one of the two; if both | 
| +         * are set, the behavior of `offlineAlwaysPrompt` will override `offline`. | 
| +         */ | 
| +        offline: { | 
| +          type: Boolean, | 
| +          value: false, | 
| +          observer: '_offlineChanged' | 
| +        }, | 
| + | 
| +        /** | 
| +          * Works the same as `offline` with the addition that it will always | 
| +          * force a re-prompt to the user, guaranteeing that you will get a | 
| +          * refresh_token even if the user has already granted offline access to | 
| +          * this application. You only need to set one of `offline` or | 
| +          * `offlineAlwaysPrompt`, not both. | 
| +          */ | 
| +        offlineAlwaysPrompt: { | 
| +          type: Boolean, | 
| +          value: false, | 
| +          observer: '_offlineAlwaysPromptChanged' | 
| +        }, | 
| + | 
| +       /** | 
| +         * The scopes to provide access to (e.g https://www.googleapis.com/auth/drive) | 
| +         * and should be space-delimited. | 
| +         */ | 
| +        scopes: { | 
| +          type: String, | 
| +          value: 'profile', | 
| +          observer: '_scopesChanged' | 
| +        }, | 
| + | 
| +        /** | 
| +         * Space-delimited, case-sensitive list of strings that | 
| +         * specifies whether the the user is prompted for reauthentication | 
| +         * and/or consent. The defined values are: | 
| +         *   none: do not display authentication or consent pages. | 
| +         *     This value is mutually exclusive with the rest. | 
| +         *   login: always prompt the user for reauthentication. | 
| +         *   consent: always show consent screen. | 
| +         *   select_account: always show account selection page. | 
| +         *     This enables a user who has multiple accounts to select amongst | 
| +         *     the multiple accounts that they might have current sessions for. | 
| +         * For more information, see "prompt" parameter description in | 
| +         * https://openid.net/specs/openid-connect-basic-1_0.html#RequestParameters | 
| +         */ | 
| +        openidPrompt: { | 
| +          type: String, | 
| +          value: '', | 
| +          observer: '_openidPromptChanged' | 
| +        }, | 
| + | 
| +        /** | 
| +         * True if user is signed in | 
| +         */ | 
| +        signedIn: { | 
| +          type: Boolean, | 
| +          notify: true, | 
| +          readOnly: true | 
| +        }, | 
| + | 
| +        /** | 
| +         * True if authorizations for *this* element have been granted | 
| +         */ | 
| +        isAuthorized: { | 
| +          type: Boolean, | 
| +          notify: true, | 
| +          readOnly: true, | 
| +          value: false | 
| +        }, | 
| + | 
| +        /** | 
| +         * True if additional authorizations for *any* element are required | 
| +         */ | 
| +        needAdditionalAuth: { | 
| +          type: Boolean, | 
| +          notify: true, | 
| +          readOnly: true | 
| +        }, | 
| + | 
| +        /** | 
| +         * True if *any* element has google+ scopes | 
| +         */ | 
| +        hasPlusScopes: { | 
| +          type: Boolean, | 
| +          value: false, | 
| +          notify: true, | 
| +          readOnly: true | 
| +        } | 
| +      }, | 
| + | 
| +      attached: function() { | 
| +        AuthEngine.attachSigninAware(this); | 
| +      }, | 
| + | 
| +      detached: function() { | 
| +        AuthEngine.detachSigninAware(this); | 
| +      }, | 
| + | 
| +      /** pops up the authorization dialog */ | 
| +      signIn: function() { | 
| +        AuthEngine.signIn(); | 
| +      }, | 
| + | 
| +      /** signs user out */ | 
| +      signOut: function() { | 
| +        AuthEngine.signOut(); | 
| +      }, | 
| + | 
| +      errorNotify: function(error) { | 
| +        this.fire('google-signin-aware-error', error); | 
| +      }, | 
| + | 
| +      _appPackageNameChanged: function(newName, oldName) { | 
| +        AuthEngine.appPackageName = newName; | 
| +      }, | 
| + | 
| +      _clientIdChanged: function(newId, oldId) { | 
| +        AuthEngine.clientId = newId; | 
| +      }, | 
| + | 
| +      _cookiePolicyChanged: function(newPolicy, oldPolicy) { | 
| +        AuthEngine.cookiePolicy = newPolicy; | 
| +      }, | 
| + | 
| +      _requestVisibleActionsChanged: function(newVal, oldVal) { | 
| +        AuthEngine.requestVisibleActions = newVal; | 
| +      }, | 
| + | 
| +      _hostedDomainChanged: function(newVal, oldVal) { | 
| +        AuthEngine.hostedDomain = newVal; | 
| +      }, | 
| + | 
| +      _offlineChanged: function(newVal, oldVal) { | 
| +        AuthEngine.offline = newVal; | 
| +      }, | 
| + | 
| +      _offlineAlwaysPromptChanged: function(newVal, oldVal) { | 
| +        AuthEngine.offlineAlwaysPrompt = newVal; | 
| +      }, | 
| + | 
| +      _scopesChanged: function(newVal, oldVal) { | 
| +        AuthEngine.requestScopes(newVal); | 
| +        this._updateScopeStatus(undefined); | 
| +      }, | 
| + | 
| +      _openidPromptChanged: function(newVal, oldVal) { | 
| +        AuthEngine.openidPrompt = newVal; | 
| +      }, | 
| + | 
| +      _updateScopeStatus: function(user) { | 
| +        var newAuthorized = this.signedIn && AuthEngine.hasGrantedScopes(this.scopes); | 
| +        if (newAuthorized !== this.isAuthorized) { | 
| +          this._setIsAuthorized(newAuthorized); | 
| +          if (newAuthorized) { | 
| +            this.fire('google-signin-aware-success', user); | 
| +          } | 
| +          else { | 
| +            this.fire('google-signin-aware-signed-out', user); | 
| +          } | 
| +        } | 
| +      }, | 
| + | 
| +      _updateOfflineCode: function(code) { | 
| +        if (code) { | 
| +          this.fire('google-signin-offline-success', {code: code}); | 
| +        } | 
| +      } | 
| +    }); | 
| +  })(); | 
| +</script> | 
| +<dom-module id="auth-signin" assetpath="imp/common/"> | 
| +  <template> | 
| +    <style> | 
| +      #avatar { | 
| +        border-radius: 5px; | 
| +      } | 
| +      #signinContainer { | 
| +        margin-top: 14px; | 
| +      } | 
| +    </style> | 
| + | 
| +    <google-signin-aware id="aware" client-id="[[clientId]]" scopes="email" on-google-signin-aware-success="_onSignin" on-google-signin-aware-signed-out="_onSignout"> | 
| +    </google-signin-aware> | 
| + | 
| +    <template is="dom-if" if="[[!signedIn]]"> | 
| +      <div id="signinContainer"> | 
| +        <a on-tap="signIn" href="#">Sign in</a> | 
| +      </div> | 
| +    </template> | 
| + | 
| +    <template is="dom-if" if="[[signedIn]]"> | 
| +      <img id="avatar" src="[[profile.imageUrl]]" width="30" height="30"> | 
| +      <span>[[profile.email]]</span> | 
| +      <span>|</span> | 
| +      <a on-tap="signOut" href="#">Sign out</a> | 
| +    </template> | 
| +  </template> | 
| +  <script> | 
| +    'use strict'; | 
| +    Polymer({ | 
| +      is: 'auth-signin', | 
| +      properties: { | 
| +        authHeaders: { | 
| +          type: Object, | 
| +          computed: "_makeHeader(authResponse)", | 
| +          notify: true, | 
| +        }, | 
| +        authResponse: { | 
| +          type: Object, | 
| +          notify: true, | 
| +        }, | 
| +        clientId: { | 
| +          type: String, | 
| +        }, | 
| +        profile: { | 
| +          type: Object, | 
| +          readOnly: true | 
| +        }, | 
| +        signedIn: { | 
| +          type: Boolean, | 
| +          readOnly: true, | 
| +          value: false | 
| +        } | 
| +      }, | 
| + | 
| +      _onSignin: function(e) { | 
| +        this._setSignedIn(true); | 
| +        var user = gapi.auth2.getAuthInstance().currentUser.get(); | 
| +        var profile = user.getBasicProfile(); | 
| +        this._setProfile({ | 
| +          email: profile.getEmail(), | 
| +          imageUrl: profile.getImageUrl() | 
| +        }); | 
| +        this.set("authResponse", user.getAuthResponse()); | 
| +        this.fire("auth-signin"); | 
| +      }, | 
| + | 
| +      _onSignout: function(e) { | 
| +        this._setSignedIn(false); | 
| +        this._setProfile(null); | 
| +      }, | 
| + | 
| +      _makeHeader: function(authResponse) { | 
| +        if (!authResponse) { | 
| +          return {}; | 
| +        } | 
| +        return { | 
| +          "authorization": authResponse.token_type + " " + authResponse.access_token | 
| +        }; | 
| +      }, | 
| + | 
| +      signIn: function() { | 
| +        this.$.aware.signIn(); | 
| +      }, | 
| + | 
| +      signOut: function() { | 
| +        this.$.aware.signOut(); | 
| +      } | 
| +    }); | 
| +  </script> | 
| +</dom-module><dom-module id="swarming-index" assetpath="imp/index/"> | 
| +  <template> | 
| +    <style> | 
| +      :host { | 
| +        display: block; | 
| +      } | 
| +    </style> | 
| + | 
| +    <h1>HELLO WORLD</h1><h1> | 
| + | 
| + | 
| +    <auth-signin auth-headers="{{auth}}" client-id="20770472288-t5smpbpjptka4nd888fv0ctd23ftba2o.apps.googleusercontent.com" on-auth-signin="signIn"> | 
| +    </auth-signin> | 
| + | 
| +    <iron-ajax id="request" url="/_ah/api/swarming/v1/server/details" headers="[[auth]]" handle-as="json" on-response="handleResponse"> | 
| +    </iron-ajax> | 
| + | 
| +  </h1></template> | 
| +  <script> | 
| +    Polymer({ | 
| +      is: 'swarming-index', | 
| + | 
| +      signIn: function(){ | 
| +        this.$.request.generateRequest(); | 
| +      }, | 
| + | 
| +      handleResponse: function(a,b){ | 
| +        console.log(this.$.request.lastResponse); | 
| +      } | 
| +    }); | 
| +  </script> | 
| +</dom-module></div> | 
| +  <swarming-index></swarming-index> | 
| + | 
| + | 
| +</body></html> | 
|  |