Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Side by Side Diff: appengine/swarming/elements/build/index-build.html

Issue 2177353002: Add top level app element (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@hello-oauth
Patch Set: Fix presubmits to ignore build files Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <!DOCTYPE html><html><head><!--
2 @license
3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
4 This code may only be used under the BSD style license found at http://polymer.g ithub.io/LICENSE.txt
5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 The complete set of contributors may be found at http://polymer.github.io/CONTRI BUTORS.txt
7 Code distributed by Google as part of the polymer project is also
8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
9 --><!--
10 @license
11 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
12 This code may only be used under the BSD style license found at http://polymer.g ithub.io/LICENSE.txt
13 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
14 The complete set of contributors may be found at http://polymer.github.io/CONTRI BUTORS.txt
15 Code distributed by Google as part of the polymer project is also
16 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
17 -->
18 <title>Many World, wow such hello</title>
19 <meta charset="utf-8">
20 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
21 <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial- scale=1, user-scalable=yes">
22
23 <script>/**
24 * @license
25 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
26 * This code may only be used under the BSD style license found at http://polyme r.github.io/LICENSE.txt
27 * The complete set of authors may be found at http://polymer.github.io/AUTHORS. txt
28 * The complete set of contributors may be found at http://polymer.github.io/CON TRIBUTORS.txt
29 * Code distributed by Google as part of the polymer project is also
30 * subject to an additional IP rights grant found at http://polymer.github.io/PA TENTS.txt
31 */
32 // @version 0.7.22
33 !function(){window.WebComponents=window.WebComponents||{flags:{}};var e="webcomp onents-lite.js",t=document.querySelector('script[src*="'+e+'"]'),n={};if(!n.noOp ts){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.at tributes[r];r++)"src"!==o.name&&(n[o.name]=o.value||!0);if(n.log&&n.log.split){v ar 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.Cus tomElements.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._isIn valid=!0}function o(e){return""==e&&n.call(this),e.toLowerCase()}function r(e){v ar t=e.charCodeAt(0);return t>32&&127>t&&-1==[34,35,60,62,63,96].indexOf(t)?e:en codeURIComponent(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.tes t(b)){if(a){c("Invalid scheme.");break e}u="",d="no scheme";continue}u+=b.toLowe rCase(),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 firs t 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._schem e&&(this._scheme=s._scheme),p==b){this._host=s._host,this._port=s._port,this._pa th=s._path.slice(),this._query=s._query,this._username=s._username,this._passwor d=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._sche me||!m.test(b)||":"!=y&&"|"!=y||p!=E&&"/"!=E&&"\\"!=E&&"?"!=E&&"#"!=E)&&(this._h ost=s._host,this._port=s._port,this._username=s._username,this._password=s._pass word,this._path=s._path.slice(),this._path.pop()),d="relative path";continue}thi s._host=s._host,this._port=s._port,this._path=s._path.slice(),this._query=s._que ry,this._fragment="#",this._username=s._username,this._password=s._password,d="f ragment"}break;case"relative slash":if("/"!=b&&"\\"!=b){"file"!=this._scheme&&(t his._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"autho rity first slash":if("/"!=b){c("Expected '/', got: "+b),d="authority ignore slas hes";continue}d="authority second slash";break;case"authority second slash":if(d ="authority ignore slashes","/"!=b){c("Expected '/', got: "+b);continue}break;ca se"authority ignore slashes":if("/"!=b&&"\\"!=b){d="authority";continue}c("Expec ted 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="rela tive path start":(this._host=o.call(this,u),u="",d="relative path start"):d="rel ative path";continue}" "==b||"\n"==b||"\r"==b?c("Invalid whitespace in file hos t."):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)br eak 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;els e{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";co ntinue}" "==b||"\n"==b||"\r"==b?c("Invalid code point in port: "+b):n.cal l(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.lengt h&&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")}brea k;case"query":a||"#"!=b?p!=b&&" "!=b&&"\n"!=b&&"\r"!=b&&(this._query+=i(b)):(thi s._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}functi on c(e,t){void 0===t||t instanceof c||(t=new c(String(t))),this._url=e,s.call(th is);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="ht tp://a/c%20d"===l.href}catch(u){}if(!d){var h=Object.create(null);h.ftp=21,h.fil e=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._usernam e&&null==this._password||(e=this._username+(null!=this._password?":"+this._passw ord:"")+"@"),this.protocol+(this._isRelative?"//"+e+this.host:"")+this.pathname+ this._query+this._fragment},set href(e){s.call(this),a.call(this,e)},get protoco l(){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(th is,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._sch emeData},set pathname(e){!this._isInvalid&&this._isRelative&&(this._path=[],a.ca ll(this,e,"relative path start"))},get search(){return this._isInvalid||!this._q uery||"?"==this._query?"":this._query},set search(e){!this._isInvalid&&this._isR elative&&(this._query="?","?"==e[0]&&(e=e.slice(1)),a.call(this,e,"query"))},get hash(){return this._isInvalid||!this._fragment||"#"==this._fragment?"":this._fr agment},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._sch eme)return"";switch(this._scheme){case"data":case"file":case"javascript":case"ma ilto":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.r evokeObjectURL=function(e){w.revokeObjectURL(e)}),e.URL=c}}(self),"undefined"==t ypeof WeakMap&&!function(){var e=Object.defineProperty,t=Date.now()%1e9,n=functi on(){this.name="__st"+(1e9*Math.random()>>>0)+(t++ +"__")};n.prototype={set:func tion(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){re turn window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(e)||e}funct ion 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.forEac h(function(t){t.observer===e&&t.removeTransientObservers()})})}function i(e,t){f or(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.previ ousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeName space=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.previo usSibling=e.previousSibling,t.nextSibling=e.nextSibling,t.attributeName=e.attrib uteName,t.attributeNamespace=e.attributeNamespace,t.oldValue=e.oldValue,t}functi on d(e,t){return E=new s(e,t)}function l(e){return L?L:(L=c(E),L.oldValue=e,L)}f unction 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.opti ons=n,this.transientObservedNodes=[]}if(!e.JsMutationObserver){var m,v=new WeakM ap;if(/Trident|Edge/.test(navigator.userAgent))m=setTimeout;else if(window.setIm mediate)m=window.setImmediate;else{var w=[],_=String(Math.random());window.addEv entListener("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.c haracterData||t.attributeOldValue&&!t.attributes||t.attributeFilter&&t.attribute Filter.length&&!t.attributes||t.characterDataOldValue&&!t.characterData)throw ne w 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(thi s,e,t),o.push(r),this.nodes_.push(e)),r.addListeners()},disconnect:function(){th is.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.reco rds_=[]},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.obs erver);n[o]=e},addListeners:function(){this.addListeners_(this.target)},addListe ners_:function(e){var t=this.options;t.attributes&&e.addEventListener("DOMAttrMo dified",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:func tion(){this.removeListeners_(this.target)},removeListeners_:function(e){var t=th is.options;t.attributes&&e.removeEventListener("DOMAttrModified",this,!0),t.char acterData&&e.removeEventListener("DOMCharacterDataModified",this,!0),t.childList &&e.removeEventListener("DOMNodeInserted",this,!0),(t.childList||t.subtree)&&e.r emoveEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(e){i f(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(funct ion(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.stopImmediat ePropagation(),e.type){case"DOMAttrModified":var t=e.attrName,n=e.relatedNode.na mespaceURI,o=e.target,r=new d("attributes",o);r.attributeName=t,r.attributeNames pace=n;var a=e.attrChange===MutationEvent.ADDITION?null:e.prevValue;i(o,function (e){return!e.attributes||e.attributeFilter&&e.attributeFilter.length&&-1===e.att ributeFilter.indexOf(t)&&-1===e.attributeFilter.indexOf(n)?void 0:e.attributeOld Value?l(a):r});break;case"DOMCharacterDataModified":var o=e.target,r=d("characte rData",o),a=e.prevValue;i(o,function(e){return e.characterData?e.characterDataOl dValue?l(a):r:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(e.ta rget);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.ta rget.parentNode);r.addedNodes=s,r.removedNodes=c,r.previousSibling=f,r.nextSibli ng=p,i(e.relatedNode,function(e){return e.childList?r:void 0})}u()}},e.JsMutatio nObserver=a,e.MutationObserver||(e.MutationObserver=a,a._isPolyfilled=!0)}}(self ),function(){function e(e){switch(e){case"&":return"&amp;";case"<":return"&lt;"; case">":return"&gt;";case" ":return"&nbsp;"}}function t(t){return t.replace(u,e) }var n="undefined"==typeof HTMLTemplateElement;/Trident/.test(navigator.userAgen t)&&!function(){var e=document.importNode;document.importNode=function(){var t=e .apply(document,arguments);if(t.nodeType===Node.DOCUMENT_FRAGMENT_NODE){var n=do cument.createDocumentFragment();return n.appendChild(t),n}return t}}();var o=fun ction(){if(!n){var e=document.createElement("template"),t=document.createElement ("template");t.content.appendChild(document.createElement("div")),e.content.appe ndChild(t);var o=e.cloneNode(!0);return 0===o.content.childNodes.length||0===o.c ontent.firstChild.content.childNodes.length}}(),r="template",i=function(){};if(n ){var a=document.implementation.createHTMLDocument("template"),s=!0,c=document.c reateElement("style");c.textContent=r+"{display:none;}";var d=document.head;d.in sertBefore(c,d.firstElementChild),i.prototype=Object.create(HTMLElement.prototyp e),i.decorate=function(e){if(!e.content){e.content=a.createDocumentFragment();fo r(var n;n=e.firstChild;)e.content.appendChild(n);if(e.cloneNode=function(e){retu rn 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.d ata);return e},set:function(e){for(a.body.innerHTML=e,i.bootstrap(a);this.conten t.firstChild;)this.content.removeChild(this.content.firstChild);for(;a.body.firs tChild;)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.querySelecto rAll(r),o=0,a=n.length;a>o&&(t=n[o]);o++)i.decorate(t)},document.addEventListene r("DOMContentLoaded",function(){i.bootstrap(document)});var l=document.createEle ment;document.createElement=function(){"use strict";var e=l.apply(document,argum ents);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.conte nt,!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.parentN ode.replaceChild(o.cloneNode(!0),n)};var f=document.importNode;Node.prototype.cl oneNode=function(e){var t=h.call(this,e);return e&&i.fixClonedDom(t,this),t},doc ument.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.pr ototype.cloneNode=function(e){return i.cloneNode(this,e)})}n&&(window.HTMLTempla teElement=i)}(),function(e){"use strict";if(!window.performance){var t=Date.now( );window.performance={now:function(){return Date.now()-t}}}window.requestAnimati onFrame||(window.requestAnimationFrame=function(){var e=window.webkitRequestAnim ationFrame||window.mozRequestAnimationFrame;return e?function(t){return e(functi on(){t(performance.now())})}:function(e){return window.setTimeout(e,1e3/60)}}()) ,window.cancelAnimationFrame||(window.cancelAnimationFrame=function(){return win dow.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(e){clea rTimeout(e)}}());var n=function(){var e=document.createEvent("Event");return e.i nitEvent("foo",!0,!0),e.preventDefault(),e.defaultPrevented}();if(!n){var o=Even t.prototype.preventDefault;Event.prototype.preventDefault=function(){this.cancel able&&(o.call(this),Object.defineProperty(this,"defaultPrevented",{get:function( ){return!0},configurable:!0}))}}var r=/Trident/.test(navigator.userAgent);if((!w indow.CustomEvent||r&&"function"!=typeof window.CustomEvent)&&(window.CustomEven t=function(e,t){t=t||{};var n=document.createEvent("CustomEvent");return n.initC ustomEvent(e,Boolean(t.bubbles),Boolean(t.cancelable),t.detail),n},window.Custom Event.prototype=window.Event.prototype),!window.Event||r&&"function"!=typeof win dow.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.cancelabl e)),n},window.Event.prototype=i.prototype}}(window.WebComponents),window.HTMLImp orts=window.HTMLImports||{flags:{}},function(e){function t(e,t){t=t||p,o(functio n(){i(e,t)},t)}function n(e){return"complete"===e.readyState||e.readyState===w}f unction 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)}}f unction r(e){e.target.__loaded=!0}function i(e,t){function n(){c==d&&e&&e({allIm ports: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"].readySt ate: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.addEventList ener("error",r))}var l="import",u=Boolean(l in document.createElement("link")),h =Boolean(window.ShadowDOMPolyfill),f=function(e){return h?window.ShadowDOMPolyfi ll.wrapIfNeeded(e):e},p=f(document),m={get:function(){var e=window.HTMLImports.c urrentScript||document.currentScript||("complete"!==document.readyState?document .scripts[document.scripts.length-1]:null);return f(e)},configurable:!0};Object.d efineProperty(document,"_currentScript",m),Object.defineProperty(p,"_currentScri pt",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,{childL ist:!0}),function(){if("loading"===document.readyState)for(var e,t=document.quer ySelectorAll("link[rel=import]"),n=0,o=t.length;o>n&&(e=t[n]);n++)d(e)}()),t(fun ction(e){window.HTMLImports.ready=!0,window.HTMLImports.readyTime=(new Date).get Time();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.initializ eModules=o}(window.HTMLImports),window.HTMLImports.addModule(function(e){var t=/ (url\()([^)]*)(\))/g,n=/(@import[\s]+(?!url\())([^;]*)(;)/g,o={resolveUrlsInStyl e:function(e,t){var n=e.ownerDocument,o=n.createElement("a");return e.textConten t=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)},repla ceUrls: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+="?"+Ma th.random()),i.open("GET",n,t.async),i.addEventListener("readystatechange",funct ion(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.HTM LImports.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++,t his.require(e),this.checkDone()},require:function(e){var t=e.src||e.href;e.__nod eUrl=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.c ache[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.receiv e(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.prototyp e={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.HTMLImp orts.addModule(function(e){function t(e){return"link"===e.localName&&e.rel===l}f unction n(e){var t=o(e);return"data:text/javascript;charset=utf-8,"+encodeURICom ponent(t)}function o(e){return e.textContent+r(e)}function r(e){var t=e.ownerDoc ument;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("s tyle");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])","sty le:not([type])","script:not([type])",'script[type="application/javascript"]','sc ript[type="text/javascript"]'].join(","),map:{link:"parseLink",script:"parseScri pt",style:"parseStyle"},dynamicElements:[],parseNext:function(){var e=this.nextT oParse();e&&this.parse(e)},parse:function(e){if(this.isParsed(e))return void(c.p arse&&console.log("[%s] is already parsed",e.localName));var t=this[this.map[e.l ocalName]];t&&(this.markParsing(e),t.call(this,e))},parseDynamic:function(e,t){t his.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.__importEleme nt)),this.parsingElement=null,c.parse&&console.log("completed",e)},markDynamicPa rsingComplete:function(e){var t=this.dynamicElements.indexOf(e);t>=0&&this.dynam icElements.splice(t,1)},parseImport:function(e){if(e["import"]=e.__doc,window.HT MLImports.__importsParsingHook&&window.HTMLImports.__importsParsingHook(e),e["im port"]&&(e["import"].__importParsed=!0),this.markParsingComplete(e),e.__resource &&!e.__error?e.dispatchEvent(new CustomEvent("load",{bubbles:!1})):e.dispatchEve nt(new CustomEvent("error",{bubbles:!1})),e.__pending)for(var t;e.__pending.leng th;)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:fun ction(e){var t=e;e=i(e),t.__appliedElement=e,e.__importElement=t,this.parseGener ic(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=th is.rootImportForElement(e.__importElement||e);t.parentNode.insertBefore(e,t)},tr ackElement: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.d ispatchEvent(new CustomEvent("load",{bubbles:!1}))})}},parseScript:function(t){v ar 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.re moveChild(o),e.currentScript=null}),this.addElementToDocument(o)},nextToParse:fu nction(){return this._mayParse=[],!this.parsingElement&&(this.nextToParseInDoc(s )||this.nextToParseDynamic())},nextToParseInDoc:function(e,n){if(e&&this._mayPar se.indexOf(e)<0){this._mayParse.push(e);for(var o,r=e.querySelectorAll(this.pars eSelectorsForNode(e)),i=0,a=r.length;a>i&&(o=r[i]);i++)if(!this.isParsed(o))retu rn this.hasResource(o)?t(o)?this.nextToParseInDoc(o.__doc,o):o:void 0}return n}, nextToParseDynamic:function(){return this.dynamicElements[0]},parseSelectorsForN ode:function(e){var t=e.ownerDocument||e;return t===s?this.documentSelectors:thi s.importsSelectors},isParsed:function(e){return e.__importParsed},needsDynamicPa rsing:function(e){return this.dynamicElements.indexOf(e)>=0},hasResource:functio n(e){return!t(e)||void 0!==e.__doc}};e.parser=h,e.IMPORT_SELECTOR=u}),window.HTM LImports.addModule(function(e){function t(e){return n(e,a)}function n(e,t){retur n"link"===e.localName&&e.getAttribute("rel")===t}function o(e){return!!Object.ge tOwnPropertyDescriptor(e,"baseURI")}function r(e,t){var n=document.implementatio n.createHTMLDocument(a);n._URL=t;var r=n.createElement("base");r.setAttribute("h ref",t),n.baseURI||o(n)||Object.defineProperty(n,"baseURI",{value:t});var i=n.cr eateElement("meta");return i.setAttribute("charset","utf-8"),n.head.appendChild( i),n.head.appendChild(r),n.body.innerHTML=e,window.HTMLTemplateElement&&HTMLTemp lateElement.bootstrap&&HTMLTemplateElement.bootstrap(n),n}var i=e.flags,a=e.IMPO RT_LINK_TYPE,s=e.IMPORT_SELECTOR,c=e.rootDocument,d=e.Loader,l=e.Observer,u=e.pa rser,h={documents:{},documentPreloadSelectors:s,importsPreloadSelectors:[s].join (","),loadNode:function(e){f.addNode(e)},loadSubtree:function(e){var t=this.mars halNodes(e);f.addNodes(t)},marshalNodes:function(e){return e.querySelectorAll(th is.loadSelectorsForNode(e))},loadSelectorsForNode:function(e){var t=e.ownerDocum ent||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.parseN ext()},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=doc ument.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))},shouldPa rseNode:function(e){return 1===e.nodeType&&r.call(e,t.parseSelectorsForNode(e))} };n.observer.addCallback=o.added.bind(o);var r=HTMLElement.prototype.matches||HT MLElement.prototype.matchesSelector||HTMLElement.prototype.webkitMatchesSelector ||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelec tor}),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),windo w.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.addModul e=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.firstE lementChild;if(!r)for(r=e.firstChild;r&&r.nodeType!==Node.ELEMENT_NODE;)r=r.next Sibling;for(;r;)t(r,o)!==!0&&n(r,t,o),r=r.nextElementSibling;return null}functio n 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.CustomEleme nts.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(fun ction(){s(e)}):s(e)}function s(e){
34 e.__upgraded__&&!e.__attached&&(e.__attached=!0,e.attachedCallback&&e.attachedCa llback())}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.deta chedCallback&&e.detachedCallback())}function u(e){for(var t=e,n=window.wrap(docu ment);t;){if(t==n)return!0;t=t.parentNode||t.nodeType===Node.DOCUMENT_FRAGMENT_N ODE&&t.host}}function h(e){if(e.shadowRoot&&!e.shadowRoot.__watched){_.dom&&cons ole.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.leng th,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.takeR ecords()),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("/").po p());var n=e===window.wrap(document);t(e,n),m(e),_.dom&&console.groupEnd()}funct ion w(e){b(e,v)}var _=e.flags,g=e.forSubtree,b=e.forDocumentTree,y=window.Mutati onObserver._isPolyfilled&&_["throttle-attached"];e.hasPolyfillMutations=y,e.hasT hrottledAttached=y;var E=!1,L=[],N=Array.prototype.forEach.call.bind(Array.proto type.forEach),M=Element.prototype.createShadowRoot;M&&(Element.prototype.createS hadowRoot=function(){var e=M.call(this);return window.CustomElements.watchShadow (this),e}),e.watchShadow=h,e.upgradeDocumentTree=w,e.upgradeDocument=v,e.upgrade Subtree=o,e.upgradeAll=t,e.attached=a,e.takeRecords=p}),window.CustomElements.ad dModule(function(e){function t(t,o){if("template"===t.localName&&window.HTMLTemp lateElement&&HTMLTemplateElement.decorate&&HTMLTemplateElement.decorate(t),!t.__ upgraded__&&t.nodeType===Node.ELEMENT_NODE){var r=t.getAttribute("is"),i=e.getRe gisteredDefinition(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.upgra de&&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&&consol e.groupEnd(),t}function o(e,t){Object.__proto__?e.__proto__=t.prototype:(r(e,t.p rototype,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.crea tedCallback()}var a=e.flags;e.upgrade=t,e.upgradeWithDefinition=n,e.implementPro totype=o}),window.CustomElements.addModule(function(e){function t(t,o){var c=o|| {};if(!t)throw new Error("document.registerElement: first argument `name` must n ot be empty");if(t.indexOf("-")<0)throw new Error("document.registerElement: fir st argument ('name') must contain a dash ('-'). Argument provided was '"+String( t)+"'.");if(r(t))throw new Error("Failed to execute 'registerElement' on 'Docume nt': Registration failed for type '"+String(t)+"'. The type name is invalid.");i f(d(t))throw new Error("DuplicateDefinitionError: a type with name '"+String(t)+ "' is already registered");return c.prototype||(c.prototype=Object.create(HTMLEl ement.prototype)),c.__name=t.toLowerCase(),c["extends"]&&(c["extends"]=c["extend s"].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.prot otype.constructor=c.ctor,e.ready&&v(document),c.ctor}function n(e){if(!e.setAttr ibute._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,nul l,n)},e.setAttribute._polyfilled=!0}}function o(e,t,n){e=e.toLowerCase();var o=t his.getAttribute(e);n.apply(this,arguments);var r=this.getAttribute(e);this.attr ibuteChangedCallback&&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.creat eElement(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){re turn e===L?f(t,n):M(e,t)}function f(e,t){e&&(e=e.toLowerCase()),t&&(t=t.toLowerC ase());var n=d(t||e);if(n){if(e==n.tag&&t==n.is)return new n.ctor;if(!t&&!n.is)r eturn new n.ctor}var o;return t?(o=f(e),o.setAttribute("is",t),o):(o=N(e),e.inde xOf("-")>=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","f ont-face-format","font-face-name","missing-glyph"],E={},L="http://www.w3.org/199 9/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"),docume nt.registerElement=t,document.createElement=f,document.createElementNS=h,e.regis try=E,e["instanceof"]=m,e.reservedTagList=y,e.getRegisteredDefinition=d,document .register=document.registerElement}),function(e){function t(){i(window.wrap(docu ment)),window.CustomElements.ready=!0;var e=window.requestAnimationFrame||functi on(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(ne w CustomEvent("WebComponentsReady",{bubbles:!0}))})})}var n=e.useNative,o=e.init ializeModules;e.isIE;if(n){var r=function(){};e.watchShadow=r,e.upgrade=r,e.upgr adeAll=r,e.upgradeDocumentTree=r,e.upgradeSubtree=r,e.takeRecords=r,e["instanceo f"]=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.unwrapIfNe eded):window.wrap=window.unwrap=function(e){return e}),window.HTMLImports&&(wind ow.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 {transiti on: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; over flow: hidden; position: relative; } \n";var n=document.querySelector("head");n.i nsertBefore(t,n.firstChild)}(window.WebComponents);</script>
35 </head>
36
37 <body><div hidden="" by-vulcanize=""><script>(function () {
38 function resolve() {
39 document.body.removeAttribute('unresolved');
40 }
41 if (window.WebComponents) {
42 addEventListener('WebComponentsReady', resolve);
43 } else {
44 if (document.readyState === 'interactive' || document.readyState === 'complete') {
45 resolve();
46 } else {
47 addEventListener('DOMContentLoaded', resolve);
48 }
49 }
50 }());window.Polymer = {
51 Settings: function () {
52 var settings = window.Polymer || {};
53 var parts = location.search.slice(1).split('&');
54 for (var i = 0, o; i < parts.length && (o = parts[i]); i++) {
55 o = o.split('=');
56 o[0] && (settings[o[0]] = o[1] || true);
57 }
58 settings.wantShadow = settings.dom === 'shadow';
59 settings.hasShadow = Boolean(Element.prototype.createShadowRoot);
60 settings.nativeShadow = settings.hasShadow && !window.ShadowDOMPolyfill;
61 settings.useShadow = settings.wantShadow && settings.hasShadow;
62 settings.hasNativeImports = Boolean('import' in document.createElement('link'));
63 settings.useNativeImports = settings.hasNativeImports;
64 settings.useNativeCustomElements = !window.CustomElements || window.CustomElemen ts.useNative;
65 settings.useNativeShadow = settings.useShadow && settings.nativeShadow;
66 settings.usePolyfillProto = !settings.useNativeCustomElements && !Object.__proto __;
67 settings.hasNativeCSSProperties = !navigator.userAgent.match('AppleWebKit/601') && window.CSS && CSS.supports && CSS.supports('box-shadow', '0 0 0 var(--foo)');
68 settings.useNativeCSSProperties = settings.hasNativeCSSProperties && settings.la zyRegister && settings.useNativeCSSProperties;
69 return settings;
70 }()
71 };(function () {
72 var userPolymer = window.Polymer;
73 window.Polymer = function (prototype) {
74 if (typeof prototype === 'function') {
75 prototype = prototype.prototype;
76 }
77 if (!prototype) {
78 prototype = {};
79 }
80 var factory = desugar(prototype);
81 prototype = factory.prototype;
82 var options = { prototype: prototype };
83 if (prototype.extends) {
84 options.extends = prototype.extends;
85 }
86 Polymer.telemetry._registrate(prototype);
87 document.registerElement(prototype.is, options);
88 return factory;
89 };
90 var desugar = function (prototype) {
91 var base = Polymer.Base;
92 if (prototype.extends) {
93 base = Polymer.Base._getExtendedPrototype(prototype.extends);
94 }
95 prototype = Polymer.Base.chainObject(prototype, base);
96 prototype.registerCallback();
97 return prototype.constructor;
98 };
99 if (userPolymer) {
100 for (var i in userPolymer) {
101 Polymer[i] = userPolymer[i];
102 }
103 }
104 Polymer.Class = desugar;
105 }());
106 Polymer.telemetry = {
107 registrations: [],
108 _regLog: function (prototype) {
109 console.log('[' + prototype.is + ']: registered');
110 },
111 _registrate: function (prototype) {
112 this.registrations.push(prototype);
113 Polymer.log && this._regLog(prototype);
114 },
115 dumpRegistrations: function () {
116 this.registrations.forEach(this._regLog);
117 }
118 };Object.defineProperty(window, 'currentImport', {
119 enumerable: true,
120 configurable: true,
121 get: function () {
122 return (document._currentScript || document.currentScript).ownerDocument;
123 }
124 });Polymer.RenderStatus = {
125 _ready: false,
126 _callbacks: [],
127 whenReady: function (cb) {
128 if (this._ready) {
129 cb();
130 } else {
131 this._callbacks.push(cb);
132 }
133 },
134 _makeReady: function () {
135 this._ready = true;
136 for (var i = 0; i < this._callbacks.length; i++) {
137 this._callbacks[i]();
138 }
139 this._callbacks = [];
140 },
141 _catchFirstRender: function () {
142 requestAnimationFrame(function () {
143 Polymer.RenderStatus._makeReady();
144 });
145 },
146 _afterNextRenderQueue: [],
147 _waitingNextRender: false,
148 afterNextRender: function (element, fn, args) {
149 this._watchNextRender();
150 this._afterNextRenderQueue.push([
151 element,
152 fn,
153 args
154 ]);
155 },
156 hasRendered: function () {
157 return this._ready;
158 },
159 _watchNextRender: function () {
160 if (!this._waitingNextRender) {
161 this._waitingNextRender = true;
162 var fn = function () {
163 Polymer.RenderStatus._flushNextRender();
164 };
165 if (!this._ready) {
166 this.whenReady(fn);
167 } else {
168 requestAnimationFrame(fn);
169 }
170 }
171 },
172 _flushNextRender: function () {
173 var self = this;
174 setTimeout(function () {
175 self._flushRenderCallbacks(self._afterNextRenderQueue);
176 self._afterNextRenderQueue = [];
177 self._waitingNextRender = false;
178 });
179 },
180 _flushRenderCallbacks: function (callbacks) {
181 for (var i = 0, h; i < callbacks.length; i++) {
182 h = callbacks[i];
183 h[1].apply(h[0], h[2] || Polymer.nar);
184 }
185 }
186 };
187 if (window.HTMLImports) {
188 HTMLImports.whenReady(function () {
189 Polymer.RenderStatus._catchFirstRender();
190 });
191 } else {
192 Polymer.RenderStatus._catchFirstRender();
193 }
194 Polymer.ImportStatus = Polymer.RenderStatus;
195 Polymer.ImportStatus.whenLoaded = Polymer.ImportStatus.whenReady;(function () {
196 'use strict';
197 var settings = Polymer.Settings;
198 Polymer.Base = {
199 __isPolymerInstance__: true,
200 _addFeature: function (feature) {
201 this.extend(this, feature);
202 },
203 registerCallback: function () {
204 this._desugarBehaviors();
205 this._doBehavior('beforeRegister');
206 this._registerFeatures();
207 if (!settings.lazyRegister) {
208 this.ensureRegisterFinished();
209 }
210 },
211 createdCallback: function () {
212 if (!this.__hasRegisterFinished) {
213 this._ensureRegisterFinished(this.__proto__);
214 }
215 Polymer.telemetry.instanceCount++;
216 this.root = this;
217 this._doBehavior('created');
218 this._initFeatures();
219 },
220 ensureRegisterFinished: function () {
221 this._ensureRegisterFinished(this);
222 },
223 _ensureRegisterFinished: function (proto) {
224 if (proto.__hasRegisterFinished !== proto.is) {
225 proto.__hasRegisterFinished = proto.is;
226 if (proto._finishRegisterFeatures) {
227 proto._finishRegisterFeatures();
228 }
229 proto._doBehavior('registered');
230 if (settings.usePolyfillProto && proto !== this) {
231 proto.extend(this, proto);
232 }
233 }
234 },
235 attachedCallback: function () {
236 var self = this;
237 Polymer.RenderStatus.whenReady(function () {
238 self.isAttached = true;
239 self._doBehavior('attached');
240 });
241 },
242 detachedCallback: function () {
243 var self = this;
244 Polymer.RenderStatus.whenReady(function () {
245 self.isAttached = false;
246 self._doBehavior('detached');
247 });
248 },
249 attributeChangedCallback: function (name, oldValue, newValue) {
250 this._attributeChangedImpl(name);
251 this._doBehavior('attributeChanged', [
252 name,
253 oldValue,
254 newValue
255 ]);
256 },
257 _attributeChangedImpl: function (name) {
258 this._setAttributeToProperty(this, name);
259 },
260 extend: function (prototype, api) {
261 if (prototype && api) {
262 var n$ = Object.getOwnPropertyNames(api);
263 for (var i = 0, n; i < n$.length && (n = n$[i]); i++) {
264 this.copyOwnProperty(n, api, prototype);
265 }
266 }
267 return prototype || api;
268 },
269 mixin: function (target, source) {
270 for (var i in source) {
271 target[i] = source[i];
272 }
273 return target;
274 },
275 copyOwnProperty: function (name, source, target) {
276 var pd = Object.getOwnPropertyDescriptor(source, name);
277 if (pd) {
278 Object.defineProperty(target, name, pd);
279 }
280 },
281 _logger: function (level, args) {
282 if (args.length === 1 && Array.isArray(args[0])) {
283 args = args[0];
284 }
285 switch (level) {
286 case 'log':
287 case 'warn':
288 case 'error':
289 console[level].apply(console, args);
290 break;
291 }
292 },
293 _log: function () {
294 var args = Array.prototype.slice.call(arguments, 0);
295 this._logger('log', args);
296 },
297 _warn: function () {
298 var args = Array.prototype.slice.call(arguments, 0);
299 this._logger('warn', args);
300 },
301 _error: function () {
302 var args = Array.prototype.slice.call(arguments, 0);
303 this._logger('error', args);
304 },
305 _logf: function () {
306 return this._logPrefix.concat(this.is).concat(Array.prototype.slice.call(argumen ts, 0));
307 }
308 };
309 Polymer.Base._logPrefix = function () {
310 var color = window.chrome && !/edge/i.test(navigator.userAgent) || /firefox/i.te st(navigator.userAgent);
311 return color ? [
312 '%c[%s::%s]:',
313 'font-weight: bold; background-color:#EEEE00;'
314 ] : ['[%s::%s]:'];
315 }();
316 Polymer.Base.chainObject = function (object, inherited) {
317 if (object && inherited && object !== inherited) {
318 if (!Object.__proto__) {
319 object = Polymer.Base.extend(Object.create(inherited), object);
320 }
321 object.__proto__ = inherited;
322 }
323 return object;
324 };
325 Polymer.Base = Polymer.Base.chainObject(Polymer.Base, HTMLElement.prototype);
326 if (window.CustomElements) {
327 Polymer.instanceof = CustomElements.instanceof;
328 } else {
329 Polymer.instanceof = function (obj, ctor) {
330 return obj instanceof ctor;
331 };
332 }
333 Polymer.isInstance = function (obj) {
334 return Boolean(obj && obj.__isPolymerInstance__);
335 };
336 Polymer.telemetry.instanceCount = 0;
337 }());(function () {
338 var modules = {};
339 var lcModules = {};
340 var findModule = function (id) {
341 return modules[id] || lcModules[id.toLowerCase()];
342 };
343 var DomModule = function () {
344 return document.createElement('dom-module');
345 };
346 DomModule.prototype = Object.create(HTMLElement.prototype);
347 Polymer.Base.extend(DomModule.prototype, {
348 constructor: DomModule,
349 createdCallback: function () {
350 this.register();
351 },
352 register: function (id) {
353 id = id || this.id || this.getAttribute('name') || this.getAttribute('is');
354 if (id) {
355 this.id = id;
356 modules[id] = this;
357 lcModules[id.toLowerCase()] = this;
358 }
359 },
360 import: function (id, selector) {
361 if (id) {
362 var m = findModule(id);
363 if (!m) {
364 forceDomModulesUpgrade();
365 m = findModule(id);
366 }
367 if (m && selector) {
368 m = m.querySelector(selector);
369 }
370 return m;
371 }
372 }
373 });
374 var cePolyfill = window.CustomElements && !CustomElements.useNative;
375 document.registerElement('dom-module', DomModule);
376 function forceDomModulesUpgrade() {
377 if (cePolyfill) {
378 var script = document._currentScript || document.currentScript;
379 var doc = script && script.ownerDocument || document;
380 var modules = doc.querySelectorAll('dom-module');
381 for (var i = modules.length - 1, m; i >= 0 && (m = modules[i]); i--) {
382 if (m.__upgraded__) {
383 return;
384 } else {
385 CustomElements.upgrade(m);
386 }
387 }
388 }
389 }
390 }());Polymer.Base._addFeature({
391 _prepIs: function () {
392 if (!this.is) {
393 var module = (document._currentScript || document.currentScript).parentNode;
394 if (module.localName === 'dom-module') {
395 var id = module.id || module.getAttribute('name') || module.getAttribute('is');
396 this.is = id;
397 }
398 }
399 if (this.is) {
400 this.is = this.is.toLowerCase();
401 }
402 }
403 });Polymer.Base._addFeature({
404 behaviors: [],
405 _desugarBehaviors: function () {
406 if (this.behaviors.length) {
407 this.behaviors = this._desugarSomeBehaviors(this.behaviors);
408 }
409 },
410 _desugarSomeBehaviors: function (behaviors) {
411 var behaviorSet = [];
412 behaviors = this._flattenBehaviorsList(behaviors);
413 for (var i = behaviors.length - 1; i >= 0; i--) {
414 var b = behaviors[i];
415 if (behaviorSet.indexOf(b) === -1) {
416 this._mixinBehavior(b);
417 behaviorSet.unshift(b);
418 }
419 }
420 return behaviorSet;
421 },
422 _flattenBehaviorsList: function (behaviors) {
423 var flat = [];
424 for (var i = 0; i < behaviors.length; i++) {
425 var b = behaviors[i];
426 if (b instanceof Array) {
427 flat = flat.concat(this._flattenBehaviorsList(b));
428 } else if (b) {
429 flat.push(b);
430 } else {
431 this._warn(this._logf('_flattenBehaviorsList', 'behavior is null, check for miss ing or 404 import'));
432 }
433 }
434 return flat;
435 },
436 _mixinBehavior: function (b) {
437 var n$ = Object.getOwnPropertyNames(b);
438 for (var i = 0, n; i < n$.length && (n = n$[i]); i++) {
439 if (!Polymer.Base._behaviorProperties[n] && !this.hasOwnProperty(n)) {
440 this.copyOwnProperty(n, b, this);
441 }
442 }
443 },
444 _prepBehaviors: function () {
445 this._prepFlattenedBehaviors(this.behaviors);
446 },
447 _prepFlattenedBehaviors: function (behaviors) {
448 for (var i = 0, l = behaviors.length; i < l; i++) {
449 this._prepBehavior(behaviors[i]);
450 }
451 this._prepBehavior(this);
452 },
453 _doBehavior: function (name, args) {
454 for (var i = 0; i < this.behaviors.length; i++) {
455 this._invokeBehavior(this.behaviors[i], name, args);
456 }
457 this._invokeBehavior(this, name, args);
458 },
459 _invokeBehavior: function (b, name, args) {
460 var fn = b[name];
461 if (fn) {
462 fn.apply(this, args || Polymer.nar);
463 }
464 },
465 _marshalBehaviors: function () {
466 for (var i = 0; i < this.behaviors.length; i++) {
467 this._marshalBehavior(this.behaviors[i]);
468 }
469 this._marshalBehavior(this);
470 }
471 });
472 Polymer.Base._behaviorProperties = {
473 hostAttributes: true,
474 beforeRegister: true,
475 registered: true,
476 properties: true,
477 observers: true,
478 listeners: true,
479 created: true,
480 attached: true,
481 detached: true,
482 attributeChanged: true,
483 ready: true
484 };Polymer.Base._addFeature({
485 _getExtendedPrototype: function (tag) {
486 return this._getExtendedNativePrototype(tag);
487 },
488 _nativePrototypes: {},
489 _getExtendedNativePrototype: function (tag) {
490 var p = this._nativePrototypes[tag];
491 if (!p) {
492 var np = this.getNativePrototype(tag);
493 p = this.extend(Object.create(np), Polymer.Base);
494 this._nativePrototypes[tag] = p;
495 }
496 return p;
497 },
498 getNativePrototype: function (tag) {
499 return Object.getPrototypeOf(document.createElement(tag));
500 }
501 });Polymer.Base._addFeature({
502 _prepConstructor: function () {
503 this._factoryArgs = this.extends ? [
504 this.extends,
505 this.is
506 ] : [this.is];
507 var ctor = function () {
508 return this._factory(arguments);
509 };
510 if (this.hasOwnProperty('extends')) {
511 ctor.extends = this.extends;
512 }
513 Object.defineProperty(this, 'constructor', {
514 value: ctor,
515 writable: true,
516 configurable: true
517 });
518 ctor.prototype = this;
519 },
520 _factory: function (args) {
521 var elt = document.createElement.apply(document, this._factoryArgs);
522 if (this.factoryImpl) {
523 this.factoryImpl.apply(elt, args);
524 }
525 return elt;
526 }
527 });Polymer.nob = Object.create(null);
528 Polymer.Base._addFeature({
529 properties: {},
530 getPropertyInfo: function (property) {
531 var info = this._getPropertyInfo(property, this.properties);
532 if (!info) {
533 for (var i = 0; i < this.behaviors.length; i++) {
534 info = this._getPropertyInfo(property, this.behaviors[i].properties);
535 if (info) {
536 return info;
537 }
538 }
539 }
540 return info || Polymer.nob;
541 },
542 _getPropertyInfo: function (property, properties) {
543 var p = properties && properties[property];
544 if (typeof p === 'function') {
545 p = properties[property] = { type: p };
546 }
547 if (p) {
548 p.defined = true;
549 }
550 return p;
551 },
552 _prepPropertyInfo: function () {
553 this._propertyInfo = {};
554 for (var i = 0; i < this.behaviors.length; i++) {
555 this._addPropertyInfo(this._propertyInfo, this.behaviors[i].properties);
556 }
557 this._addPropertyInfo(this._propertyInfo, this.properties);
558 this._addPropertyInfo(this._propertyInfo, this._propertyEffects);
559 },
560 _addPropertyInfo: function (target, source) {
561 if (source) {
562 var t, s;
563 for (var i in source) {
564 t = target[i];
565 s = source[i];
566 if (i[0] === '_' && !s.readOnly) {
567 continue;
568 }
569 if (!target[i]) {
570 target[i] = {
571 type: typeof s === 'function' ? s : s.type,
572 readOnly: s.readOnly,
573 attribute: Polymer.CaseMap.camelToDashCase(i)
574 };
575 } else {
576 if (!t.type) {
577 t.type = s.type;
578 }
579 if (!t.readOnly) {
580 t.readOnly = s.readOnly;
581 }
582 }
583 }
584 }
585 }
586 });Polymer.CaseMap = {
587 _caseMap: {},
588 _rx: {
589 dashToCamel: /-[a-z]/g,
590 camelToDash: /([A-Z])/g
591 },
592 dashToCamelCase: function (dash) {
593 return this._caseMap[dash] || (this._caseMap[dash] = dash.indexOf('-') < 0 ? das h : dash.replace(this._rx.dashToCamel, function (m) {
594 return m[1].toUpperCase();
595 }));
596 },
597 camelToDashCase: function (camel) {
598 return this._caseMap[camel] || (this._caseMap[camel] = camel.replace(this._rx.ca melToDash, '-$1').toLowerCase());
599 }
600 };Polymer.Base._addFeature({
601 _addHostAttributes: function (attributes) {
602 if (!this._aggregatedAttributes) {
603 this._aggregatedAttributes = {};
604 }
605 if (attributes) {
606 this.mixin(this._aggregatedAttributes, attributes);
607 }
608 },
609 _marshalHostAttributes: function () {
610 if (this._aggregatedAttributes) {
611 this._applyAttributes(this, this._aggregatedAttributes);
612 }
613 },
614 _applyAttributes: function (node, attr$) {
615 for (var n in attr$) {
616 if (!this.hasAttribute(n) && n !== 'class') {
617 var v = attr$[n];
618 this.serializeValueToAttribute(v, n, this);
619 }
620 }
621 },
622 _marshalAttributes: function () {
623 this._takeAttributesToModel(this);
624 },
625 _takeAttributesToModel: function (model) {
626 if (this.hasAttributes()) {
627 for (var i in this._propertyInfo) {
628 var info = this._propertyInfo[i];
629 if (this.hasAttribute(info.attribute)) {
630 this._setAttributeToProperty(model, info.attribute, i, info);
631 }
632 }
633 }
634 },
635 _setAttributeToProperty: function (model, attribute, property, info) {
636 if (!this._serializing) {
637 property = property || Polymer.CaseMap.dashToCamelCase(attribute);
638 info = info || this._propertyInfo && this._propertyInfo[property];
639 if (info && !info.readOnly) {
640 var v = this.getAttribute(attribute);
641 model[property] = this.deserialize(v, info.type);
642 }
643 }
644 },
645 _serializing: false,
646 reflectPropertyToAttribute: function (property, attribute, value) {
647 this._serializing = true;
648 value = value === undefined ? this[property] : value;
649 this.serializeValueToAttribute(value, attribute || Polymer.CaseMap.camelToDashCa se(property));
650 this._serializing = false;
651 },
652 serializeValueToAttribute: function (value, attribute, node) {
653 var str = this.serialize(value);
654 node = node || this;
655 if (str === undefined) {
656 node.removeAttribute(attribute);
657 } else {
658 node.setAttribute(attribute, str);
659 }
660 },
661 deserialize: function (value, type) {
662 switch (type) {
663 case Number:
664 value = Number(value);
665 break;
666 case Boolean:
667 value = value != null;
668 break;
669 case Object:
670 try {
671 value = JSON.parse(value);
672 } catch (x) {
673 }
674 break;
675 case Array:
676 try {
677 value = JSON.parse(value);
678 } catch (x) {
679 value = null;
680 console.warn('Polymer::Attributes: couldn`t decode Array as JSON');
681 }
682 break;
683 case Date:
684 value = new Date(value);
685 break;
686 case String:
687 default:
688 break;
689 }
690 return value;
691 },
692 serialize: function (value) {
693 switch (typeof value) {
694 case 'boolean':
695 return value ? '' : undefined;
696 case 'object':
697 if (value instanceof Date) {
698 return value.toString();
699 } else if (value) {
700 try {
701 return JSON.stringify(value);
702 } catch (x) {
703 return '';
704 }
705 }
706 default:
707 return value != null ? value : undefined;
708 }
709 }
710 });Polymer.version = '1.6.0';Polymer.Base._addFeature({
711 _registerFeatures: function () {
712 this._prepIs();
713 this._prepBehaviors();
714 this._prepConstructor();
715 this._prepPropertyInfo();
716 },
717 _prepBehavior: function (b) {
718 this._addHostAttributes(b.hostAttributes);
719 },
720 _marshalBehavior: function (b) {
721 },
722 _initFeatures: function () {
723 this._marshalHostAttributes();
724 this._marshalBehaviors();
725 }
726 });</script>
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744 <script>Polymer.Base._addFeature({
745 _prepTemplate: function () {
746 if (this._template === undefined) {
747 this._template = Polymer.DomModule.import(this.is, 'template');
748 }
749 if (this._template && this._template.hasAttribute('is')) {
750 this._warn(this._logf('_prepTemplate', 'top-level Polymer template ' + 'must not be a type-extension, found', this._template, 'Move inside simple <template>.')) ;
751 }
752 if (this._template && !this._template.content && window.HTMLTemplateElement && H TMLTemplateElement.decorate) {
753 HTMLTemplateElement.decorate(this._template);
754 }
755 },
756 _stampTemplate: function () {
757 if (this._template) {
758 this.root = this.instanceTemplate(this._template);
759 }
760 },
761 instanceTemplate: function (template) {
762 var dom = document.importNode(template._content || template.content, true);
763 return dom;
764 }
765 });(function () {
766 var baseAttachedCallback = Polymer.Base.attachedCallback;
767 Polymer.Base._addFeature({
768 _hostStack: [],
769 ready: function () {
770 },
771 _registerHost: function (host) {
772 this.dataHost = host = host || Polymer.Base._hostStack[Polymer.Base._hostStack.l ength - 1];
773 if (host && host._clients) {
774 host._clients.push(this);
775 }
776 this._clients = null;
777 this._clientsReadied = false;
778 },
779 _beginHosting: function () {
780 Polymer.Base._hostStack.push(this);
781 if (!this._clients) {
782 this._clients = [];
783 }
784 },
785 _endHosting: function () {
786 Polymer.Base._hostStack.pop();
787 },
788 _tryReady: function () {
789 this._readied = false;
790 if (this._canReady()) {
791 this._ready();
792 }
793 },
794 _canReady: function () {
795 return !this.dataHost || this.dataHost._clientsReadied;
796 },
797 _ready: function () {
798 this._beforeClientsReady();
799 if (this._template) {
800 this._setupRoot();
801 this._readyClients();
802 }
803 this._clientsReadied = true;
804 this._clients = null;
805 this._afterClientsReady();
806 this._readySelf();
807 },
808 _readyClients: function () {
809 this._beginDistribute();
810 var c$ = this._clients;
811 if (c$) {
812 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
813 c._ready();
814 }
815 }
816 this._finishDistribute();
817 },
818 _readySelf: function () {
819 this._doBehavior('ready');
820 this._readied = true;
821 if (this._attachedPending) {
822 this._attachedPending = false;
823 this.attachedCallback();
824 }
825 },
826 _beforeClientsReady: function () {
827 },
828 _afterClientsReady: function () {
829 },
830 _beforeAttached: function () {
831 },
832 attachedCallback: function () {
833 if (this._readied) {
834 this._beforeAttached();
835 baseAttachedCallback.call(this);
836 } else {
837 this._attachedPending = true;
838 }
839 }
840 });
841 }());Polymer.ArraySplice = function () {
842 function newSplice(index, removed, addedCount) {
843 return {
844 index: index,
845 removed: removed,
846 addedCount: addedCount
847 };
848 }
849 var EDIT_LEAVE = 0;
850 var EDIT_UPDATE = 1;
851 var EDIT_ADD = 2;
852 var EDIT_DELETE = 3;
853 function ArraySplice() {
854 }
855 ArraySplice.prototype = {
856 calcEditDistances: function (current, currentStart, currentEnd, old, oldStart, o ldEnd) {
857 var rowCount = oldEnd - oldStart + 1;
858 var columnCount = currentEnd - currentStart + 1;
859 var distances = new Array(rowCount);
860 for (var i = 0; i < rowCount; i++) {
861 distances[i] = new Array(columnCount);
862 distances[i][0] = i;
863 }
864 for (var j = 0; j < columnCount; j++)
865 distances[0][j] = j;
866 for (i = 1; i < rowCount; i++) {
867 for (j = 1; j < columnCount; j++) {
868 if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1]))
869 distances[i][j] = distances[i - 1][j - 1];
870 else {
871 var north = distances[i - 1][j] + 1;
872 var west = distances[i][j - 1] + 1;
873 distances[i][j] = north < west ? north : west;
874 }
875 }
876 }
877 return distances;
878 },
879 spliceOperationsFromEditDistances: function (distances) {
880 var i = distances.length - 1;
881 var j = distances[0].length - 1;
882 var current = distances[i][j];
883 var edits = [];
884 while (i > 0 || j > 0) {
885 if (i == 0) {
886 edits.push(EDIT_ADD);
887 j--;
888 continue;
889 }
890 if (j == 0) {
891 edits.push(EDIT_DELETE);
892 i--;
893 continue;
894 }
895 var northWest = distances[i - 1][j - 1];
896 var west = distances[i - 1][j];
897 var north = distances[i][j - 1];
898 var min;
899 if (west < north)
900 min = west < northWest ? west : northWest;
901 else
902 min = north < northWest ? north : northWest;
903 if (min == northWest) {
904 if (northWest == current) {
905 edits.push(EDIT_LEAVE);
906 } else {
907 edits.push(EDIT_UPDATE);
908 current = northWest;
909 }
910 i--;
911 j--;
912 } else if (min == west) {
913 edits.push(EDIT_DELETE);
914 i--;
915 current = west;
916 } else {
917 edits.push(EDIT_ADD);
918 j--;
919 current = north;
920 }
921 }
922 edits.reverse();
923 return edits;
924 },
925 calcSplices: function (current, currentStart, currentEnd, old, oldStart, oldEnd) {
926 var prefixCount = 0;
927 var suffixCount = 0;
928 var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
929 if (currentStart == 0 && oldStart == 0)
930 prefixCount = this.sharedPrefix(current, old, minLength);
931 if (currentEnd == current.length && oldEnd == old.length)
932 suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
933 currentStart += prefixCount;
934 oldStart += prefixCount;
935 currentEnd -= suffixCount;
936 oldEnd -= suffixCount;
937 if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0)
938 return [];
939 if (currentStart == currentEnd) {
940 var splice = newSplice(currentStart, [], 0);
941 while (oldStart < oldEnd)
942 splice.removed.push(old[oldStart++]);
943 return [splice];
944 } else if (oldStart == oldEnd)
945 return [newSplice(currentStart, [], currentEnd - currentStart)];
946 var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
947 splice = undefined;
948 var splices = [];
949 var index = currentStart;
950 var oldIndex = oldStart;
951 for (var i = 0; i < ops.length; i++) {
952 switch (ops[i]) {
953 case EDIT_LEAVE:
954 if (splice) {
955 splices.push(splice);
956 splice = undefined;
957 }
958 index++;
959 oldIndex++;
960 break;
961 case EDIT_UPDATE:
962 if (!splice)
963 splice = newSplice(index, [], 0);
964 splice.addedCount++;
965 index++;
966 splice.removed.push(old[oldIndex]);
967 oldIndex++;
968 break;
969 case EDIT_ADD:
970 if (!splice)
971 splice = newSplice(index, [], 0);
972 splice.addedCount++;
973 index++;
974 break;
975 case EDIT_DELETE:
976 if (!splice)
977 splice = newSplice(index, [], 0);
978 splice.removed.push(old[oldIndex]);
979 oldIndex++;
980 break;
981 }
982 }
983 if (splice) {
984 splices.push(splice);
985 }
986 return splices;
987 },
988 sharedPrefix: function (current, old, searchLength) {
989 for (var i = 0; i < searchLength; i++)
990 if (!this.equals(current[i], old[i]))
991 return i;
992 return searchLength;
993 },
994 sharedSuffix: function (current, old, searchLength) {
995 var index1 = current.length;
996 var index2 = old.length;
997 var count = 0;
998 while (count < searchLength && this.equals(current[--index1], old[--index2]))
999 count++;
1000 return count;
1001 },
1002 calculateSplices: function (current, previous) {
1003 return this.calcSplices(current, 0, current.length, previous, 0, previous.length );
1004 },
1005 equals: function (currentValue, previousValue) {
1006 return currentValue === previousValue;
1007 }
1008 };
1009 return new ArraySplice();
1010 }();Polymer.domInnerHTML = function () {
1011 var escapeAttrRegExp = /[&\u00A0"]/g;
1012 var escapeDataRegExp = /[&\u00A0<>]/g;
1013 function escapeReplace(c) {
1014 switch (c) {
1015 case '&':
1016 return '&amp;';
1017 case '<':
1018 return '&lt;';
1019 case '>':
1020 return '&gt;';
1021 case '"':
1022 return '&quot;';
1023 case '\xA0':
1024 return '&nbsp;';
1025 }
1026 }
1027 function escapeAttr(s) {
1028 return s.replace(escapeAttrRegExp, escapeReplace);
1029 }
1030 function escapeData(s) {
1031 return s.replace(escapeDataRegExp, escapeReplace);
1032 }
1033 function makeSet(arr) {
1034 var set = {};
1035 for (var i = 0; i < arr.length; i++) {
1036 set[arr[i]] = true;
1037 }
1038 return set;
1039 }
1040 var voidElements = makeSet([
1041 'area',
1042 'base',
1043 'br',
1044 'col',
1045 'command',
1046 'embed',
1047 'hr',
1048 'img',
1049 'input',
1050 'keygen',
1051 'link',
1052 'meta',
1053 'param',
1054 'source',
1055 'track',
1056 'wbr'
1057 ]);
1058 var plaintextParents = makeSet([
1059 'style',
1060 'script',
1061 'xmp',
1062 'iframe',
1063 'noembed',
1064 'noframes',
1065 'plaintext',
1066 'noscript'
1067 ]);
1068 function getOuterHTML(node, parentNode, composed) {
1069 switch (node.nodeType) {
1070 case Node.ELEMENT_NODE:
1071 var tagName = node.localName;
1072 var s = '<' + tagName;
1073 var attrs = node.attributes;
1074 for (var i = 0, attr; attr = attrs[i]; i++) {
1075 s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"';
1076 }
1077 s += '>';
1078 if (voidElements[tagName]) {
1079 return s;
1080 }
1081 return s + getInnerHTML(node, composed) + '</' + tagName + '>';
1082 case Node.TEXT_NODE:
1083 var data = node.data;
1084 if (parentNode && plaintextParents[parentNode.localName]) {
1085 return data;
1086 }
1087 return escapeData(data);
1088 case Node.COMMENT_NODE:
1089 return '<!--' + node.data + '-->';
1090 default:
1091 console.error(node);
1092 throw new Error('not implemented');
1093 }
1094 }
1095 function getInnerHTML(node, composed) {
1096 if (node instanceof HTMLTemplateElement)
1097 node = node.content;
1098 var s = '';
1099 var c$ = Polymer.dom(node).childNodes;
1100 for (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) {
1101 s += getOuterHTML(child, node, composed);
1102 }
1103 return s;
1104 }
1105 return { getInnerHTML: getInnerHTML };
1106 }();(function () {
1107 'use strict';
1108 var nativeInsertBefore = Element.prototype.insertBefore;
1109 var nativeAppendChild = Element.prototype.appendChild;
1110 var nativeRemoveChild = Element.prototype.removeChild;
1111 Polymer.TreeApi = {
1112 arrayCopyChildNodes: function (parent) {
1113 var copy = [], i = 0;
1114 for (var n = parent.firstChild; n; n = n.nextSibling) {
1115 copy[i++] = n;
1116 }
1117 return copy;
1118 },
1119 arrayCopyChildren: function (parent) {
1120 var copy = [], i = 0;
1121 for (var n = parent.firstElementChild; n; n = n.nextElementSibling) {
1122 copy[i++] = n;
1123 }
1124 return copy;
1125 },
1126 arrayCopy: function (a$) {
1127 var l = a$.length;
1128 var copy = new Array(l);
1129 for (var i = 0; i < l; i++) {
1130 copy[i] = a$[i];
1131 }
1132 return copy;
1133 }
1134 };
1135 Polymer.TreeApi.Logical = {
1136 hasParentNode: function (node) {
1137 return Boolean(node.__dom && node.__dom.parentNode);
1138 },
1139 hasChildNodes: function (node) {
1140 return Boolean(node.__dom && node.__dom.childNodes !== undefined);
1141 },
1142 getChildNodes: function (node) {
1143 return this.hasChildNodes(node) ? this._getChildNodes(node) : node.childNodes;
1144 },
1145 _getChildNodes: function (node) {
1146 if (!node.__dom.childNodes) {
1147 node.__dom.childNodes = [];
1148 for (var n = node.__dom.firstChild; n; n = n.__dom.nextSibling) {
1149 node.__dom.childNodes.push(n);
1150 }
1151 }
1152 return node.__dom.childNodes;
1153 },
1154 getParentNode: function (node) {
1155 return node.__dom && node.__dom.parentNode !== undefined ? node.__dom.parentNode : node.parentNode;
1156 },
1157 getFirstChild: function (node) {
1158 return node.__dom && node.__dom.firstChild !== undefined ? node.__dom.firstChild : node.firstChild;
1159 },
1160 getLastChild: function (node) {
1161 return node.__dom && node.__dom.lastChild !== undefined ? node.__dom.lastChild : node.lastChild;
1162 },
1163 getNextSibling: function (node) {
1164 return node.__dom && node.__dom.nextSibling !== undefined ? node.__dom.nextSibli ng : node.nextSibling;
1165 },
1166 getPreviousSibling: function (node) {
1167 return node.__dom && node.__dom.previousSibling !== undefined ? node.__dom.previ ousSibling : node.previousSibling;
1168 },
1169 getFirstElementChild: function (node) {
1170 return node.__dom && node.__dom.firstChild !== undefined ? this._getFirstElement Child(node) : node.firstElementChild;
1171 },
1172 _getFirstElementChild: function (node) {
1173 var n = node.__dom.firstChild;
1174 while (n && n.nodeType !== Node.ELEMENT_NODE) {
1175 n = n.__dom.nextSibling;
1176 }
1177 return n;
1178 },
1179 getLastElementChild: function (node) {
1180 return node.__dom && node.__dom.lastChild !== undefined ? this._getLastElementCh ild(node) : node.lastElementChild;
1181 },
1182 _getLastElementChild: function (node) {
1183 var n = node.__dom.lastChild;
1184 while (n && n.nodeType !== Node.ELEMENT_NODE) {
1185 n = n.__dom.previousSibling;
1186 }
1187 return n;
1188 },
1189 getNextElementSibling: function (node) {
1190 return node.__dom && node.__dom.nextSibling !== undefined ? this._getNextElement Sibling(node) : node.nextElementSibling;
1191 },
1192 _getNextElementSibling: function (node) {
1193 var n = node.__dom.nextSibling;
1194 while (n && n.nodeType !== Node.ELEMENT_NODE) {
1195 n = n.__dom.nextSibling;
1196 }
1197 return n;
1198 },
1199 getPreviousElementSibling: function (node) {
1200 return node.__dom && node.__dom.previousSibling !== undefined ? this._getPreviou sElementSibling(node) : node.previousElementSibling;
1201 },
1202 _getPreviousElementSibling: function (node) {
1203 var n = node.__dom.previousSibling;
1204 while (n && n.nodeType !== Node.ELEMENT_NODE) {
1205 n = n.__dom.previousSibling;
1206 }
1207 return n;
1208 },
1209 saveChildNodes: function (node) {
1210 if (!this.hasChildNodes(node)) {
1211 node.__dom = node.__dom || {};
1212 node.__dom.firstChild = node.firstChild;
1213 node.__dom.lastChild = node.lastChild;
1214 node.__dom.childNodes = [];
1215 for (var n = node.firstChild; n; n = n.nextSibling) {
1216 n.__dom = n.__dom || {};
1217 n.__dom.parentNode = node;
1218 node.__dom.childNodes.push(n);
1219 n.__dom.nextSibling = n.nextSibling;
1220 n.__dom.previousSibling = n.previousSibling;
1221 }
1222 }
1223 },
1224 recordInsertBefore: function (node, container, ref_node) {
1225 container.__dom.childNodes = null;
1226 if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
1227 for (var n = node.firstChild; n; n = n.nextSibling) {
1228 this._linkNode(n, container, ref_node);
1229 }
1230 } else {
1231 this._linkNode(node, container, ref_node);
1232 }
1233 },
1234 _linkNode: function (node, container, ref_node) {
1235 node.__dom = node.__dom || {};
1236 container.__dom = container.__dom || {};
1237 if (ref_node) {
1238 ref_node.__dom = ref_node.__dom || {};
1239 }
1240 node.__dom.previousSibling = ref_node ? ref_node.__dom.previousSibling : contain er.__dom.lastChild;
1241 if (node.__dom.previousSibling) {
1242 node.__dom.previousSibling.__dom.nextSibling = node;
1243 }
1244 node.__dom.nextSibling = ref_node || null;
1245 if (node.__dom.nextSibling) {
1246 node.__dom.nextSibling.__dom.previousSibling = node;
1247 }
1248 node.__dom.parentNode = container;
1249 if (ref_node) {
1250 if (ref_node === container.__dom.firstChild) {
1251 container.__dom.firstChild = node;
1252 }
1253 } else {
1254 container.__dom.lastChild = node;
1255 if (!container.__dom.firstChild) {
1256 container.__dom.firstChild = node;
1257 }
1258 }
1259 container.__dom.childNodes = null;
1260 },
1261 recordRemoveChild: function (node, container) {
1262 node.__dom = node.__dom || {};
1263 container.__dom = container.__dom || {};
1264 if (node === container.__dom.firstChild) {
1265 container.__dom.firstChild = node.__dom.nextSibling;
1266 }
1267 if (node === container.__dom.lastChild) {
1268 container.__dom.lastChild = node.__dom.previousSibling;
1269 }
1270 var p = node.__dom.previousSibling;
1271 var n = node.__dom.nextSibling;
1272 if (p) {
1273 p.__dom.nextSibling = n;
1274 }
1275 if (n) {
1276 n.__dom.previousSibling = p;
1277 }
1278 node.__dom.parentNode = node.__dom.previousSibling = node.__dom.nextSibling = un defined;
1279 container.__dom.childNodes = null;
1280 }
1281 };
1282 Polymer.TreeApi.Composed = {
1283 getChildNodes: function (node) {
1284 return Polymer.TreeApi.arrayCopyChildNodes(node);
1285 },
1286 getParentNode: function (node) {
1287 return node.parentNode;
1288 },
1289 clearChildNodes: function (node) {
1290 node.textContent = '';
1291 },
1292 insertBefore: function (parentNode, newChild, refChild) {
1293 return nativeInsertBefore.call(parentNode, newChild, refChild || null);
1294 },
1295 appendChild: function (parentNode, newChild) {
1296 return nativeAppendChild.call(parentNode, newChild);
1297 },
1298 removeChild: function (parentNode, node) {
1299 return nativeRemoveChild.call(parentNode, node);
1300 }
1301 };
1302 }());Polymer.DomApi = function () {
1303 'use strict';
1304 var Settings = Polymer.Settings;
1305 var TreeApi = Polymer.TreeApi;
1306 var DomApi = function (node) {
1307 this.node = needsToWrap ? DomApi.wrap(node) : node;
1308 };
1309 var needsToWrap = Settings.hasShadow && !Settings.nativeShadow;
1310 DomApi.wrap = window.wrap ? window.wrap : function (node) {
1311 return node;
1312 };
1313 DomApi.prototype = {
1314 flush: function () {
1315 Polymer.dom.flush();
1316 },
1317 deepContains: function (node) {
1318 if (this.node.contains(node)) {
1319 return true;
1320 }
1321 var n = node;
1322 var doc = node.ownerDocument;
1323 while (n && n !== doc && n !== this.node) {
1324 n = Polymer.dom(n).parentNode || n.host;
1325 }
1326 return n === this.node;
1327 },
1328 queryDistributedElements: function (selector) {
1329 var c$ = this.getEffectiveChildNodes();
1330 var list = [];
1331 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
1332 if (c.nodeType === Node.ELEMENT_NODE && DomApi.matchesSelector.call(c, selector) ) {
1333 list.push(c);
1334 }
1335 }
1336 return list;
1337 },
1338 getEffectiveChildNodes: function () {
1339 var list = [];
1340 var c$ = this.childNodes;
1341 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
1342 if (c.localName === CONTENT) {
1343 var d$ = dom(c).getDistributedNodes();
1344 for (var j = 0; j < d$.length; j++) {
1345 list.push(d$[j]);
1346 }
1347 } else {
1348 list.push(c);
1349 }
1350 }
1351 return list;
1352 },
1353 observeNodes: function (callback) {
1354 if (callback) {
1355 if (!this.observer) {
1356 this.observer = this.node.localName === CONTENT ? new DomApi.DistributedNodesObs erver(this) : new DomApi.EffectiveNodesObserver(this);
1357 }
1358 return this.observer.addListener(callback);
1359 }
1360 },
1361 unobserveNodes: function (handle) {
1362 if (this.observer) {
1363 this.observer.removeListener(handle);
1364 }
1365 },
1366 notifyObserver: function () {
1367 if (this.observer) {
1368 this.observer.notify();
1369 }
1370 },
1371 _query: function (matcher, node, halter) {
1372 node = node || this.node;
1373 var list = [];
1374 this._queryElements(TreeApi.Logical.getChildNodes(node), matcher, halter, list);
1375 return list;
1376 },
1377 _queryElements: function (elements, matcher, halter, list) {
1378 for (var i = 0, l = elements.length, c; i < l && (c = elements[i]); i++) {
1379 if (c.nodeType === Node.ELEMENT_NODE) {
1380 if (this._queryElement(c, matcher, halter, list)) {
1381 return true;
1382 }
1383 }
1384 }
1385 },
1386 _queryElement: function (node, matcher, halter, list) {
1387 var result = matcher(node);
1388 if (result) {
1389 list.push(node);
1390 }
1391 if (halter && halter(result)) {
1392 return result;
1393 }
1394 this._queryElements(TreeApi.Logical.getChildNodes(node), matcher, halter, list);
1395 }
1396 };
1397 var CONTENT = DomApi.CONTENT = 'content';
1398 var dom = DomApi.factory = function (node) {
1399 node = node || document;
1400 if (!node.__domApi) {
1401 node.__domApi = new DomApi.ctor(node);
1402 }
1403 return node.__domApi;
1404 };
1405 DomApi.hasApi = function (node) {
1406 return Boolean(node.__domApi);
1407 };
1408 DomApi.ctor = DomApi;
1409 Polymer.dom = function (obj, patch) {
1410 if (obj instanceof Event) {
1411 return Polymer.EventApi.factory(obj);
1412 } else {
1413 return DomApi.factory(obj, patch);
1414 }
1415 };
1416 var p = Element.prototype;
1417 DomApi.matchesSelector = p.matches || p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector;
1418 return DomApi;
1419 }();(function () {
1420 'use strict';
1421 var Settings = Polymer.Settings;
1422 var DomApi = Polymer.DomApi;
1423 var dom = DomApi.factory;
1424 var TreeApi = Polymer.TreeApi;
1425 var getInnerHTML = Polymer.domInnerHTML.getInnerHTML;
1426 var CONTENT = DomApi.CONTENT;
1427 if (Settings.useShadow) {
1428 return;
1429 }
1430 var nativeCloneNode = Element.prototype.cloneNode;
1431 var nativeImportNode = Document.prototype.importNode;
1432 Polymer.Base.extend(DomApi.prototype, {
1433 _lazyDistribute: function (host) {
1434 if (host.shadyRoot && host.shadyRoot._distributionClean) {
1435 host.shadyRoot._distributionClean = false;
1436 Polymer.dom.addDebouncer(host.debounce('_distribute', host._distributeContent));
1437 }
1438 },
1439 appendChild: function (node) {
1440 return this.insertBefore(node);
1441 },
1442 insertBefore: function (node, ref_node) {
1443 if (ref_node && TreeApi.Logical.getParentNode(ref_node) !== this.node) {
1444 throw Error('The ref_node to be inserted before is not a child ' + 'of this node ');
1445 }
1446 if (node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
1447 var parent = TreeApi.Logical.getParentNode(node);
1448 if (parent) {
1449 if (DomApi.hasApi(parent)) {
1450 dom(parent).notifyObserver();
1451 }
1452 this._removeNode(node);
1453 } else {
1454 this._removeOwnerShadyRoot(node);
1455 }
1456 }
1457 if (!this._addNode(node, ref_node)) {
1458 if (ref_node) {
1459 ref_node = ref_node.localName === CONTENT ? this._firstComposedNode(ref_node) : ref_node;
1460 }
1461 var container = this.node._isShadyRoot ? this.node.host : this.node;
1462 if (ref_node) {
1463 TreeApi.Composed.insertBefore(container, node, ref_node);
1464 } else {
1465 TreeApi.Composed.appendChild(container, node);
1466 }
1467 }
1468 this.notifyObserver();
1469 return node;
1470 },
1471 _addNode: function (node, ref_node) {
1472 var root = this.getOwnerRoot();
1473 if (root) {
1474 var ipAdded = this._maybeAddInsertionPoint(node, this.node);
1475 if (!root._invalidInsertionPoints) {
1476 root._invalidInsertionPoints = ipAdded;
1477 }
1478 this._addNodeToHost(root.host, node);
1479 }
1480 if (TreeApi.Logical.hasChildNodes(this.node)) {
1481 TreeApi.Logical.recordInsertBefore(node, this.node, ref_node);
1482 }
1483 var handled = this._maybeDistribute(node) || this.node.shadyRoot;
1484 if (handled) {
1485 if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
1486 while (node.firstChild) {
1487 TreeApi.Composed.removeChild(node, node.firstChild);
1488 }
1489 } else {
1490 var parent = TreeApi.Composed.getParentNode(node);
1491 if (parent) {
1492 TreeApi.Composed.removeChild(parent, node);
1493 }
1494 }
1495 }
1496 return handled;
1497 },
1498 removeChild: function (node) {
1499 if (TreeApi.Logical.getParentNode(node) !== this.node) {
1500 throw Error('The node to be removed is not a child of this node: ' + node);
1501 }
1502 if (!this._removeNode(node)) {
1503 var container = this.node._isShadyRoot ? this.node.host : this.node;
1504 var parent = TreeApi.Composed.getParentNode(node);
1505 if (container === parent) {
1506 TreeApi.Composed.removeChild(container, node);
1507 }
1508 }
1509 this.notifyObserver();
1510 return node;
1511 },
1512 _removeNode: function (node) {
1513 var logicalParent = TreeApi.Logical.hasParentNode(node) && TreeApi.Logical.getPa rentNode(node);
1514 var distributed;
1515 var root = this._ownerShadyRootForNode(node);
1516 if (logicalParent) {
1517 distributed = dom(node)._maybeDistributeParent();
1518 TreeApi.Logical.recordRemoveChild(node, logicalParent);
1519 if (root && this._removeDistributedChildren(root, node)) {
1520 root._invalidInsertionPoints = true;
1521 this._lazyDistribute(root.host);
1522 }
1523 }
1524 this._removeOwnerShadyRoot(node);
1525 if (root) {
1526 this._removeNodeFromHost(root.host, node);
1527 }
1528 return distributed;
1529 },
1530 replaceChild: function (node, ref_node) {
1531 this.insertBefore(node, ref_node);
1532 this.removeChild(ref_node);
1533 return node;
1534 },
1535 _hasCachedOwnerRoot: function (node) {
1536 return Boolean(node._ownerShadyRoot !== undefined);
1537 },
1538 getOwnerRoot: function () {
1539 return this._ownerShadyRootForNode(this.node);
1540 },
1541 _ownerShadyRootForNode: function (node) {
1542 if (!node) {
1543 return;
1544 }
1545 var root = node._ownerShadyRoot;
1546 if (root === undefined) {
1547 if (node._isShadyRoot) {
1548 root = node;
1549 } else {
1550 var parent = TreeApi.Logical.getParentNode(node);
1551 if (parent) {
1552 root = parent._isShadyRoot ? parent : this._ownerShadyRootForNode(parent);
1553 } else {
1554 root = null;
1555 }
1556 }
1557 if (root || document.documentElement.contains(node)) {
1558 node._ownerShadyRoot = root;
1559 }
1560 }
1561 return root;
1562 },
1563 _maybeDistribute: function (node) {
1564 var fragContent = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noCon tent && dom(node).querySelector(CONTENT);
1565 var wrappedContent = fragContent && TreeApi.Logical.getParentNode(fragContent).n odeType !== Node.DOCUMENT_FRAGMENT_NODE;
1566 var hasContent = fragContent || node.localName === CONTENT;
1567 if (hasContent) {
1568 var root = this.getOwnerRoot();
1569 if (root) {
1570 this._lazyDistribute(root.host);
1571 }
1572 }
1573 var needsDist = this._nodeNeedsDistribution(this.node);
1574 if (needsDist) {
1575 this._lazyDistribute(this.node);
1576 }
1577 return needsDist || hasContent && !wrappedContent;
1578 },
1579 _maybeAddInsertionPoint: function (node, parent) {
1580 var added;
1581 if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !node.__noContent) {
1582 var c$ = dom(node).querySelectorAll(CONTENT);
1583 for (var i = 0, n, np, na; i < c$.length && (n = c$[i]); i++) {
1584 np = TreeApi.Logical.getParentNode(n);
1585 if (np === node) {
1586 np = parent;
1587 }
1588 na = this._maybeAddInsertionPoint(n, np);
1589 added = added || na;
1590 }
1591 } else if (node.localName === CONTENT) {
1592 TreeApi.Logical.saveChildNodes(parent);
1593 TreeApi.Logical.saveChildNodes(node);
1594 added = true;
1595 }
1596 return added;
1597 },
1598 _updateInsertionPoints: function (host) {
1599 var i$ = host.shadyRoot._insertionPoints = dom(host.shadyRoot).querySelectorAll( CONTENT);
1600 for (var i = 0, c; i < i$.length; i++) {
1601 c = i$[i];
1602 TreeApi.Logical.saveChildNodes(c);
1603 TreeApi.Logical.saveChildNodes(TreeApi.Logical.getParentNode(c));
1604 }
1605 },
1606 _nodeNeedsDistribution: function (node) {
1607 return node && node.shadyRoot && DomApi.hasInsertionPoint(node.shadyRoot);
1608 },
1609 _addNodeToHost: function (host, node) {
1610 if (host._elementAdd) {
1611 host._elementAdd(node);
1612 }
1613 },
1614 _removeNodeFromHost: function (host, node) {
1615 if (host._elementRemove) {
1616 host._elementRemove(node);
1617 }
1618 },
1619 _removeDistributedChildren: function (root, container) {
1620 var hostNeedsDist;
1621 var ip$ = root._insertionPoints;
1622 for (var i = 0; i < ip$.length; i++) {
1623 var content = ip$[i];
1624 if (this._contains(container, content)) {
1625 var dc$ = dom(content).getDistributedNodes();
1626 for (var j = 0; j < dc$.length; j++) {
1627 hostNeedsDist = true;
1628 var node = dc$[j];
1629 var parent = TreeApi.Composed.getParentNode(node);
1630 if (parent) {
1631 TreeApi.Composed.removeChild(parent, node);
1632 }
1633 }
1634 }
1635 }
1636 return hostNeedsDist;
1637 },
1638 _contains: function (container, node) {
1639 while (node) {
1640 if (node == container) {
1641 return true;
1642 }
1643 node = TreeApi.Logical.getParentNode(node);
1644 }
1645 },
1646 _removeOwnerShadyRoot: function (node) {
1647 if (this._hasCachedOwnerRoot(node)) {
1648 var c$ = TreeApi.Logical.getChildNodes(node);
1649 for (var i = 0, l = c$.length, n; i < l && (n = c$[i]); i++) {
1650 this._removeOwnerShadyRoot(n);
1651 }
1652 }
1653 node._ownerShadyRoot = undefined;
1654 },
1655 _firstComposedNode: function (content) {
1656 var n$ = dom(content).getDistributedNodes();
1657 for (var i = 0, l = n$.length, n, p$; i < l && (n = n$[i]); i++) {
1658 p$ = dom(n).getDestinationInsertionPoints();
1659 if (p$[p$.length - 1] === content) {
1660 return n;
1661 }
1662 }
1663 },
1664 querySelector: function (selector) {
1665 var result = this._query(function (n) {
1666 return DomApi.matchesSelector.call(n, selector);
1667 }, this.node, function (n) {
1668 return Boolean(n);
1669 })[0];
1670 return result || null;
1671 },
1672 querySelectorAll: function (selector) {
1673 return this._query(function (n) {
1674 return DomApi.matchesSelector.call(n, selector);
1675 }, this.node);
1676 },
1677 getDestinationInsertionPoints: function () {
1678 return this.node._destinationInsertionPoints || [];
1679 },
1680 getDistributedNodes: function () {
1681 return this.node._distributedNodes || [];
1682 },
1683 _clear: function () {
1684 while (this.childNodes.length) {
1685 this.removeChild(this.childNodes[0]);
1686 }
1687 },
1688 setAttribute: function (name, value) {
1689 this.node.setAttribute(name, value);
1690 this._maybeDistributeParent();
1691 },
1692 removeAttribute: function (name) {
1693 this.node.removeAttribute(name);
1694 this._maybeDistributeParent();
1695 },
1696 _maybeDistributeParent: function () {
1697 if (this._nodeNeedsDistribution(this.parentNode)) {
1698 this._lazyDistribute(this.parentNode);
1699 return true;
1700 }
1701 },
1702 cloneNode: function (deep) {
1703 var n = nativeCloneNode.call(this.node, false);
1704 if (deep) {
1705 var c$ = this.childNodes;
1706 var d = dom(n);
1707 for (var i = 0, nc; i < c$.length; i++) {
1708 nc = dom(c$[i]).cloneNode(true);
1709 d.appendChild(nc);
1710 }
1711 }
1712 return n;
1713 },
1714 importNode: function (externalNode, deep) {
1715 var doc = this.node instanceof Document ? this.node : this.node.ownerDocument;
1716 var n = nativeImportNode.call(doc, externalNode, false);
1717 if (deep) {
1718 var c$ = TreeApi.Logical.getChildNodes(externalNode);
1719 var d = dom(n);
1720 for (var i = 0, nc; i < c$.length; i++) {
1721 nc = dom(doc).importNode(c$[i], true);
1722 d.appendChild(nc);
1723 }
1724 }
1725 return n;
1726 },
1727 _getComposedInnerHTML: function () {
1728 return getInnerHTML(this.node, true);
1729 }
1730 });
1731 Object.defineProperties(DomApi.prototype, {
1732 activeElement: {
1733 get: function () {
1734 var active = document.activeElement;
1735 if (!active) {
1736 return null;
1737 }
1738 var isShadyRoot = !!this.node._isShadyRoot;
1739 if (this.node !== document) {
1740 if (!isShadyRoot) {
1741 return null;
1742 }
1743 if (this.node.host === active || !this.node.host.contains(active)) {
1744 return null;
1745 }
1746 }
1747 var activeRoot = dom(active).getOwnerRoot();
1748 while (activeRoot && activeRoot !== this.node) {
1749 active = activeRoot.host;
1750 activeRoot = dom(active).getOwnerRoot();
1751 }
1752 if (this.node === document) {
1753 return activeRoot ? null : active;
1754 } else {
1755 return activeRoot === this.node ? active : null;
1756 }
1757 },
1758 configurable: true
1759 },
1760 childNodes: {
1761 get: function () {
1762 var c$ = TreeApi.Logical.getChildNodes(this.node);
1763 return Array.isArray(c$) ? c$ : TreeApi.arrayCopyChildNodes(this.node);
1764 },
1765 configurable: true
1766 },
1767 children: {
1768 get: function () {
1769 if (TreeApi.Logical.hasChildNodes(this.node)) {
1770 return Array.prototype.filter.call(this.childNodes, function (n) {
1771 return n.nodeType === Node.ELEMENT_NODE;
1772 });
1773 } else {
1774 return TreeApi.arrayCopyChildren(this.node);
1775 }
1776 },
1777 configurable: true
1778 },
1779 parentNode: {
1780 get: function () {
1781 return TreeApi.Logical.getParentNode(this.node);
1782 },
1783 configurable: true
1784 },
1785 firstChild: {
1786 get: function () {
1787 return TreeApi.Logical.getFirstChild(this.node);
1788 },
1789 configurable: true
1790 },
1791 lastChild: {
1792 get: function () {
1793 return TreeApi.Logical.getLastChild(this.node);
1794 },
1795 configurable: true
1796 },
1797 nextSibling: {
1798 get: function () {
1799 return TreeApi.Logical.getNextSibling(this.node);
1800 },
1801 configurable: true
1802 },
1803 previousSibling: {
1804 get: function () {
1805 return TreeApi.Logical.getPreviousSibling(this.node);
1806 },
1807 configurable: true
1808 },
1809 firstElementChild: {
1810 get: function () {
1811 return TreeApi.Logical.getFirstElementChild(this.node);
1812 },
1813 configurable: true
1814 },
1815 lastElementChild: {
1816 get: function () {
1817 return TreeApi.Logical.getLastElementChild(this.node);
1818 },
1819 configurable: true
1820 },
1821 nextElementSibling: {
1822 get: function () {
1823 return TreeApi.Logical.getNextElementSibling(this.node);
1824 },
1825 configurable: true
1826 },
1827 previousElementSibling: {
1828 get: function () {
1829 return TreeApi.Logical.getPreviousElementSibling(this.node);
1830 },
1831 configurable: true
1832 },
1833 textContent: {
1834 get: function () {
1835 var nt = this.node.nodeType;
1836 if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) {
1837 return this.node.textContent;
1838 } else {
1839 var tc = [];
1840 for (var i = 0, cn = this.childNodes, c; c = cn[i]; i++) {
1841 if (c.nodeType !== Node.COMMENT_NODE) {
1842 tc.push(c.textContent);
1843 }
1844 }
1845 return tc.join('');
1846 }
1847 },
1848 set: function (text) {
1849 var nt = this.node.nodeType;
1850 if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) {
1851 this.node.textContent = text;
1852 } else {
1853 this._clear();
1854 if (text) {
1855 this.appendChild(document.createTextNode(text));
1856 }
1857 }
1858 },
1859 configurable: true
1860 },
1861 innerHTML: {
1862 get: function () {
1863 var nt = this.node.nodeType;
1864 if (nt === Node.TEXT_NODE || nt === Node.COMMENT_NODE) {
1865 return null;
1866 } else {
1867 return getInnerHTML(this.node);
1868 }
1869 },
1870 set: function (text) {
1871 var nt = this.node.nodeType;
1872 if (nt !== Node.TEXT_NODE || nt !== Node.COMMENT_NODE) {
1873 this._clear();
1874 var d = document.createElement('div');
1875 d.innerHTML = text;
1876 var c$ = TreeApi.arrayCopyChildNodes(d);
1877 for (var i = 0; i < c$.length; i++) {
1878 this.appendChild(c$[i]);
1879 }
1880 }
1881 },
1882 configurable: true
1883 }
1884 });
1885 DomApi.hasInsertionPoint = function (root) {
1886 return Boolean(root && root._insertionPoints.length);
1887 };
1888 }());(function () {
1889 'use strict';
1890 var Settings = Polymer.Settings;
1891 var TreeApi = Polymer.TreeApi;
1892 var DomApi = Polymer.DomApi;
1893 if (!Settings.useShadow) {
1894 return;
1895 }
1896 Polymer.Base.extend(DomApi.prototype, {
1897 querySelectorAll: function (selector) {
1898 return TreeApi.arrayCopy(this.node.querySelectorAll(selector));
1899 },
1900 getOwnerRoot: function () {
1901 var n = this.node;
1902 while (n) {
1903 if (n.nodeType === Node.DOCUMENT_FRAGMENT_NODE && n.host) {
1904 return n;
1905 }
1906 n = n.parentNode;
1907 }
1908 },
1909 importNode: function (externalNode, deep) {
1910 var doc = this.node instanceof Document ? this.node : this.node.ownerDocument;
1911 return doc.importNode(externalNode, deep);
1912 },
1913 getDestinationInsertionPoints: function () {
1914 var n$ = this.node.getDestinationInsertionPoints && this.node.getDestinationInse rtionPoints();
1915 return n$ ? TreeApi.arrayCopy(n$) : [];
1916 },
1917 getDistributedNodes: function () {
1918 var n$ = this.node.getDistributedNodes && this.node.getDistributedNodes();
1919 return n$ ? TreeApi.arrayCopy(n$) : [];
1920 }
1921 });
1922 Object.defineProperties(DomApi.prototype, {
1923 activeElement: {
1924 get: function () {
1925 var node = DomApi.wrap(this.node);
1926 var activeElement = node.activeElement;
1927 return node.contains(activeElement) ? activeElement : null;
1928 },
1929 configurable: true
1930 },
1931 childNodes: {
1932 get: function () {
1933 return TreeApi.arrayCopyChildNodes(this.node);
1934 },
1935 configurable: true
1936 },
1937 children: {
1938 get: function () {
1939 return TreeApi.arrayCopyChildren(this.node);
1940 },
1941 configurable: true
1942 },
1943 textContent: {
1944 get: function () {
1945 return this.node.textContent;
1946 },
1947 set: function (value) {
1948 return this.node.textContent = value;
1949 },
1950 configurable: true
1951 },
1952 innerHTML: {
1953 get: function () {
1954 return this.node.innerHTML;
1955 },
1956 set: function (value) {
1957 return this.node.innerHTML = value;
1958 },
1959 configurable: true
1960 }
1961 });
1962 var forwardMethods = function (m$) {
1963 for (var i = 0; i < m$.length; i++) {
1964 forwardMethod(m$[i]);
1965 }
1966 };
1967 var forwardMethod = function (method) {
1968 DomApi.prototype[method] = function () {
1969 return this.node[method].apply(this.node, arguments);
1970 };
1971 };
1972 forwardMethods([
1973 'cloneNode',
1974 'appendChild',
1975 'insertBefore',
1976 'removeChild',
1977 'replaceChild',
1978 'setAttribute',
1979 'removeAttribute',
1980 'querySelector'
1981 ]);
1982 var forwardProperties = function (f$) {
1983 for (var i = 0; i < f$.length; i++) {
1984 forwardProperty(f$[i]);
1985 }
1986 };
1987 var forwardProperty = function (name) {
1988 Object.defineProperty(DomApi.prototype, name, {
1989 get: function () {
1990 return this.node[name];
1991 },
1992 configurable: true
1993 });
1994 };
1995 forwardProperties([
1996 'parentNode',
1997 'firstChild',
1998 'lastChild',
1999 'nextSibling',
2000 'previousSibling',
2001 'firstElementChild',
2002 'lastElementChild',
2003 'nextElementSibling',
2004 'previousElementSibling'
2005 ]);
2006 }());Polymer.Base.extend(Polymer.dom, {
2007 _flushGuard: 0,
2008 _FLUSH_MAX: 100,
2009 _needsTakeRecords: !Polymer.Settings.useNativeCustomElements,
2010 _debouncers: [],
2011 _staticFlushList: [],
2012 _finishDebouncer: null,
2013 flush: function () {
2014 this._flushGuard = 0;
2015 this._prepareFlush();
2016 while (this._debouncers.length && this._flushGuard < this._FLUSH_MAX) {
2017 while (this._debouncers.length) {
2018 this._debouncers.shift().complete();
2019 }
2020 if (this._finishDebouncer) {
2021 this._finishDebouncer.complete();
2022 }
2023 this._prepareFlush();
2024 this._flushGuard++;
2025 }
2026 if (this._flushGuard >= this._FLUSH_MAX) {
2027 console.warn('Polymer.dom.flush aborted. Flush may not be complete.');
2028 }
2029 },
2030 _prepareFlush: function () {
2031 if (this._needsTakeRecords) {
2032 CustomElements.takeRecords();
2033 }
2034 for (var i = 0; i < this._staticFlushList.length; i++) {
2035 this._staticFlushList[i]();
2036 }
2037 },
2038 addStaticFlush: function (fn) {
2039 this._staticFlushList.push(fn);
2040 },
2041 removeStaticFlush: function (fn) {
2042 var i = this._staticFlushList.indexOf(fn);
2043 if (i >= 0) {
2044 this._staticFlushList.splice(i, 1);
2045 }
2046 },
2047 addDebouncer: function (debouncer) {
2048 this._debouncers.push(debouncer);
2049 this._finishDebouncer = Polymer.Debounce(this._finishDebouncer, this._finishFlus h);
2050 },
2051 _finishFlush: function () {
2052 Polymer.dom._debouncers = [];
2053 }
2054 });Polymer.EventApi = function () {
2055 'use strict';
2056 var DomApi = Polymer.DomApi.ctor;
2057 var Settings = Polymer.Settings;
2058 DomApi.Event = function (event) {
2059 this.event = event;
2060 };
2061 if (Settings.useShadow) {
2062 DomApi.Event.prototype = {
2063 get rootTarget() {
2064 return this.event.path[0];
2065 },
2066 get localTarget() {
2067 return this.event.target;
2068 },
2069 get path() {
2070 var path = this.event.path;
2071 if (!Array.isArray(path)) {
2072 path = Array.prototype.slice.call(path);
2073 }
2074 return path;
2075 }
2076 };
2077 } else {
2078 DomApi.Event.prototype = {
2079 get rootTarget() {
2080 return this.event.target;
2081 },
2082 get localTarget() {
2083 var current = this.event.currentTarget;
2084 var currentRoot = current && Polymer.dom(current).getOwnerRoot();
2085 var p$ = this.path;
2086 for (var i = 0; i < p$.length; i++) {
2087 if (Polymer.dom(p$[i]).getOwnerRoot() === currentRoot) {
2088 return p$[i];
2089 }
2090 }
2091 },
2092 get path() {
2093 if (!this.event._path) {
2094 var path = [];
2095 var current = this.rootTarget;
2096 while (current) {
2097 path.push(current);
2098 var insertionPoints = Polymer.dom(current).getDestinationInsertionPoints();
2099 if (insertionPoints.length) {
2100 for (var i = 0; i < insertionPoints.length - 1; i++) {
2101 path.push(insertionPoints[i]);
2102 }
2103 current = insertionPoints[insertionPoints.length - 1];
2104 } else {
2105 current = Polymer.dom(current).parentNode || current.host;
2106 }
2107 }
2108 path.push(window);
2109 this.event._path = path;
2110 }
2111 return this.event._path;
2112 }
2113 };
2114 }
2115 var factory = function (event) {
2116 if (!event.__eventApi) {
2117 event.__eventApi = new DomApi.Event(event);
2118 }
2119 return event.__eventApi;
2120 };
2121 return { factory: factory };
2122 }();(function () {
2123 'use strict';
2124 var DomApi = Polymer.DomApi.ctor;
2125 var useShadow = Polymer.Settings.useShadow;
2126 Object.defineProperty(DomApi.prototype, 'classList', {
2127 get: function () {
2128 if (!this._classList) {
2129 this._classList = new DomApi.ClassList(this);
2130 }
2131 return this._classList;
2132 },
2133 configurable: true
2134 });
2135 DomApi.ClassList = function (host) {
2136 this.domApi = host;
2137 this.node = host.node;
2138 };
2139 DomApi.ClassList.prototype = {
2140 add: function () {
2141 this.node.classList.add.apply(this.node.classList, arguments);
2142 this._distributeParent();
2143 },
2144 remove: function () {
2145 this.node.classList.remove.apply(this.node.classList, arguments);
2146 this._distributeParent();
2147 },
2148 toggle: function () {
2149 this.node.classList.toggle.apply(this.node.classList, arguments);
2150 this._distributeParent();
2151 },
2152 _distributeParent: function () {
2153 if (!useShadow) {
2154 this.domApi._maybeDistributeParent();
2155 }
2156 },
2157 contains: function () {
2158 return this.node.classList.contains.apply(this.node.classList, arguments);
2159 }
2160 };
2161 }());(function () {
2162 'use strict';
2163 var DomApi = Polymer.DomApi.ctor;
2164 var Settings = Polymer.Settings;
2165 DomApi.EffectiveNodesObserver = function (domApi) {
2166 this.domApi = domApi;
2167 this.node = this.domApi.node;
2168 this._listeners = [];
2169 };
2170 DomApi.EffectiveNodesObserver.prototype = {
2171 addListener: function (callback) {
2172 if (!this._isSetup) {
2173 this._setup();
2174 this._isSetup = true;
2175 }
2176 var listener = {
2177 fn: callback,
2178 _nodes: []
2179 };
2180 this._listeners.push(listener);
2181 this._scheduleNotify();
2182 return listener;
2183 },
2184 removeListener: function (handle) {
2185 var i = this._listeners.indexOf(handle);
2186 if (i >= 0) {
2187 this._listeners.splice(i, 1);
2188 handle._nodes = [];
2189 }
2190 if (!this._hasListeners()) {
2191 this._cleanup();
2192 this._isSetup = false;
2193 }
2194 },
2195 _setup: function () {
2196 this._observeContentElements(this.domApi.childNodes);
2197 },
2198 _cleanup: function () {
2199 this._unobserveContentElements(this.domApi.childNodes);
2200 },
2201 _hasListeners: function () {
2202 return Boolean(this._listeners.length);
2203 },
2204 _scheduleNotify: function () {
2205 if (this._debouncer) {
2206 this._debouncer.stop();
2207 }
2208 this._debouncer = Polymer.Debounce(this._debouncer, this._notify);
2209 this._debouncer.context = this;
2210 Polymer.dom.addDebouncer(this._debouncer);
2211 },
2212 notify: function () {
2213 if (this._hasListeners()) {
2214 this._scheduleNotify();
2215 }
2216 },
2217 _notify: function () {
2218 this._beforeCallListeners();
2219 this._callListeners();
2220 },
2221 _beforeCallListeners: function () {
2222 this._updateContentElements();
2223 },
2224 _updateContentElements: function () {
2225 this._observeContentElements(this.domApi.childNodes);
2226 },
2227 _observeContentElements: function (elements) {
2228 for (var i = 0, n; i < elements.length && (n = elements[i]); i++) {
2229 if (this._isContent(n)) {
2230 n.__observeNodesMap = n.__observeNodesMap || new WeakMap();
2231 if (!n.__observeNodesMap.has(this)) {
2232 n.__observeNodesMap.set(this, this._observeContent(n));
2233 }
2234 }
2235 }
2236 },
2237 _observeContent: function (content) {
2238 var self = this;
2239 var h = Polymer.dom(content).observeNodes(function () {
2240 self._scheduleNotify();
2241 });
2242 h._avoidChangeCalculation = true;
2243 return h;
2244 },
2245 _unobserveContentElements: function (elements) {
2246 for (var i = 0, n, h; i < elements.length && (n = elements[i]); i++) {
2247 if (this._isContent(n)) {
2248 h = n.__observeNodesMap.get(this);
2249 if (h) {
2250 Polymer.dom(n).unobserveNodes(h);
2251 n.__observeNodesMap.delete(this);
2252 }
2253 }
2254 }
2255 },
2256 _isContent: function (node) {
2257 return node.localName === 'content';
2258 },
2259 _callListeners: function () {
2260 var o$ = this._listeners;
2261 var nodes = this._getEffectiveNodes();
2262 for (var i = 0, o; i < o$.length && (o = o$[i]); i++) {
2263 var info = this._generateListenerInfo(o, nodes);
2264 if (info || o._alwaysNotify) {
2265 this._callListener(o, info);
2266 }
2267 }
2268 },
2269 _getEffectiveNodes: function () {
2270 return this.domApi.getEffectiveChildNodes();
2271 },
2272 _generateListenerInfo: function (listener, newNodes) {
2273 if (listener._avoidChangeCalculation) {
2274 return true;
2275 }
2276 var oldNodes = listener._nodes;
2277 var info = {
2278 target: this.node,
2279 addedNodes: [],
2280 removedNodes: []
2281 };
2282 var splices = Polymer.ArraySplice.calculateSplices(newNodes, oldNodes);
2283 for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
2284 for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) {
2285 info.removedNodes.push(n);
2286 }
2287 }
2288 for (i = 0, s; i < splices.length && (s = splices[i]); i++) {
2289 for (j = s.index; j < s.index + s.addedCount; j++) {
2290 info.addedNodes.push(newNodes[j]);
2291 }
2292 }
2293 listener._nodes = newNodes;
2294 if (info.addedNodes.length || info.removedNodes.length) {
2295 return info;
2296 }
2297 },
2298 _callListener: function (listener, info) {
2299 return listener.fn.call(this.node, info);
2300 },
2301 enableShadowAttributeTracking: function () {
2302 }
2303 };
2304 if (Settings.useShadow) {
2305 var baseSetup = DomApi.EffectiveNodesObserver.prototype._setup;
2306 var baseCleanup = DomApi.EffectiveNodesObserver.prototype._cleanup;
2307 Polymer.Base.extend(DomApi.EffectiveNodesObserver.prototype, {
2308 _setup: function () {
2309 if (!this._observer) {
2310 var self = this;
2311 this._mutationHandler = function (mxns) {
2312 if (mxns && mxns.length) {
2313 self._scheduleNotify();
2314 }
2315 };
2316 this._observer = new MutationObserver(this._mutationHandler);
2317 this._boundFlush = function () {
2318 self._flush();
2319 };
2320 Polymer.dom.addStaticFlush(this._boundFlush);
2321 this._observer.observe(this.node, { childList: true });
2322 }
2323 baseSetup.call(this);
2324 },
2325 _cleanup: function () {
2326 this._observer.disconnect();
2327 this._observer = null;
2328 this._mutationHandler = null;
2329 Polymer.dom.removeStaticFlush(this._boundFlush);
2330 baseCleanup.call(this);
2331 },
2332 _flush: function () {
2333 if (this._observer) {
2334 this._mutationHandler(this._observer.takeRecords());
2335 }
2336 },
2337 enableShadowAttributeTracking: function () {
2338 if (this._observer) {
2339 this._makeContentListenersAlwaysNotify();
2340 this._observer.disconnect();
2341 this._observer.observe(this.node, {
2342 childList: true,
2343 attributes: true,
2344 subtree: true
2345 });
2346 var root = this.domApi.getOwnerRoot();
2347 var host = root && root.host;
2348 if (host && Polymer.dom(host).observer) {
2349 Polymer.dom(host).observer.enableShadowAttributeTracking();
2350 }
2351 }
2352 },
2353 _makeContentListenersAlwaysNotify: function () {
2354 for (var i = 0, h; i < this._listeners.length; i++) {
2355 h = this._listeners[i];
2356 h._alwaysNotify = h._isContentListener;
2357 }
2358 }
2359 });
2360 }
2361 }());(function () {
2362 'use strict';
2363 var DomApi = Polymer.DomApi.ctor;
2364 var Settings = Polymer.Settings;
2365 DomApi.DistributedNodesObserver = function (domApi) {
2366 DomApi.EffectiveNodesObserver.call(this, domApi);
2367 };
2368 DomApi.DistributedNodesObserver.prototype = Object.create(DomApi.EffectiveNodesO bserver.prototype);
2369 Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, {
2370 _setup: function () {
2371 },
2372 _cleanup: function () {
2373 },
2374 _beforeCallListeners: function () {
2375 },
2376 _getEffectiveNodes: function () {
2377 return this.domApi.getDistributedNodes();
2378 }
2379 });
2380 if (Settings.useShadow) {
2381 Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype, {
2382 _setup: function () {
2383 if (!this._observer) {
2384 var root = this.domApi.getOwnerRoot();
2385 var host = root && root.host;
2386 if (host) {
2387 var self = this;
2388 this._observer = Polymer.dom(host).observeNodes(function () {
2389 self._scheduleNotify();
2390 });
2391 this._observer._isContentListener = true;
2392 if (this._hasAttrSelect()) {
2393 Polymer.dom(host).observer.enableShadowAttributeTracking();
2394 }
2395 }
2396 }
2397 },
2398 _hasAttrSelect: function () {
2399 var select = this.node.getAttribute('select');
2400 return select && select.match(/[[.]+/);
2401 },
2402 _cleanup: function () {
2403 var root = this.domApi.getOwnerRoot();
2404 var host = root && root.host;
2405 if (host) {
2406 Polymer.dom(host).unobserveNodes(this._observer);
2407 }
2408 this._observer = null;
2409 }
2410 });
2411 }
2412 }());(function () {
2413 var DomApi = Polymer.DomApi;
2414 var TreeApi = Polymer.TreeApi;
2415 Polymer.Base._addFeature({
2416 _prepShady: function () {
2417 this._useContent = this._useContent || Boolean(this._template);
2418 },
2419 _setupShady: function () {
2420 this.shadyRoot = null;
2421 if (!this.__domApi) {
2422 this.__domApi = null;
2423 }
2424 if (!this.__dom) {
2425 this.__dom = null;
2426 }
2427 if (!this._ownerShadyRoot) {
2428 this._ownerShadyRoot = undefined;
2429 }
2430 },
2431 _poolContent: function () {
2432 if (this._useContent) {
2433 TreeApi.Logical.saveChildNodes(this);
2434 }
2435 },
2436 _setupRoot: function () {
2437 if (this._useContent) {
2438 this._createLocalRoot();
2439 if (!this.dataHost) {
2440 upgradeLogicalChildren(TreeApi.Logical.getChildNodes(this));
2441 }
2442 }
2443 },
2444 _createLocalRoot: function () {
2445 this.shadyRoot = this.root;
2446 this.shadyRoot._distributionClean = false;
2447 this.shadyRoot._hasDistributed = false;
2448 this.shadyRoot._isShadyRoot = true;
2449 this.shadyRoot._dirtyRoots = [];
2450 var i$ = this.shadyRoot._insertionPoints = !this._notes || this._notes._hasConte nt ? this.shadyRoot.querySelectorAll('content') : [];
2451 TreeApi.Logical.saveChildNodes(this.shadyRoot);
2452 for (var i = 0, c; i < i$.length; i++) {
2453 c = i$[i];
2454 TreeApi.Logical.saveChildNodes(c);
2455 TreeApi.Logical.saveChildNodes(c.parentNode);
2456 }
2457 this.shadyRoot.host = this;
2458 },
2459 get domHost() {
2460 var root = Polymer.dom(this).getOwnerRoot();
2461 return root && root.host;
2462 },
2463 distributeContent: function (updateInsertionPoints) {
2464 if (this.shadyRoot) {
2465 this.shadyRoot._invalidInsertionPoints = this.shadyRoot._invalidInsertionPoints || updateInsertionPoints;
2466 var host = getTopDistributingHost(this);
2467 Polymer.dom(this)._lazyDistribute(host);
2468 }
2469 },
2470 _distributeContent: function () {
2471 if (this._useContent && !this.shadyRoot._distributionClean) {
2472 if (this.shadyRoot._invalidInsertionPoints) {
2473 Polymer.dom(this)._updateInsertionPoints(this);
2474 this.shadyRoot._invalidInsertionPoints = false;
2475 }
2476 this._beginDistribute();
2477 this._distributeDirtyRoots();
2478 this._finishDistribute();
2479 }
2480 },
2481 _beginDistribute: function () {
2482 if (this._useContent && DomApi.hasInsertionPoint(this.shadyRoot)) {
2483 this._resetDistribution();
2484 this._distributePool(this.shadyRoot, this._collectPool());
2485 }
2486 },
2487 _distributeDirtyRoots: function () {
2488 var c$ = this.shadyRoot._dirtyRoots;
2489 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
2490 c._distributeContent();
2491 }
2492 this.shadyRoot._dirtyRoots = [];
2493 },
2494 _finishDistribute: function () {
2495 if (this._useContent) {
2496 this.shadyRoot._distributionClean = true;
2497 if (DomApi.hasInsertionPoint(this.shadyRoot)) {
2498 this._composeTree();
2499 notifyContentObservers(this.shadyRoot);
2500 } else {
2501 if (!this.shadyRoot._hasDistributed) {
2502 TreeApi.Composed.clearChildNodes(this);
2503 this.appendChild(this.shadyRoot);
2504 } else {
2505 var children = this._composeNode(this);
2506 this._updateChildNodes(this, children);
2507 }
2508 }
2509 if (!this.shadyRoot._hasDistributed) {
2510 notifyInitialDistribution(this);
2511 }
2512 this.shadyRoot._hasDistributed = true;
2513 }
2514 },
2515 elementMatches: function (selector, node) {
2516 node = node || this;
2517 return DomApi.matchesSelector.call(node, selector);
2518 },
2519 _resetDistribution: function () {
2520 var children = TreeApi.Logical.getChildNodes(this);
2521 for (var i = 0; i < children.length; i++) {
2522 var child = children[i];
2523 if (child._destinationInsertionPoints) {
2524 child._destinationInsertionPoints = undefined;
2525 }
2526 if (isInsertionPoint(child)) {
2527 clearDistributedDestinationInsertionPoints(child);
2528 }
2529 }
2530 var root = this.shadyRoot;
2531 var p$ = root._insertionPoints;
2532 for (var j = 0; j < p$.length; j++) {
2533 p$[j]._distributedNodes = [];
2534 }
2535 },
2536 _collectPool: function () {
2537 var pool = [];
2538 var children = TreeApi.Logical.getChildNodes(this);
2539 for (var i = 0; i < children.length; i++) {
2540 var child = children[i];
2541 if (isInsertionPoint(child)) {
2542 pool.push.apply(pool, child._distributedNodes);
2543 } else {
2544 pool.push(child);
2545 }
2546 }
2547 return pool;
2548 },
2549 _distributePool: function (node, pool) {
2550 var p$ = node._insertionPoints;
2551 for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) {
2552 this._distributeInsertionPoint(p, pool);
2553 maybeRedistributeParent(p, this);
2554 }
2555 },
2556 _distributeInsertionPoint: function (content, pool) {
2557 var anyDistributed = false;
2558 for (var i = 0, l = pool.length, node; i < l; i++) {
2559 node = pool[i];
2560 if (!node) {
2561 continue;
2562 }
2563 if (this._matchesContentSelect(node, content)) {
2564 distributeNodeInto(node, content);
2565 pool[i] = undefined;
2566 anyDistributed = true;
2567 }
2568 }
2569 if (!anyDistributed) {
2570 var children = TreeApi.Logical.getChildNodes(content);
2571 for (var j = 0; j < children.length; j++) {
2572 distributeNodeInto(children[j], content);
2573 }
2574 }
2575 },
2576 _composeTree: function () {
2577 this._updateChildNodes(this, this._composeNode(this));
2578 var p$ = this.shadyRoot._insertionPoints;
2579 for (var i = 0, l = p$.length, p, parent; i < l && (p = p$[i]); i++) {
2580 parent = TreeApi.Logical.getParentNode(p);
2581 if (!parent._useContent && parent !== this && parent !== this.shadyRoot) {
2582 this._updateChildNodes(parent, this._composeNode(parent));
2583 }
2584 }
2585 },
2586 _composeNode: function (node) {
2587 var children = [];
2588 var c$ = TreeApi.Logical.getChildNodes(node.shadyRoot || node);
2589 for (var i = 0; i < c$.length; i++) {
2590 var child = c$[i];
2591 if (isInsertionPoint(child)) {
2592 var distributedNodes = child._distributedNodes;
2593 for (var j = 0; j < distributedNodes.length; j++) {
2594 var distributedNode = distributedNodes[j];
2595 if (isFinalDestination(child, distributedNode)) {
2596 children.push(distributedNode);
2597 }
2598 }
2599 } else {
2600 children.push(child);
2601 }
2602 }
2603 return children;
2604 },
2605 _updateChildNodes: function (container, children) {
2606 var composed = TreeApi.Composed.getChildNodes(container);
2607 var splices = Polymer.ArraySplice.calculateSplices(children, composed);
2608 for (var i = 0, d = 0, s; i < splices.length && (s = splices[i]); i++) {
2609 for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) {
2610 if (TreeApi.Composed.getParentNode(n) === container) {
2611 TreeApi.Composed.removeChild(container, n);
2612 }
2613 composed.splice(s.index + d, 1);
2614 }
2615 d -= s.addedCount;
2616 }
2617 for (var i = 0, s, next; i < splices.length && (s = splices[i]); i++) {
2618 next = composed[s.index];
2619 for (j = s.index, n; j < s.index + s.addedCount; j++) {
2620 n = children[j];
2621 TreeApi.Composed.insertBefore(container, n, next);
2622 composed.splice(j, 0, n);
2623 }
2624 }
2625 },
2626 _matchesContentSelect: function (node, contentElement) {
2627 var select = contentElement.getAttribute('select');
2628 if (!select) {
2629 return true;
2630 }
2631 select = select.trim();
2632 if (!select) {
2633 return true;
2634 }
2635 if (!(node instanceof Element)) {
2636 return false;
2637 }
2638 var validSelectors = /^(:not\()?[*.#[a-zA-Z_|]/;
2639 if (!validSelectors.test(select)) {
2640 return false;
2641 }
2642 return this.elementMatches(select, node);
2643 },
2644 _elementAdd: function () {
2645 },
2646 _elementRemove: function () {
2647 }
2648 });
2649 function distributeNodeInto(child, insertionPoint) {
2650 insertionPoint._distributedNodes.push(child);
2651 var points = child._destinationInsertionPoints;
2652 if (!points) {
2653 child._destinationInsertionPoints = [insertionPoint];
2654 } else {
2655 points.push(insertionPoint);
2656 }
2657 }
2658 function clearDistributedDestinationInsertionPoints(content) {
2659 var e$ = content._distributedNodes;
2660 if (e$) {
2661 for (var i = 0; i < e$.length; i++) {
2662 var d = e$[i]._destinationInsertionPoints;
2663 if (d) {
2664 d.splice(d.indexOf(content) + 1, d.length);
2665 }
2666 }
2667 }
2668 }
2669 function maybeRedistributeParent(content, host) {
2670 var parent = TreeApi.Logical.getParentNode(content);
2671 if (parent && parent.shadyRoot && DomApi.hasInsertionPoint(parent.shadyRoot) && parent.shadyRoot._distributionClean) {
2672 parent.shadyRoot._distributionClean = false;
2673 host.shadyRoot._dirtyRoots.push(parent);
2674 }
2675 }
2676 function isFinalDestination(insertionPoint, node) {
2677 var points = node._destinationInsertionPoints;
2678 return points && points[points.length - 1] === insertionPoint;
2679 }
2680 function isInsertionPoint(node) {
2681 return node.localName == 'content';
2682 }
2683 function getTopDistributingHost(host) {
2684 while (host && hostNeedsRedistribution(host)) {
2685 host = host.domHost;
2686 }
2687 return host;
2688 }
2689 function hostNeedsRedistribution(host) {
2690 var c$ = TreeApi.Logical.getChildNodes(host);
2691 for (var i = 0, c; i < c$.length; i++) {
2692 c = c$[i];
2693 if (c.localName && c.localName === 'content') {
2694 return host.domHost;
2695 }
2696 }
2697 }
2698 function notifyContentObservers(root) {
2699 for (var i = 0, c; i < root._insertionPoints.length; i++) {
2700 c = root._insertionPoints[i];
2701 if (DomApi.hasApi(c)) {
2702 Polymer.dom(c).notifyObserver();
2703 }
2704 }
2705 }
2706 function notifyInitialDistribution(host) {
2707 if (DomApi.hasApi(host)) {
2708 Polymer.dom(host).notifyObserver();
2709 }
2710 }
2711 var needsUpgrade = window.CustomElements && !CustomElements.useNative;
2712 function upgradeLogicalChildren(children) {
2713 if (needsUpgrade && children) {
2714 for (var i = 0; i < children.length; i++) {
2715 CustomElements.upgrade(children[i]);
2716 }
2717 }
2718 }
2719 }());if (Polymer.Settings.useShadow) {
2720 Polymer.Base._addFeature({
2721 _poolContent: function () {
2722 },
2723 _beginDistribute: function () {
2724 },
2725 distributeContent: function () {
2726 },
2727 _distributeContent: function () {
2728 },
2729 _finishDistribute: function () {
2730 },
2731 _createLocalRoot: function () {
2732 this.createShadowRoot();
2733 this.shadowRoot.appendChild(this.root);
2734 this.root = this.shadowRoot;
2735 }
2736 });
2737 }Polymer.Async = {
2738 _currVal: 0,
2739 _lastVal: 0,
2740 _callbacks: [],
2741 _twiddleContent: 0,
2742 _twiddle: document.createTextNode(''),
2743 run: function (callback, waitTime) {
2744 if (waitTime > 0) {
2745 return ~setTimeout(callback, waitTime);
2746 } else {
2747 this._twiddle.textContent = this._twiddleContent++;
2748 this._callbacks.push(callback);
2749 return this._currVal++;
2750 }
2751 },
2752 cancel: function (handle) {
2753 if (handle < 0) {
2754 clearTimeout(~handle);
2755 } else {
2756 var idx = handle - this._lastVal;
2757 if (idx >= 0) {
2758 if (!this._callbacks[idx]) {
2759 throw 'invalid async handle: ' + handle;
2760 }
2761 this._callbacks[idx] = null;
2762 }
2763 }
2764 },
2765 _atEndOfMicrotask: function () {
2766 var len = this._callbacks.length;
2767 for (var i = 0; i < len; i++) {
2768 var cb = this._callbacks[i];
2769 if (cb) {
2770 try {
2771 cb();
2772 } catch (e) {
2773 i++;
2774 this._callbacks.splice(0, i);
2775 this._lastVal += i;
2776 this._twiddle.textContent = this._twiddleContent++;
2777 throw e;
2778 }
2779 }
2780 }
2781 this._callbacks.splice(0, len);
2782 this._lastVal += len;
2783 }
2784 };
2785 new window.MutationObserver(function () {
2786 Polymer.Async._atEndOfMicrotask();
2787 }).observe(Polymer.Async._twiddle, { characterData: true });Polymer.Debounce = f unction () {
2788 var Async = Polymer.Async;
2789 var Debouncer = function (context) {
2790 this.context = context;
2791 var self = this;
2792 this.boundComplete = function () {
2793 self.complete();
2794 };
2795 };
2796 Debouncer.prototype = {
2797 go: function (callback, wait) {
2798 var h;
2799 this.finish = function () {
2800 Async.cancel(h);
2801 };
2802 h = Async.run(this.boundComplete, wait);
2803 this.callback = callback;
2804 },
2805 stop: function () {
2806 if (this.finish) {
2807 this.finish();
2808 this.finish = null;
2809 this.callback = null;
2810 }
2811 },
2812 complete: function () {
2813 if (this.finish) {
2814 var callback = this.callback;
2815 this.stop();
2816 callback.call(this.context);
2817 }
2818 }
2819 };
2820 function debounce(debouncer, callback, wait) {
2821 if (debouncer) {
2822 debouncer.stop();
2823 } else {
2824 debouncer = new Debouncer(this);
2825 }
2826 debouncer.go(callback, wait);
2827 return debouncer;
2828 }
2829 return debounce;
2830 }();Polymer.Base._addFeature({
2831 _setupDebouncers: function () {
2832 this._debouncers = {};
2833 },
2834 debounce: function (jobName, callback, wait) {
2835 return this._debouncers[jobName] = Polymer.Debounce.call(this, this._debouncers[ jobName], callback, wait);
2836 },
2837 isDebouncerActive: function (jobName) {
2838 var debouncer = this._debouncers[jobName];
2839 return !!(debouncer && debouncer.finish);
2840 },
2841 flushDebouncer: function (jobName) {
2842 var debouncer = this._debouncers[jobName];
2843 if (debouncer) {
2844 debouncer.complete();
2845 }
2846 },
2847 cancelDebouncer: function (jobName) {
2848 var debouncer = this._debouncers[jobName];
2849 if (debouncer) {
2850 debouncer.stop();
2851 }
2852 }
2853 });Polymer.DomModule = document.createElement('dom-module');
2854 Polymer.Base._addFeature({
2855 _registerFeatures: function () {
2856 this._prepIs();
2857 this._prepBehaviors();
2858 this._prepConstructor();
2859 this._prepTemplate();
2860 this._prepShady();
2861 this._prepPropertyInfo();
2862 },
2863 _prepBehavior: function (b) {
2864 this._addHostAttributes(b.hostAttributes);
2865 },
2866 _initFeatures: function () {
2867 this._registerHost();
2868 if (this._template) {
2869 this._poolContent();
2870 this._beginHosting();
2871 this._stampTemplate();
2872 this._endHosting();
2873 }
2874 this._marshalHostAttributes();
2875 this._setupDebouncers();
2876 this._marshalBehaviors();
2877 this._tryReady();
2878 },
2879 _marshalBehavior: function (b) {
2880 }
2881 });</script>
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898 <script>Polymer.nar = [];
2899 Polymer.Annotations = {
2900 parseAnnotations: function (template) {
2901 var list = [];
2902 var content = template._content || template.content;
2903 this._parseNodeAnnotations(content, list, template.hasAttribute('strip-whitespac e'));
2904 return list;
2905 },
2906 _parseNodeAnnotations: function (node, list, stripWhiteSpace) {
2907 return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, li st) : this._parseElementAnnotations(node, list, stripWhiteSpace);
2908 },
2909 _bindingRegex: function () {
2910 var IDENT = '(?:' + '[a-zA-Z_$][\\w.:$\\-*]*' + ')';
2911 var NUMBER = '(?:' + '[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?' + ')';
2912 var SQUOTE_STRING = '(?:' + '\'(?:[^\'\\\\]|\\\\.)*\'' + ')';
2913 var DQUOTE_STRING = '(?:' + '"(?:[^"\\\\]|\\\\.)*"' + ')';
2914 var STRING = '(?:' + SQUOTE_STRING + '|' + DQUOTE_STRING + ')';
2915 var ARGUMENT = '(?:' + IDENT + '|' + NUMBER + '|' + STRING + '\\s*' + ')';
2916 var ARGUMENTS = '(?:' + ARGUMENT + '(?:,\\s*' + ARGUMENT + ')*' + ')';
2917 var ARGUMENT_LIST = '(?:' + '\\(\\s*' + '(?:' + ARGUMENTS + '?' + ')' + '\\)\\s* ' + ')';
2918 var BINDING = '(' + IDENT + '\\s*' + ARGUMENT_LIST + '?' + ')';
2919 var OPEN_BRACKET = '(\\[\\[|{{)' + '\\s*';
2920 var CLOSE_BRACKET = '(?:]]|}})';
2921 var NEGATE = '(?:(!)\\s*)?';
2922 var EXPRESSION = OPEN_BRACKET + NEGATE + BINDING + CLOSE_BRACKET;
2923 return new RegExp(EXPRESSION, 'g');
2924 }(),
2925 _parseBindings: function (text) {
2926 var re = this._bindingRegex;
2927 var parts = [];
2928 var lastIndex = 0;
2929 var m;
2930 while ((m = re.exec(text)) !== null) {
2931 if (m.index > lastIndex) {
2932 parts.push({ literal: text.slice(lastIndex, m.index) });
2933 }
2934 var mode = m[1][0];
2935 var negate = Boolean(m[2]);
2936 var value = m[3].trim();
2937 var customEvent, notifyEvent, colon;
2938 if (mode == '{' && (colon = value.indexOf('::')) > 0) {
2939 notifyEvent = value.substring(colon + 2);
2940 value = value.substring(0, colon);
2941 customEvent = true;
2942 }
2943 parts.push({
2944 compoundIndex: parts.length,
2945 value: value,
2946 mode: mode,
2947 negate: negate,
2948 event: notifyEvent,
2949 customEvent: customEvent
2950 });
2951 lastIndex = re.lastIndex;
2952 }
2953 if (lastIndex && lastIndex < text.length) {
2954 var literal = text.substring(lastIndex);
2955 if (literal) {
2956 parts.push({ literal: literal });
2957 }
2958 }
2959 if (parts.length) {
2960 return parts;
2961 }
2962 },
2963 _literalFromParts: function (parts) {
2964 var s = '';
2965 for (var i = 0; i < parts.length; i++) {
2966 var literal = parts[i].literal;
2967 s += literal || '';
2968 }
2969 return s;
2970 },
2971 _parseTextNodeAnnotation: function (node, list) {
2972 var parts = this._parseBindings(node.textContent);
2973 if (parts) {
2974 node.textContent = this._literalFromParts(parts) || ' ';
2975 var annote = {
2976 bindings: [{
2977 kind: 'text',
2978 name: 'textContent',
2979 parts: parts,
2980 isCompound: parts.length !== 1
2981 }]
2982 };
2983 list.push(annote);
2984 return annote;
2985 }
2986 },
2987 _parseElementAnnotations: function (element, list, stripWhiteSpace) {
2988 var annote = {
2989 bindings: [],
2990 events: []
2991 };
2992 if (element.localName === 'content') {
2993 list._hasContent = true;
2994 }
2995 this._parseChildNodesAnnotations(element, annote, list, stripWhiteSpace);
2996 if (element.attributes) {
2997 this._parseNodeAttributeAnnotations(element, annote, list);
2998 if (this.prepElement) {
2999 this.prepElement(element);
3000 }
3001 }
3002 if (annote.bindings.length || annote.events.length || annote.id) {
3003 list.push(annote);
3004 }
3005 return annote;
3006 },
3007 _parseChildNodesAnnotations: function (root, annote, list, stripWhiteSpace) {
3008 if (root.firstChild) {
3009 var node = root.firstChild;
3010 var i = 0;
3011 while (node) {
3012 var next = node.nextSibling;
3013 if (node.localName === 'template' && !node.hasAttribute('preserve-content')) {
3014 this._parseTemplate(node, i, list, annote);
3015 }
3016 if (node.nodeType === Node.TEXT_NODE) {
3017 var n = next;
3018 while (n && n.nodeType === Node.TEXT_NODE) {
3019 node.textContent += n.textContent;
3020 next = n.nextSibling;
3021 root.removeChild(n);
3022 n = next;
3023 }
3024 if (stripWhiteSpace && !node.textContent.trim()) {
3025 root.removeChild(node);
3026 i--;
3027 }
3028 }
3029 if (node.parentNode) {
3030 var childAnnotation = this._parseNodeAnnotations(node, list, stripWhiteSpace);
3031 if (childAnnotation) {
3032 childAnnotation.parent = annote;
3033 childAnnotation.index = i;
3034 }
3035 }
3036 node = next;
3037 i++;
3038 }
3039 }
3040 },
3041 _parseTemplate: function (node, index, list, parent) {
3042 var content = document.createDocumentFragment();
3043 content._notes = this.parseAnnotations(node);
3044 content.appendChild(node.content);
3045 list.push({
3046 bindings: Polymer.nar,
3047 events: Polymer.nar,
3048 templateContent: content,
3049 parent: parent,
3050 index: index
3051 });
3052 },
3053 _parseNodeAttributeAnnotations: function (node, annotation) {
3054 var attrs = Array.prototype.slice.call(node.attributes);
3055 for (var i = attrs.length - 1, a; a = attrs[i]; i--) {
3056 var n = a.name;
3057 var v = a.value;
3058 var b;
3059 if (n.slice(0, 3) === 'on-') {
3060 node.removeAttribute(n);
3061 annotation.events.push({
3062 name: n.slice(3),
3063 value: v
3064 });
3065 } else if (b = this._parseNodeAttributeAnnotation(node, n, v)) {
3066 annotation.bindings.push(b);
3067 } else if (n === 'id') {
3068 annotation.id = v;
3069 }
3070 }
3071 },
3072 _parseNodeAttributeAnnotation: function (node, name, value) {
3073 var parts = this._parseBindings(value);
3074 if (parts) {
3075 var origName = name;
3076 var kind = 'property';
3077 if (name[name.length - 1] == '$') {
3078 name = name.slice(0, -1);
3079 kind = 'attribute';
3080 }
3081 var literal = this._literalFromParts(parts);
3082 if (literal && kind == 'attribute') {
3083 node.setAttribute(name, literal);
3084 }
3085 if (node.localName === 'input' && origName === 'value') {
3086 node.setAttribute(origName, '');
3087 }
3088 node.removeAttribute(origName);
3089 var propertyName = Polymer.CaseMap.dashToCamelCase(name);
3090 if (kind === 'property') {
3091 name = propertyName;
3092 }
3093 return {
3094 kind: kind,
3095 name: name,
3096 propertyName: propertyName,
3097 parts: parts,
3098 literal: literal,
3099 isCompound: parts.length !== 1
3100 };
3101 }
3102 },
3103 findAnnotatedNode: function (root, annote) {
3104 var parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote .parent);
3105 if (parent) {
3106 for (var n = parent.firstChild, i = 0; n; n = n.nextSibling) {
3107 if (annote.index === i++) {
3108 return n;
3109 }
3110 }
3111 } else {
3112 return root;
3113 }
3114 }
3115 };(function () {
3116 function resolveCss(cssText, ownerDocument) {
3117 return cssText.replace(CSS_URL_RX, function (m, pre, url, post) {
3118 return pre + '\'' + resolve(url.replace(/["']/g, ''), ownerDocument) + '\'' + po st;
3119 });
3120 }
3121 function resolveAttrs(element, ownerDocument) {
3122 for (var name in URL_ATTRS) {
3123 var a$ = URL_ATTRS[name];
3124 for (var i = 0, l = a$.length, a, at, v; i < l && (a = a$[i]); i++) {
3125 if (name === '*' || element.localName === name) {
3126 at = element.attributes[a];
3127 v = at && at.value;
3128 if (v && v.search(BINDING_RX) < 0) {
3129 at.value = a === 'style' ? resolveCss(v, ownerDocument) : resolve(v, ownerDocume nt);
3130 }
3131 }
3132 }
3133 }
3134 }
3135 function resolve(url, ownerDocument) {
3136 if (url && url[0] === '#') {
3137 return url;
3138 }
3139 var resolver = getUrlResolver(ownerDocument);
3140 resolver.href = url;
3141 return resolver.href || url;
3142 }
3143 var tempDoc;
3144 var tempDocBase;
3145 function resolveUrl(url, baseUri) {
3146 if (!tempDoc) {
3147 tempDoc = document.implementation.createHTMLDocument('temp');
3148 tempDocBase = tempDoc.createElement('base');
3149 tempDoc.head.appendChild(tempDocBase);
3150 }
3151 tempDocBase.href = baseUri;
3152 return resolve(url, tempDoc);
3153 }
3154 function getUrlResolver(ownerDocument) {
3155 return ownerDocument.__urlResolver || (ownerDocument.__urlResolver = ownerDocume nt.createElement('a'));
3156 }
3157 var CSS_URL_RX = /(url\()([^)]*)(\))/g;
3158 var URL_ATTRS = {
3159 '*': [
3160 'href',
3161 'src',
3162 'style',
3163 'url'
3164 ],
3165 form: ['action']
3166 };
3167 var BINDING_RX = /\{\{|\[\[/;
3168 Polymer.ResolveUrl = {
3169 resolveCss: resolveCss,
3170 resolveAttrs: resolveAttrs,
3171 resolveUrl: resolveUrl
3172 };
3173 }());Polymer.Base._addFeature({
3174 _prepAnnotations: function () {
3175 if (!this._template) {
3176 this._notes = [];
3177 } else {
3178 var self = this;
3179 Polymer.Annotations.prepElement = function (element) {
3180 self._prepElement(element);
3181 };
3182 if (this._template._content && this._template._content._notes) {
3183 this._notes = this._template._content._notes;
3184 } else {
3185 this._notes = Polymer.Annotations.parseAnnotations(this._template);
3186 this._processAnnotations(this._notes);
3187 }
3188 Polymer.Annotations.prepElement = null;
3189 }
3190 },
3191 _processAnnotations: function (notes) {
3192 for (var i = 0; i < notes.length; i++) {
3193 var note = notes[i];
3194 for (var j = 0; j < note.bindings.length; j++) {
3195 var b = note.bindings[j];
3196 for (var k = 0; k < b.parts.length; k++) {
3197 var p = b.parts[k];
3198 if (!p.literal) {
3199 var signature = this._parseMethod(p.value);
3200 if (signature) {
3201 p.signature = signature;
3202 } else {
3203 p.model = this._modelForPath(p.value);
3204 }
3205 }
3206 }
3207 }
3208 if (note.templateContent) {
3209 this._processAnnotations(note.templateContent._notes);
3210 var pp = note.templateContent._parentProps = this._discoverTemplateParentProps(n ote.templateContent._notes);
3211 var bindings = [];
3212 for (var prop in pp) {
3213 var name = '_parent_' + prop;
3214 bindings.push({
3215 index: note.index,
3216 kind: 'property',
3217 name: name,
3218 propertyName: name,
3219 parts: [{
3220 mode: '{',
3221 model: prop,
3222 value: prop
3223 }]
3224 });
3225 }
3226 note.bindings = note.bindings.concat(bindings);
3227 }
3228 }
3229 },
3230 _discoverTemplateParentProps: function (notes) {
3231 var pp = {};
3232 for (var i = 0, n; i < notes.length && (n = notes[i]); i++) {
3233 for (var j = 0, b$ = n.bindings, b; j < b$.length && (b = b$[j]); j++) {
3234 for (var k = 0, p$ = b.parts, p; k < p$.length && (p = p$[k]); k++) {
3235 if (p.signature) {
3236 var args = p.signature.args;
3237 for (var kk = 0; kk < args.length; kk++) {
3238 var model = args[kk].model;
3239 if (model) {
3240 pp[model] = true;
3241 }
3242 }
3243 if (p.signature.dynamicFn) {
3244 pp[p.signature.method] = true;
3245 }
3246 } else {
3247 if (p.model) {
3248 pp[p.model] = true;
3249 }
3250 }
3251 }
3252 }
3253 if (n.templateContent) {
3254 var tpp = n.templateContent._parentProps;
3255 Polymer.Base.mixin(pp, tpp);
3256 }
3257 }
3258 return pp;
3259 },
3260 _prepElement: function (element) {
3261 Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument);
3262 },
3263 _findAnnotatedNode: Polymer.Annotations.findAnnotatedNode,
3264 _marshalAnnotationReferences: function () {
3265 if (this._template) {
3266 this._marshalIdNodes();
3267 this._marshalAnnotatedNodes();
3268 this._marshalAnnotatedListeners();
3269 }
3270 },
3271 _configureAnnotationReferences: function () {
3272 var notes = this._notes;
3273 var nodes = this._nodes;
3274 for (var i = 0; i < notes.length; i++) {
3275 var note = notes[i];
3276 var node = nodes[i];
3277 this._configureTemplateContent(note, node);
3278 this._configureCompoundBindings(note, node);
3279 }
3280 },
3281 _configureTemplateContent: function (note, node) {
3282 if (note.templateContent) {
3283 node._content = note.templateContent;
3284 }
3285 },
3286 _configureCompoundBindings: function (note, node) {
3287 var bindings = note.bindings;
3288 for (var i = 0; i < bindings.length; i++) {
3289 var binding = bindings[i];
3290 if (binding.isCompound) {
3291 var storage = node.__compoundStorage__ || (node.__compoundStorage__ = {});
3292 var parts = binding.parts;
3293 var literals = new Array(parts.length);
3294 for (var j = 0; j < parts.length; j++) {
3295 literals[j] = parts[j].literal;
3296 }
3297 var name = binding.name;
3298 storage[name] = literals;
3299 if (binding.literal && binding.kind == 'property') {
3300 if (node._configValue) {
3301 node._configValue(name, binding.literal);
3302 } else {
3303 node[name] = binding.literal;
3304 }
3305 }
3306 }
3307 }
3308 },
3309 _marshalIdNodes: function () {
3310 this.$ = {};
3311 for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) {
3312 if (a.id) {
3313 this.$[a.id] = this._findAnnotatedNode(this.root, a);
3314 }
3315 }
3316 },
3317 _marshalAnnotatedNodes: function () {
3318 if (this._notes && this._notes.length) {
3319 var r = new Array(this._notes.length);
3320 for (var i = 0; i < this._notes.length; i++) {
3321 r[i] = this._findAnnotatedNode(this.root, this._notes[i]);
3322 }
3323 this._nodes = r;
3324 }
3325 },
3326 _marshalAnnotatedListeners: function () {
3327 for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) {
3328 if (a.events && a.events.length) {
3329 var node = this._findAnnotatedNode(this.root, a);
3330 for (var j = 0, e$ = a.events, e; j < e$.length && (e = e$[j]); j++) {
3331 this.listen(node, e.name, e.value);
3332 }
3333 }
3334 }
3335 }
3336 });Polymer.Base._addFeature({
3337 listeners: {},
3338 _listenListeners: function (listeners) {
3339 var node, name, eventName;
3340 for (eventName in listeners) {
3341 if (eventName.indexOf('.') < 0) {
3342 node = this;
3343 name = eventName;
3344 } else {
3345 name = eventName.split('.');
3346 node = this.$[name[0]];
3347 name = name[1];
3348 }
3349 this.listen(node, name, listeners[eventName]);
3350 }
3351 },
3352 listen: function (node, eventName, methodName) {
3353 var handler = this._recallEventHandler(this, eventName, node, methodName);
3354 if (!handler) {
3355 handler = this._createEventHandler(node, eventName, methodName);
3356 }
3357 if (handler._listening) {
3358 return;
3359 }
3360 this._listen(node, eventName, handler);
3361 handler._listening = true;
3362 },
3363 _boundListenerKey: function (eventName, methodName) {
3364 return eventName + ':' + methodName;
3365 },
3366 _recordEventHandler: function (host, eventName, target, methodName, handler) {
3367 var hbl = host.__boundListeners;
3368 if (!hbl) {
3369 hbl = host.__boundListeners = new WeakMap();
3370 }
3371 var bl = hbl.get(target);
3372 if (!bl) {
3373 bl = {};
3374 hbl.set(target, bl);
3375 }
3376 var key = this._boundListenerKey(eventName, methodName);
3377 bl[key] = handler;
3378 },
3379 _recallEventHandler: function (host, eventName, target, methodName) {
3380 var hbl = host.__boundListeners;
3381 if (!hbl) {
3382 return;
3383 }
3384 var bl = hbl.get(target);
3385 if (!bl) {
3386 return;
3387 }
3388 var key = this._boundListenerKey(eventName, methodName);
3389 return bl[key];
3390 },
3391 _createEventHandler: function (node, eventName, methodName) {
3392 var host = this;
3393 var handler = function (e) {
3394 if (host[methodName]) {
3395 host[methodName](e, e.detail);
3396 } else {
3397 host._warn(host._logf('_createEventHandler', 'listener method `' + methodName + '` not defined'));
3398 }
3399 };
3400 handler._listening = false;
3401 this._recordEventHandler(host, eventName, node, methodName, handler);
3402 return handler;
3403 },
3404 unlisten: function (node, eventName, methodName) {
3405 var handler = this._recallEventHandler(this, eventName, node, methodName);
3406 if (handler) {
3407 this._unlisten(node, eventName, handler);
3408 handler._listening = false;
3409 }
3410 },
3411 _listen: function (node, eventName, handler) {
3412 node.addEventListener(eventName, handler);
3413 },
3414 _unlisten: function (node, eventName, handler) {
3415 node.removeEventListener(eventName, handler);
3416 }
3417 });(function () {
3418 'use strict';
3419 var wrap = Polymer.DomApi.wrap;
3420 var HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
3421 var GESTURE_KEY = '__polymerGestures';
3422 var HANDLED_OBJ = '__polymerGesturesHandled';
3423 var TOUCH_ACTION = '__polymerGesturesTouchAction';
3424 var TAP_DISTANCE = 25;
3425 var TRACK_DISTANCE = 5;
3426 var TRACK_LENGTH = 2;
3427 var MOUSE_TIMEOUT = 2500;
3428 var MOUSE_EVENTS = [
3429 'mousedown',
3430 'mousemove',
3431 'mouseup',
3432 'click'
3433 ];
3434 var MOUSE_WHICH_TO_BUTTONS = [
3435 0,
3436 1,
3437 4,
3438 2
3439 ];
3440 var MOUSE_HAS_BUTTONS = function () {
3441 try {
3442 return new MouseEvent('test', { buttons: 1 }).buttons === 1;
3443 } catch (e) {
3444 return false;
3445 }
3446 }();
3447 var IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);
3448 var mouseCanceller = function (mouseEvent) {
3449 mouseEvent[HANDLED_OBJ] = { skip: true };
3450 if (mouseEvent.type === 'click') {
3451 var path = Polymer.dom(mouseEvent).path;
3452 for (var i = 0; i < path.length; i++) {
3453 if (path[i] === POINTERSTATE.mouse.target) {
3454 return;
3455 }
3456 }
3457 mouseEvent.preventDefault();
3458 mouseEvent.stopPropagation();
3459 }
3460 };
3461 function setupTeardownMouseCanceller(setup) {
3462 for (var i = 0, en; i < MOUSE_EVENTS.length; i++) {
3463 en = MOUSE_EVENTS[i];
3464 if (setup) {
3465 document.addEventListener(en, mouseCanceller, true);
3466 } else {
3467 document.removeEventListener(en, mouseCanceller, true);
3468 }
3469 }
3470 }
3471 function ignoreMouse() {
3472 if (IS_TOUCH_ONLY) {
3473 return;
3474 }
3475 if (!POINTERSTATE.mouse.mouseIgnoreJob) {
3476 setupTeardownMouseCanceller(true);
3477 }
3478 var unset = function () {
3479 setupTeardownMouseCanceller();
3480 POINTERSTATE.mouse.target = null;
3481 POINTERSTATE.mouse.mouseIgnoreJob = null;
3482 };
3483 POINTERSTATE.mouse.mouseIgnoreJob = Polymer.Debounce(POINTERSTATE.mouse.mouseIgn oreJob, unset, MOUSE_TIMEOUT);
3484 }
3485 function hasLeftMouseButton(ev) {
3486 var type = ev.type;
3487 if (MOUSE_EVENTS.indexOf(type) === -1) {
3488 return false;
3489 }
3490 if (type === 'mousemove') {
3491 var buttons = ev.buttons === undefined ? 1 : ev.buttons;
3492 if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
3493 buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
3494 }
3495 return Boolean(buttons & 1);
3496 } else {
3497 var button = ev.button === undefined ? 0 : ev.button;
3498 return button === 0;
3499 }
3500 }
3501 function isSyntheticClick(ev) {
3502 if (ev.type === 'click') {
3503 if (ev.detail === 0) {
3504 return true;
3505 }
3506 var t = Gestures.findOriginalTarget(ev);
3507 var bcr = t.getBoundingClientRect();
3508 var x = ev.pageX, y = ev.pageY;
3509 return !(x >= bcr.left && x <= bcr.right && (y >= bcr.top && y <= bcr.bottom));
3510 }
3511 return false;
3512 }
3513 var POINTERSTATE = {
3514 mouse: {
3515 target: null,
3516 mouseIgnoreJob: null
3517 },
3518 touch: {
3519 x: 0,
3520 y: 0,
3521 id: -1,
3522 scrollDecided: false
3523 }
3524 };
3525 function firstTouchAction(ev) {
3526 var path = Polymer.dom(ev).path;
3527 var ta = 'auto';
3528 for (var i = 0, n; i < path.length; i++) {
3529 n = path[i];
3530 if (n[TOUCH_ACTION]) {
3531 ta = n[TOUCH_ACTION];
3532 break;
3533 }
3534 }
3535 return ta;
3536 }
3537 function trackDocument(stateObj, movefn, upfn) {
3538 stateObj.movefn = movefn;
3539 stateObj.upfn = upfn;
3540 document.addEventListener('mousemove', movefn);
3541 document.addEventListener('mouseup', upfn);
3542 }
3543 function untrackDocument(stateObj) {
3544 document.removeEventListener('mousemove', stateObj.movefn);
3545 document.removeEventListener('mouseup', stateObj.upfn);
3546 stateObj.movefn = null;
3547 stateObj.upfn = null;
3548 }
3549 var Gestures = {
3550 gestures: {},
3551 recognizers: [],
3552 deepTargetFind: function (x, y) {
3553 var node = document.elementFromPoint(x, y);
3554 var next = node;
3555 while (next && next.shadowRoot) {
3556 next = next.shadowRoot.elementFromPoint(x, y);
3557 if (next) {
3558 node = next;
3559 }
3560 }
3561 return node;
3562 },
3563 findOriginalTarget: function (ev) {
3564 if (ev.path) {
3565 return ev.path[0];
3566 }
3567 return ev.target;
3568 },
3569 handleNative: function (ev) {
3570 var handled;
3571 var type = ev.type;
3572 var node = wrap(ev.currentTarget);
3573 var gobj = node[GESTURE_KEY];
3574 if (!gobj) {
3575 return;
3576 }
3577 var gs = gobj[type];
3578 if (!gs) {
3579 return;
3580 }
3581 if (!ev[HANDLED_OBJ]) {
3582 ev[HANDLED_OBJ] = {};
3583 if (type.slice(0, 5) === 'touch') {
3584 var t = ev.changedTouches[0];
3585 if (type === 'touchstart') {
3586 if (ev.touches.length === 1) {
3587 POINTERSTATE.touch.id = t.identifier;
3588 }
3589 }
3590 if (POINTERSTATE.touch.id !== t.identifier) {
3591 return;
3592 }
3593 if (!HAS_NATIVE_TA) {
3594 if (type === 'touchstart' || type === 'touchmove') {
3595 Gestures.handleTouchAction(ev);
3596 }
3597 }
3598 if (type === 'touchend') {
3599 POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget;
3600 ignoreMouse();
3601 }
3602 }
3603 }
3604 handled = ev[HANDLED_OBJ];
3605 if (handled.skip) {
3606 return;
3607 }
3608 var recognizers = Gestures.recognizers;
3609 for (var i = 0, r; i < recognizers.length; i++) {
3610 r = recognizers[i];
3611 if (gs[r.name] && !handled[r.name]) {
3612 if (r.flow && r.flow.start.indexOf(ev.type) > -1 && r.reset) {
3613 r.reset();
3614 }
3615 }
3616 }
3617 for (i = 0, r; i < recognizers.length; i++) {
3618 r = recognizers[i];
3619 if (gs[r.name] && !handled[r.name]) {
3620 handled[r.name] = true;
3621 r[type](ev);
3622 }
3623 }
3624 },
3625 handleTouchAction: function (ev) {
3626 var t = ev.changedTouches[0];
3627 var type = ev.type;
3628 if (type === 'touchstart') {
3629 POINTERSTATE.touch.x = t.clientX;
3630 POINTERSTATE.touch.y = t.clientY;
3631 POINTERSTATE.touch.scrollDecided = false;
3632 } else if (type === 'touchmove') {
3633 if (POINTERSTATE.touch.scrollDecided) {
3634 return;
3635 }
3636 POINTERSTATE.touch.scrollDecided = true;
3637 var ta = firstTouchAction(ev);
3638 var prevent = false;
3639 var dx = Math.abs(POINTERSTATE.touch.x - t.clientX);
3640 var dy = Math.abs(POINTERSTATE.touch.y - t.clientY);
3641 if (!ev.cancelable) {
3642 } else if (ta === 'none') {
3643 prevent = true;
3644 } else if (ta === 'pan-x') {
3645 prevent = dy > dx;
3646 } else if (ta === 'pan-y') {
3647 prevent = dx > dy;
3648 }
3649 if (prevent) {
3650 ev.preventDefault();
3651 } else {
3652 Gestures.prevent('track');
3653 }
3654 }
3655 },
3656 add: function (node, evType, handler) {
3657 node = wrap(node);
3658 var recognizer = this.gestures[evType];
3659 var deps = recognizer.deps;
3660 var name = recognizer.name;
3661 var gobj = node[GESTURE_KEY];
3662 if (!gobj) {
3663 node[GESTURE_KEY] = gobj = {};
3664 }
3665 for (var i = 0, dep, gd; i < deps.length; i++) {
3666 dep = deps[i];
3667 if (IS_TOUCH_ONLY && MOUSE_EVENTS.indexOf(dep) > -1) {
3668 continue;
3669 }
3670 gd = gobj[dep];
3671 if (!gd) {
3672 gobj[dep] = gd = { _count: 0 };
3673 }
3674 if (gd._count === 0) {
3675 node.addEventListener(dep, this.handleNative);
3676 }
3677 gd[name] = (gd[name] || 0) + 1;
3678 gd._count = (gd._count || 0) + 1;
3679 }
3680 node.addEventListener(evType, handler);
3681 if (recognizer.touchAction) {
3682 this.setTouchAction(node, recognizer.touchAction);
3683 }
3684 },
3685 remove: function (node, evType, handler) {
3686 node = wrap(node);
3687 var recognizer = this.gestures[evType];
3688 var deps = recognizer.deps;
3689 var name = recognizer.name;
3690 var gobj = node[GESTURE_KEY];
3691 if (gobj) {
3692 for (var i = 0, dep, gd; i < deps.length; i++) {
3693 dep = deps[i];
3694 gd = gobj[dep];
3695 if (gd && gd[name]) {
3696 gd[name] = (gd[name] || 1) - 1;
3697 gd._count = (gd._count || 1) - 1;
3698 if (gd._count === 0) {
3699 node.removeEventListener(dep, this.handleNative);
3700 }
3701 }
3702 }
3703 }
3704 node.removeEventListener(evType, handler);
3705 },
3706 register: function (recog) {
3707 this.recognizers.push(recog);
3708 for (var i = 0; i < recog.emits.length; i++) {
3709 this.gestures[recog.emits[i]] = recog;
3710 }
3711 },
3712 findRecognizerByEvent: function (evName) {
3713 for (var i = 0, r; i < this.recognizers.length; i++) {
3714 r = this.recognizers[i];
3715 for (var j = 0, n; j < r.emits.length; j++) {
3716 n = r.emits[j];
3717 if (n === evName) {
3718 return r;
3719 }
3720 }
3721 }
3722 return null;
3723 },
3724 setTouchAction: function (node, value) {
3725 if (HAS_NATIVE_TA) {
3726 node.style.touchAction = value;
3727 }
3728 node[TOUCH_ACTION] = value;
3729 },
3730 fire: function (target, type, detail) {
3731 var ev = Polymer.Base.fire(type, detail, {
3732 node: target,
3733 bubbles: true,
3734 cancelable: true
3735 });
3736 if (ev.defaultPrevented) {
3737 var preventer = detail.preventer || detail.sourceEvent;
3738 if (preventer && preventer.preventDefault) {
3739 preventer.preventDefault();
3740 }
3741 }
3742 },
3743 prevent: function (evName) {
3744 var recognizer = this.findRecognizerByEvent(evName);
3745 if (recognizer.info) {
3746 recognizer.info.prevent = true;
3747 }
3748 },
3749 resetMouseCanceller: function () {
3750 if (POINTERSTATE.mouse.mouseIgnoreJob) {
3751 POINTERSTATE.mouse.mouseIgnoreJob.complete();
3752 }
3753 }
3754 };
3755 Gestures.register({
3756 name: 'downup',
3757 deps: [
3758 'mousedown',
3759 'touchstart',
3760 'touchend'
3761 ],
3762 flow: {
3763 start: [
3764 'mousedown',
3765 'touchstart'
3766 ],
3767 end: [
3768 'mouseup',
3769 'touchend'
3770 ]
3771 },
3772 emits: [
3773 'down',
3774 'up'
3775 ],
3776 info: {
3777 movefn: null,
3778 upfn: null
3779 },
3780 reset: function () {
3781 untrackDocument(this.info);
3782 },
3783 mousedown: function (e) {
3784 if (!hasLeftMouseButton(e)) {
3785 return;
3786 }
3787 var t = Gestures.findOriginalTarget(e);
3788 var self = this;
3789 var movefn = function movefn(e) {
3790 if (!hasLeftMouseButton(e)) {
3791 self.fire('up', t, e);
3792 untrackDocument(self.info);
3793 }
3794 };
3795 var upfn = function upfn(e) {
3796 if (hasLeftMouseButton(e)) {
3797 self.fire('up', t, e);
3798 }
3799 untrackDocument(self.info);
3800 };
3801 trackDocument(this.info, movefn, upfn);
3802 this.fire('down', t, e);
3803 },
3804 touchstart: function (e) {
3805 this.fire('down', Gestures.findOriginalTarget(e), e.changedTouches[0], e);
3806 },
3807 touchend: function (e) {
3808 this.fire('up', Gestures.findOriginalTarget(e), e.changedTouches[0], e);
3809 },
3810 fire: function (type, target, event, preventer) {
3811 Gestures.fire(target, type, {
3812 x: event.clientX,
3813 y: event.clientY,
3814 sourceEvent: event,
3815 preventer: preventer,
3816 prevent: function (e) {
3817 return Gestures.prevent(e);
3818 }
3819 });
3820 }
3821 });
3822 Gestures.register({
3823 name: 'track',
3824 touchAction: 'none',
3825 deps: [
3826 'mousedown',
3827 'touchstart',
3828 'touchmove',
3829 'touchend'
3830 ],
3831 flow: {
3832 start: [
3833 'mousedown',
3834 'touchstart'
3835 ],
3836 end: [
3837 'mouseup',
3838 'touchend'
3839 ]
3840 },
3841 emits: ['track'],
3842 info: {
3843 x: 0,
3844 y: 0,
3845 state: 'start',
3846 started: false,
3847 moves: [],
3848 addMove: function (move) {
3849 if (this.moves.length > TRACK_LENGTH) {
3850 this.moves.shift();
3851 }
3852 this.moves.push(move);
3853 },
3854 movefn: null,
3855 upfn: null,
3856 prevent: false
3857 },
3858 reset: function () {
3859 this.info.state = 'start';
3860 this.info.started = false;
3861 this.info.moves = [];
3862 this.info.x = 0;
3863 this.info.y = 0;
3864 this.info.prevent = false;
3865 untrackDocument(this.info);
3866 },
3867 hasMovedEnough: function (x, y) {
3868 if (this.info.prevent) {
3869 return false;
3870 }
3871 if (this.info.started) {
3872 return true;
3873 }
3874 var dx = Math.abs(this.info.x - x);
3875 var dy = Math.abs(this.info.y - y);
3876 return dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE;
3877 },
3878 mousedown: function (e) {
3879 if (!hasLeftMouseButton(e)) {
3880 return;
3881 }
3882 var t = Gestures.findOriginalTarget(e);
3883 var self = this;
3884 var movefn = function movefn(e) {
3885 var x = e.clientX, y = e.clientY;
3886 if (self.hasMovedEnough(x, y)) {
3887 self.info.state = self.info.started ? e.type === 'mouseup' ? 'end' : 'track' : ' start';
3888 if (self.info.state === 'start') {
3889 Gestures.prevent('tap');
3890 }
3891 self.info.addMove({
3892 x: x,
3893 y: y
3894 });
3895 if (!hasLeftMouseButton(e)) {
3896 self.info.state = 'end';
3897 untrackDocument(self.info);
3898 }
3899 self.fire(t, e);
3900 self.info.started = true;
3901 }
3902 };
3903 var upfn = function upfn(e) {
3904 if (self.info.started) {
3905 movefn(e);
3906 }
3907 untrackDocument(self.info);
3908 };
3909 trackDocument(this.info, movefn, upfn);
3910 this.info.x = e.clientX;
3911 this.info.y = e.clientY;
3912 },
3913 touchstart: function (e) {
3914 var ct = e.changedTouches[0];
3915 this.info.x = ct.clientX;
3916 this.info.y = ct.clientY;
3917 },
3918 touchmove: function (e) {
3919 var t = Gestures.findOriginalTarget(e);
3920 var ct = e.changedTouches[0];
3921 var x = ct.clientX, y = ct.clientY;
3922 if (this.hasMovedEnough(x, y)) {
3923 if (this.info.state === 'start') {
3924 Gestures.prevent('tap');
3925 }
3926 this.info.addMove({
3927 x: x,
3928 y: y
3929 });
3930 this.fire(t, ct);
3931 this.info.state = 'track';
3932 this.info.started = true;
3933 }
3934 },
3935 touchend: function (e) {
3936 var t = Gestures.findOriginalTarget(e);
3937 var ct = e.changedTouches[0];
3938 if (this.info.started) {
3939 this.info.state = 'end';
3940 this.info.addMove({
3941 x: ct.clientX,
3942 y: ct.clientY
3943 });
3944 this.fire(t, ct, e);
3945 }
3946 },
3947 fire: function (target, touch, preventer) {
3948 var secondlast = this.info.moves[this.info.moves.length - 2];
3949 var lastmove = this.info.moves[this.info.moves.length - 1];
3950 var dx = lastmove.x - this.info.x;
3951 var dy = lastmove.y - this.info.y;
3952 var ddx, ddy = 0;
3953 if (secondlast) {
3954 ddx = lastmove.x - secondlast.x;
3955 ddy = lastmove.y - secondlast.y;
3956 }
3957 return Gestures.fire(target, 'track', {
3958 state: this.info.state,
3959 x: touch.clientX,
3960 y: touch.clientY,
3961 dx: dx,
3962 dy: dy,
3963 ddx: ddx,
3964 ddy: ddy,
3965 sourceEvent: touch,
3966 preventer: preventer,
3967 hover: function () {
3968 return Gestures.deepTargetFind(touch.clientX, touch.clientY);
3969 }
3970 });
3971 }
3972 });
3973 Gestures.register({
3974 name: 'tap',
3975 deps: [
3976 'mousedown',
3977 'click',
3978 'touchstart',
3979 'touchend'
3980 ],
3981 flow: {
3982 start: [
3983 'mousedown',
3984 'touchstart'
3985 ],
3986 end: [
3987 'click',
3988 'touchend'
3989 ]
3990 },
3991 emits: ['tap'],
3992 info: {
3993 x: NaN,
3994 y: NaN,
3995 prevent: false
3996 },
3997 reset: function () {
3998 this.info.x = NaN;
3999 this.info.y = NaN;
4000 this.info.prevent = false;
4001 },
4002 save: function (e) {
4003 this.info.x = e.clientX;
4004 this.info.y = e.clientY;
4005 },
4006 mousedown: function (e) {
4007 if (hasLeftMouseButton(e)) {
4008 this.save(e);
4009 }
4010 },
4011 click: function (e) {
4012 if (hasLeftMouseButton(e)) {
4013 this.forward(e);
4014 }
4015 },
4016 touchstart: function (e) {
4017 this.save(e.changedTouches[0], e);
4018 },
4019 touchend: function (e) {
4020 this.forward(e.changedTouches[0], e);
4021 },
4022 forward: function (e, preventer) {
4023 var dx = Math.abs(e.clientX - this.info.x);
4024 var dy = Math.abs(e.clientY - this.info.y);
4025 var t = Gestures.findOriginalTarget(e);
4026 if (isNaN(dx) || isNaN(dy) || dx <= TAP_DISTANCE && dy <= TAP_DISTANCE || isSynt heticClick(e)) {
4027 if (!this.info.prevent) {
4028 Gestures.fire(t, 'tap', {
4029 x: e.clientX,
4030 y: e.clientY,
4031 sourceEvent: e,
4032 preventer: preventer
4033 });
4034 }
4035 }
4036 }
4037 });
4038 var DIRECTION_MAP = {
4039 x: 'pan-x',
4040 y: 'pan-y',
4041 none: 'none',
4042 all: 'auto'
4043 };
4044 Polymer.Base._addFeature({
4045 _setupGestures: function () {
4046 this.__polymerGestures = null;
4047 },
4048 _listen: function (node, eventName, handler) {
4049 if (Gestures.gestures[eventName]) {
4050 Gestures.add(node, eventName, handler);
4051 } else {
4052 node.addEventListener(eventName, handler);
4053 }
4054 },
4055 _unlisten: function (node, eventName, handler) {
4056 if (Gestures.gestures[eventName]) {
4057 Gestures.remove(node, eventName, handler);
4058 } else {
4059 node.removeEventListener(eventName, handler);
4060 }
4061 },
4062 setScrollDirection: function (direction, node) {
4063 node = node || this;
4064 Gestures.setTouchAction(node, DIRECTION_MAP[direction] || 'auto');
4065 }
4066 });
4067 Polymer.Gestures = Gestures;
4068 }());(function () {
4069 'use strict';
4070 Polymer.Base._addFeature({
4071 $$: function (slctr) {
4072 return Polymer.dom(this.root).querySelector(slctr);
4073 },
4074 toggleClass: function (name, bool, node) {
4075 node = node || this;
4076 if (arguments.length == 1) {
4077 bool = !node.classList.contains(name);
4078 }
4079 if (bool) {
4080 Polymer.dom(node).classList.add(name);
4081 } else {
4082 Polymer.dom(node).classList.remove(name);
4083 }
4084 },
4085 toggleAttribute: function (name, bool, node) {
4086 node = node || this;
4087 if (arguments.length == 1) {
4088 bool = !node.hasAttribute(name);
4089 }
4090 if (bool) {
4091 Polymer.dom(node).setAttribute(name, '');
4092 } else {
4093 Polymer.dom(node).removeAttribute(name);
4094 }
4095 },
4096 classFollows: function (name, toElement, fromElement) {
4097 if (fromElement) {
4098 Polymer.dom(fromElement).classList.remove(name);
4099 }
4100 if (toElement) {
4101 Polymer.dom(toElement).classList.add(name);
4102 }
4103 },
4104 attributeFollows: function (name, toElement, fromElement) {
4105 if (fromElement) {
4106 Polymer.dom(fromElement).removeAttribute(name);
4107 }
4108 if (toElement) {
4109 Polymer.dom(toElement).setAttribute(name, '');
4110 }
4111 },
4112 getEffectiveChildNodes: function () {
4113 return Polymer.dom(this).getEffectiveChildNodes();
4114 },
4115 getEffectiveChildren: function () {
4116 var list = Polymer.dom(this).getEffectiveChildNodes();
4117 return list.filter(function (n) {
4118 return n.nodeType === Node.ELEMENT_NODE;
4119 });
4120 },
4121 getEffectiveTextContent: function () {
4122 var cn = this.getEffectiveChildNodes();
4123 var tc = [];
4124 for (var i = 0, c; c = cn[i]; i++) {
4125 if (c.nodeType !== Node.COMMENT_NODE) {
4126 tc.push(Polymer.dom(c).textContent);
4127 }
4128 }
4129 return tc.join('');
4130 },
4131 queryEffectiveChildren: function (slctr) {
4132 var e$ = Polymer.dom(this).queryDistributedElements(slctr);
4133 return e$ && e$[0];
4134 },
4135 queryAllEffectiveChildren: function (slctr) {
4136 return Polymer.dom(this).queryDistributedElements(slctr);
4137 },
4138 getContentChildNodes: function (slctr) {
4139 var content = Polymer.dom(this.root).querySelector(slctr || 'content');
4140 return content ? Polymer.dom(content).getDistributedNodes() : [];
4141 },
4142 getContentChildren: function (slctr) {
4143 return this.getContentChildNodes(slctr).filter(function (n) {
4144 return n.nodeType === Node.ELEMENT_NODE;
4145 });
4146 },
4147 fire: function (type, detail, options) {
4148 options = options || Polymer.nob;
4149 var node = options.node || this;
4150 detail = detail === null || detail === undefined ? {} : detail;
4151 var bubbles = options.bubbles === undefined ? true : options.bubbles;
4152 var cancelable = Boolean(options.cancelable);
4153 var useCache = options._useCache;
4154 var event = this._getEvent(type, bubbles, cancelable, useCache);
4155 event.detail = detail;
4156 if (useCache) {
4157 this.__eventCache[type] = null;
4158 }
4159 node.dispatchEvent(event);
4160 if (useCache) {
4161 this.__eventCache[type] = event;
4162 }
4163 return event;
4164 },
4165 __eventCache: {},
4166 _getEvent: function (type, bubbles, cancelable, useCache) {
4167 var event = useCache && this.__eventCache[type];
4168 if (!event || (event.bubbles != bubbles || event.cancelable != cancelable)) {
4169 event = new Event(type, {
4170 bubbles: Boolean(bubbles),
4171 cancelable: cancelable
4172 });
4173 }
4174 return event;
4175 },
4176 async: function (callback, waitTime) {
4177 var self = this;
4178 return Polymer.Async.run(function () {
4179 callback.call(self);
4180 }, waitTime);
4181 },
4182 cancelAsync: function (handle) {
4183 Polymer.Async.cancel(handle);
4184 },
4185 arrayDelete: function (path, item) {
4186 var index;
4187 if (Array.isArray(path)) {
4188 index = path.indexOf(item);
4189 if (index >= 0) {
4190 return path.splice(index, 1);
4191 }
4192 } else {
4193 var arr = this._get(path);
4194 index = arr.indexOf(item);
4195 if (index >= 0) {
4196 return this.splice(path, index, 1);
4197 }
4198 }
4199 },
4200 transform: function (transform, node) {
4201 node = node || this;
4202 node.style.webkitTransform = transform;
4203 node.style.transform = transform;
4204 },
4205 translate3d: function (x, y, z, node) {
4206 node = node || this;
4207 this.transform('translate3d(' + x + ',' + y + ',' + z + ')', node);
4208 },
4209 importHref: function (href, onload, onerror, optAsync) {
4210 var link = document.createElement('link');
4211 link.rel = 'import';
4212 link.href = href;
4213 var list = Polymer.Base.importHref.imported = Polymer.Base.importHref.imported | | {};
4214 var cached = list[link.href];
4215 var imprt = cached || link;
4216 var self = this;
4217 if (onload) {
4218 var loadListener = function (e) {
4219 e.target.__firedLoad = true;
4220 e.target.removeEventListener('load', loadListener);
4221 return onload.call(self, e);
4222 };
4223 imprt.addEventListener('load', loadListener);
4224 }
4225 if (onerror) {
4226 var errorListener = function (e) {
4227 e.target.__firedError = true;
4228 e.target.removeEventListener('error', errorListener);
4229 return onerror.call(self, e);
4230 };
4231 imprt.addEventListener('error', errorListener);
4232 }
4233 if (cached) {
4234 if (cached.__firedLoad) {
4235 cached.dispatchEvent(new Event('load'));
4236 }
4237 if (cached.__firedError) {
4238 cached.dispatchEvent(new Event('error'));
4239 }
4240 } else {
4241 list[link.href] = link;
4242 optAsync = Boolean(optAsync);
4243 if (optAsync) {
4244 link.setAttribute('async', '');
4245 }
4246 document.head.appendChild(link);
4247 }
4248 return imprt;
4249 },
4250 create: function (tag, props) {
4251 var elt = document.createElement(tag);
4252 if (props) {
4253 for (var n in props) {
4254 elt[n] = props[n];
4255 }
4256 }
4257 return elt;
4258 },
4259 isLightDescendant: function (node) {
4260 return this !== node && this.contains(node) && Polymer.dom(this).getOwnerRoot() === Polymer.dom(node).getOwnerRoot();
4261 },
4262 isLocalDescendant: function (node) {
4263 return this.root === Polymer.dom(node).getOwnerRoot();
4264 }
4265 });
4266 if (!Polymer.Settings.useNativeCustomElements) {
4267 var importHref = Polymer.Base.importHref;
4268 Polymer.Base.importHref = function (href, onload, onerror, optAsync) {
4269 CustomElements.ready = false;
4270 var loadFn = function (e) {
4271 CustomElements.upgradeDocumentTree(document);
4272 CustomElements.ready = true;
4273 if (onload) {
4274 return onload.call(this, e);
4275 }
4276 };
4277 return importHref.call(this, href, loadFn, onerror, optAsync);
4278 };
4279 }
4280 }());Polymer.Bind = {
4281 prepareModel: function (model) {
4282 Polymer.Base.mixin(model, this._modelApi);
4283 },
4284 _modelApi: {
4285 _notifyChange: function (source, event, value) {
4286 value = value === undefined ? this[source] : value;
4287 event = event || Polymer.CaseMap.camelToDashCase(source) + '-changed';
4288 this.fire(event, { value: value }, {
4289 bubbles: false,
4290 cancelable: false,
4291 _useCache: true
4292 });
4293 },
4294 _propertySetter: function (property, value, effects, fromAbove) {
4295 var old = this.__data__[property];
4296 if (old !== value && (old === old || value === value)) {
4297 this.__data__[property] = value;
4298 if (typeof value == 'object') {
4299 this._clearPath(property);
4300 }
4301 if (this._propertyChanged) {
4302 this._propertyChanged(property, value, old);
4303 }
4304 if (effects) {
4305 this._effectEffects(property, value, effects, old, fromAbove);
4306 }
4307 }
4308 return old;
4309 },
4310 __setProperty: function (property, value, quiet, node) {
4311 node = node || this;
4312 var effects = node._propertyEffects && node._propertyEffects[property];
4313 if (effects) {
4314 node._propertySetter(property, value, effects, quiet);
4315 } else {
4316 node[property] = value;
4317 }
4318 },
4319 _effectEffects: function (property, value, effects, old, fromAbove) {
4320 for (var i = 0, l = effects.length, fx; i < l && (fx = effects[i]); i++) {
4321 fx.fn.call(this, property, this[property], fx.effect, old, fromAbove);
4322 }
4323 },
4324 _clearPath: function (path) {
4325 for (var prop in this.__data__) {
4326 if (prop.indexOf(path + '.') === 0) {
4327 this.__data__[prop] = undefined;
4328 }
4329 }
4330 }
4331 },
4332 ensurePropertyEffects: function (model, property) {
4333 if (!model._propertyEffects) {
4334 model._propertyEffects = {};
4335 }
4336 var fx = model._propertyEffects[property];
4337 if (!fx) {
4338 fx = model._propertyEffects[property] = [];
4339 }
4340 return fx;
4341 },
4342 addPropertyEffect: function (model, property, kind, effect) {
4343 var fx = this.ensurePropertyEffects(model, property);
4344 var propEffect = {
4345 kind: kind,
4346 effect: effect,
4347 fn: Polymer.Bind['_' + kind + 'Effect']
4348 };
4349 fx.push(propEffect);
4350 return propEffect;
4351 },
4352 createBindings: function (model) {
4353 var fx$ = model._propertyEffects;
4354 if (fx$) {
4355 for (var n in fx$) {
4356 var fx = fx$[n];
4357 fx.sort(this._sortPropertyEffects);
4358 this._createAccessors(model, n, fx);
4359 }
4360 }
4361 },
4362 _sortPropertyEffects: function () {
4363 var EFFECT_ORDER = {
4364 'compute': 0,
4365 'annotation': 1,
4366 'annotatedComputation': 2,
4367 'reflect': 3,
4368 'notify': 4,
4369 'observer': 5,
4370 'complexObserver': 6,
4371 'function': 7
4372 };
4373 return function (a, b) {
4374 return EFFECT_ORDER[a.kind] - EFFECT_ORDER[b.kind];
4375 };
4376 }(),
4377 _createAccessors: function (model, property, effects) {
4378 var defun = {
4379 get: function () {
4380 return this.__data__[property];
4381 }
4382 };
4383 var setter = function (value) {
4384 this._propertySetter(property, value, effects);
4385 };
4386 var info = model.getPropertyInfo && model.getPropertyInfo(property);
4387 if (info && info.readOnly) {
4388 if (!info.computed) {
4389 model['_set' + this.upper(property)] = setter;
4390 }
4391 } else {
4392 defun.set = setter;
4393 }
4394 Object.defineProperty(model, property, defun);
4395 },
4396 upper: function (name) {
4397 return name[0].toUpperCase() + name.substring(1);
4398 },
4399 _addAnnotatedListener: function (model, index, property, path, event, negated) {
4400 if (!model._bindListeners) {
4401 model._bindListeners = [];
4402 }
4403 var fn = this._notedListenerFactory(property, path, this._isStructured(path), ne gated);
4404 var eventName = event || Polymer.CaseMap.camelToDashCase(property) + '-changed';
4405 model._bindListeners.push({
4406 index: index,
4407 property: property,
4408 path: path,
4409 changedFn: fn,
4410 event: eventName
4411 });
4412 },
4413 _isStructured: function (path) {
4414 return path.indexOf('.') > 0;
4415 },
4416 _isEventBogus: function (e, target) {
4417 return e.path && e.path[0] !== target;
4418 },
4419 _notedListenerFactory: function (property, path, isStructured, negated) {
4420 return function (target, value, targetPath) {
4421 if (targetPath) {
4422 this._notifyPath(this._fixPath(path, property, targetPath), value);
4423 } else {
4424 value = target[property];
4425 if (negated) {
4426 value = !value;
4427 }
4428 if (!isStructured) {
4429 this[path] = value;
4430 } else {
4431 if (this.__data__[path] != value) {
4432 this.set(path, value);
4433 }
4434 }
4435 }
4436 };
4437 },
4438 prepareInstance: function (inst) {
4439 inst.__data__ = Object.create(null);
4440 },
4441 setupBindListeners: function (inst) {
4442 var b$ = inst._bindListeners;
4443 for (var i = 0, l = b$.length, info; i < l && (info = b$[i]); i++) {
4444 var node = inst._nodes[info.index];
4445 this._addNotifyListener(node, inst, info.event, info.changedFn);
4446 }
4447 },
4448 _addNotifyListener: function (element, context, event, changedFn) {
4449 element.addEventListener(event, function (e) {
4450 return context._notifyListener(changedFn, e);
4451 });
4452 }
4453 };Polymer.Base.extend(Polymer.Bind, {
4454 _shouldAddListener: function (effect) {
4455 return effect.name && effect.kind != 'attribute' && effect.kind != 'text' && !ef fect.isCompound && effect.parts[0].mode === '{';
4456 },
4457 _annotationEffect: function (source, value, effect) {
4458 if (source != effect.value) {
4459 value = this._get(effect.value);
4460 this.__data__[effect.value] = value;
4461 }
4462 this._applyEffectValue(effect, value);
4463 },
4464 _reflectEffect: function (source, value, effect) {
4465 this.reflectPropertyToAttribute(source, effect.attribute, value);
4466 },
4467 _notifyEffect: function (source, value, effect, old, fromAbove) {
4468 if (!fromAbove) {
4469 this._notifyChange(source, effect.event, value);
4470 }
4471 },
4472 _functionEffect: function (source, value, fn, old, fromAbove) {
4473 fn.call(this, source, value, old, fromAbove);
4474 },
4475 _observerEffect: function (source, value, effect, old) {
4476 var fn = this[effect.method];
4477 if (fn) {
4478 fn.call(this, value, old);
4479 } else {
4480 this._warn(this._logf('_observerEffect', 'observer method `' + effect.method + ' ` not defined'));
4481 }
4482 },
4483 _complexObserverEffect: function (source, value, effect) {
4484 var fn = this[effect.method];
4485 if (fn) {
4486 var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
4487 if (args) {
4488 fn.apply(this, args);
4489 }
4490 } else if (effect.dynamicFn) {
4491 } else {
4492 this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.met hod + '` not defined'));
4493 }
4494 },
4495 _computeEffect: function (source, value, effect) {
4496 var fn = this[effect.method];
4497 if (fn) {
4498 var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
4499 if (args) {
4500 var computedvalue = fn.apply(this, args);
4501 this.__setProperty(effect.name, computedvalue);
4502 }
4503 } else if (effect.dynamicFn) {
4504 } else {
4505 this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined'));
4506 }
4507 },
4508 _annotatedComputationEffect: function (source, value, effect) {
4509 var computedHost = this._rootDataHost || this;
4510 var fn = computedHost[effect.method];
4511 if (fn) {
4512 var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
4513 if (args) {
4514 var computedvalue = fn.apply(computedHost, args);
4515 this._applyEffectValue(effect, computedvalue);
4516 }
4517 } else if (effect.dynamicFn) {
4518 } else {
4519 computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute me thod `' + effect.method + '` not defined'));
4520 }
4521 },
4522 _marshalArgs: function (model, effect, path, value) {
4523 var values = [];
4524 var args = effect.args;
4525 var bailoutEarly = args.length > 1 || effect.dynamicFn;
4526 for (var i = 0, l = args.length; i < l; i++) {
4527 var arg = args[i];
4528 var name = arg.name;
4529 var v;
4530 if (arg.literal) {
4531 v = arg.value;
4532 } else if (path === name) {
4533 v = value;
4534 } else {
4535 v = model[name];
4536 if (v === undefined && arg.structured) {
4537 v = Polymer.Base._get(name, model);
4538 }
4539 }
4540 if (bailoutEarly && v === undefined) {
4541 return;
4542 }
4543 if (arg.wildcard) {
4544 var matches = path.indexOf(name + '.') === 0;
4545 values[i] = {
4546 path: matches ? path : name,
4547 value: matches ? value : v,
4548 base: v
4549 };
4550 } else {
4551 values[i] = v;
4552 }
4553 }
4554 return values;
4555 }
4556 });Polymer.Base._addFeature({
4557 _addPropertyEffect: function (property, kind, effect) {
4558 var prop = Polymer.Bind.addPropertyEffect(this, property, kind, effect);
4559 prop.pathFn = this['_' + prop.kind + 'PathEffect'];
4560 },
4561 _prepEffects: function () {
4562 Polymer.Bind.prepareModel(this);
4563 this._addAnnotationEffects(this._notes);
4564 },
4565 _prepBindings: function () {
4566 Polymer.Bind.createBindings(this);
4567 },
4568 _addPropertyEffects: function (properties) {
4569 if (properties) {
4570 for (var p in properties) {
4571 var prop = properties[p];
4572 if (prop.observer) {
4573 this._addObserverEffect(p, prop.observer);
4574 }
4575 if (prop.computed) {
4576 prop.readOnly = true;
4577 this._addComputedEffect(p, prop.computed);
4578 }
4579 if (prop.notify) {
4580 this._addPropertyEffect(p, 'notify', { event: Polymer.CaseMap.camelToDashCase(p) + '-changed' });
4581 }
4582 if (prop.reflectToAttribute) {
4583 var attr = Polymer.CaseMap.camelToDashCase(p);
4584 if (attr[0] === '-') {
4585 this._warn(this._logf('_addPropertyEffects', 'Property ' + p + ' cannot be refle cted to attribute ' + attr + ' because "-" is not a valid starting attribute nam e. Use a lowercase first letter for the property instead.'));
4586 } else {
4587 this._addPropertyEffect(p, 'reflect', { attribute: attr });
4588 }
4589 }
4590 if (prop.readOnly) {
4591 Polymer.Bind.ensurePropertyEffects(this, p);
4592 }
4593 }
4594 }
4595 },
4596 _addComputedEffect: function (name, expression) {
4597 var sig = this._parseMethod(expression);
4598 var dynamicFn = sig.dynamicFn;
4599 for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) {
4600 this._addPropertyEffect(arg.model, 'compute', {
4601 method: sig.method,
4602 args: sig.args,
4603 trigger: arg,
4604 name: name,
4605 dynamicFn: dynamicFn
4606 });
4607 }
4608 if (dynamicFn) {
4609 this._addPropertyEffect(sig.method, 'compute', {
4610 method: sig.method,
4611 args: sig.args,
4612 trigger: null,
4613 name: name,
4614 dynamicFn: dynamicFn
4615 });
4616 }
4617 },
4618 _addObserverEffect: function (property, observer) {
4619 this._addPropertyEffect(property, 'observer', {
4620 method: observer,
4621 property: property
4622 });
4623 },
4624 _addComplexObserverEffects: function (observers) {
4625 if (observers) {
4626 for (var i = 0, o; i < observers.length && (o = observers[i]); i++) {
4627 this._addComplexObserverEffect(o);
4628 }
4629 }
4630 },
4631 _addComplexObserverEffect: function (observer) {
4632 var sig = this._parseMethod(observer);
4633 if (!sig) {
4634 throw new Error('Malformed observer expression \'' + observer + '\'');
4635 }
4636 var dynamicFn = sig.dynamicFn;
4637 for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) {
4638 this._addPropertyEffect(arg.model, 'complexObserver', {
4639 method: sig.method,
4640 args: sig.args,
4641 trigger: arg,
4642 dynamicFn: dynamicFn
4643 });
4644 }
4645 if (dynamicFn) {
4646 this._addPropertyEffect(sig.method, 'complexObserver', {
4647 method: sig.method,
4648 args: sig.args,
4649 trigger: null,
4650 dynamicFn: dynamicFn
4651 });
4652 }
4653 },
4654 _addAnnotationEffects: function (notes) {
4655 for (var i = 0, note; i < notes.length && (note = notes[i]); i++) {
4656 var b$ = note.bindings;
4657 for (var j = 0, binding; j < b$.length && (binding = b$[j]); j++) {
4658 this._addAnnotationEffect(binding, i);
4659 }
4660 }
4661 },
4662 _addAnnotationEffect: function (note, index) {
4663 if (Polymer.Bind._shouldAddListener(note)) {
4664 Polymer.Bind._addAnnotatedListener(this, index, note.name, note.parts[0].value, note.parts[0].event, note.parts[0].negate);
4665 }
4666 for (var i = 0; i < note.parts.length; i++) {
4667 var part = note.parts[i];
4668 if (part.signature) {
4669 this._addAnnotatedComputationEffect(note, part, index);
4670 } else if (!part.literal) {
4671 if (note.kind === 'attribute' && note.name[0] === '-') {
4672 this._warn(this._logf('_addAnnotationEffect', 'Cannot set attribute ' + note.nam e + ' because "-" is not a valid attribute starting character'));
4673 } else {
4674 this._addPropertyEffect(part.model, 'annotation', {
4675 kind: note.kind,
4676 index: index,
4677 name: note.name,
4678 propertyName: note.propertyName,
4679 value: part.value,
4680 isCompound: note.isCompound,
4681 compoundIndex: part.compoundIndex,
4682 event: part.event,
4683 customEvent: part.customEvent,
4684 negate: part.negate
4685 });
4686 }
4687 }
4688 }
4689 },
4690 _addAnnotatedComputationEffect: function (note, part, index) {
4691 var sig = part.signature;
4692 if (sig.static) {
4693 this.__addAnnotatedComputationEffect('__static__', index, note, part, null);
4694 } else {
4695 for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) {
4696 if (!arg.literal) {
4697 this.__addAnnotatedComputationEffect(arg.model, index, note, part, arg);
4698 }
4699 }
4700 if (sig.dynamicFn) {
4701 this.__addAnnotatedComputationEffect(sig.method, index, note, part, null);
4702 }
4703 }
4704 },
4705 __addAnnotatedComputationEffect: function (property, index, note, part, trigger) {
4706 this._addPropertyEffect(property, 'annotatedComputation', {
4707 index: index,
4708 isCompound: note.isCompound,
4709 compoundIndex: part.compoundIndex,
4710 kind: note.kind,
4711 name: note.name,
4712 negate: part.negate,
4713 method: part.signature.method,
4714 args: part.signature.args,
4715 trigger: trigger,
4716 dynamicFn: part.signature.dynamicFn
4717 });
4718 },
4719 _parseMethod: function (expression) {
4720 var m = expression.match(/([^\s]+?)\(([\s\S]*)\)/);
4721 if (m) {
4722 var sig = {
4723 method: m[1],
4724 static: true
4725 };
4726 if (this.getPropertyInfo(sig.method) !== Polymer.nob) {
4727 sig.static = false;
4728 sig.dynamicFn = true;
4729 }
4730 if (m[2].trim()) {
4731 var args = m[2].replace(/\\,/g, '&comma;').split(',');
4732 return this._parseArgs(args, sig);
4733 } else {
4734 sig.args = Polymer.nar;
4735 return sig;
4736 }
4737 }
4738 },
4739 _parseArgs: function (argList, sig) {
4740 sig.args = argList.map(function (rawArg) {
4741 var arg = this._parseArg(rawArg);
4742 if (!arg.literal) {
4743 sig.static = false;
4744 }
4745 return arg;
4746 }, this);
4747 return sig;
4748 },
4749 _parseArg: function (rawArg) {
4750 var arg = rawArg.trim().replace(/&comma;/g, ',').replace(/\\(.)/g, '$1');
4751 var a = { name: arg };
4752 var fc = arg[0];
4753 if (fc === '-') {
4754 fc = arg[1];
4755 }
4756 if (fc >= '0' && fc <= '9') {
4757 fc = '#';
4758 }
4759 switch (fc) {
4760 case '\'':
4761 case '"':
4762 a.value = arg.slice(1, -1);
4763 a.literal = true;
4764 break;
4765 case '#':
4766 a.value = Number(arg);
4767 a.literal = true;
4768 break;
4769 }
4770 if (!a.literal) {
4771 a.model = this._modelForPath(arg);
4772 a.structured = arg.indexOf('.') > 0;
4773 if (a.structured) {
4774 a.wildcard = arg.slice(-2) == '.*';
4775 if (a.wildcard) {
4776 a.name = arg.slice(0, -2);
4777 }
4778 }
4779 }
4780 return a;
4781 },
4782 _marshalInstanceEffects: function () {
4783 Polymer.Bind.prepareInstance(this);
4784 if (this._bindListeners) {
4785 Polymer.Bind.setupBindListeners(this);
4786 }
4787 },
4788 _applyEffectValue: function (info, value) {
4789 var node = this._nodes[info.index];
4790 var property = info.name;
4791 value = this._computeFinalAnnotationValue(node, property, value, info);
4792 if (info.customEvent && node[property] === value) {
4793 return;
4794 }
4795 if (info.kind == 'attribute') {
4796 this.serializeValueToAttribute(value, property, node);
4797 } else {
4798 var pinfo = node._propertyInfo && node._propertyInfo[property];
4799 if (pinfo && pinfo.readOnly) {
4800 return;
4801 }
4802 this.__setProperty(property, value, false, node);
4803 }
4804 },
4805 _computeFinalAnnotationValue: function (node, property, value, info) {
4806 if (info.negate) {
4807 value = !value;
4808 }
4809 if (info.isCompound) {
4810 var storage = node.__compoundStorage__[property];
4811 storage[info.compoundIndex] = value;
4812 value = storage.join('');
4813 }
4814 if (info.kind !== 'attribute') {
4815 if (property === 'className') {
4816 value = this._scopeElementClass(node, value);
4817 }
4818 if (property === 'textContent' || node.localName == 'input' && property == 'valu e') {
4819 value = value == undefined ? '' : value;
4820 }
4821 }
4822 return value;
4823 },
4824 _executeStaticEffects: function () {
4825 if (this._propertyEffects && this._propertyEffects.__static__) {
4826 this._effectEffects('__static__', null, this._propertyEffects.__static__);
4827 }
4828 }
4829 });(function () {
4830 var usePolyfillProto = Polymer.Settings.usePolyfillProto;
4831 Polymer.Base._addFeature({
4832 _setupConfigure: function (initialConfig) {
4833 this._config = {};
4834 this._handlers = [];
4835 this._aboveConfig = null;
4836 if (initialConfig) {
4837 for (var i in initialConfig) {
4838 if (initialConfig[i] !== undefined) {
4839 this._config[i] = initialConfig[i];
4840 }
4841 }
4842 }
4843 },
4844 _marshalAttributes: function () {
4845 this._takeAttributesToModel(this._config);
4846 },
4847 _attributeChangedImpl: function (name) {
4848 var model = this._clientsReadied ? this : this._config;
4849 this._setAttributeToProperty(model, name);
4850 },
4851 _configValue: function (name, value) {
4852 var info = this._propertyInfo[name];
4853 if (!info || !info.readOnly) {
4854 this._config[name] = value;
4855 }
4856 },
4857 _beforeClientsReady: function () {
4858 this._configure();
4859 },
4860 _configure: function () {
4861 this._configureAnnotationReferences();
4862 this._aboveConfig = this.mixin({}, this._config);
4863 var config = {};
4864 for (var i = 0; i < this.behaviors.length; i++) {
4865 this._configureProperties(this.behaviors[i].properties, config);
4866 }
4867 this._configureProperties(this.properties, config);
4868 this.mixin(config, this._aboveConfig);
4869 this._config = config;
4870 if (this._clients && this._clients.length) {
4871 this._distributeConfig(this._config);
4872 }
4873 },
4874 _configureProperties: function (properties, config) {
4875 for (var i in properties) {
4876 var c = properties[i];
4877 if (!usePolyfillProto && this.hasOwnProperty(i) && this._propertyEffects && this ._propertyEffects[i]) {
4878 config[i] = this[i];
4879 delete this[i];
4880 } else if (c.value !== undefined) {
4881 var value = c.value;
4882 if (typeof value == 'function') {
4883 value = value.call(this, this._config);
4884 }
4885 config[i] = value;
4886 }
4887 }
4888 },
4889 _distributeConfig: function (config) {
4890 var fx$ = this._propertyEffects;
4891 if (fx$) {
4892 for (var p in config) {
4893 var fx = fx$[p];
4894 if (fx) {
4895 for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) {
4896 if (x.kind === 'annotation') {
4897 var node = this._nodes[x.effect.index];
4898 var name = x.effect.propertyName;
4899 var isAttr = x.effect.kind == 'attribute';
4900 var hasEffect = node._propertyEffects && node._propertyEffects[name];
4901 if (node._configValue && (hasEffect || !isAttr)) {
4902 var value = p === x.effect.value ? config[p] : this._get(x.effect.value, config) ;
4903 value = this._computeFinalAnnotationValue(node, name, value, x.effect);
4904 if (isAttr) {
4905 value = node.deserialize(this.serialize(value), node._propertyInfo[name].type);
4906 }
4907 node._configValue(name, value);
4908 }
4909 }
4910 }
4911 }
4912 }
4913 }
4914 },
4915 _afterClientsReady: function () {
4916 this._executeStaticEffects();
4917 this._applyConfig(this._config, this._aboveConfig);
4918 this._flushHandlers();
4919 },
4920 _applyConfig: function (config, aboveConfig) {
4921 for (var n in config) {
4922 if (this[n] === undefined) {
4923 this.__setProperty(n, config[n], n in aboveConfig);
4924 }
4925 }
4926 },
4927 _notifyListener: function (fn, e) {
4928 if (!Polymer.Bind._isEventBogus(e, e.target)) {
4929 var value, path;
4930 if (e.detail) {
4931 value = e.detail.value;
4932 path = e.detail.path;
4933 }
4934 if (!this._clientsReadied) {
4935 this._queueHandler([
4936 fn,
4937 e.target,
4938 value,
4939 path
4940 ]);
4941 } else {
4942 return fn.call(this, e.target, value, path);
4943 }
4944 }
4945 },
4946 _queueHandler: function (args) {
4947 this._handlers.push(args);
4948 },
4949 _flushHandlers: function () {
4950 var h$ = this._handlers;
4951 for (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) {
4952 h[0].call(this, h[1], h[2], h[3]);
4953 }
4954 this._handlers = [];
4955 }
4956 });
4957 }());(function () {
4958 'use strict';
4959 Polymer.Base._addFeature({
4960 notifyPath: function (path, value, fromAbove) {
4961 var info = {};
4962 var v = this._get(path, this, info);
4963 if (arguments.length === 1) {
4964 value = v;
4965 }
4966 if (info.path) {
4967 this._notifyPath(info.path, value, fromAbove);
4968 }
4969 },
4970 _notifyPath: function (path, value, fromAbove) {
4971 var old = this._propertySetter(path, value);
4972 if (old !== value && (old === old || value === value)) {
4973 this._pathEffector(path, value);
4974 if (!fromAbove) {
4975 this._notifyPathUp(path, value);
4976 }
4977 return true;
4978 }
4979 },
4980 _getPathParts: function (path) {
4981 if (Array.isArray(path)) {
4982 var parts = [];
4983 for (var i = 0; i < path.length; i++) {
4984 var args = path[i].toString().split('.');
4985 for (var j = 0; j < args.length; j++) {
4986 parts.push(args[j]);
4987 }
4988 }
4989 return parts;
4990 } else {
4991 return path.toString().split('.');
4992 }
4993 },
4994 set: function (path, value, root) {
4995 var prop = root || this;
4996 var parts = this._getPathParts(path);
4997 var array;
4998 var last = parts[parts.length - 1];
4999 if (parts.length > 1) {
5000 for (var i = 0; i < parts.length - 1; i++) {
5001 var part = parts[i];
5002 if (array && part[0] == '#') {
5003 prop = Polymer.Collection.get(array).getItem(part);
5004 } else {
5005 prop = prop[part];
5006 if (array && parseInt(part, 10) == part) {
5007 parts[i] = Polymer.Collection.get(array).getKey(prop);
5008 }
5009 }
5010 if (!prop) {
5011 return;
5012 }
5013 array = Array.isArray(prop) ? prop : null;
5014 }
5015 if (array) {
5016 var coll = Polymer.Collection.get(array);
5017 var old, key;
5018 if (last[0] == '#') {
5019 key = last;
5020 old = coll.getItem(key);
5021 last = array.indexOf(old);
5022 coll.setItem(key, value);
5023 } else if (parseInt(last, 10) == last) {
5024 old = prop[last];
5025 key = coll.getKey(old);
5026 parts[i] = key;
5027 coll.setItem(key, value);
5028 }
5029 }
5030 prop[last] = value;
5031 if (!root) {
5032 this._notifyPath(parts.join('.'), value);
5033 }
5034 } else {
5035 prop[path] = value;
5036 }
5037 },
5038 get: function (path, root) {
5039 return this._get(path, root);
5040 },
5041 _get: function (path, root, info) {
5042 var prop = root || this;
5043 var parts = this._getPathParts(path);
5044 var array;
5045 for (var i = 0; i < parts.length; i++) {
5046 if (!prop) {
5047 return;
5048 }
5049 var part = parts[i];
5050 if (array && part[0] == '#') {
5051 prop = Polymer.Collection.get(array).getItem(part);
5052 } else {
5053 prop = prop[part];
5054 if (info && array && parseInt(part, 10) == part) {
5055 parts[i] = Polymer.Collection.get(array).getKey(prop);
5056 }
5057 }
5058 array = Array.isArray(prop) ? prop : null;
5059 }
5060 if (info) {
5061 info.path = parts.join('.');
5062 }
5063 return prop;
5064 },
5065 _pathEffector: function (path, value) {
5066 var model = this._modelForPath(path);
5067 var fx$ = this._propertyEffects && this._propertyEffects[model];
5068 if (fx$) {
5069 for (var i = 0, fx; i < fx$.length && (fx = fx$[i]); i++) {
5070 var fxFn = fx.pathFn;
5071 if (fxFn) {
5072 fxFn.call(this, path, value, fx.effect);
5073 }
5074 }
5075 }
5076 if (this._boundPaths) {
5077 this._notifyBoundPaths(path, value);
5078 }
5079 },
5080 _annotationPathEffect: function (path, value, effect) {
5081 if (effect.value === path || effect.value.indexOf(path + '.') === 0) {
5082 Polymer.Bind._annotationEffect.call(this, path, value, effect);
5083 } else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) {
5084 var node = this._nodes[effect.index];
5085 if (node && node._notifyPath) {
5086 var p = this._fixPath(effect.name, effect.value, path);
5087 node._notifyPath(p, value, true);
5088 }
5089 }
5090 },
5091 _complexObserverPathEffect: function (path, value, effect) {
5092 if (this._pathMatchesEffect(path, effect)) {
5093 Polymer.Bind._complexObserverEffect.call(this, path, value, effect);
5094 }
5095 },
5096 _computePathEffect: function (path, value, effect) {
5097 if (this._pathMatchesEffect(path, effect)) {
5098 Polymer.Bind._computeEffect.call(this, path, value, effect);
5099 }
5100 },
5101 _annotatedComputationPathEffect: function (path, value, effect) {
5102 if (this._pathMatchesEffect(path, effect)) {
5103 Polymer.Bind._annotatedComputationEffect.call(this, path, value, effect);
5104 }
5105 },
5106 _pathMatchesEffect: function (path, effect) {
5107 var effectArg = effect.trigger.name;
5108 return effectArg == path || effectArg.indexOf(path + '.') === 0 || effect.trigge r.wildcard && path.indexOf(effectArg + '.') === 0;
5109 },
5110 linkPaths: function (to, from) {
5111 this._boundPaths = this._boundPaths || {};
5112 if (from) {
5113 this._boundPaths[to] = from;
5114 } else {
5115 this.unlinkPaths(to);
5116 }
5117 },
5118 unlinkPaths: function (path) {
5119 if (this._boundPaths) {
5120 delete this._boundPaths[path];
5121 }
5122 },
5123 _notifyBoundPaths: function (path, value) {
5124 for (var a in this._boundPaths) {
5125 var b = this._boundPaths[a];
5126 if (path.indexOf(a + '.') == 0) {
5127 this._notifyPath(this._fixPath(b, a, path), value);
5128 } else if (path.indexOf(b + '.') == 0) {
5129 this._notifyPath(this._fixPath(a, b, path), value);
5130 }
5131 }
5132 },
5133 _fixPath: function (property, root, path) {
5134 return property + path.slice(root.length);
5135 },
5136 _notifyPathUp: function (path, value) {
5137 var rootName = this._modelForPath(path);
5138 var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName);
5139 var eventName = dashCaseName + this._EVENT_CHANGED;
5140 this.fire(eventName, {
5141 path: path,
5142 value: value
5143 }, {
5144 bubbles: false,
5145 _useCache: true
5146 });
5147 },
5148 _modelForPath: function (path) {
5149 var dot = path.indexOf('.');
5150 return dot < 0 ? path : path.slice(0, dot);
5151 },
5152 _EVENT_CHANGED: '-changed',
5153 notifySplices: function (path, splices) {
5154 var info = {};
5155 var array = this._get(path, this, info);
5156 this._notifySplices(array, info.path, splices);
5157 },
5158 _notifySplices: function (array, path, splices) {
5159 var change = {
5160 keySplices: Polymer.Collection.applySplices(array, splices),
5161 indexSplices: splices
5162 };
5163 var splicesPath = path + '.splices';
5164 this._notifyPath(splicesPath, change);
5165 this._notifyPath(path + '.length', array.length);
5166 this.__data__[splicesPath] = {
5167 keySplices: null,
5168 indexSplices: null
5169 };
5170 },
5171 _notifySplice: function (array, path, index, added, removed) {
5172 this._notifySplices(array, path, [{
5173 index: index,
5174 addedCount: added,
5175 removed: removed,
5176 object: array,
5177 type: 'splice'
5178 }]);
5179 },
5180 push: function (path) {
5181 var info = {};
5182 var array = this._get(path, this, info);
5183 var args = Array.prototype.slice.call(arguments, 1);
5184 var len = array.length;
5185 var ret = array.push.apply(array, args);
5186 if (args.length) {
5187 this._notifySplice(array, info.path, len, args.length, []);
5188 }
5189 return ret;
5190 },
5191 pop: function (path) {
5192 var info = {};
5193 var array = this._get(path, this, info);
5194 var hadLength = Boolean(array.length);
5195 var args = Array.prototype.slice.call(arguments, 1);
5196 var ret = array.pop.apply(array, args);
5197 if (hadLength) {
5198 this._notifySplice(array, info.path, array.length, 0, [ret]);
5199 }
5200 return ret;
5201 },
5202 splice: function (path, start) {
5203 var info = {};
5204 var array = this._get(path, this, info);
5205 if (start < 0) {
5206 start = array.length - Math.floor(-start);
5207 } else {
5208 start = Math.floor(start);
5209 }
5210 if (!start) {
5211 start = 0;
5212 }
5213 var args = Array.prototype.slice.call(arguments, 1);
5214 var ret = array.splice.apply(array, args);
5215 var addedCount = Math.max(args.length - 2, 0);
5216 if (addedCount || ret.length) {
5217 this._notifySplice(array, info.path, start, addedCount, ret);
5218 }
5219 return ret;
5220 },
5221 shift: function (path) {
5222 var info = {};
5223 var array = this._get(path, this, info);
5224 var hadLength = Boolean(array.length);
5225 var args = Array.prototype.slice.call(arguments, 1);
5226 var ret = array.shift.apply(array, args);
5227 if (hadLength) {
5228 this._notifySplice(array, info.path, 0, 0, [ret]);
5229 }
5230 return ret;
5231 },
5232 unshift: function (path) {
5233 var info = {};
5234 var array = this._get(path, this, info);
5235 var args = Array.prototype.slice.call(arguments, 1);
5236 var ret = array.unshift.apply(array, args);
5237 if (args.length) {
5238 this._notifySplice(array, info.path, 0, args.length, []);
5239 }
5240 return ret;
5241 },
5242 prepareModelNotifyPath: function (model) {
5243 this.mixin(model, {
5244 fire: Polymer.Base.fire,
5245 _getEvent: Polymer.Base._getEvent,
5246 __eventCache: Polymer.Base.__eventCache,
5247 notifyPath: Polymer.Base.notifyPath,
5248 _get: Polymer.Base._get,
5249 _EVENT_CHANGED: Polymer.Base._EVENT_CHANGED,
5250 _notifyPath: Polymer.Base._notifyPath,
5251 _notifyPathUp: Polymer.Base._notifyPathUp,
5252 _pathEffector: Polymer.Base._pathEffector,
5253 _annotationPathEffect: Polymer.Base._annotationPathEffect,
5254 _complexObserverPathEffect: Polymer.Base._complexObserverPathEffect,
5255 _annotatedComputationPathEffect: Polymer.Base._annotatedComputationPathEffect,
5256 _computePathEffect: Polymer.Base._computePathEffect,
5257 _modelForPath: Polymer.Base._modelForPath,
5258 _pathMatchesEffect: Polymer.Base._pathMatchesEffect,
5259 _notifyBoundPaths: Polymer.Base._notifyBoundPaths,
5260 _getPathParts: Polymer.Base._getPathParts
5261 });
5262 }
5263 });
5264 }());Polymer.Base._addFeature({
5265 resolveUrl: function (url) {
5266 var module = Polymer.DomModule.import(this.is);
5267 var root = '';
5268 if (module) {
5269 var assetPath = module.getAttribute('assetpath') || '';
5270 root = Polymer.ResolveUrl.resolveUrl(assetPath, module.ownerDocument.baseURI);
5271 }
5272 return Polymer.ResolveUrl.resolveUrl(url, root);
5273 }
5274 });Polymer.CssParse = function () {
5275 return {
5276 parse: function (text) {
5277 text = this._clean(text);
5278 return this._parseCss(this._lex(text), text);
5279 },
5280 _clean: function (cssText) {
5281 return cssText.replace(this._rx.comments, '').replace(this._rx.port, '');
5282 },
5283 _lex: function (text) {
5284 var root = {
5285 start: 0,
5286 end: text.length
5287 };
5288 var n = root;
5289 for (var i = 0, l = text.length; i < l; i++) {
5290 switch (text[i]) {
5291 case this.OPEN_BRACE:
5292 if (!n.rules) {
5293 n.rules = [];
5294 }
5295 var p = n;
5296 var previous = p.rules[p.rules.length - 1];
5297 n = {
5298 start: i + 1,
5299 parent: p,
5300 previous: previous
5301 };
5302 p.rules.push(n);
5303 break;
5304 case this.CLOSE_BRACE:
5305 n.end = i + 1;
5306 n = n.parent || root;
5307 break;
5308 }
5309 }
5310 return root;
5311 },
5312 _parseCss: function (node, text) {
5313 var t = text.substring(node.start, node.end - 1);
5314 node.parsedCssText = node.cssText = t.trim();
5315 if (node.parent) {
5316 var ss = node.previous ? node.previous.end : node.parent.start;
5317 t = text.substring(ss, node.start - 1);
5318 t = this._expandUnicodeEscapes(t);
5319 t = t.replace(this._rx.multipleSpaces, ' ');
5320 t = t.substring(t.lastIndexOf(';') + 1);
5321 var s = node.parsedSelector = node.selector = t.trim();
5322 node.atRule = s.indexOf(this.AT_START) === 0;
5323 if (node.atRule) {
5324 if (s.indexOf(this.MEDIA_START) === 0) {
5325 node.type = this.types.MEDIA_RULE;
5326 } else if (s.match(this._rx.keyframesRule)) {
5327 node.type = this.types.KEYFRAMES_RULE;
5328 node.keyframesName = node.selector.split(this._rx.multipleSpaces).pop();
5329 }
5330 } else {
5331 if (s.indexOf(this.VAR_START) === 0) {
5332 node.type = this.types.MIXIN_RULE;
5333 } else {
5334 node.type = this.types.STYLE_RULE;
5335 }
5336 }
5337 }
5338 var r$ = node.rules;
5339 if (r$) {
5340 for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
5341 this._parseCss(r, text);
5342 }
5343 }
5344 return node;
5345 },
5346 _expandUnicodeEscapes: function (s) {
5347 return s.replace(/\\([0-9a-f]{1,6})\s/gi, function () {
5348 var code = arguments[1], repeat = 6 - code.length;
5349 while (repeat--) {
5350 code = '0' + code;
5351 }
5352 return '\\' + code;
5353 });
5354 },
5355 stringify: function (node, preserveProperties, text) {
5356 text = text || '';
5357 var cssText = '';
5358 if (node.cssText || node.rules) {
5359 var r$ = node.rules;
5360 if (r$ && !this._hasMixinRules(r$)) {
5361 for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
5362 cssText = this.stringify(r, preserveProperties, cssText);
5363 }
5364 } else {
5365 cssText = preserveProperties ? node.cssText : this.removeCustomProps(node.cssTex t);
5366 cssText = cssText.trim();
5367 if (cssText) {
5368 cssText = ' ' + cssText + '\n';
5369 }
5370 }
5371 }
5372 if (cssText) {
5373 if (node.selector) {
5374 text += node.selector + ' ' + this.OPEN_BRACE + '\n';
5375 }
5376 text += cssText;
5377 if (node.selector) {
5378 text += this.CLOSE_BRACE + '\n\n';
5379 }
5380 }
5381 return text;
5382 },
5383 _hasMixinRules: function (rules) {
5384 return rules[0].selector.indexOf(this.VAR_START) === 0;
5385 },
5386 removeCustomProps: function (cssText) {
5387 cssText = this.removeCustomPropAssignment(cssText);
5388 return this.removeCustomPropApply(cssText);
5389 },
5390 removeCustomPropAssignment: function (cssText) {
5391 return cssText.replace(this._rx.customProp, '').replace(this._rx.mixinProp, '');
5392 },
5393 removeCustomPropApply: function (cssText) {
5394 return cssText.replace(this._rx.mixinApply, '').replace(this._rx.varApply, '');
5395 },
5396 types: {
5397 STYLE_RULE: 1,
5398 KEYFRAMES_RULE: 7,
5399 MEDIA_RULE: 4,
5400 MIXIN_RULE: 1000
5401 },
5402 OPEN_BRACE: '{',
5403 CLOSE_BRACE: '}',
5404 _rx: {
5405 comments: /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim,
5406 port: /@import[^;]*;/gim,
5407 customProp: /(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\n]|$)/gim,
5408 mixinProp: /(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\n]|$)?/gim,
5409 mixinApply: /@apply\s*\(?[^);]*\)?\s*(?:[;\n]|$)?/gim,
5410 varApply: /[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim,
5411 keyframesRule: /^@[^\s]*keyframes/,
5412 multipleSpaces: /\s+/g
5413 },
5414 VAR_START: '--',
5415 MEDIA_START: '@media',
5416 AT_START: '@'
5417 };
5418 }();Polymer.StyleUtil = function () {
5419 var settings = Polymer.Settings;
5420 return {
5421 NATIVE_VARIABLES: Polymer.Settings.useNativeCSSProperties,
5422 MODULE_STYLES_SELECTOR: 'style, link[rel=import][type~=css], template',
5423 INCLUDE_ATTR: 'include',
5424 toCssText: function (rules, callback) {
5425 if (typeof rules === 'string') {
5426 rules = this.parser.parse(rules);
5427 }
5428 if (callback) {
5429 this.forEachRule(rules, callback);
5430 }
5431 return this.parser.stringify(rules, this.NATIVE_VARIABLES);
5432 },
5433 forRulesInStyles: function (styles, styleRuleCallback, keyframesRuleCallback) {
5434 if (styles) {
5435 for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
5436 this.forEachRuleInStyle(s, styleRuleCallback, keyframesRuleCallback);
5437 }
5438 }
5439 },
5440 forActiveRulesInStyles: function (styles, styleRuleCallback, keyframesRuleCallba ck) {
5441 if (styles) {
5442 for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
5443 this.forEachRuleInStyle(s, styleRuleCallback, keyframesRuleCallback, true);
5444 }
5445 }
5446 },
5447 rulesForStyle: function (style) {
5448 if (!style.__cssRules && style.textContent) {
5449 style.__cssRules = this.parser.parse(style.textContent);
5450 }
5451 return style.__cssRules;
5452 },
5453 isKeyframesSelector: function (rule) {
5454 return rule.parent && rule.parent.type === this.ruleTypes.KEYFRAMES_RULE;
5455 },
5456 forEachRuleInStyle: function (style, styleRuleCallback, keyframesRuleCallback, o nlyActiveRules) {
5457 var rules = this.rulesForStyle(style);
5458 var styleCallback, keyframeCallback;
5459 if (styleRuleCallback) {
5460 styleCallback = function (rule) {
5461 styleRuleCallback(rule, style);
5462 };
5463 }
5464 if (keyframesRuleCallback) {
5465 keyframeCallback = function (rule) {
5466 keyframesRuleCallback(rule, style);
5467 };
5468 }
5469 this.forEachRule(rules, styleCallback, keyframeCallback, onlyActiveRules);
5470 },
5471 forEachRule: function (node, styleRuleCallback, keyframesRuleCallback, onlyActiv eRules) {
5472 if (!node) {
5473 return;
5474 }
5475 var skipRules = false;
5476 if (onlyActiveRules) {
5477 if (node.type === this.ruleTypes.MEDIA_RULE) {
5478 var matchMedia = node.selector.match(this.rx.MEDIA_MATCH);
5479 if (matchMedia) {
5480 if (!window.matchMedia(matchMedia[1]).matches) {
5481 skipRules = true;
5482 }
5483 }
5484 }
5485 }
5486 if (node.type === this.ruleTypes.STYLE_RULE) {
5487 styleRuleCallback(node);
5488 } else if (keyframesRuleCallback && node.type === this.ruleTypes.KEYFRAMES_RULE) {
5489 keyframesRuleCallback(node);
5490 } else if (node.type === this.ruleTypes.MIXIN_RULE) {
5491 skipRules = true;
5492 }
5493 var r$ = node.rules;
5494 if (r$ && !skipRules) {
5495 for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
5496 this.forEachRule(r, styleRuleCallback, keyframesRuleCallback, onlyActiveRules);
5497 }
5498 }
5499 },
5500 applyCss: function (cssText, moniker, target, contextNode) {
5501 var style = this.createScopeStyle(cssText, moniker);
5502 return this.applyStyle(style, target, contextNode);
5503 },
5504 applyStyle: function (style, target, contextNode) {
5505 target = target || document.head;
5506 var after = contextNode && contextNode.nextSibling || target.firstChild;
5507 this.__lastHeadApplyNode = style;
5508 return target.insertBefore(style, after);
5509 },
5510 createScopeStyle: function (cssText, moniker) {
5511 var style = document.createElement('style');
5512 if (moniker) {
5513 style.setAttribute('scope', moniker);
5514 }
5515 style.textContent = cssText;
5516 return style;
5517 },
5518 __lastHeadApplyNode: null,
5519 applyStylePlaceHolder: function (moniker) {
5520 var placeHolder = document.createComment(' Shady DOM styles for ' + moniker + ' ');
5521 var after = this.__lastHeadApplyNode ? this.__lastHeadApplyNode.nextSibling : nu ll;
5522 var scope = document.head;
5523 scope.insertBefore(placeHolder, after || scope.firstChild);
5524 this.__lastHeadApplyNode = placeHolder;
5525 return placeHolder;
5526 },
5527 cssFromModules: function (moduleIds, warnIfNotFound) {
5528 var modules = moduleIds.trim().split(' ');
5529 var cssText = '';
5530 for (var i = 0; i < modules.length; i++) {
5531 cssText += this.cssFromModule(modules[i], warnIfNotFound);
5532 }
5533 return cssText;
5534 },
5535 cssFromModule: function (moduleId, warnIfNotFound) {
5536 var m = Polymer.DomModule.import(moduleId);
5537 if (m && !m._cssText) {
5538 m._cssText = this.cssFromElement(m);
5539 }
5540 if (!m && warnIfNotFound) {
5541 console.warn('Could not find style data in module named', moduleId);
5542 }
5543 return m && m._cssText || '';
5544 },
5545 cssFromElement: function (element) {
5546 var cssText = '';
5547 var content = element.content || element;
5548 var e$ = Polymer.TreeApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_S ELECTOR));
5549 for (var i = 0, e; i < e$.length; i++) {
5550 e = e$[i];
5551 if (e.localName === 'template') {
5552 cssText += this.cssFromElement(e);
5553 } else {
5554 if (e.localName === 'style') {
5555 var include = e.getAttribute(this.INCLUDE_ATTR);
5556 if (include) {
5557 cssText += this.cssFromModules(include, true);
5558 }
5559 e = e.__appliedElement || e;
5560 e.parentNode.removeChild(e);
5561 cssText += this.resolveCss(e.textContent, element.ownerDocument);
5562 } else if (e.import && e.import.body) {
5563 cssText += this.resolveCss(e.import.body.textContent, e.import);
5564 }
5565 }
5566 }
5567 return cssText;
5568 },
5569 isTargetedBuild: function (buildType) {
5570 return settings.useNativeShadow ? buildType === 'shadow' : buildType === 'shady' ;
5571 },
5572 cssBuildTypeForModule: function (module) {
5573 var dm = Polymer.DomModule.import(module);
5574 if (dm) {
5575 return this.getCssBuildType(dm);
5576 }
5577 },
5578 getCssBuildType: function (element) {
5579 return element.getAttribute('css-build');
5580 },
5581 rx: {
5582 VAR_ASSIGN: /(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}] )|$)/gi,
5583 MIXIN_MATCH: /(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi,
5584 VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,()]*)|(?:[^;()]*\([^;)]* \)+))[\s]*?\)/gi,
5585 VAR_CONSUMED: /(--[\w-]+)\s*([:,;)]|$)/gi,
5586 ANIMATION_MATCH: /(animation\s*:)|(animation-name\s*:)/,
5587 MEDIA_MATCH: /@media[^(]*(\([^)]*\))/,
5588 IS_VAR: /^--/,
5589 BRACKETED: /\{[^}]*\}/g,
5590 HOST_PREFIX: '(?:^|[^.#[:])',
5591 HOST_SUFFIX: '($|[.:[\\s>+~])'
5592 },
5593 resolveCss: Polymer.ResolveUrl.resolveCss,
5594 parser: Polymer.CssParse,
5595 ruleTypes: Polymer.CssParse.types
5596 };
5597 }();Polymer.StyleTransformer = function () {
5598 var styleUtil = Polymer.StyleUtil;
5599 var settings = Polymer.Settings;
5600 var api = {
5601 dom: function (node, scope, useAttr, shouldRemoveScope) {
5602 this._transformDom(node, scope || '', useAttr, shouldRemoveScope);
5603 },
5604 _transformDom: function (node, selector, useAttr, shouldRemoveScope) {
5605 if (node.setAttribute) {
5606 this.element(node, selector, useAttr, shouldRemoveScope);
5607 }
5608 var c$ = Polymer.dom(node).childNodes;
5609 for (var i = 0; i < c$.length; i++) {
5610 this._transformDom(c$[i], selector, useAttr, shouldRemoveScope);
5611 }
5612 },
5613 element: function (element, scope, useAttr, shouldRemoveScope) {
5614 if (useAttr) {
5615 if (shouldRemoveScope) {
5616 element.removeAttribute(SCOPE_NAME);
5617 } else {
5618 element.setAttribute(SCOPE_NAME, scope);
5619 }
5620 } else {
5621 if (scope) {
5622 if (element.classList) {
5623 if (shouldRemoveScope) {
5624 element.classList.remove(SCOPE_NAME);
5625 element.classList.remove(scope);
5626 } else {
5627 element.classList.add(SCOPE_NAME);
5628 element.classList.add(scope);
5629 }
5630 } else if (element.getAttribute) {
5631 var c = element.getAttribute(CLASS);
5632 if (shouldRemoveScope) {
5633 if (c) {
5634 element.setAttribute(CLASS, c.replace(SCOPE_NAME, '').replace(scope, ''));
5635 }
5636 } else {
5637 element.setAttribute(CLASS, (c ? c + ' ' : '') + SCOPE_NAME + ' ' + scope);
5638 }
5639 }
5640 }
5641 }
5642 },
5643 elementStyles: function (element, callback) {
5644 var styles = element._styles;
5645 var cssText = '';
5646 var cssBuildType = element.__cssBuild;
5647 for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
5648 var rules = styleUtil.rulesForStyle(s);
5649 cssText += settings.useNativeShadow || cssBuildType === 'shady' ? styleUtil.toCs sText(rules, callback) : this.css(rules, element.is, element.extends, callback, element._scopeCssViaAttr) + '\n\n';
5650 }
5651 return cssText.trim();
5652 },
5653 css: function (rules, scope, ext, callback, useAttr) {
5654 var hostScope = this._calcHostScope(scope, ext);
5655 scope = this._calcElementScope(scope, useAttr);
5656 var self = this;
5657 return styleUtil.toCssText(rules, function (rule) {
5658 if (!rule.isScoped) {
5659 self.rule(rule, scope, hostScope);
5660 rule.isScoped = true;
5661 }
5662 if (callback) {
5663 callback(rule, scope, hostScope);
5664 }
5665 });
5666 },
5667 _calcElementScope: function (scope, useAttr) {
5668 if (scope) {
5669 return useAttr ? CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX : CSS_CLASS_PREFIX + scope;
5670 } else {
5671 return '';
5672 }
5673 },
5674 _calcHostScope: function (scope, ext) {
5675 return ext ? '[is=' + scope + ']' : scope;
5676 },
5677 rule: function (rule, scope, hostScope) {
5678 this._transformRule(rule, this._transformComplexSelector, scope, hostScope);
5679 },
5680 _transformRule: function (rule, transformer, scope, hostScope) {
5681 rule.selector = rule.transformedSelector = this._transformRuleCss(rule, transfor mer, scope, hostScope);
5682 },
5683 _transformRuleCss: function (rule, transformer, scope, hostScope) {
5684 var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);
5685 if (!styleUtil.isKeyframesSelector(rule)) {
5686 for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) {
5687 p$[i] = transformer.call(this, p, scope, hostScope);
5688 }
5689 }
5690 return p$.join(COMPLEX_SELECTOR_SEP);
5691 },
5692 _transformComplexSelector: function (selector, scope, hostScope) {
5693 var stop = false;
5694 var hostContext = false;
5695 var self = this;
5696 selector = selector.trim();
5697 selector = selector.replace(CONTENT_START, HOST + ' $1');
5698 selector = selector.replace(SIMPLE_SELECTOR_SEP, function (m, c, s) {
5699 if (!stop) {
5700 var info = self._transformCompoundSelector(s, c, scope, hostScope);
5701 stop = stop || info.stop;
5702 hostContext = hostContext || info.hostContext;
5703 c = info.combinator;
5704 s = info.value;
5705 } else {
5706 s = s.replace(SCOPE_JUMP, ' ');
5707 }
5708 return c + s;
5709 });
5710 if (hostContext) {
5711 selector = selector.replace(HOST_CONTEXT_PAREN, function (m, pre, paren, post) {
5712 return pre + paren + ' ' + hostScope + post + COMPLEX_SELECTOR_SEP + ' ' + pre + hostScope + paren + post;
5713 });
5714 }
5715 return selector;
5716 },
5717 _transformCompoundSelector: function (selector, combinator, scope, hostScope) {
5718 var jumpIndex = selector.search(SCOPE_JUMP);
5719 var hostContext = false;
5720 if (selector.indexOf(HOST_CONTEXT) >= 0) {
5721 hostContext = true;
5722 } else if (selector.indexOf(HOST) >= 0) {
5723 selector = this._transformHostSelector(selector, hostScope);
5724 } else if (jumpIndex !== 0) {
5725 selector = scope ? this._transformSimpleSelector(selector, scope) : selector;
5726 }
5727 if (selector.indexOf(CONTENT) >= 0) {
5728 combinator = '';
5729 }
5730 var stop;
5731 if (jumpIndex >= 0) {
5732 selector = selector.replace(SCOPE_JUMP, ' ');
5733 stop = true;
5734 }
5735 return {
5736 value: selector,
5737 combinator: combinator,
5738 stop: stop,
5739 hostContext: hostContext
5740 };
5741 },
5742 _transformSimpleSelector: function (selector, scope) {
5743 var p$ = selector.split(PSEUDO_PREFIX);
5744 p$[0] += scope;
5745 return p$.join(PSEUDO_PREFIX);
5746 },
5747 _transformHostSelector: function (selector, hostScope) {
5748 var m = selector.match(HOST_PAREN);
5749 var paren = m && m[2].trim() || '';
5750 if (paren) {
5751 if (!paren[0].match(SIMPLE_SELECTOR_PREFIX)) {
5752 var typeSelector = paren.split(SIMPLE_SELECTOR_PREFIX)[0];
5753 if (typeSelector === hostScope) {
5754 return paren;
5755 } else {
5756 return SELECTOR_NO_MATCH;
5757 }
5758 } else {
5759 return selector.replace(HOST_PAREN, function (m, host, paren) {
5760 return hostScope + paren;
5761 });
5762 }
5763 } else {
5764 return selector.replace(HOST, hostScope);
5765 }
5766 },
5767 documentRule: function (rule) {
5768 rule.selector = rule.parsedSelector;
5769 this.normalizeRootSelector(rule);
5770 if (!settings.useNativeShadow) {
5771 this._transformRule(rule, this._transformDocumentSelector);
5772 }
5773 },
5774 normalizeRootSelector: function (rule) {
5775 if (rule.selector === ROOT) {
5776 rule.selector = 'html';
5777 }
5778 },
5779 _transformDocumentSelector: function (selector) {
5780 return selector.match(SCOPE_JUMP) ? this._transformComplexSelector(selector, SCO PE_DOC_SELECTOR) : this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELE CTOR);
5781 },
5782 SCOPE_NAME: 'style-scope'
5783 };
5784 var SCOPE_NAME = api.SCOPE_NAME;
5785 var SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' + ':not(.' + SCOPE_NAME + ')';
5786 var COMPLEX_SELECTOR_SEP = ',';
5787 var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)((?:\[.+?\]|[^\s>+~=\[])+)/g;
5788 var SIMPLE_SELECTOR_PREFIX = /[[.:#*]/;
5789 var HOST = ':host';
5790 var ROOT = ':root';
5791 var HOST_PAREN = /(:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/;
5792 var HOST_CONTEXT = ':host-context';
5793 var HOST_CONTEXT_PAREN = /(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\)) (.*)/;
5794 var CONTENT = '::content';
5795 var SCOPE_JUMP = /::content|::shadow|\/deep\//;
5796 var CSS_CLASS_PREFIX = '.';
5797 var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';
5798 var CSS_ATTR_SUFFIX = ']';
5799 var PSEUDO_PREFIX = ':';
5800 var CLASS = 'class';
5801 var CONTENT_START = new RegExp('^(' + CONTENT + ')');
5802 var SELECTOR_NO_MATCH = 'should_not_match';
5803 return api;
5804 }();Polymer.StyleExtends = function () {
5805 var styleUtil = Polymer.StyleUtil;
5806 return {
5807 hasExtends: function (cssText) {
5808 return Boolean(cssText.match(this.rx.EXTEND));
5809 },
5810 transform: function (style) {
5811 var rules = styleUtil.rulesForStyle(style);
5812 var self = this;
5813 styleUtil.forEachRule(rules, function (rule) {
5814 self._mapRuleOntoParent(rule);
5815 if (rule.parent) {
5816 var m;
5817 while (m = self.rx.EXTEND.exec(rule.cssText)) {
5818 var extend = m[1];
5819 var extendor = self._findExtendor(extend, rule);
5820 if (extendor) {
5821 self._extendRule(rule, extendor);
5822 }
5823 }
5824 }
5825 rule.cssText = rule.cssText.replace(self.rx.EXTEND, '');
5826 });
5827 return styleUtil.toCssText(rules, function (rule) {
5828 if (rule.selector.match(self.rx.STRIP)) {
5829 rule.cssText = '';
5830 }
5831 }, true);
5832 },
5833 _mapRuleOntoParent: function (rule) {
5834 if (rule.parent) {
5835 var map = rule.parent.map || (rule.parent.map = {});
5836 var parts = rule.selector.split(',');
5837 for (var i = 0, p; i < parts.length; i++) {
5838 p = parts[i];
5839 map[p.trim()] = rule;
5840 }
5841 return map;
5842 }
5843 },
5844 _findExtendor: function (extend, rule) {
5845 return rule.parent && rule.parent.map && rule.parent.map[extend] || this._findEx tendor(extend, rule.parent);
5846 },
5847 _extendRule: function (target, source) {
5848 if (target.parent !== source.parent) {
5849 this._cloneAndAddRuleToParent(source, target.parent);
5850 }
5851 target.extends = target.extends || [];
5852 target.extends.push(source);
5853 source.selector = source.selector.replace(this.rx.STRIP, '');
5854 source.selector = (source.selector && source.selector + ',\n') + target.selector ;
5855 if (source.extends) {
5856 source.extends.forEach(function (e) {
5857 this._extendRule(target, e);
5858 }, this);
5859 }
5860 },
5861 _cloneAndAddRuleToParent: function (rule, parent) {
5862 rule = Object.create(rule);
5863 rule.parent = parent;
5864 if (rule.extends) {
5865 rule.extends = rule.extends.slice();
5866 }
5867 parent.rules.push(rule);
5868 },
5869 rx: {
5870 EXTEND: /@extends\(([^)]*)\)\s*?;/gim,
5871 STRIP: /%[^,]*$/
5872 }
5873 };
5874 }();Polymer.ApplyShim = function () {
5875 'use strict';
5876 var styleUtil = Polymer.StyleUtil;
5877 var MIXIN_MATCH = styleUtil.rx.MIXIN_MATCH;
5878 var VAR_ASSIGN = styleUtil.rx.VAR_ASSIGN;
5879 var VAR_MATCH = styleUtil.rx.VAR_MATCH;
5880 var APPLY_NAME_CLEAN = /;\s*/m;
5881 var MIXIN_VAR_SEP = '_-_';
5882 var mixinMap = {};
5883 function mapSet(name, prop) {
5884 name = name.trim();
5885 mixinMap[name] = prop;
5886 }
5887 function mapGet(name) {
5888 name = name.trim();
5889 return mixinMap[name];
5890 }
5891 function cssTextToMap(text) {
5892 var props = text.split(';');
5893 var out = {};
5894 for (var i = 0, p, sp; i < props.length; i++) {
5895 p = props[i];
5896 if (p) {
5897 sp = p.split(':');
5898 if (sp.length > 1) {
5899 out[sp[0].trim()] = sp.slice(1).join(':');
5900 }
5901 }
5902 }
5903 return out;
5904 }
5905 function produceCssProperties(matchText, propertyName, valueProperty, valueMixin ) {
5906 if (valueProperty) {
5907 VAR_MATCH.lastIndex = 0;
5908 var m = VAR_MATCH.exec(valueProperty);
5909 if (m) {
5910 var value = m[2];
5911 if (mapGet(value)) {
5912 valueMixin = '@apply ' + value + ';';
5913 }
5914 }
5915 }
5916 if (!valueMixin) {
5917 return matchText;
5918 }
5919 var mixinAsProperties = consumeCssProperties(valueMixin);
5920 var prefix = matchText.slice(0, matchText.indexOf('--'));
5921 var mixinValues = cssTextToMap(mixinAsProperties);
5922 var oldProperties = mapGet(propertyName);
5923 var combinedProps = mixinValues;
5924 if (oldProperties) {
5925 combinedProps = Polymer.Base.mixin(oldProperties, mixinValues);
5926 } else {
5927 mapSet(propertyName, combinedProps);
5928 }
5929 var out = [];
5930 var p, v;
5931 for (p in combinedProps) {
5932 v = mixinValues[p];
5933 if (v === undefined) {
5934 v = 'initial';
5935 }
5936 out.push(propertyName + MIXIN_VAR_SEP + p + ': ' + v);
5937 }
5938 return prefix + out.join('; ') + ';';
5939 }
5940 function fixVars(matchText, prefix, value, fallback) {
5941 if (!fallback || fallback.indexOf('--') !== 0) {
5942 return matchText;
5943 }
5944 return [
5945 prefix,
5946 'var(',
5947 value,
5948 ', var(',
5949 fallback,
5950 '));'
5951 ].join('');
5952 }
5953 function atApplyToCssProperties(mixinName, fallbacks) {
5954 mixinName = mixinName.replace(APPLY_NAME_CLEAN, '');
5955 var vars = [];
5956 var mixinProperties = mapGet(mixinName);
5957 if (mixinProperties) {
5958 var p, parts, f;
5959 for (p in mixinProperties) {
5960 f = fallbacks && fallbacks[p];
5961 parts = [
5962 p,
5963 ': var(',
5964 mixinName,
5965 MIXIN_VAR_SEP,
5966 p
5967 ];
5968 if (f) {
5969 parts.push(',', f);
5970 }
5971 parts.push(')');
5972 vars.push(parts.join(''));
5973 }
5974 }
5975 return vars.join('; ');
5976 }
5977 function consumeCssProperties(text) {
5978 var m;
5979 while (m = MIXIN_MATCH.exec(text)) {
5980 var matchText = m[0];
5981 var mixinName = m[1];
5982 var idx = m.index;
5983 var applyPos = idx + matchText.indexOf('@apply');
5984 var afterApplyPos = idx + matchText.length;
5985 var textBeforeApply = text.slice(0, applyPos);
5986 var textAfterApply = text.slice(afterApplyPos);
5987 var defaults = cssTextToMap(textBeforeApply);
5988 var replacement = atApplyToCssProperties(mixinName, defaults);
5989 text = [
5990 textBeforeApply,
5991 replacement,
5992 textAfterApply
5993 ].join('');
5994 MIXIN_MATCH.lastIndex = idx + replacement.length;
5995 }
5996 return text;
5997 }
5998 var ApplyShim = {
5999 _map: mixinMap,
6000 _separator: MIXIN_VAR_SEP,
6001 transform: function (styles) {
6002 styleUtil.forRulesInStyles(styles, this._boundTransformRule);
6003 },
6004 transformRule: function (rule) {
6005 rule.cssText = this.transformCssText(rule.parsedCssText);
6006 if (rule.selector === ':root') {
6007 rule.selector = ':host > *';
6008 }
6009 },
6010 transformCssText: function (cssText) {
6011 cssText = cssText.replace(VAR_MATCH, fixVars);
6012 cssText = cssText.replace(VAR_ASSIGN, produceCssProperties);
6013 return consumeCssProperties(cssText);
6014 }
6015 };
6016 ApplyShim._boundTransformRule = ApplyShim.transformRule.bind(ApplyShim);
6017 return ApplyShim;
6018 }();(function () {
6019 var prepElement = Polymer.Base._prepElement;
6020 var nativeShadow = Polymer.Settings.useNativeShadow;
6021 var styleUtil = Polymer.StyleUtil;
6022 var styleTransformer = Polymer.StyleTransformer;
6023 var styleExtends = Polymer.StyleExtends;
6024 var applyShim = Polymer.ApplyShim;
6025 var settings = Polymer.Settings;
6026 Polymer.Base._addFeature({
6027 _prepElement: function (element) {
6028 if (this._encapsulateStyle && this.__cssBuild !== 'shady') {
6029 styleTransformer.element(element, this.is, this._scopeCssViaAttr);
6030 }
6031 prepElement.call(this, element);
6032 },
6033 _prepStyles: function () {
6034 if (this._encapsulateStyle === undefined) {
6035 this._encapsulateStyle = !nativeShadow;
6036 }
6037 if (!nativeShadow) {
6038 this._scopeStyle = styleUtil.applyStylePlaceHolder(this.is);
6039 }
6040 this.__cssBuild = styleUtil.cssBuildTypeForModule(this.is);
6041 },
6042 _prepShimStyles: function () {
6043 if (this._template) {
6044 var hasTargetedCssBuild = styleUtil.isTargetedBuild(this.__cssBuild);
6045 if (settings.useNativeCSSProperties && this.__cssBuild === 'shadow' && hasTarget edCssBuild) {
6046 return;
6047 }
6048 this._styles = this._styles || this._collectStyles();
6049 if (settings.useNativeCSSProperties && !this.__cssBuild) {
6050 applyShim.transform(this._styles);
6051 }
6052 var cssText = settings.useNativeCSSProperties && hasTargetedCssBuild ? this._sty les.length && this._styles[0].textContent.trim() : styleTransformer.elementStyle s(this);
6053 this._prepStyleProperties();
6054 if (!this._needsStyleProperties() && cssText) {
6055 styleUtil.applyCss(cssText, this.is, nativeShadow ? this._template.content : nul l, this._scopeStyle);
6056 }
6057 } else {
6058 this._styles = [];
6059 }
6060 },
6061 _collectStyles: function () {
6062 var styles = [];
6063 var cssText = '', m$ = this.styleModules;
6064 if (m$) {
6065 for (var i = 0, l = m$.length, m; i < l && (m = m$[i]); i++) {
6066 cssText += styleUtil.cssFromModule(m);
6067 }
6068 }
6069 cssText += styleUtil.cssFromModule(this.is);
6070 var p = this._template && this._template.parentNode;
6071 if (this._template && (!p || p.id.toLowerCase() !== this.is)) {
6072 cssText += styleUtil.cssFromElement(this._template);
6073 }
6074 if (cssText) {
6075 var style = document.createElement('style');
6076 style.textContent = cssText;
6077 if (styleExtends.hasExtends(style.textContent)) {
6078 cssText = styleExtends.transform(style);
6079 }
6080 styles.push(style);
6081 }
6082 return styles;
6083 },
6084 _elementAdd: function (node) {
6085 if (this._encapsulateStyle) {
6086 if (node.__styleScoped) {
6087 node.__styleScoped = false;
6088 } else {
6089 styleTransformer.dom(node, this.is, this._scopeCssViaAttr);
6090 }
6091 }
6092 },
6093 _elementRemove: function (node) {
6094 if (this._encapsulateStyle) {
6095 styleTransformer.dom(node, this.is, this._scopeCssViaAttr, true);
6096 }
6097 },
6098 scopeSubtree: function (container, shouldObserve) {
6099 if (nativeShadow) {
6100 return;
6101 }
6102 var self = this;
6103 var scopify = function (node) {
6104 if (node.nodeType === Node.ELEMENT_NODE) {
6105 var className = node.getAttribute('class');
6106 node.setAttribute('class', self._scopeElementClass(node, className));
6107 var n$ = node.querySelectorAll('*');
6108 for (var i = 0, n; i < n$.length && (n = n$[i]); i++) {
6109 className = n.getAttribute('class');
6110 n.setAttribute('class', self._scopeElementClass(n, className));
6111 }
6112 }
6113 };
6114 scopify(container);
6115 if (shouldObserve) {
6116 var mo = new MutationObserver(function (mxns) {
6117 for (var i = 0, m; i < mxns.length && (m = mxns[i]); i++) {
6118 if (m.addedNodes) {
6119 for (var j = 0; j < m.addedNodes.length; j++) {
6120 scopify(m.addedNodes[j]);
6121 }
6122 }
6123 }
6124 });
6125 mo.observe(container, {
6126 childList: true,
6127 subtree: true
6128 });
6129 return mo;
6130 }
6131 }
6132 });
6133 }());Polymer.StyleProperties = function () {
6134 'use strict';
6135 var matchesSelector = Polymer.DomApi.matchesSelector;
6136 var styleUtil = Polymer.StyleUtil;
6137 var styleTransformer = Polymer.StyleTransformer;
6138 var settings = Polymer.Settings;
6139 return {
6140 decorateStyles: function (styles, scope) {
6141 var self = this, props = {}, keyframes = [], ruleIndex = 0;
6142 var scopeSelector = styleTransformer._calcHostScope(scope.is, scope.extends);
6143 styleUtil.forRulesInStyles(styles, function (rule, style) {
6144 self.decorateRule(rule);
6145 rule.index = ruleIndex++;
6146 self.whenHostOrRootRule(scope, rule, style, function (info) {
6147 if (rule.parent.type === styleUtil.ruleTypes.MEDIA_RULE) {
6148 scope.__notStyleScopeCacheable = true;
6149 }
6150 if (info.isHost) {
6151 var hostContextOrFunction = info.selector.split(' ').some(function (s) {
6152 return s.indexOf(scopeSelector) === 0 && s.length !== scopeSelector.length;
6153 });
6154 scope.__notStyleScopeCacheable = scope.__notStyleScopeCacheable || hostContextOr Function;
6155 }
6156 });
6157 self.collectPropertiesInCssText(rule.propertyInfo.cssText, props);
6158 }, function onKeyframesRule(rule) {
6159 keyframes.push(rule);
6160 });
6161 styles._keyframes = keyframes;
6162 var names = [];
6163 for (var i in props) {
6164 names.push(i);
6165 }
6166 return names;
6167 },
6168 decorateRule: function (rule) {
6169 if (rule.propertyInfo) {
6170 return rule.propertyInfo;
6171 }
6172 var info = {}, properties = {};
6173 var hasProperties = this.collectProperties(rule, properties);
6174 if (hasProperties) {
6175 info.properties = properties;
6176 rule.rules = null;
6177 }
6178 info.cssText = this.collectCssText(rule);
6179 rule.propertyInfo = info;
6180 return info;
6181 },
6182 collectProperties: function (rule, properties) {
6183 var info = rule.propertyInfo;
6184 if (info) {
6185 if (info.properties) {
6186 Polymer.Base.mixin(properties, info.properties);
6187 return true;
6188 }
6189 } else {
6190 var m, rx = this.rx.VAR_ASSIGN;
6191 var cssText = rule.parsedCssText;
6192 var any;
6193 while (m = rx.exec(cssText)) {
6194 properties[m[1].trim()] = (m[2] || m[3]).trim();
6195 any = true;
6196 }
6197 return any;
6198 }
6199 },
6200 collectCssText: function (rule) {
6201 return this.collectConsumingCssText(rule.parsedCssText);
6202 },
6203 collectConsumingCssText: function (cssText) {
6204 return cssText.replace(this.rx.BRACKETED, '').replace(this.rx.VAR_ASSIGN, '');
6205 },
6206 collectPropertiesInCssText: function (cssText, props) {
6207 var m;
6208 while (m = this.rx.VAR_CONSUMED.exec(cssText)) {
6209 var name = m[1];
6210 if (m[2] !== ':') {
6211 props[name] = true;
6212 }
6213 }
6214 },
6215 reify: function (props) {
6216 var names = Object.getOwnPropertyNames(props);
6217 for (var i = 0, n; i < names.length; i++) {
6218 n = names[i];
6219 props[n] = this.valueForProperty(props[n], props);
6220 }
6221 },
6222 valueForProperty: function (property, props) {
6223 if (property) {
6224 if (property.indexOf(';') >= 0) {
6225 property = this.valueForProperties(property, props);
6226 } else {
6227 var self = this;
6228 var fn = function (all, prefix, value, fallback) {
6229 var propertyValue = self.valueForProperty(props[value], props) || self.valueForP roperty(props[fallback] || fallback, props) || fallback;
6230 return prefix + (propertyValue || '');
6231 };
6232 property = property.replace(this.rx.VAR_MATCH, fn);
6233 }
6234 }
6235 return property && property.trim() || '';
6236 },
6237 valueForProperties: function (property, props) {
6238 var parts = property.split(';');
6239 for (var i = 0, p, m; i < parts.length; i++) {
6240 if (p = parts[i]) {
6241 this.rx.MIXIN_MATCH.lastIndex = 0;
6242 m = this.rx.MIXIN_MATCH.exec(p);
6243 if (m) {
6244 p = this.valueForProperty(props[m[1]], props);
6245 } else {
6246 var colon = p.indexOf(':');
6247 if (colon !== -1) {
6248 var pp = p.substring(colon);
6249 pp = pp.trim();
6250 pp = this.valueForProperty(pp, props) || pp;
6251 p = p.substring(0, colon) + pp;
6252 }
6253 }
6254 parts[i] = p && p.lastIndexOf(';') === p.length - 1 ? p.slice(0, -1) : p || '';
6255 }
6256 }
6257 return parts.join(';');
6258 },
6259 applyProperties: function (rule, props) {
6260 var output = '';
6261 if (!rule.propertyInfo) {
6262 this.decorateRule(rule);
6263 }
6264 if (rule.propertyInfo.cssText) {
6265 output = this.valueForProperties(rule.propertyInfo.cssText, props);
6266 }
6267 rule.cssText = output;
6268 },
6269 applyKeyframeTransforms: function (rule, keyframeTransforms) {
6270 var input = rule.cssText;
6271 var output = rule.cssText;
6272 if (rule.hasAnimations == null) {
6273 rule.hasAnimations = this.rx.ANIMATION_MATCH.test(input);
6274 }
6275 if (rule.hasAnimations) {
6276 var transform;
6277 if (rule.keyframeNamesToTransform == null) {
6278 rule.keyframeNamesToTransform = [];
6279 for (var keyframe in keyframeTransforms) {
6280 transform = keyframeTransforms[keyframe];
6281 output = transform(input);
6282 if (input !== output) {
6283 input = output;
6284 rule.keyframeNamesToTransform.push(keyframe);
6285 }
6286 }
6287 } else {
6288 for (var i = 0; i < rule.keyframeNamesToTransform.length; ++i) {
6289 transform = keyframeTransforms[rule.keyframeNamesToTransform[i]];
6290 input = transform(input);
6291 }
6292 output = input;
6293 }
6294 }
6295 rule.cssText = output;
6296 },
6297 propertyDataFromStyles: function (styles, element) {
6298 var props = {}, self = this;
6299 var o = [];
6300 styleUtil.forActiveRulesInStyles(styles, function (rule) {
6301 if (!rule.propertyInfo) {
6302 self.decorateRule(rule);
6303 }
6304 var selectorToMatch = rule.transformedSelector || rule.parsedSelector;
6305 if (element && rule.propertyInfo.properties && selectorToMatch) {
6306 if (matchesSelector.call(element, selectorToMatch)) {
6307 self.collectProperties(rule, props);
6308 addToBitMask(rule.index, o);
6309 }
6310 }
6311 });
6312 return {
6313 properties: props,
6314 key: o
6315 };
6316 },
6317 whenHostOrRootRule: function (scope, rule, style, callback) {
6318 if (!rule.propertyInfo) {
6319 self.decorateRule(rule);
6320 }
6321 if (!rule.propertyInfo.properties) {
6322 return;
6323 }
6324 var hostScope = scope.is ? styleTransformer._calcHostScope(scope.is, scope.exten ds) : 'html';
6325 var parsedSelector = rule.parsedSelector;
6326 var isRoot = parsedSelector === ':root';
6327 var isHost = parsedSelector.indexOf(':host') === 0;
6328 var cssBuild = scope.__cssBuild || style.__cssBuild;
6329 if (cssBuild === 'shady') {
6330 isRoot = parsedSelector === hostScope + '> *.' + hostScope || parsedSelector.ind exOf('html') !== -1;
6331 isHost = !isRoot && parsedSelector.indexOf(hostScope) === 0;
6332 }
6333 if (cssBuild === 'shadow') {
6334 isRoot = parsedSelector === ':host > *' || parsedSelector === 'html';
6335 isHost = isHost && !isRoot;
6336 }
6337 if (!isRoot && !isHost) {
6338 return;
6339 }
6340 var selectorToMatch = hostScope;
6341 if (isHost) {
6342 if (settings.useNativeShadow && !rule.transformedSelector) {
6343 rule.transformedSelector = styleTransformer._transformRuleCss(rule, styleTransfo rmer._transformComplexSelector, scope.is, hostScope);
6344 }
6345 selectorToMatch = rule.transformedSelector || hostScope;
6346 }
6347 callback({
6348 selector: selectorToMatch,
6349 isHost: isHost,
6350 isRoot: isRoot
6351 });
6352 },
6353 hostAndRootPropertiesForScope: function (scope) {
6354 var hostProps = {}, rootProps = {}, self = this;
6355 styleUtil.forActiveRulesInStyles(scope._styles, function (rule, style) {
6356 self.whenHostOrRootRule(scope, rule, style, function (info) {
6357 var element = scope._element || scope;
6358 if (matchesSelector.call(element, info.selector)) {
6359 if (info.isHost) {
6360 self.collectProperties(rule, hostProps);
6361 } else {
6362 self.collectProperties(rule, rootProps);
6363 }
6364 }
6365 });
6366 });
6367 return {
6368 rootProps: rootProps,
6369 hostProps: hostProps
6370 };
6371 },
6372 transformStyles: function (element, properties, scopeSelector) {
6373 var self = this;
6374 var hostSelector = styleTransformer._calcHostScope(element.is, element.extends);
6375 var rxHostSelector = element.extends ? '\\' + hostSelector.slice(0, -1) + '\\]' : hostSelector;
6376 var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector + this.rx.HOST_SUFF IX);
6377 var keyframeTransforms = this._elementKeyframeTransforms(element, scopeSelector) ;
6378 return styleTransformer.elementStyles(element, function (rule) {
6379 self.applyProperties(rule, properties);
6380 if (!settings.useNativeShadow && !Polymer.StyleUtil.isKeyframesSelector(rule) && rule.cssText) {
6381 self.applyKeyframeTransforms(rule, keyframeTransforms);
6382 self._scopeSelector(rule, hostRx, hostSelector, element._scopeCssViaAttr, scopeS elector);
6383 }
6384 });
6385 },
6386 _elementKeyframeTransforms: function (element, scopeSelector) {
6387 var keyframesRules = element._styles._keyframes;
6388 var keyframeTransforms = {};
6389 if (!settings.useNativeShadow && keyframesRules) {
6390 for (var i = 0, keyframesRule = keyframesRules[i]; i < keyframesRules.length; ke yframesRule = keyframesRules[++i]) {
6391 this._scopeKeyframes(keyframesRule, scopeSelector);
6392 keyframeTransforms[keyframesRule.keyframesName] = this._keyframesRuleTransformer (keyframesRule);
6393 }
6394 }
6395 return keyframeTransforms;
6396 },
6397 _keyframesRuleTransformer: function (keyframesRule) {
6398 return function (cssText) {
6399 return cssText.replace(keyframesRule.keyframesNameRx, keyframesRule.transformedK eyframesName);
6400 };
6401 },
6402 _scopeKeyframes: function (rule, scopeId) {
6403 rule.keyframesNameRx = new RegExp(rule.keyframesName, 'g');
6404 rule.transformedKeyframesName = rule.keyframesName + '-' + scopeId;
6405 rule.transformedSelector = rule.transformedSelector || rule.selector;
6406 rule.selector = rule.transformedSelector.replace(rule.keyframesName, rule.transf ormedKeyframesName);
6407 },
6408 _scopeSelector: function (rule, hostRx, hostSelector, viaAttr, scopeId) {
6409 rule.transformedSelector = rule.transformedSelector || rule.selector;
6410 var selector = rule.transformedSelector;
6411 var scope = viaAttr ? '[' + styleTransformer.SCOPE_NAME + '~=' + scopeId + ']' : '.' + scopeId;
6412 var parts = selector.split(',');
6413 for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {
6414 parts[i] = p.match(hostRx) ? p.replace(hostSelector, scope) : scope + ' ' + p;
6415 }
6416 rule.selector = parts.join(',');
6417 },
6418 applyElementScopeSelector: function (element, selector, old, viaAttr) {
6419 var c = viaAttr ? element.getAttribute(styleTransformer.SCOPE_NAME) : element.ge tAttribute('class') || '';
6420 var v = old ? c.replace(old, selector) : (c ? c + ' ' : '') + this.XSCOPE_NAME + ' ' + selector;
6421 if (c !== v) {
6422 if (viaAttr) {
6423 element.setAttribute(styleTransformer.SCOPE_NAME, v);
6424 } else {
6425 element.setAttribute('class', v);
6426 }
6427 }
6428 },
6429 applyElementStyle: function (element, properties, selector, style) {
6430 var cssText = style ? style.textContent || '' : this.transformStyles(element, pr operties, selector);
6431 var s = element._customStyle;
6432 if (s && !settings.useNativeShadow && s !== style) {
6433 s._useCount--;
6434 if (s._useCount <= 0 && s.parentNode) {
6435 s.parentNode.removeChild(s);
6436 }
6437 }
6438 if (settings.useNativeShadow) {
6439 if (element._customStyle) {
6440 element._customStyle.textContent = cssText;
6441 style = element._customStyle;
6442 } else if (cssText) {
6443 style = styleUtil.applyCss(cssText, selector, element.root, element._scopeStyle) ;
6444 }
6445 } else {
6446 if (!style) {
6447 if (cssText) {
6448 style = styleUtil.applyCss(cssText, selector, null, element._scopeStyle);
6449 }
6450 } else if (!style.parentNode) {
6451 styleUtil.applyStyle(style, null, element._scopeStyle);
6452 }
6453 }
6454 if (style) {
6455 style._useCount = style._useCount || 0;
6456 if (element._customStyle != style) {
6457 style._useCount++;
6458 }
6459 element._customStyle = style;
6460 }
6461 return style;
6462 },
6463 mixinCustomStyle: function (props, customStyle) {
6464 var v;
6465 for (var i in customStyle) {
6466 v = customStyle[i];
6467 if (v || v === 0) {
6468 props[i] = v;
6469 }
6470 }
6471 },
6472 updateNativeStyleProperties: function (element, properties) {
6473 for (var i = 0; i < element.style.length; i++) {
6474 element.style.removeProperty(element.style[i]);
6475 }
6476 for (var p in properties) {
6477 if (properties[p] !== null) {
6478 element.style.setProperty(p, properties[p]);
6479 }
6480 }
6481 },
6482 rx: styleUtil.rx,
6483 XSCOPE_NAME: 'x-scope'
6484 };
6485 function addToBitMask(n, bits) {
6486 var o = parseInt(n / 32);
6487 var v = 1 << n % 32;
6488 bits[o] = (bits[o] || 0) | v;
6489 }
6490 }();(function () {
6491 Polymer.StyleCache = function () {
6492 this.cache = {};
6493 };
6494 Polymer.StyleCache.prototype = {
6495 MAX: 100,
6496 store: function (is, data, keyValues, keyStyles) {
6497 data.keyValues = keyValues;
6498 data.styles = keyStyles;
6499 var s$ = this.cache[is] = this.cache[is] || [];
6500 s$.push(data);
6501 if (s$.length > this.MAX) {
6502 s$.shift();
6503 }
6504 },
6505 retrieve: function (is, keyValues, keyStyles) {
6506 var cache = this.cache[is];
6507 if (cache) {
6508 for (var i = cache.length - 1, data; i >= 0; i--) {
6509 data = cache[i];
6510 if (keyStyles === data.styles && this._objectsEqual(keyValues, data.keyValues)) {
6511 return data;
6512 }
6513 }
6514 }
6515 },
6516 clear: function () {
6517 this.cache = {};
6518 },
6519 _objectsEqual: function (target, source) {
6520 var t, s;
6521 for (var i in target) {
6522 t = target[i], s = source[i];
6523 if (!(typeof t === 'object' && t ? this._objectsStrictlyEqual(t, s) : t === s)) {
6524 return false;
6525 }
6526 }
6527 if (Array.isArray(target)) {
6528 return target.length === source.length;
6529 }
6530 return true;
6531 },
6532 _objectsStrictlyEqual: function (target, source) {
6533 return this._objectsEqual(target, source) && this._objectsEqual(source, target);
6534 }
6535 };
6536 }());Polymer.StyleDefaults = function () {
6537 var styleProperties = Polymer.StyleProperties;
6538 var StyleCache = Polymer.StyleCache;
6539 var nativeVariables = Polymer.Settings.useNativeCSSProperties;
6540 var api = {
6541 _styles: [],
6542 _properties: null,
6543 customStyle: {},
6544 _styleCache: new StyleCache(),
6545 _element: Polymer.DomApi.wrap(document.documentElement),
6546 addStyle: function (style) {
6547 this._styles.push(style);
6548 this._properties = null;
6549 },
6550 get _styleProperties() {
6551 if (!this._properties) {
6552 styleProperties.decorateStyles(this._styles, this);
6553 this._styles._scopeStyleProperties = null;
6554 this._properties = styleProperties.hostAndRootPropertiesForScope(this).rootProps ;
6555 styleProperties.mixinCustomStyle(this._properties, this.customStyle);
6556 styleProperties.reify(this._properties);
6557 }
6558 return this._properties;
6559 },
6560 hasStyleProperties: function () {
6561 return Boolean(this._properties);
6562 },
6563 _needsStyleProperties: function () {
6564 },
6565 _computeStyleProperties: function () {
6566 return this._styleProperties;
6567 },
6568 updateStyles: function (properties) {
6569 this._properties = null;
6570 if (properties) {
6571 Polymer.Base.mixin(this.customStyle, properties);
6572 }
6573 this._styleCache.clear();
6574 for (var i = 0, s; i < this._styles.length; i++) {
6575 s = this._styles[i];
6576 s = s.__importElement || s;
6577 s._apply();
6578 }
6579 if (nativeVariables) {
6580 styleProperties.updateNativeStyleProperties(document.documentElement, this.custo mStyle);
6581 }
6582 }
6583 };
6584 return api;
6585 }();(function () {
6586 'use strict';
6587 var serializeValueToAttribute = Polymer.Base.serializeValueToAttribute;
6588 var propertyUtils = Polymer.StyleProperties;
6589 var styleTransformer = Polymer.StyleTransformer;
6590 var styleDefaults = Polymer.StyleDefaults;
6591 var nativeShadow = Polymer.Settings.useNativeShadow;
6592 var nativeVariables = Polymer.Settings.useNativeCSSProperties;
6593 Polymer.Base._addFeature({
6594 _prepStyleProperties: function () {
6595 if (!nativeVariables) {
6596 this._ownStylePropertyNames = this._styles && this._styles.length ? propertyUtil s.decorateStyles(this._styles, this) : null;
6597 }
6598 },
6599 customStyle: null,
6600 getComputedStyleValue: function (property) {
6601 return !nativeVariables && this._styleProperties && this._styleProperties[proper ty] || getComputedStyle(this).getPropertyValue(property);
6602 },
6603 _setupStyleProperties: function () {
6604 this.customStyle = {};
6605 this._styleCache = null;
6606 this._styleProperties = null;
6607 this._scopeSelector = null;
6608 this._ownStyleProperties = null;
6609 this._customStyle = null;
6610 },
6611 _needsStyleProperties: function () {
6612 return Boolean(!nativeVariables && this._ownStylePropertyNames && this._ownStyle PropertyNames.length);
6613 },
6614 _beforeAttached: function () {
6615 if ((!this._scopeSelector || this.__stylePropertiesInvalid) && this._needsStyleP roperties()) {
6616 this.__stylePropertiesInvalid = false;
6617 this._updateStyleProperties();
6618 }
6619 },
6620 _findStyleHost: function () {
6621 var e = this, root;
6622 while (root = Polymer.dom(e).getOwnerRoot()) {
6623 if (Polymer.isInstance(root.host)) {
6624 return root.host;
6625 }
6626 e = root.host;
6627 }
6628 return styleDefaults;
6629 },
6630 _updateStyleProperties: function () {
6631 var info, scope = this._findStyleHost();
6632 if (!scope._styleCache) {
6633 scope._styleCache = new Polymer.StyleCache();
6634 }
6635 var scopeData = propertyUtils.propertyDataFromStyles(scope._styles, this);
6636 var scopeCacheable = !this.__notStyleScopeCacheable;
6637 if (scopeCacheable) {
6638 scopeData.key.customStyle = this.customStyle;
6639 info = scope._styleCache.retrieve(this.is, scopeData.key, this._styles);
6640 }
6641 var scopeCached = Boolean(info);
6642 if (scopeCached) {
6643 this._styleProperties = info._styleProperties;
6644 } else {
6645 this._computeStyleProperties(scopeData.properties);
6646 }
6647 this._computeOwnStyleProperties();
6648 if (!scopeCached) {
6649 info = styleCache.retrieve(this.is, this._ownStyleProperties, this._styles);
6650 }
6651 var globalCached = Boolean(info) && !scopeCached;
6652 var style = this._applyStyleProperties(info);
6653 if (!scopeCached) {
6654 style = style && nativeShadow ? style.cloneNode(true) : style;
6655 info = {
6656 style: style,
6657 _scopeSelector: this._scopeSelector,
6658 _styleProperties: this._styleProperties
6659 };
6660 if (scopeCacheable) {
6661 scopeData.key.customStyle = {};
6662 this.mixin(scopeData.key.customStyle, this.customStyle);
6663 scope._styleCache.store(this.is, info, scopeData.key, this._styles);
6664 }
6665 if (!globalCached) {
6666 styleCache.store(this.is, Object.create(info), this._ownStyleProperties, this._s tyles);
6667 }
6668 }
6669 },
6670 _computeStyleProperties: function (scopeProps) {
6671 var scope = this._findStyleHost();
6672 if (!scope._styleProperties) {
6673 scope._computeStyleProperties();
6674 }
6675 var props = Object.create(scope._styleProperties);
6676 var hostAndRootProps = propertyUtils.hostAndRootPropertiesForScope(this);
6677 this.mixin(props, hostAndRootProps.hostProps);
6678 scopeProps = scopeProps || propertyUtils.propertyDataFromStyles(scope._styles, t his).properties;
6679 this.mixin(props, scopeProps);
6680 this.mixin(props, hostAndRootProps.rootProps);
6681 propertyUtils.mixinCustomStyle(props, this.customStyle);
6682 propertyUtils.reify(props);
6683 this._styleProperties = props;
6684 },
6685 _computeOwnStyleProperties: function () {
6686 var props = {};
6687 for (var i = 0, n; i < this._ownStylePropertyNames.length; i++) {
6688 n = this._ownStylePropertyNames[i];
6689 props[n] = this._styleProperties[n];
6690 }
6691 this._ownStyleProperties = props;
6692 },
6693 _scopeCount: 0,
6694 _applyStyleProperties: function (info) {
6695 var oldScopeSelector = this._scopeSelector;
6696 this._scopeSelector = info ? info._scopeSelector : this.is + '-' + this.__proto_ _._scopeCount++;
6697 var style = propertyUtils.applyElementStyle(this, this._styleProperties, this._s copeSelector, info && info.style);
6698 if (!nativeShadow) {
6699 propertyUtils.applyElementScopeSelector(this, this._scopeSelector, oldScopeSelec tor, this._scopeCssViaAttr);
6700 }
6701 return style;
6702 },
6703 serializeValueToAttribute: function (value, attribute, node) {
6704 node = node || this;
6705 if (attribute === 'class' && !nativeShadow) {
6706 var host = node === this ? this.domHost || this.dataHost : this;
6707 if (host) {
6708 value = host._scopeElementClass(node, value);
6709 }
6710 }
6711 node = this.shadyRoot && this.shadyRoot._hasDistributed ? Polymer.dom(node) : no de;
6712 serializeValueToAttribute.call(this, value, attribute, node);
6713 },
6714 _scopeElementClass: function (element, selector) {
6715 if (!nativeShadow && !this._scopeCssViaAttr) {
6716 selector = (selector ? selector + ' ' : '') + SCOPE_NAME + ' ' + this.is + (elem ent._scopeSelector ? ' ' + XSCOPE_NAME + ' ' + element._scopeSelector : '');
6717 }
6718 return selector;
6719 },
6720 updateStyles: function (properties) {
6721 if (properties) {
6722 this.mixin(this.customStyle, properties);
6723 }
6724 if (nativeVariables) {
6725 propertyUtils.updateNativeStyleProperties(this, this.customStyle);
6726 } else {
6727 if (this.isAttached) {
6728 if (this._needsStyleProperties()) {
6729 this._updateStyleProperties();
6730 } else {
6731 this._styleProperties = null;
6732 }
6733 } else {
6734 this.__stylePropertiesInvalid = true;
6735 }
6736 if (this._styleCache) {
6737 this._styleCache.clear();
6738 }
6739 this._updateRootStyles();
6740 }
6741 },
6742 _updateRootStyles: function (root) {
6743 root = root || this.root;
6744 var c$ = Polymer.dom(root)._query(function (e) {
6745 return e.shadyRoot || e.shadowRoot;
6746 });
6747 for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
6748 if (c.updateStyles) {
6749 c.updateStyles();
6750 }
6751 }
6752 }
6753 });
6754 Polymer.updateStyles = function (properties) {
6755 styleDefaults.updateStyles(properties);
6756 Polymer.Base._updateRootStyles(document);
6757 };
6758 var styleCache = new Polymer.StyleCache();
6759 Polymer.customStyleCache = styleCache;
6760 var SCOPE_NAME = styleTransformer.SCOPE_NAME;
6761 var XSCOPE_NAME = propertyUtils.XSCOPE_NAME;
6762 }());Polymer.Base._addFeature({
6763 _registerFeatures: function () {
6764 this._prepIs();
6765 this._prepConstructor();
6766 this._prepStyles();
6767 },
6768 _finishRegisterFeatures: function () {
6769 this._prepTemplate();
6770 this._prepShimStyles();
6771 this._prepAnnotations();
6772 this._prepEffects();
6773 this._prepBehaviors();
6774 this._prepPropertyInfo();
6775 this._prepBindings();
6776 this._prepShady();
6777 },
6778 _prepBehavior: function (b) {
6779 this._addPropertyEffects(b.properties);
6780 this._addComplexObserverEffects(b.observers);
6781 this._addHostAttributes(b.hostAttributes);
6782 },
6783 _initFeatures: function () {
6784 this._setupGestures();
6785 this._setupConfigure();
6786 this._setupStyleProperties();
6787 this._setupDebouncers();
6788 this._setupShady();
6789 this._registerHost();
6790 if (this._template) {
6791 this._poolContent();
6792 this._beginHosting();
6793 this._stampTemplate();
6794 this._endHosting();
6795 this._marshalAnnotationReferences();
6796 }
6797 this._marshalInstanceEffects();
6798 this._marshalBehaviors();
6799 this._marshalHostAttributes();
6800 this._marshalAttributes();
6801 this._tryReady();
6802 },
6803 _marshalBehavior: function (b) {
6804 if (b.listeners) {
6805 this._listenListeners(b.listeners);
6806 }
6807 }
6808 });(function () {
6809 var propertyUtils = Polymer.StyleProperties;
6810 var styleUtil = Polymer.StyleUtil;
6811 var cssParse = Polymer.CssParse;
6812 var styleDefaults = Polymer.StyleDefaults;
6813 var styleTransformer = Polymer.StyleTransformer;
6814 var applyShim = Polymer.ApplyShim;
6815 var debounce = Polymer.Debounce;
6816 var settings = Polymer.Settings;
6817 var updateDebouncer;
6818 Polymer({
6819 is: 'custom-style',
6820 extends: 'style',
6821 _template: null,
6822 properties: { include: String },
6823 ready: function () {
6824 this.__appliedElement = this.__appliedElement || this;
6825 this.__cssBuild = styleUtil.getCssBuildType(this);
6826 if (this.__appliedElement !== this) {
6827 this.__appliedElement.__cssBuild = this.__cssBuild;
6828 }
6829 this._tryApply();
6830 },
6831 attached: function () {
6832 this._tryApply();
6833 },
6834 _tryApply: function () {
6835 if (!this._appliesToDocument) {
6836 if (this.parentNode && this.parentNode.localName !== 'dom-module') {
6837 this._appliesToDocument = true;
6838 var e = this.__appliedElement;
6839 if (!settings.useNativeCSSProperties) {
6840 this.__needsUpdateStyles = styleDefaults.hasStyleProperties();
6841 styleDefaults.addStyle(e);
6842 }
6843 if (e.textContent || this.include) {
6844 this._apply(true);
6845 } else {
6846 var self = this;
6847 var observer = new MutationObserver(function () {
6848 observer.disconnect();
6849 self._apply(true);
6850 });
6851 observer.observe(e, { childList: true });
6852 }
6853 }
6854 }
6855 },
6856 _updateStyles: function () {
6857 Polymer.updateStyles();
6858 },
6859 _apply: function (initialApply) {
6860 var e = this.__appliedElement;
6861 if (this.include) {
6862 e.textContent = styleUtil.cssFromModules(this.include, true) + e.textContent;
6863 }
6864 if (!e.textContent) {
6865 return;
6866 }
6867 var buildType = this.__cssBuild;
6868 var targetedBuild = styleUtil.isTargetedBuild(buildType);
6869 if (settings.useNativeCSSProperties && targetedBuild) {
6870 return;
6871 }
6872 var styleRules = styleUtil.rulesForStyle(e);
6873 if (!targetedBuild) {
6874 styleUtil.forEachRule(styleRules, function (rule) {
6875 styleTransformer.documentRule(rule);
6876 if (settings.useNativeCSSProperties && !buildType) {
6877 applyShim.transformRule(rule);
6878 }
6879 });
6880 }
6881 if (settings.useNativeCSSProperties) {
6882 e.textContent = styleUtil.toCssText(styleRules);
6883 } else {
6884 var self = this;
6885 var fn = function fn() {
6886 self._flushCustomProperties();
6887 };
6888 if (initialApply) {
6889 Polymer.RenderStatus.whenReady(fn);
6890 } else {
6891 fn();
6892 }
6893 }
6894 },
6895 _flushCustomProperties: function () {
6896 if (this.__needsUpdateStyles) {
6897 this.__needsUpdateStyles = false;
6898 updateDebouncer = debounce(updateDebouncer, this._updateStyles);
6899 } else {
6900 this._applyCustomProperties();
6901 }
6902 },
6903 _applyCustomProperties: function () {
6904 var element = this.__appliedElement;
6905 this._computeStyleProperties();
6906 var props = this._styleProperties;
6907 var rules = styleUtil.rulesForStyle(element);
6908 if (!rules) {
6909 return;
6910 }
6911 element.textContent = styleUtil.toCssText(rules, function (rule) {
6912 var css = rule.cssText = rule.parsedCssText;
6913 if (rule.propertyInfo && rule.propertyInfo.cssText) {
6914 css = cssParse.removeCustomPropAssignment(css);
6915 rule.cssText = propertyUtils.valueForProperties(css, props);
6916 }
6917 });
6918 }
6919 });
6920 }());Polymer.Templatizer = {
6921 properties: { __hideTemplateChildren__: { observer: '_showHideChildren' } },
6922 _instanceProps: Polymer.nob,
6923 _parentPropPrefix: '_parent_',
6924 templatize: function (template) {
6925 this._templatized = template;
6926 if (!template._content) {
6927 template._content = template.content;
6928 }
6929 if (template._content._ctor) {
6930 this.ctor = template._content._ctor;
6931 this._prepParentProperties(this.ctor.prototype, template);
6932 return;
6933 }
6934 var archetype = Object.create(Polymer.Base);
6935 this._customPrepAnnotations(archetype, template);
6936 this._prepParentProperties(archetype, template);
6937 archetype._prepEffects();
6938 this._customPrepEffects(archetype);
6939 archetype._prepBehaviors();
6940 archetype._prepPropertyInfo();
6941 archetype._prepBindings();
6942 archetype._notifyPathUp = this._notifyPathUpImpl;
6943 archetype._scopeElementClass = this._scopeElementClassImpl;
6944 archetype.listen = this._listenImpl;
6945 archetype._showHideChildren = this._showHideChildrenImpl;
6946 archetype.__setPropertyOrig = this.__setProperty;
6947 archetype.__setProperty = this.__setPropertyImpl;
6948 var _constructor = this._constructorImpl;
6949 var ctor = function TemplateInstance(model, host) {
6950 _constructor.call(this, model, host);
6951 };
6952 ctor.prototype = archetype;
6953 archetype.constructor = ctor;
6954 template._content._ctor = ctor;
6955 this.ctor = ctor;
6956 },
6957 _getRootDataHost: function () {
6958 return this.dataHost && this.dataHost._rootDataHost || this.dataHost;
6959 },
6960 _showHideChildrenImpl: function (hide) {
6961 var c = this._children;
6962 for (var i = 0; i < c.length; i++) {
6963 var n = c[i];
6964 if (Boolean(hide) != Boolean(n.__hideTemplateChildren__)) {
6965 if (n.nodeType === Node.TEXT_NODE) {
6966 if (hide) {
6967 n.__polymerTextContent__ = n.textContent;
6968 n.textContent = '';
6969 } else {
6970 n.textContent = n.__polymerTextContent__;
6971 }
6972 } else if (n.style) {
6973 if (hide) {
6974 n.__polymerDisplay__ = n.style.display;
6975 n.style.display = 'none';
6976 } else {
6977 n.style.display = n.__polymerDisplay__;
6978 }
6979 }
6980 }
6981 n.__hideTemplateChildren__ = hide;
6982 }
6983 },
6984 __setPropertyImpl: function (property, value, fromAbove, node) {
6985 if (node && node.__hideTemplateChildren__ && property == 'textContent') {
6986 property = '__polymerTextContent__';
6987 }
6988 this.__setPropertyOrig(property, value, fromAbove, node);
6989 },
6990 _debounceTemplate: function (fn) {
6991 Polymer.dom.addDebouncer(this.debounce('_debounceTemplate', fn));
6992 },
6993 _flushTemplates: function () {
6994 Polymer.dom.flush();
6995 },
6996 _customPrepEffects: function (archetype) {
6997 var parentProps = archetype._parentProps;
6998 for (var prop in parentProps) {
6999 archetype._addPropertyEffect(prop, 'function', this._createHostPropEffector(prop ));
7000 }
7001 for (prop in this._instanceProps) {
7002 archetype._addPropertyEffect(prop, 'function', this._createInstancePropEffector( prop));
7003 }
7004 },
7005 _customPrepAnnotations: function (archetype, template) {
7006 archetype._template = template;
7007 var c = template._content;
7008 if (!c._notes) {
7009 var rootDataHost = archetype._rootDataHost;
7010 if (rootDataHost) {
7011 Polymer.Annotations.prepElement = function () {
7012 rootDataHost._prepElement();
7013 };
7014 }
7015 c._notes = Polymer.Annotations.parseAnnotations(template);
7016 Polymer.Annotations.prepElement = null;
7017 this._processAnnotations(c._notes);
7018 }
7019 archetype._notes = c._notes;
7020 archetype._parentProps = c._parentProps;
7021 },
7022 _prepParentProperties: function (archetype, template) {
7023 var parentProps = this._parentProps = archetype._parentProps;
7024 if (this._forwardParentProp && parentProps) {
7025 var proto = archetype._parentPropProto;
7026 var prop;
7027 if (!proto) {
7028 for (prop in this._instanceProps) {
7029 delete parentProps[prop];
7030 }
7031 proto = archetype._parentPropProto = Object.create(null);
7032 if (template != this) {
7033 Polymer.Bind.prepareModel(proto);
7034 Polymer.Base.prepareModelNotifyPath(proto);
7035 }
7036 for (prop in parentProps) {
7037 var parentProp = this._parentPropPrefix + prop;
7038 var effects = [
7039 {
7040 kind: 'function',
7041 effect: this._createForwardPropEffector(prop),
7042 fn: Polymer.Bind._functionEffect
7043 },
7044 {
7045 kind: 'notify',
7046 fn: Polymer.Bind._notifyEffect,
7047 effect: { event: Polymer.CaseMap.camelToDashCase(parentProp) + '-changed' }
7048 }
7049 ];
7050 Polymer.Bind._createAccessors(proto, parentProp, effects);
7051 }
7052 }
7053 var self = this;
7054 if (template != this) {
7055 Polymer.Bind.prepareInstance(template);
7056 template._forwardParentProp = function (source, value) {
7057 self._forwardParentProp(source, value);
7058 };
7059 }
7060 this._extendTemplate(template, proto);
7061 template._pathEffector = function (path, value, fromAbove) {
7062 return self._pathEffectorImpl(path, value, fromAbove);
7063 };
7064 }
7065 },
7066 _createForwardPropEffector: function (prop) {
7067 return function (source, value) {
7068 this._forwardParentProp(prop, value);
7069 };
7070 },
7071 _createHostPropEffector: function (prop) {
7072 var prefix = this._parentPropPrefix;
7073 return function (source, value) {
7074 this.dataHost._templatized[prefix + prop] = value;
7075 };
7076 },
7077 _createInstancePropEffector: function (prop) {
7078 return function (source, value, old, fromAbove) {
7079 if (!fromAbove) {
7080 this.dataHost._forwardInstanceProp(this, prop, value);
7081 }
7082 };
7083 },
7084 _extendTemplate: function (template, proto) {
7085 var n$ = Object.getOwnPropertyNames(proto);
7086 if (proto._propertySetter) {
7087 template._propertySetter = proto._propertySetter;
7088 }
7089 for (var i = 0, n; i < n$.length && (n = n$[i]); i++) {
7090 var val = template[n];
7091 var pd = Object.getOwnPropertyDescriptor(proto, n);
7092 Object.defineProperty(template, n, pd);
7093 if (val !== undefined) {
7094 template._propertySetter(n, val);
7095 }
7096 }
7097 },
7098 _showHideChildren: function (hidden) {
7099 },
7100 _forwardInstancePath: function (inst, path, value) {
7101 },
7102 _forwardInstanceProp: function (inst, prop, value) {
7103 },
7104 _notifyPathUpImpl: function (path, value) {
7105 var dataHost = this.dataHost;
7106 var dot = path.indexOf('.');
7107 var root = dot < 0 ? path : path.slice(0, dot);
7108 dataHost._forwardInstancePath.call(dataHost, this, path, value);
7109 if (root in dataHost._parentProps) {
7110 dataHost._templatized._notifyPath(dataHost._parentPropPrefix + path, value);
7111 }
7112 },
7113 _pathEffectorImpl: function (path, value, fromAbove) {
7114 if (this._forwardParentPath) {
7115 if (path.indexOf(this._parentPropPrefix) === 0) {
7116 var subPath = path.substring(this._parentPropPrefix.length);
7117 var model = this._modelForPath(subPath);
7118 if (model in this._parentProps) {
7119 this._forwardParentPath(subPath, value);
7120 }
7121 }
7122 }
7123 Polymer.Base._pathEffector.call(this._templatized, path, value, fromAbove);
7124 },
7125 _constructorImpl: function (model, host) {
7126 this._rootDataHost = host._getRootDataHost();
7127 this._setupConfigure(model);
7128 this._registerHost(host);
7129 this._beginHosting();
7130 this.root = this.instanceTemplate(this._template);
7131 this.root.__noContent = !this._notes._hasContent;
7132 this.root.__styleScoped = true;
7133 this._endHosting();
7134 this._marshalAnnotatedNodes();
7135 this._marshalInstanceEffects();
7136 this._marshalAnnotatedListeners();
7137 var children = [];
7138 for (var n = this.root.firstChild; n; n = n.nextSibling) {
7139 children.push(n);
7140 n._templateInstance = this;
7141 }
7142 this._children = children;
7143 if (host.__hideTemplateChildren__) {
7144 this._showHideChildren(true);
7145 }
7146 this._tryReady();
7147 },
7148 _listenImpl: function (node, eventName, methodName) {
7149 var model = this;
7150 var host = this._rootDataHost;
7151 var handler = host._createEventHandler(node, eventName, methodName);
7152 var decorated = function (e) {
7153 e.model = model;
7154 handler(e);
7155 };
7156 host._listen(node, eventName, decorated);
7157 },
7158 _scopeElementClassImpl: function (node, value) {
7159 var host = this._rootDataHost;
7160 if (host) {
7161 return host._scopeElementClass(node, value);
7162 }
7163 return value;
7164 },
7165 stamp: function (model) {
7166 model = model || {};
7167 if (this._parentProps) {
7168 var templatized = this._templatized;
7169 for (var prop in this._parentProps) {
7170 if (model[prop] === undefined) {
7171 model[prop] = templatized[this._parentPropPrefix + prop];
7172 }
7173 }
7174 }
7175 return new this.ctor(model, this);
7176 },
7177 modelForElement: function (el) {
7178 var model;
7179 while (el) {
7180 if (model = el._templateInstance) {
7181 if (model.dataHost != this) {
7182 el = model.dataHost;
7183 } else {
7184 return model;
7185 }
7186 } else {
7187 el = el.parentNode;
7188 }
7189 }
7190 }
7191 };Polymer({
7192 is: 'dom-template',
7193 extends: 'template',
7194 _template: null,
7195 behaviors: [Polymer.Templatizer],
7196 ready: function () {
7197 this.templatize(this);
7198 }
7199 });Polymer._collections = new WeakMap();
7200 Polymer.Collection = function (userArray) {
7201 Polymer._collections.set(userArray, this);
7202 this.userArray = userArray;
7203 this.store = userArray.slice();
7204 this.initMap();
7205 };
7206 Polymer.Collection.prototype = {
7207 constructor: Polymer.Collection,
7208 initMap: function () {
7209 var omap = this.omap = new WeakMap();
7210 var pmap = this.pmap = {};
7211 var s = this.store;
7212 for (var i = 0; i < s.length; i++) {
7213 var item = s[i];
7214 if (item && typeof item == 'object') {
7215 omap.set(item, i);
7216 } else {
7217 pmap[item] = i;
7218 }
7219 }
7220 },
7221 add: function (item) {
7222 var key = this.store.push(item) - 1;
7223 if (item && typeof item == 'object') {
7224 this.omap.set(item, key);
7225 } else {
7226 this.pmap[item] = key;
7227 }
7228 return '#' + key;
7229 },
7230 removeKey: function (key) {
7231 if (key = this._parseKey(key)) {
7232 this._removeFromMap(this.store[key]);
7233 delete this.store[key];
7234 }
7235 },
7236 _removeFromMap: function (item) {
7237 if (item && typeof item == 'object') {
7238 this.omap.delete(item);
7239 } else {
7240 delete this.pmap[item];
7241 }
7242 },
7243 remove: function (item) {
7244 var key = this.getKey(item);
7245 this.removeKey(key);
7246 return key;
7247 },
7248 getKey: function (item) {
7249 var key;
7250 if (item && typeof item == 'object') {
7251 key = this.omap.get(item);
7252 } else {
7253 key = this.pmap[item];
7254 }
7255 if (key != undefined) {
7256 return '#' + key;
7257 }
7258 },
7259 getKeys: function () {
7260 return Object.keys(this.store).map(function (key) {
7261 return '#' + key;
7262 });
7263 },
7264 _parseKey: function (key) {
7265 if (key && key[0] == '#') {
7266 return key.slice(1);
7267 }
7268 },
7269 setItem: function (key, item) {
7270 if (key = this._parseKey(key)) {
7271 var old = this.store[key];
7272 if (old) {
7273 this._removeFromMap(old);
7274 }
7275 if (item && typeof item == 'object') {
7276 this.omap.set(item, key);
7277 } else {
7278 this.pmap[item] = key;
7279 }
7280 this.store[key] = item;
7281 }
7282 },
7283 getItem: function (key) {
7284 if (key = this._parseKey(key)) {
7285 return this.store[key];
7286 }
7287 },
7288 getItems: function () {
7289 var items = [], store = this.store;
7290 for (var key in store) {
7291 items.push(store[key]);
7292 }
7293 return items;
7294 },
7295 _applySplices: function (splices) {
7296 var keyMap = {}, key;
7297 for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
7298 s.addedKeys = [];
7299 for (var j = 0; j < s.removed.length; j++) {
7300 key = this.getKey(s.removed[j]);
7301 keyMap[key] = keyMap[key] ? null : -1;
7302 }
7303 for (j = 0; j < s.addedCount; j++) {
7304 var item = this.userArray[s.index + j];
7305 key = this.getKey(item);
7306 key = key === undefined ? this.add(item) : key;
7307 keyMap[key] = keyMap[key] ? null : 1;
7308 s.addedKeys.push(key);
7309 }
7310 }
7311 var removed = [];
7312 var added = [];
7313 for (key in keyMap) {
7314 if (keyMap[key] < 0) {
7315 this.removeKey(key);
7316 removed.push(key);
7317 }
7318 if (keyMap[key] > 0) {
7319 added.push(key);
7320 }
7321 }
7322 return [{
7323 removed: removed,
7324 added: added
7325 }];
7326 }
7327 };
7328 Polymer.Collection.get = function (userArray) {
7329 return Polymer._collections.get(userArray) || new Polymer.Collection(userArray);
7330 };
7331 Polymer.Collection.applySplices = function (userArray, splices) {
7332 var coll = Polymer._collections.get(userArray);
7333 return coll ? coll._applySplices(splices) : null;
7334 };Polymer({
7335 is: 'dom-repeat',
7336 extends: 'template',
7337 _template: null,
7338 properties: {
7339 items: { type: Array },
7340 as: {
7341 type: String,
7342 value: 'item'
7343 },
7344 indexAs: {
7345 type: String,
7346 value: 'index'
7347 },
7348 sort: {
7349 type: Function,
7350 observer: '_sortChanged'
7351 },
7352 filter: {
7353 type: Function,
7354 observer: '_filterChanged'
7355 },
7356 observe: {
7357 type: String,
7358 observer: '_observeChanged'
7359 },
7360 delay: Number,
7361 renderedItemCount: {
7362 type: Number,
7363 notify: true,
7364 readOnly: true
7365 },
7366 initialCount: {
7367 type: Number,
7368 observer: '_initializeChunking'
7369 },
7370 targetFramerate: {
7371 type: Number,
7372 value: 20
7373 },
7374 _targetFrameTime: {
7375 type: Number,
7376 computed: '_computeFrameTime(targetFramerate)'
7377 }
7378 },
7379 behaviors: [Polymer.Templatizer],
7380 observers: ['_itemsChanged(items.*)'],
7381 created: function () {
7382 this._instances = [];
7383 this._pool = [];
7384 this._limit = Infinity;
7385 var self = this;
7386 this._boundRenderChunk = function () {
7387 self._renderChunk();
7388 };
7389 },
7390 detached: function () {
7391 this.__isDetached = true;
7392 for (var i = 0; i < this._instances.length; i++) {
7393 this._detachInstance(i);
7394 }
7395 },
7396 attached: function () {
7397 if (this.__isDetached) {
7398 this.__isDetached = false;
7399 var parent = Polymer.dom(Polymer.dom(this).parentNode);
7400 for (var i = 0; i < this._instances.length; i++) {
7401 this._attachInstance(i, parent);
7402 }
7403 }
7404 },
7405 ready: function () {
7406 this._instanceProps = { __key__: true };
7407 this._instanceProps[this.as] = true;
7408 this._instanceProps[this.indexAs] = true;
7409 if (!this.ctor) {
7410 this.templatize(this);
7411 }
7412 },
7413 _sortChanged: function (sort) {
7414 var dataHost = this._getRootDataHost();
7415 this._sortFn = sort && (typeof sort == 'function' ? sort : function () {
7416 return dataHost[sort].apply(dataHost, arguments);
7417 });
7418 this._needFullRefresh = true;
7419 if (this.items) {
7420 this._debounceTemplate(this._render);
7421 }
7422 },
7423 _filterChanged: function (filter) {
7424 var dataHost = this._getRootDataHost();
7425 this._filterFn = filter && (typeof filter == 'function' ? filter : function () {
7426 return dataHost[filter].apply(dataHost, arguments);
7427 });
7428 this._needFullRefresh = true;
7429 if (this.items) {
7430 this._debounceTemplate(this._render);
7431 }
7432 },
7433 _computeFrameTime: function (rate) {
7434 return Math.ceil(1000 / rate);
7435 },
7436 _initializeChunking: function () {
7437 if (this.initialCount) {
7438 this._limit = this.initialCount;
7439 this._chunkCount = this.initialCount;
7440 this._lastChunkTime = performance.now();
7441 }
7442 },
7443 _tryRenderChunk: function () {
7444 if (this.items && this._limit < this.items.length) {
7445 this.debounce('renderChunk', this._requestRenderChunk);
7446 }
7447 },
7448 _requestRenderChunk: function () {
7449 requestAnimationFrame(this._boundRenderChunk);
7450 },
7451 _renderChunk: function () {
7452 var currChunkTime = performance.now();
7453 var ratio = this._targetFrameTime / (currChunkTime - this._lastChunkTime);
7454 this._chunkCount = Math.round(this._chunkCount * ratio) || 1;
7455 this._limit += this._chunkCount;
7456 this._lastChunkTime = currChunkTime;
7457 this._debounceTemplate(this._render);
7458 },
7459 _observeChanged: function () {
7460 this._observePaths = this.observe && this.observe.replace('.*', '.').split(' ');
7461 },
7462 _itemsChanged: function (change) {
7463 if (change.path == 'items') {
7464 if (Array.isArray(this.items)) {
7465 this.collection = Polymer.Collection.get(this.items);
7466 } else if (!this.items) {
7467 this.collection = null;
7468 } else {
7469 this._error(this._logf('dom-repeat', 'expected array for `items`,' + ' found', t his.items));
7470 }
7471 this._keySplices = [];
7472 this._indexSplices = [];
7473 this._needFullRefresh = true;
7474 this._initializeChunking();
7475 this._debounceTemplate(this._render);
7476 } else if (change.path == 'items.splices') {
7477 this._keySplices = this._keySplices.concat(change.value.keySplices);
7478 this._indexSplices = this._indexSplices.concat(change.value.indexSplices);
7479 this._debounceTemplate(this._render);
7480 } else {
7481 var subpath = change.path.slice(6);
7482 this._forwardItemPath(subpath, change.value);
7483 this._checkObservedPaths(subpath);
7484 }
7485 },
7486 _checkObservedPaths: function (path) {
7487 if (this._observePaths) {
7488 path = path.substring(path.indexOf('.') + 1);
7489 var paths = this._observePaths;
7490 for (var i = 0; i < paths.length; i++) {
7491 if (path.indexOf(paths[i]) === 0) {
7492 this._needFullRefresh = true;
7493 if (this.delay) {
7494 this.debounce('render', this._render, this.delay);
7495 } else {
7496 this._debounceTemplate(this._render);
7497 }
7498 return;
7499 }
7500 }
7501 }
7502 },
7503 render: function () {
7504 this._needFullRefresh = true;
7505 this._debounceTemplate(this._render);
7506 this._flushTemplates();
7507 },
7508 _render: function () {
7509 if (this._needFullRefresh) {
7510 this._applyFullRefresh();
7511 this._needFullRefresh = false;
7512 } else if (this._keySplices.length) {
7513 if (this._sortFn) {
7514 this._applySplicesUserSort(this._keySplices);
7515 } else {
7516 if (this._filterFn) {
7517 this._applyFullRefresh();
7518 } else {
7519 this._applySplicesArrayOrder(this._indexSplices);
7520 }
7521 }
7522 } else {
7523 }
7524 this._keySplices = [];
7525 this._indexSplices = [];
7526 var keyToIdx = this._keyToInstIdx = {};
7527 for (var i = this._instances.length - 1; i >= 0; i--) {
7528 var inst = this._instances[i];
7529 if (inst.isPlaceholder && i < this._limit) {
7530 inst = this._insertInstance(i, inst.__key__);
7531 } else if (!inst.isPlaceholder && i >= this._limit) {
7532 inst = this._downgradeInstance(i, inst.__key__);
7533 }
7534 keyToIdx[inst.__key__] = i;
7535 if (!inst.isPlaceholder) {
7536 inst.__setProperty(this.indexAs, i, true);
7537 }
7538 }
7539 this._pool.length = 0;
7540 this._setRenderedItemCount(this._instances.length);
7541 this.fire('dom-change');
7542 this._tryRenderChunk();
7543 },
7544 _applyFullRefresh: function () {
7545 var c = this.collection;
7546 var keys;
7547 if (this._sortFn) {
7548 keys = c ? c.getKeys() : [];
7549 } else {
7550 keys = [];
7551 var items = this.items;
7552 if (items) {
7553 for (var i = 0; i < items.length; i++) {
7554 keys.push(c.getKey(items[i]));
7555 }
7556 }
7557 }
7558 var self = this;
7559 if (this._filterFn) {
7560 keys = keys.filter(function (a) {
7561 return self._filterFn(c.getItem(a));
7562 });
7563 }
7564 if (this._sortFn) {
7565 keys.sort(function (a, b) {
7566 return self._sortFn(c.getItem(a), c.getItem(b));
7567 });
7568 }
7569 for (i = 0; i < keys.length; i++) {
7570 var key = keys[i];
7571 var inst = this._instances[i];
7572 if (inst) {
7573 inst.__key__ = key;
7574 if (!inst.isPlaceholder && i < this._limit) {
7575 inst.__setProperty(this.as, c.getItem(key), true);
7576 }
7577 } else if (i < this._limit) {
7578 this._insertInstance(i, key);
7579 } else {
7580 this._insertPlaceholder(i, key);
7581 }
7582 }
7583 for (var j = this._instances.length - 1; j >= i; j--) {
7584 this._detachAndRemoveInstance(j);
7585 }
7586 },
7587 _numericSort: function (a, b) {
7588 return a - b;
7589 },
7590 _applySplicesUserSort: function (splices) {
7591 var c = this.collection;
7592 var keyMap = {};
7593 var key;
7594 for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
7595 for (var j = 0; j < s.removed.length; j++) {
7596 key = s.removed[j];
7597 keyMap[key] = keyMap[key] ? null : -1;
7598 }
7599 for (j = 0; j < s.added.length; j++) {
7600 key = s.added[j];
7601 keyMap[key] = keyMap[key] ? null : 1;
7602 }
7603 }
7604 var removedIdxs = [];
7605 var addedKeys = [];
7606 for (key in keyMap) {
7607 if (keyMap[key] === -1) {
7608 removedIdxs.push(this._keyToInstIdx[key]);
7609 }
7610 if (keyMap[key] === 1) {
7611 addedKeys.push(key);
7612 }
7613 }
7614 if (removedIdxs.length) {
7615 removedIdxs.sort(this._numericSort);
7616 for (i = removedIdxs.length - 1; i >= 0; i--) {
7617 var idx = removedIdxs[i];
7618 if (idx !== undefined) {
7619 this._detachAndRemoveInstance(idx);
7620 }
7621 }
7622 }
7623 var self = this;
7624 if (addedKeys.length) {
7625 if (this._filterFn) {
7626 addedKeys = addedKeys.filter(function (a) {
7627 return self._filterFn(c.getItem(a));
7628 });
7629 }
7630 addedKeys.sort(function (a, b) {
7631 return self._sortFn(c.getItem(a), c.getItem(b));
7632 });
7633 var start = 0;
7634 for (i = 0; i < addedKeys.length; i++) {
7635 start = this._insertRowUserSort(start, addedKeys[i]);
7636 }
7637 }
7638 },
7639 _insertRowUserSort: function (start, key) {
7640 var c = this.collection;
7641 var item = c.getItem(key);
7642 var end = this._instances.length - 1;
7643 var idx = -1;
7644 while (start <= end) {
7645 var mid = start + end >> 1;
7646 var midKey = this._instances[mid].__key__;
7647 var cmp = this._sortFn(c.getItem(midKey), item);
7648 if (cmp < 0) {
7649 start = mid + 1;
7650 } else if (cmp > 0) {
7651 end = mid - 1;
7652 } else {
7653 idx = mid;
7654 break;
7655 }
7656 }
7657 if (idx < 0) {
7658 idx = end + 1;
7659 }
7660 this._insertPlaceholder(idx, key);
7661 return idx;
7662 },
7663 _applySplicesArrayOrder: function (splices) {
7664 for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
7665 for (var j = 0; j < s.removed.length; j++) {
7666 this._detachAndRemoveInstance(s.index);
7667 }
7668 for (j = 0; j < s.addedKeys.length; j++) {
7669 this._insertPlaceholder(s.index + j, s.addedKeys[j]);
7670 }
7671 }
7672 },
7673 _detachInstance: function (idx) {
7674 var inst = this._instances[idx];
7675 if (!inst.isPlaceholder) {
7676 for (var i = 0; i < inst._children.length; i++) {
7677 var el = inst._children[i];
7678 Polymer.dom(inst.root).appendChild(el);
7679 }
7680 return inst;
7681 }
7682 },
7683 _attachInstance: function (idx, parent) {
7684 var inst = this._instances[idx];
7685 if (!inst.isPlaceholder) {
7686 parent.insertBefore(inst.root, this);
7687 }
7688 },
7689 _detachAndRemoveInstance: function (idx) {
7690 var inst = this._detachInstance(idx);
7691 if (inst) {
7692 this._pool.push(inst);
7693 }
7694 this._instances.splice(idx, 1);
7695 },
7696 _insertPlaceholder: function (idx, key) {
7697 this._instances.splice(idx, 0, {
7698 isPlaceholder: true,
7699 __key__: key
7700 });
7701 },
7702 _stampInstance: function (idx, key) {
7703 var model = { __key__: key };
7704 model[this.as] = this.collection.getItem(key);
7705 model[this.indexAs] = idx;
7706 return this.stamp(model);
7707 },
7708 _insertInstance: function (idx, key) {
7709 var inst = this._pool.pop();
7710 if (inst) {
7711 inst.__setProperty(this.as, this.collection.getItem(key), true);
7712 inst.__setProperty('__key__', key, true);
7713 } else {
7714 inst = this._stampInstance(idx, key);
7715 }
7716 var beforeRow = this._instances[idx + 1];
7717 var beforeNode = beforeRow && !beforeRow.isPlaceholder ? beforeRow._children[0] : this;
7718 var parentNode = Polymer.dom(this).parentNode;
7719 Polymer.dom(parentNode).insertBefore(inst.root, beforeNode);
7720 this._instances[idx] = inst;
7721 return inst;
7722 },
7723 _downgradeInstance: function (idx, key) {
7724 var inst = this._detachInstance(idx);
7725 if (inst) {
7726 this._pool.push(inst);
7727 }
7728 inst = {
7729 isPlaceholder: true,
7730 __key__: key
7731 };
7732 this._instances[idx] = inst;
7733 return inst;
7734 },
7735 _showHideChildren: function (hidden) {
7736 for (var i = 0; i < this._instances.length; i++) {
7737 this._instances[i]._showHideChildren(hidden);
7738 }
7739 },
7740 _forwardInstanceProp: function (inst, prop, value) {
7741 if (prop == this.as) {
7742 var idx;
7743 if (this._sortFn || this._filterFn) {
7744 idx = this.items.indexOf(this.collection.getItem(inst.__key__));
7745 } else {
7746 idx = inst[this.indexAs];
7747 }
7748 this.set('items.' + idx, value);
7749 }
7750 },
7751 _forwardInstancePath: function (inst, path, value) {
7752 if (path.indexOf(this.as + '.') === 0) {
7753 this._notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value);
7754 }
7755 },
7756 _forwardParentProp: function (prop, value) {
7757 var i$ = this._instances;
7758 for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) {
7759 if (!inst.isPlaceholder) {
7760 inst.__setProperty(prop, value, true);
7761 }
7762 }
7763 },
7764 _forwardParentPath: function (path, value) {
7765 var i$ = this._instances;
7766 for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) {
7767 if (!inst.isPlaceholder) {
7768 inst._notifyPath(path, value, true);
7769 }
7770 }
7771 },
7772 _forwardItemPath: function (path, value) {
7773 if (this._keyToInstIdx) {
7774 var dot = path.indexOf('.');
7775 var key = path.substring(0, dot < 0 ? path.length : dot);
7776 var idx = this._keyToInstIdx[key];
7777 var inst = this._instances[idx];
7778 if (inst && !inst.isPlaceholder) {
7779 if (dot >= 0) {
7780 path = this.as + '.' + path.substring(dot + 1);
7781 inst._notifyPath(path, value, true);
7782 } else {
7783 inst.__setProperty(this.as, value, true);
7784 }
7785 }
7786 }
7787 },
7788 itemForElement: function (el) {
7789 var instance = this.modelForElement(el);
7790 return instance && instance[this.as];
7791 },
7792 keyForElement: function (el) {
7793 var instance = this.modelForElement(el);
7794 return instance && instance.__key__;
7795 },
7796 indexForElement: function (el) {
7797 var instance = this.modelForElement(el);
7798 return instance && instance[this.indexAs];
7799 }
7800 });Polymer({
7801 is: 'array-selector',
7802 _template: null,
7803 properties: {
7804 items: {
7805 type: Array,
7806 observer: 'clearSelection'
7807 },
7808 multi: {
7809 type: Boolean,
7810 value: false,
7811 observer: 'clearSelection'
7812 },
7813 selected: {
7814 type: Object,
7815 notify: true
7816 },
7817 selectedItem: {
7818 type: Object,
7819 notify: true
7820 },
7821 toggle: {
7822 type: Boolean,
7823 value: false
7824 }
7825 },
7826 clearSelection: function () {
7827 if (Array.isArray(this.selected)) {
7828 for (var i = 0; i < this.selected.length; i++) {
7829 this.unlinkPaths('selected.' + i);
7830 }
7831 } else {
7832 this.unlinkPaths('selected');
7833 this.unlinkPaths('selectedItem');
7834 }
7835 if (this.multi) {
7836 if (!this.selected || this.selected.length) {
7837 this.selected = [];
7838 this._selectedColl = Polymer.Collection.get(this.selected);
7839 }
7840 } else {
7841 this.selected = null;
7842 this._selectedColl = null;
7843 }
7844 this.selectedItem = null;
7845 },
7846 isSelected: function (item) {
7847 if (this.multi) {
7848 return this._selectedColl.getKey(item) !== undefined;
7849 } else {
7850 return this.selected == item;
7851 }
7852 },
7853 deselect: function (item) {
7854 if (this.multi) {
7855 if (this.isSelected(item)) {
7856 var skey = this._selectedColl.getKey(item);
7857 this.arrayDelete('selected', item);
7858 this.unlinkPaths('selected.' + skey);
7859 }
7860 } else {
7861 this.selected = null;
7862 this.selectedItem = null;
7863 this.unlinkPaths('selected');
7864 this.unlinkPaths('selectedItem');
7865 }
7866 },
7867 select: function (item) {
7868 var icol = Polymer.Collection.get(this.items);
7869 var key = icol.getKey(item);
7870 if (this.multi) {
7871 if (this.isSelected(item)) {
7872 if (this.toggle) {
7873 this.deselect(item);
7874 }
7875 } else {
7876 this.push('selected', item);
7877 var skey = this._selectedColl.getKey(item);
7878 this.linkPaths('selected.' + skey, 'items.' + key);
7879 }
7880 } else {
7881 if (this.toggle && item == this.selected) {
7882 this.deselect();
7883 } else {
7884 this.selected = item;
7885 this.selectedItem = item;
7886 this.linkPaths('selected', 'items.' + key);
7887 this.linkPaths('selectedItem', 'items.' + key);
7888 }
7889 }
7890 }
7891 });Polymer({
7892 is: 'dom-if',
7893 extends: 'template',
7894 _template: null,
7895 properties: {
7896 'if': {
7897 type: Boolean,
7898 value: false,
7899 observer: '_queueRender'
7900 },
7901 restamp: {
7902 type: Boolean,
7903 value: false,
7904 observer: '_queueRender'
7905 }
7906 },
7907 behaviors: [Polymer.Templatizer],
7908 _queueRender: function () {
7909 this._debounceTemplate(this._render);
7910 },
7911 detached: function () {
7912 if (!this.parentNode || this.parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE && (!Polymer.Settings.hasShadow || !(this.parentNode instanceof ShadowRoot))) {
7913 this._teardownInstance();
7914 }
7915 },
7916 attached: function () {
7917 if (this.if && this.ctor) {
7918 this.async(this._ensureInstance);
7919 }
7920 },
7921 render: function () {
7922 this._flushTemplates();
7923 },
7924 _render: function () {
7925 if (this.if) {
7926 if (!this.ctor) {
7927 this.templatize(this);
7928 }
7929 this._ensureInstance();
7930 this._showHideChildren();
7931 } else if (this.restamp) {
7932 this._teardownInstance();
7933 }
7934 if (!this.restamp && this._instance) {
7935 this._showHideChildren();
7936 }
7937 if (this.if != this._lastIf) {
7938 this.fire('dom-change');
7939 this._lastIf = this.if;
7940 }
7941 },
7942 _ensureInstance: function () {
7943 var parentNode = Polymer.dom(this).parentNode;
7944 if (parentNode) {
7945 var parent = Polymer.dom(parentNode);
7946 if (!this._instance) {
7947 this._instance = this.stamp();
7948 var root = this._instance.root;
7949 parent.insertBefore(root, this);
7950 } else {
7951 var c$ = this._instance._children;
7952 if (c$ && c$.length) {
7953 var lastChild = Polymer.dom(this).previousSibling;
7954 if (lastChild !== c$[c$.length - 1]) {
7955 for (var i = 0, n; i < c$.length && (n = c$[i]); i++) {
7956 parent.insertBefore(n, this);
7957 }
7958 }
7959 }
7960 }
7961 }
7962 },
7963 _teardownInstance: function () {
7964 if (this._instance) {
7965 var c$ = this._instance._children;
7966 if (c$ && c$.length) {
7967 var parent = Polymer.dom(Polymer.dom(c$[0]).parentNode);
7968 for (var i = 0, n; i < c$.length && (n = c$[i]); i++) {
7969 parent.removeChild(n);
7970 }
7971 }
7972 this._instance = null;
7973 }
7974 },
7975 _showHideChildren: function () {
7976 var hidden = this.__hideTemplateChildren__ || !this.if;
7977 if (this._instance) {
7978 this._instance._showHideChildren(hidden);
7979 }
7980 },
7981 _forwardParentProp: function (prop, value) {
7982 if (this._instance) {
7983 this._instance[prop] = value;
7984 }
7985 },
7986 _forwardParentPath: function (path, value) {
7987 if (this._instance) {
7988 this._instance._notifyPath(path, value, true);
7989 }
7990 }
7991 });Polymer({
7992 is: 'dom-bind',
7993 extends: 'template',
7994 _template: null,
7995 created: function () {
7996 var self = this;
7997 Polymer.RenderStatus.whenReady(function () {
7998 if (document.readyState == 'loading') {
7999 document.addEventListener('DOMContentLoaded', function () {
8000 self._markImportsReady();
8001 });
8002 } else {
8003 self._markImportsReady();
8004 }
8005 });
8006 },
8007 _ensureReady: function () {
8008 if (!this._readied) {
8009 this._readySelf();
8010 }
8011 },
8012 _markImportsReady: function () {
8013 this._importsReady = true;
8014 this._ensureReady();
8015 },
8016 _registerFeatures: function () {
8017 this._prepConstructor();
8018 },
8019 _insertChildren: function () {
8020 var parentDom = Polymer.dom(Polymer.dom(this).parentNode);
8021 parentDom.insertBefore(this.root, this);
8022 },
8023 _removeChildren: function () {
8024 if (this._children) {
8025 for (var i = 0; i < this._children.length; i++) {
8026 this.root.appendChild(this._children[i]);
8027 }
8028 }
8029 },
8030 _initFeatures: function () {
8031 },
8032 _scopeElementClass: function (element, selector) {
8033 if (this.dataHost) {
8034 return this.dataHost._scopeElementClass(element, selector);
8035 } else {
8036 return selector;
8037 }
8038 },
8039 _prepConfigure: function () {
8040 var config = {};
8041 for (var prop in this._propertyEffects) {
8042 config[prop] = this[prop];
8043 }
8044 var setupConfigure = this._setupConfigure;
8045 this._setupConfigure = function () {
8046 setupConfigure.call(this, config);
8047 };
8048 },
8049 attached: function () {
8050 if (this._importsReady) {
8051 this.render();
8052 }
8053 },
8054 detached: function () {
8055 this._removeChildren();
8056 },
8057 render: function () {
8058 this._ensureReady();
8059 if (!this._children) {
8060 this._template = this;
8061 this._prepAnnotations();
8062 this._prepEffects();
8063 this._prepBehaviors();
8064 this._prepConfigure();
8065 this._prepBindings();
8066 this._prepPropertyInfo();
8067 Polymer.Base._initFeatures.call(this);
8068 this._children = Polymer.TreeApi.arrayCopyChildNodes(this.root);
8069 }
8070 this._insertChildren();
8071 this.fire('dom-change');
8072 }
8073 });</script>
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106 <script>function MakePromise (asap) {
8107 function Promise(fn) {
8108 if (typeof this !== 'object' || typeof fn !== 'function') throw new TypeError();
8109 this._state = null;
8110 this._value = null;
8111 this._deferreds = []
8112
8113 doResolve(fn, resolve.bind(this), reject.bind(this));
8114 }
8115
8116 function handle(deferred) {
8117 var me = this;
8118 if (this._state === null) {
8119 this._deferreds.push(deferred);
8120 return
8121 }
8122 asap(function() {
8123 var cb = me._state ? deferred.onFulfilled : deferred.onR ejected
8124 if (typeof cb !== 'function') {
8125 (me._state ? deferred.resolve : deferred.reject) (me._value);
8126 return;
8127 }
8128 var ret;
8129 try {
8130 ret = cb(me._value);
8131 }
8132 catch (e) {
8133 deferred.reject(e);
8134 return;
8135 }
8136 deferred.resolve(ret);
8137 })
8138 }
8139
8140 function resolve(newValue) {
8141 try { //Promise Resolution Procedure: https://github.com/promise s-aplus/promises-spec#the-promise-resolution-procedure
8142 if (newValue === this) throw new TypeError();
8143 if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
8144 var then = newValue.then;
8145 if (typeof then === 'function') {
8146 doResolve(then.bind(newValue), resolve.b ind(this), reject.bind(this));
8147 return;
8148 }
8149 }
8150 this._state = true;
8151 this._value = newValue;
8152 finale.call(this);
8153 } catch (e) { reject.call(this, e); }
8154 }
8155
8156 function reject(newValue) {
8157 this._state = false;
8158 this._value = newValue;
8159 finale.call(this);
8160 }
8161
8162 function finale() {
8163 for (var i = 0, len = this._deferreds.length; i < len; i++) {
8164 handle.call(this, this._deferreds[i]);
8165 }
8166 this._deferreds = null;
8167 }
8168
8169 /**
8170 * Take a potentially misbehaving resolver function and make sure
8171 * onFulfilled and onRejected are only called once.
8172 *
8173 * Makes no guarantees about asynchrony.
8174 */
8175 function doResolve(fn, onFulfilled, onRejected) {
8176 var done = false;
8177 try {
8178 fn(function (value) {
8179 if (done) return;
8180 done = true;
8181 onFulfilled(value);
8182 }, function (reason) {
8183 if (done) return;
8184 done = true;
8185 onRejected(reason);
8186 })
8187 } catch (ex) {
8188 if (done) return;
8189 done = true;
8190 onRejected(ex);
8191 }
8192 }
8193
8194 Promise.prototype['catch'] = function (onRejected) {
8195 return this.then(null, onRejected);
8196 };
8197
8198 Promise.prototype.then = function(onFulfilled, onRejected) {
8199 var me = this;
8200 return new Promise(function(resolve, reject) {
8201 handle.call(me, {
8202 onFulfilled: onFulfilled,
8203 onRejected: onRejected,
8204 resolve: resolve,
8205 reject: reject
8206 });
8207 })
8208 };
8209
8210 Promise.resolve = function (value) {
8211 if (value && typeof value === 'object' && value.constructor === Promise) {
8212 return value;
8213 }
8214
8215 return new Promise(function (resolve) {
8216 resolve(value);
8217 });
8218 };
8219
8220 Promise.reject = function (value) {
8221 return new Promise(function (resolve, reject) {
8222 reject(value);
8223 });
8224 };
8225
8226
8227 return Promise;
8228 }
8229
8230 if (typeof module !== 'undefined') {
8231 module.exports = MakePromise;
8232 }
8233
8234 </script>
8235 <script>
8236 if (!window.Promise) {
8237 window.Promise = MakePromise(Polymer.Base.async);
8238 }
8239 </script>
8240 <script>
8241 'use strict';
8242
8243 Polymer({
8244 is: 'iron-request',
8245
8246 hostAttributes: {
8247 hidden: true
8248 },
8249
8250 properties: {
8251
8252 /**
8253 * A reference to the XMLHttpRequest instance used to generate the
8254 * network request.
8255 *
8256 * @type {XMLHttpRequest}
8257 */
8258 xhr: {
8259 type: Object,
8260 notify: true,
8261 readOnly: true,
8262 value: function() {
8263 return new XMLHttpRequest();
8264 }
8265 },
8266
8267 /**
8268 * A reference to the parsed response body, if the `xhr` has completely
8269 * resolved.
8270 *
8271 * @type {*}
8272 * @default null
8273 */
8274 response: {
8275 type: Object,
8276 notify: true,
8277 readOnly: true,
8278 value: function() {
8279 return null;
8280 }
8281 },
8282
8283 /**
8284 * A reference to the status code, if the `xhr` has completely resolved.
8285 */
8286 status: {
8287 type: Number,
8288 notify: true,
8289 readOnly: true,
8290 value: 0
8291 },
8292
8293 /**
8294 * A reference to the status text, if the `xhr` has completely resolved.
8295 */
8296 statusText: {
8297 type: String,
8298 notify: true,
8299 readOnly: true,
8300 value: ''
8301 },
8302
8303 /**
8304 * A promise that resolves when the `xhr` response comes back, or rejects
8305 * if there is an error before the `xhr` completes.
8306 *
8307 * @type {Promise}
8308 */
8309 completes: {
8310 type: Object,
8311 readOnly: true,
8312 notify: true,
8313 value: function() {
8314 return new Promise(function (resolve, reject) {
8315 this.resolveCompletes = resolve;
8316 this.rejectCompletes = reject;
8317 }.bind(this));
8318 }
8319 },
8320
8321 /**
8322 * An object that contains progress information emitted by the XHR if
8323 * available.
8324 *
8325 * @default {}
8326 */
8327 progress: {
8328 type: Object,
8329 notify: true,
8330 readOnly: true,
8331 value: function() {
8332 return {};
8333 }
8334 },
8335
8336 /**
8337 * Aborted will be true if an abort of the request is attempted.
8338 */
8339 aborted: {
8340 type: Boolean,
8341 notify: true,
8342 readOnly: true,
8343 value: false,
8344 },
8345
8346 /**
8347 * Errored will be true if the browser fired an error event from the
8348 * XHR object (mainly network errors).
8349 */
8350 errored: {
8351 type: Boolean,
8352 notify: true,
8353 readOnly: true,
8354 value: false
8355 },
8356
8357 /**
8358 * TimedOut will be true if the XHR threw a timeout event.
8359 */
8360 timedOut: {
8361 type: Boolean,
8362 notify: true,
8363 readOnly: true,
8364 value: false
8365 }
8366 },
8367
8368 /**
8369 * Succeeded is true if the request succeeded. The request succeeded if it
8370 * loaded without error, wasn't aborted, and the status code is ≥ 200, and
8371 * < 300, or if the status code is 0.
8372 *
8373 * The status code 0 is accepted as a success because some schemes - e.g.
8374 * file:// - don't provide status codes.
8375 *
8376 * @return {boolean}
8377 */
8378 get succeeded() {
8379 if (this.errored || this.aborted || this.timedOut) {
8380 return false;
8381 }
8382 var status = this.xhr.status || 0;
8383
8384 // Note: if we are using the file:// protocol, the status code will be 0
8385 // for all outcomes (successful or otherwise).
8386 return status === 0 ||
8387 (status >= 200 && status < 300);
8388 },
8389
8390 /**
8391 * Sends an HTTP request to the server and returns the XHR object.
8392 *
8393 * The handling of the `body` parameter will vary based on the Content-Type
8394 * header. See the docs for iron-ajax's `body` param for details.
8395 *
8396 * @param {{
8397 * url: string,
8398 * method: (string|undefined),
8399 * async: (boolean|undefined),
8400 * body: (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|u ndefined|Object),
8401 * headers: (Object|undefined),
8402 * handleAs: (string|undefined),
8403 * jsonPrefix: (string|undefined),
8404 * withCredentials: (boolean|undefined)}} options -
8405 * url The url to which the request is sent.
8406 * method The HTTP method to use, default is GET.
8407 * async By default, all requests are sent asynchronously. To send synch ronous requests,
8408 * set to false.
8409 * body The content for the request body for POST method.
8410 * headers HTTP request headers.
8411 * handleAs The response type. Default is 'text'.
8412 * withCredentials Whether or not to send credentials on the request. De fault is false.
8413 * timeout: (Number|undefined)
8414 * @return {Promise}
8415 */
8416 send: function (options) {
8417 var xhr = this.xhr;
8418
8419 if (xhr.readyState > 0) {
8420 return null;
8421 }
8422
8423 xhr.addEventListener('progress', function (progress) {
8424 this._setProgress({
8425 lengthComputable: progress.lengthComputable,
8426 loaded: progress.loaded,
8427 total: progress.total
8428 });
8429 }.bind(this))
8430
8431 xhr.addEventListener('error', function (error) {
8432 this._setErrored(true);
8433 this._updateStatus();
8434 this.rejectCompletes(error);
8435 }.bind(this));
8436
8437 xhr.addEventListener('timeout', function (error) {
8438 this._setTimedOut(true);
8439 this._updateStatus();
8440 this.rejectCompletes(error);
8441 }.bind(this));
8442
8443 xhr.addEventListener('abort', function () {
8444 this._updateStatus();
8445 this.rejectCompletes(new Error('Request aborted.'));
8446 }.bind(this));
8447
8448 // Called after all of the above.
8449 xhr.addEventListener('loadend', function () {
8450 this._updateStatus();
8451 this._setResponse(this.parseResponse());
8452
8453 if (!this.succeeded) {
8454 this.rejectCompletes(new Error('The request failed with status code: ' + this.xhr.status));
8455 return;
8456 }
8457
8458 this.resolveCompletes(this);
8459 }.bind(this));
8460
8461 this.url = options.url;
8462 xhr.open(
8463 options.method || 'GET',
8464 options.url,
8465 options.async !== false
8466 );
8467
8468 var acceptType = {
8469 'json': 'application/json',
8470 'text': 'text/plain',
8471 'html': 'text/html',
8472 'xml': 'application/xml',
8473 'arraybuffer': 'application/octet-stream'
8474 }[options.handleAs];
8475 var headers = options.headers || Object.create(null);
8476 var newHeaders = Object.create(null);
8477 for (var key in headers) {
8478 newHeaders[key.toLowerCase()] = headers[key];
8479 }
8480 headers = newHeaders;
8481
8482 if (acceptType && !headers['accept']) {
8483 headers['accept'] = acceptType;
8484 }
8485 Object.keys(headers).forEach(function (requestHeader) {
8486 if (/[A-Z]/.test(requestHeader)) {
8487 Polymer.Base._error('Headers must be lower case, got', requestHeader);
8488 }
8489 xhr.setRequestHeader(
8490 requestHeader,
8491 headers[requestHeader]
8492 );
8493 }, this);
8494
8495 if (options.async !== false) {
8496 if (options.async) {
8497 xhr.timeout = options.timeout;
8498 }
8499
8500 var handleAs = options.handleAs;
8501
8502 // If a JSON prefix is present, the responseType must be 'text' or the
8503 // browser won’t be able to parse the response.
8504 if (!!options.jsonPrefix || !handleAs) {
8505 handleAs = 'text';
8506 }
8507
8508 // In IE, `xhr.responseType` is an empty string when the response
8509 // returns. Hence, caching it as `xhr._responseType`.
8510 xhr.responseType = xhr._responseType = handleAs;
8511
8512 // Cache the JSON prefix, if it exists.
8513 if (!!options.jsonPrefix) {
8514 xhr._jsonPrefix = options.jsonPrefix;
8515 }
8516 }
8517
8518 xhr.withCredentials = !!options.withCredentials;
8519
8520
8521 var body = this._encodeBodyObject(options.body, headers['content-type']);
8522
8523 xhr.send(
8524 /** @type {ArrayBuffer|ArrayBufferView|Blob|Document|FormData|
8525 null|string|undefined} */
8526 (body));
8527
8528 return this.completes;
8529 },
8530
8531 /**
8532 * Attempts to parse the response body of the XHR. If parsing succeeds,
8533 * the value returned will be deserialized based on the `responseType`
8534 * set on the XHR.
8535 *
8536 * @return {*} The parsed response,
8537 * or undefined if there was an empty response or parsing failed.
8538 */
8539 parseResponse: function () {
8540 var xhr = this.xhr;
8541 var responseType = xhr.responseType || xhr._responseType;
8542 var preferResponseText = !this.xhr.responseType;
8543 var prefixLen = (xhr._jsonPrefix && xhr._jsonPrefix.length) || 0;
8544
8545 try {
8546 switch (responseType) {
8547 case 'json':
8548 // If the xhr object doesn't have a natural `xhr.responseType`,
8549 // we can assume that the browser hasn't parsed the response for us,
8550 // and so parsing is our responsibility. Likewise if response is
8551 // undefined, as there's no way to encode undefined in JSON.
8552 if (preferResponseText || xhr.response === undefined) {
8553 // Try to emulate the JSON section of the response body section of
8554 // the spec: https://xhr.spec.whatwg.org/#response-body
8555 // That is to say, we try to parse as JSON, but if anything goes
8556 // wrong return null.
8557 try {
8558 return JSON.parse(xhr.responseText);
8559 } catch (_) {
8560 return null;
8561 }
8562 }
8563
8564 return xhr.response;
8565 case 'xml':
8566 return xhr.responseXML;
8567 case 'blob':
8568 case 'document':
8569 case 'arraybuffer':
8570 return xhr.response;
8571 case 'text':
8572 default: {
8573 // If `prefixLen` is set, it implies the response should be parsed
8574 // as JSON once the prefix of length `prefixLen` is stripped from
8575 // it. Emulate the behavior above where null is returned on failure
8576 // to parse.
8577 if (prefixLen) {
8578 try {
8579 return JSON.parse(xhr.responseText.substring(prefixLen));
8580 } catch (_) {
8581 return null;
8582 }
8583 }
8584 return xhr.responseText;
8585 }
8586 }
8587 } catch (e) {
8588 this.rejectCompletes(new Error('Could not parse response. ' + e.message) );
8589 }
8590 },
8591
8592 /**
8593 * Aborts the request.
8594 */
8595 abort: function () {
8596 this._setAborted(true);
8597 this.xhr.abort();
8598 },
8599
8600 /**
8601 * @param {*} body The given body of the request to try and encode.
8602 * @param {?string} contentType The given content type, to infer an encoding
8603 * from.
8604 * @return {*} Either the encoded body as a string, if successful,
8605 * or the unaltered body object if no encoding could be inferred.
8606 */
8607 _encodeBodyObject: function(body, contentType) {
8608 if (typeof body == 'string') {
8609 return body; // Already encoded.
8610 }
8611 var bodyObj = /** @type {Object} */ (body);
8612 switch(contentType) {
8613 case('application/json'):
8614 return JSON.stringify(bodyObj);
8615 case('application/x-www-form-urlencoded'):
8616 return this._wwwFormUrlEncode(bodyObj);
8617 }
8618 return body;
8619 },
8620
8621 /**
8622 * @param {Object} object The object to encode as x-www-form-urlencoded.
8623 * @return {string} .
8624 */
8625 _wwwFormUrlEncode: function(object) {
8626 if (!object) {
8627 return '';
8628 }
8629 var pieces = [];
8630 Object.keys(object).forEach(function(key) {
8631 // TODO(rictic): handle array values here, in a consistent way with
8632 // iron-ajax params.
8633 pieces.push(
8634 this._wwwFormUrlEncodePiece(key) + '=' +
8635 this._wwwFormUrlEncodePiece(object[key]));
8636 }, this);
8637 return pieces.join('&');
8638 },
8639
8640 /**
8641 * @param {*} str A key or value to encode as x-www-form-urlencoded.
8642 * @return {string} .
8643 */
8644 _wwwFormUrlEncodePiece: function(str) {
8645 // Spec says to normalize newlines to \r\n and replace %20 spaces with +.
8646 // jQuery does this as well, so this is likely to be widely compatible.
8647 if (str === null) {
8648 return '';
8649 }
8650 return encodeURIComponent(str.toString().replace(/\r?\n/g, '\r\n'))
8651 .replace(/%20/g, '+');
8652 },
8653
8654 /**
8655 * Updates the status code and status text.
8656 */
8657 _updateStatus: function() {
8658 this._setStatus(this.xhr.status);
8659 this._setStatusText((this.xhr.statusText === undefined) ? '' : this.xhr.st atusText);
8660 }
8661 });
8662 </script>
8663
8664 <script>
8665 'use strict';
8666
8667 Polymer({
8668
8669 is: 'iron-ajax',
8670
8671 /**
8672 * Fired when a request is sent.
8673 *
8674 * @event request
8675 * @event iron-ajax-request
8676 */
8677
8678 /**
8679 * Fired when a response is received.
8680 *
8681 * @event response
8682 * @event iron-ajax-response
8683 */
8684
8685 /**
8686 * Fired when an error is received.
8687 *
8688 * @event error
8689 * @event iron-ajax-error
8690 */
8691
8692 hostAttributes: {
8693 hidden: true
8694 },
8695
8696 properties: {
8697 /**
8698 * The URL target of the request.
8699 */
8700 url: {
8701 type: String
8702 },
8703
8704 /**
8705 * An object that contains query parameters to be appended to the
8706 * specified `url` when generating a request. If you wish to set the body
8707 * content when making a POST request, you should use the `body` property
8708 * instead.
8709 */
8710 params: {
8711 type: Object,
8712 value: function() {
8713 return {};
8714 }
8715 },
8716
8717 /**
8718 * The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'.
8719 * Default is 'GET'.
8720 */
8721 method: {
8722 type: String,
8723 value: 'GET'
8724 },
8725
8726 /**
8727 * HTTP request headers to send.
8728 *
8729 * Example:
8730 *
8731 * <iron-ajax
8732 * auto
8733 * url="http://somesite.com"
8734 * headers='{"X-Requested-With": "XMLHttpRequest"}'
8735 * handle-as="json"></iron-ajax>
8736 *
8737 * Note: setting a `Content-Type` header here will override the value
8738 * specified by the `contentType` property of this element.
8739 */
8740 headers: {
8741 type: Object,
8742 value: function() {
8743 return {};
8744 }
8745 },
8746
8747 /**
8748 * Content type to use when sending data. If the `contentType` property
8749 * is set and a `Content-Type` header is specified in the `headers`
8750 * property, the `headers` property value will take precedence.
8751 *
8752 * Varies the handling of the `body` param.
8753 */
8754 contentType: {
8755 type: String,
8756 value: null
8757 },
8758
8759 /**
8760 * Body content to send with the request, typically used with "POST"
8761 * requests.
8762 *
8763 * If body is a string it will be sent unmodified.
8764 *
8765 * If Content-Type is set to a value listed below, then
8766 * the body will be encoded accordingly.
8767 *
8768 * * `content-type="application/json"`
8769 * * body is encoded like `{"foo":"bar baz","x":1}`
8770 * * `content-type="application/x-www-form-urlencoded"`
8771 * * body is encoded like `foo=bar+baz&x=1`
8772 *
8773 * Otherwise the body will be passed to the browser unmodified, and it
8774 * will handle any encoding (e.g. for FormData, Blob, ArrayBuffer).
8775 *
8776 * @type (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|u ndefined|Object)
8777 */
8778 body: {
8779 type: Object,
8780 value: null
8781 },
8782
8783 /**
8784 * Toggle whether XHR is synchronous or asynchronous. Don't change this
8785 * to true unless You Know What You Are Doing™.
8786 */
8787 sync: {
8788 type: Boolean,
8789 value: false
8790 },
8791
8792 /**
8793 * Specifies what data to store in the `response` property, and
8794 * to deliver as `event.detail.response` in `response` events.
8795 *
8796 * One of:
8797 *
8798 * `text`: uses `XHR.responseText`.
8799 *
8800 * `xml`: uses `XHR.responseXML`.
8801 *
8802 * `json`: uses `XHR.responseText` parsed as JSON.
8803 *
8804 * `arraybuffer`: uses `XHR.response`.
8805 *
8806 * `blob`: uses `XHR.response`.
8807 *
8808 * `document`: uses `XHR.response`.
8809 */
8810 handleAs: {
8811 type: String,
8812 value: 'json'
8813 },
8814
8815 /**
8816 * Set the withCredentials flag on the request.
8817 */
8818 withCredentials: {
8819 type: Boolean,
8820 value: false
8821 },
8822
8823 /**
8824 * Set the timeout flag on the request.
8825 */
8826 timeout: {
8827 type: Number,
8828 value: 0
8829 },
8830
8831 /**
8832 * If true, automatically performs an Ajax request when either `url` or
8833 * `params` changes.
8834 */
8835 auto: {
8836 type: Boolean,
8837 value: false
8838 },
8839
8840 /**
8841 * If true, error messages will automatically be logged to the console.
8842 */
8843 verbose: {
8844 type: Boolean,
8845 value: false
8846 },
8847
8848 /**
8849 * The most recent request made by this iron-ajax element.
8850 */
8851 lastRequest: {
8852 type: Object,
8853 notify: true,
8854 readOnly: true
8855 },
8856
8857 /**
8858 * True while lastRequest is in flight.
8859 */
8860 loading: {
8861 type: Boolean,
8862 notify: true,
8863 readOnly: true
8864 },
8865
8866 /**
8867 * lastRequest's response.
8868 *
8869 * Note that lastResponse and lastError are set when lastRequest finishes,
8870 * so if loading is true, then lastResponse and lastError will correspond
8871 * to the result of the previous request.
8872 *
8873 * The type of the response is determined by the value of `handleAs` at
8874 * the time that the request was generated.
8875 *
8876 * @type {Object}
8877 */
8878 lastResponse: {
8879 type: Object,
8880 notify: true,
8881 readOnly: true
8882 },
8883
8884 /**
8885 * lastRequest's error, if any.
8886 *
8887 * @type {Object}
8888 */
8889 lastError: {
8890 type: Object,
8891 notify: true,
8892 readOnly: true
8893 },
8894
8895 /**
8896 * An Array of all in-flight requests originating from this iron-ajax
8897 * element.
8898 */
8899 activeRequests: {
8900 type: Array,
8901 notify: true,
8902 readOnly: true,
8903 value: function() {
8904 return [];
8905 }
8906 },
8907
8908 /**
8909 * Length of time in milliseconds to debounce multiple automatically gener ated requests.
8910 */
8911 debounceDuration: {
8912 type: Number,
8913 value: 0,
8914 notify: true
8915 },
8916
8917 /**
8918 * Prefix to be stripped from a JSON response before parsing it.
8919 *
8920 * In order to prevent an attack using CSRF with Array responses
8921 * (http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnera bility.aspx/)
8922 * many backends will mitigate this by prefixing all JSON response bodies
8923 * with a string that would be nonsensical to a JavaScript parser.
8924 *
8925 */
8926 jsonPrefix: {
8927 type: String,
8928 value: ''
8929 },
8930
8931 /**
8932 * By default, iron-ajax's events do not bubble. Setting this attribute wi ll cause its
8933 * request and response events as well as its iron-ajax-request, -response , and -error
8934 * events to bubble to the window object. The vanilla error event never bu bbles when
8935 * using shadow dom even if this.bubbles is true because a scoped flag is not passed with
8936 * it (first link) and because the shadow dom spec did not used to allow c ertain events,
8937 * including events named error, to leak outside of shadow trees (second l ink).
8938 * https://www.w3.org/TR/shadow-dom/#scoped-flag
8939 * https://www.w3.org/TR/2015/WD-shadow-dom-20151215/#events-that-are-not- leaked-into-ancestor-trees
8940 */
8941 bubbles: {
8942 type: Boolean,
8943 value: false
8944 },
8945
8946 _boundHandleResponse: {
8947 type: Function,
8948 value: function() {
8949 return this._handleResponse.bind(this);
8950 }
8951 }
8952 },
8953
8954 observers: [
8955 '_requestOptionsChanged(url, method, params.*, headers, contentType, ' +
8956 'body, sync, handleAs, jsonPrefix, withCredentials, timeout, auto)'
8957 ],
8958
8959 /**
8960 * The query string that should be appended to the `url`, serialized from
8961 * the current value of `params`.
8962 *
8963 * @return {string}
8964 */
8965 get queryString () {
8966 var queryParts = [];
8967 var param;
8968 var value;
8969
8970 for (param in this.params) {
8971 value = this.params[param];
8972 param = window.encodeURIComponent(param);
8973
8974 if (Array.isArray(value)) {
8975 for (var i = 0; i < value.length; i++) {
8976 queryParts.push(param + '=' + window.encodeURIComponent(value[i]));
8977 }
8978 } else if (value !== null) {
8979 queryParts.push(param + '=' + window.encodeURIComponent(value));
8980 } else {
8981 queryParts.push(param);
8982 }
8983 }
8984
8985 return queryParts.join('&');
8986 },
8987
8988 /**
8989 * The `url` with query string (if `params` are specified), suitable for
8990 * providing to an `iron-request` instance.
8991 *
8992 * @return {string}
8993 */
8994 get requestUrl() {
8995 var queryString = this.queryString;
8996 var url = this.url || '';
8997
8998 if (queryString) {
8999 var bindingChar = url.indexOf('?') >= 0 ? '&' : '?';
9000 return url + bindingChar + queryString;
9001 }
9002
9003 return url;
9004 },
9005
9006 /**
9007 * An object that maps header names to header values, first applying the
9008 * the value of `Content-Type` and then overlaying the headers specified
9009 * in the `headers` property.
9010 *
9011 * @return {Object}
9012 */
9013 get requestHeaders() {
9014 var headers = {};
9015 var contentType = this.contentType;
9016 if (contentType == null && (typeof this.body === 'string')) {
9017 contentType = 'application/x-www-form-urlencoded';
9018 }
9019 if (contentType) {
9020 headers['content-type'] = contentType;
9021 }
9022 var header;
9023
9024 if (this.headers instanceof Object) {
9025 for (header in this.headers) {
9026 headers[header] = this.headers[header].toString();
9027 }
9028 }
9029
9030 return headers;
9031 },
9032
9033 /**
9034 * Request options suitable for generating an `iron-request` instance based
9035 * on the current state of the `iron-ajax` instance's properties.
9036 *
9037 * @return {{
9038 * url: string,
9039 * method: (string|undefined),
9040 * async: (boolean|undefined),
9041 * body: (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|u ndefined|Object),
9042 * headers: (Object|undefined),
9043 * handleAs: (string|undefined),
9044 * jsonPrefix: (string|undefined),
9045 * withCredentials: (boolean|undefined)}}
9046 */
9047 toRequestOptions: function() {
9048 return {
9049 url: this.requestUrl || '',
9050 method: this.method,
9051 headers: this.requestHeaders,
9052 body: this.body,
9053 async: !this.sync,
9054 handleAs: this.handleAs,
9055 jsonPrefix: this.jsonPrefix,
9056 withCredentials: this.withCredentials,
9057 timeout: this.timeout
9058 };
9059 },
9060
9061 /**
9062 * Performs an AJAX request to the specified URL.
9063 *
9064 * @return {!IronRequestElement}
9065 */
9066 generateRequest: function() {
9067 var request = /** @type {!IronRequestElement} */ (document.createElement(' iron-request'));
9068 var requestOptions = this.toRequestOptions();
9069
9070 this.push('activeRequests', request);
9071
9072 request.completes.then(
9073 this._boundHandleResponse
9074 ).catch(
9075 this._handleError.bind(this, request)
9076 ).then(
9077 this._discardRequest.bind(this, request)
9078 );
9079
9080 request.send(requestOptions);
9081
9082 this._setLastRequest(request);
9083 this._setLoading(true);
9084
9085 this.fire('request', {
9086 request: request,
9087 options: requestOptions
9088 }, {bubbles: this.bubbles});
9089
9090 this.fire('iron-ajax-request', {
9091 request: request,
9092 options: requestOptions
9093 }, {bubbles: this.bubbles});
9094
9095 return request;
9096 },
9097
9098 _handleResponse: function(request) {
9099 if (request === this.lastRequest) {
9100 this._setLastResponse(request.response);
9101 this._setLastError(null);
9102 this._setLoading(false);
9103 }
9104 this.fire('response', request, {bubbles: this.bubbles});
9105 this.fire('iron-ajax-response', request, {bubbles: this.bubbles});
9106 },
9107
9108 _handleError: function(request, error) {
9109 if (this.verbose) {
9110 Polymer.Base._error(error);
9111 }
9112
9113 if (request === this.lastRequest) {
9114 this._setLastError({
9115 request: request,
9116 error: error,
9117 status: request.xhr.status,
9118 statusText: request.xhr.statusText,
9119 response: request.xhr.response
9120 });
9121 this._setLastResponse(null);
9122 this._setLoading(false);
9123 }
9124
9125 // Tests fail if this goes after the normal this.fire('error', ...)
9126 this.fire('iron-ajax-error', {
9127 request: request,
9128 error: error
9129 }, {bubbles: this.bubbles});
9130
9131 this.fire('error', {
9132 request: request,
9133 error: error
9134 }, {bubbles: this.bubbles});
9135 },
9136
9137 _discardRequest: function(request) {
9138 var requestIndex = this.activeRequests.indexOf(request);
9139
9140 if (requestIndex > -1) {
9141 this.splice('activeRequests', requestIndex, 1);
9142 }
9143 },
9144
9145 _requestOptionsChanged: function() {
9146 this.debounce('generate-request', function() {
9147 if (this.url == null) {
9148 return;
9149 }
9150
9151 if (this.auto) {
9152 this.generateRequest();
9153 }
9154 }, this.debounceDuration);
9155 },
9156
9157 });
9158 </script>
9159
9160
9161 <script>
9162 (function() {
9163 "use strict";
9164 /**
9165 `Polymer.IronJsonpLibraryBehavior` loads a jsonp library.
9166 Multiple components can request same library, only one copy will load.
9167
9168 Some libraries require a specific global function be defined.
9169 If this is the case, specify the `callbackName` property.
9170
9171 You should use an HTML Import to load library dependencies
9172 when possible instead of using this element.
9173
9174 @hero hero.svg
9175 @demo demo/index.html
9176 @polymerBehavior
9177 */
9178 Polymer.IronJsonpLibraryBehavior = {
9179
9180 properties: {
9181 /**
9182 * True if library has been successfully loaded
9183 */
9184 libraryLoaded: {
9185 type: Boolean,
9186 value: false,
9187 notify: true,
9188 readOnly: true
9189 },
9190 /**
9191 * Not null if library has failed to load
9192 */
9193 libraryErrorMessage: {
9194 type: String,
9195 value: null,
9196 notify: true,
9197 readOnly: true
9198 }
9199 // Following properties are to be set by behavior users
9200 /**
9201 * Library url. Must contain string `%%callback%%`.
9202 *
9203 * `%%callback%%` is a placeholder for jsonp wrapper function name
9204 *
9205 * Ex: https://maps.googleapis.com/maps/api/js?callback=%%callback%%
9206 * @property libraryUrl
9207 */
9208 /**
9209 * Set if library requires specific callback name.
9210 * Name will be automatically generated if not set.
9211 * @property callbackName
9212 */
9213 /**
9214 * name of event to be emitted when library loads. Standard is `api-load`
9215 * @property notifyEvent
9216 */
9217 /**
9218 * event with name specified in `notifyEvent` attribute
9219 * will fire upon successful load2
9220 * @event `notifyEvent`
9221 */
9222 },
9223
9224 observers: [
9225 '_libraryUrlChanged(libraryUrl)'
9226 ],
9227
9228 _libraryUrlChanged: function(libraryUrl) {
9229 // can't load before ready because notifyEvent might not be set
9230 if (this._isReady && this.libraryUrl)
9231 this._loadLibrary();
9232 },
9233
9234 _libraryLoadCallback: function(err, result) {
9235 if (err) {
9236 console.warn("Library load failed:", err.message);
9237 this._setLibraryErrorMessage(err.message);
9238 }
9239 else {
9240 this._setLibraryErrorMessage(null);
9241 this._setLibraryLoaded(true);
9242 if (this.notifyEvent)
9243 this.fire(this.notifyEvent, result);
9244 }
9245 },
9246
9247 /** loads the library, and fires this.notifyEvent upon completion */
9248 _loadLibrary: function() {
9249 LoaderMap.require(
9250 this.libraryUrl,
9251 this._libraryLoadCallback.bind(this),
9252 this.callbackName
9253 );
9254 },
9255
9256 ready: function() {
9257 this._isReady = true;
9258 if (this.libraryUrl)
9259 this._loadLibrary();
9260 }
9261 };
9262
9263 /**
9264 * LoaderMap keeps track of all Loaders
9265 */
9266 var LoaderMap = {
9267 apiMap: {}, // { hash -> Loader }
9268
9269 /**
9270 * @param {Function} notifyCallback loaded callback fn(result)
9271 * @param {string} jsonpCallbackName name of jsonpcallback. If API does not provide it, leave empty. Optional.
9272 */
9273 require: function(url, notifyCallback, jsonpCallbackName) {
9274
9275 // make hashable string form url
9276 var name = this.nameFromUrl(url);
9277
9278 // create a loader as needed
9279 if (!this.apiMap[name])
9280 this.apiMap[name] = new Loader(name, url, jsonpCallbackName);
9281
9282 // ask for notification
9283 this.apiMap[name].requestNotify(notifyCallback);
9284 },
9285
9286 nameFromUrl: function(url) {
9287 return url.replace(/[\:\/\%\?\&\.\=\-\,]/g, '_') + '_api';
9288 }
9289 };
9290
9291 /** @constructor */
9292 var Loader = function(name, url, callbackName) {
9293 this.notifiers = []; // array of notifyFn [ notifyFn* ]
9294
9295 // callback is specified either as callback name
9296 // or computed dynamically if url has callbackMacro in it
9297 if (!callbackName) {
9298 if (url.indexOf(this.callbackMacro) >= 0) {
9299 callbackName = name + '_loaded';
9300 url = url.replace(this.callbackMacro, callbackName);
9301 } else {
9302 this.error = new Error('IronJsonpLibraryBehavior a %%callback%% paramete r is required in libraryUrl');
9303 // TODO(sjmiles): we should probably fallback to listening to script.loa d
9304 return;
9305 }
9306 }
9307 this.callbackName = callbackName;
9308 window[this.callbackName] = this.success.bind(this);
9309 this.addScript(url);
9310 };
9311
9312 Loader.prototype = {
9313
9314 callbackMacro: '%%callback%%',
9315 loaded: false,
9316
9317 addScript: function(src) {
9318 var script = document.createElement('script');
9319 script.src = src;
9320 script.onerror = this.handleError.bind(this);
9321 var s = document.querySelector('script') || document.body;
9322 s.parentNode.insertBefore(script, s);
9323 this.script = script;
9324 },
9325
9326 removeScript: function() {
9327 if (this.script.parentNode) {
9328 this.script.parentNode.removeChild(this.script);
9329 }
9330 this.script = null;
9331 },
9332
9333 handleError: function(ev) {
9334 this.error = new Error("Library failed to load");
9335 this.notifyAll();
9336 this.cleanup();
9337 },
9338
9339 success: function() {
9340 this.loaded = true;
9341 this.result = Array.prototype.slice.call(arguments);
9342 this.notifyAll();
9343 this.cleanup();
9344 },
9345
9346 cleanup: function() {
9347 delete window[this.callbackName];
9348 },
9349
9350 notifyAll: function() {
9351 this.notifiers.forEach( function(notifyCallback) {
9352 notifyCallback(this.error, this.result);
9353 }.bind(this));
9354 this.notifiers = [];
9355 },
9356
9357 requestNotify: function(notifyCallback) {
9358 if (this.loaded || this.error) {
9359 notifyCallback( this.error, this.result);
9360 } else {
9361 this.notifiers.push(notifyCallback);
9362 }
9363 }
9364 };
9365 })();
9366 </script>
9367
9368
9369 <script>
9370 Polymer({
9371
9372 is: 'iron-jsonp-library',
9373
9374 behaviors: [ Polymer.IronJsonpLibraryBehavior ],
9375
9376 properties: {
9377 /**
9378 * Library url. Must contain string `%%callback%%`.
9379 *
9380 * `%%callback%%` is a placeholder for jsonp wrapper function name
9381 *
9382 * Ex: https://maps.googleapis.com/maps/api/js?callback=%%callback%%
9383 */
9384 libraryUrl: String,
9385 /**
9386 * Set if library requires specific callback name.
9387 * Name will be automatically generated if not set.
9388 */
9389 callbackName: String,
9390 /**
9391 * event with name specified in 'notifyEvent' attribute
9392 * will fire upon successful load
9393 */
9394 notifyEvent: String
9395 /**
9396 * event with name specified in 'notifyEvent' attribute
9397 * will fire upon successful load
9398 * @event `notifyEvent`
9399 */
9400
9401 }
9402 });
9403
9404 </script>
9405 <script>
9406 Polymer({
9407
9408 is: 'google-js-api',
9409
9410 behaviors: [
9411 Polymer.IronJsonpLibraryBehavior
9412 ],
9413
9414 properties: {
9415
9416 /** @private */
9417 libraryUrl: {
9418 type: String,
9419 value: 'https://apis.google.com/js/api.js?onload=%%callback%%'
9420 },
9421
9422 /**
9423 * Fired when the API library is loaded and available.
9424 * @event js-api-load
9425 */
9426 /**
9427 * Name of event fired when library is loaded and available.
9428 */
9429 notifyEvent: {
9430 type: String,
9431 value: 'js-api-load'
9432 },
9433 },
9434
9435 get api() {
9436 return gapi;
9437 }
9438
9439 });
9440 </script>
9441
9442 <script>
9443 (function() {
9444
9445 /**
9446 * Enum of attributes to be passed through to the login API call.
9447 * @readonly
9448 * @enum {string}
9449 */
9450 var ProxyLoginAttributes = {
9451 'appPackageName': 'apppackagename',
9452 'clientId': 'clientid',
9453 'cookiePolicy': 'cookiepolicy',
9454 'hostedDomain': 'hostedDomain',
9455 'openidPrompt': 'prompt',
9456 'requestVisibleActions': 'requestvisibleactions'
9457 };
9458
9459 /**
9460 * AuthEngine does all interactions with gapi.auth2
9461 *
9462 * It is tightly coupled with <google-signin-aware> element
9463 * The elements configure AuthEngine.
9464 * AuthEngine propagates all authentication events to all google-signin-awar e elements
9465 *
9466 * API used: https://developers.google.com/identity/sign-in/web/reference
9467 *
9468 */
9469 var AuthEngine = {
9470
9471 /**
9472 * oauth2 argument, set by google-signin-aware
9473 */
9474 _clientId: null,
9475
9476 get clientId() {
9477 return this._clientId;
9478 },
9479
9480 set clientId(val) {
9481 if (this._clientId && val && val != this._clientId) {
9482 throw new Error('clientId cannot change. Values do not match. New: ' + val + ' Old:' + this._clientId);
9483 }
9484 if (val && val != this._clientId) {
9485 this._clientId = val;
9486 this.initAuth2();
9487 }
9488 },
9489
9490 /**
9491 * oauth2 argument, set by google-signin-aware
9492 */
9493 _cookiePolicy: 'single_host_origin',
9494
9495 get cookiePolicy() {
9496 return this._cookiePolicy;
9497 },
9498
9499 set cookiePolicy(val) {
9500 if (val) {
9501 this._cookiePolicy = val;
9502 }
9503 },
9504
9505 /**
9506 * oauth2 argument, set by google-signin-aware
9507 */
9508 _appPackageName: '',
9509
9510 get appPackageName() {
9511 return this._appPackageName;
9512 },
9513
9514 set appPackageName(val) {
9515 if (this._appPackageName && val && val != this._appPackageName) {
9516 throw new Error('appPackageName cannot change. Values do not match. Ne w: ' + val + ' Old: ' + this._appPackageName);
9517 }
9518 if (val) {
9519 this._appPackageName = val;
9520 }
9521 },
9522
9523 /**
9524 * oauth2 argument, set by google-signin-aware
9525 */
9526 _requestVisibleActions: '',
9527
9528 get requestVisibleactions() {
9529 return this._requestVisibleActions;
9530 },
9531
9532 set requestVisibleactions(val) {
9533 if (this._requestVisibleActions && val && val != this._requestVisibleAct ions) {
9534 throw new Error('requestVisibleactions cannot change. Values do not ma tch. New: ' + val + ' Old: ' + this._requestVisibleActions);
9535 }
9536 if (val)
9537 this._requestVisibleActions = val;
9538 },
9539
9540 /**
9541 * oauth2 argument, set by google-signin-aware
9542 */
9543 _hostedDomain: '',
9544
9545 get hostedDomain() {
9546 return this._hostedDomain;
9547 },
9548
9549 set hostedDomain(val) {
9550 if (this._hostedDomain && val && val != this._hostedDomain) {
9551 throw new Error('hostedDomain cannot change. Values do not match. New: ' + val + ' Old: ' + this._hostedDomain);
9552 }
9553 if (val)
9554 this._hostedDomain = val;
9555 },
9556
9557 /**
9558 * oauth2 argument, set by google-signin-aware
9559 */
9560 _openidPrompt: '',
9561
9562 get openidPrompt() {
9563 return this._openidPrompt;
9564 },
9565
9566 set openidPrompt(val) {
9567 if (typeof val !== 'string') {
9568 throw new Error(
9569 'openidPrompt must be a string. Received ' + typeof val);
9570 }
9571 if (val) {
9572 var values = val.split(' ');
9573 values = values.map(function(v) {
9574 return v.trim();
9575 });
9576 values = values.filter(function(v) {
9577 return v;
9578 });
9579 var validValues = {none: 0, login: 0, consent: 0, select_account: 0};
9580 values.forEach(function(v) {
9581 if (v == 'none' && values.length > 1) {
9582 throw new Error(
9583 'none cannot be combined with other openidPrompt values');
9584 }
9585 if (!(v in validValues)) {
9586 throw new Error(
9587 'invalid openidPrompt value ' + v +
9588 '. Valid values: ' + Object.keys(validValues).join(', '));
9589 }
9590 });
9591 }
9592 this._openidPrompt = val;
9593 },
9594
9595 /** Is offline access currently enabled in the google-signin-aware element ? */
9596 _offline: false,
9597
9598 get offline() {
9599 return this._offline;
9600 },
9601
9602 set offline(val) {
9603 this._offline = val;
9604 this.updateAdditionalAuth();
9605 },
9606
9607 /** Should we force a re-prompt for offline access? */
9608 _offlineAlwaysPrompt: false,
9609
9610 get offlineAlwaysPrompt() {
9611 return this._offlineAlwaysPrompt;
9612 },
9613
9614 set offlineAlwaysPrompt(val) {
9615 this._offlineAlwaysPrompt = val;
9616 this.updateAdditionalAuth();
9617 },
9618
9619 /** Have we already gotten offline access from Google during this session? */
9620 offlineGranted: false,
9621
9622 /** <google-js-api> */
9623 _apiLoader: null,
9624
9625 /** an array of wanted scopes. oauth2 argument */
9626 _requestedScopeArray: [],
9627
9628 /** _requestedScopeArray as string */
9629 get requestedScopes() {
9630 return this._requestedScopeArray.join(' ');
9631 },
9632
9633 /** Is user signed in? */
9634 _signedIn: false,
9635
9636 /** Currently granted scopes */
9637 _grantedScopeArray: [],
9638
9639 /** True if additional authorization is required */
9640 _needAdditionalAuth: true,
9641
9642 /** True if have google+ scopes */
9643 _hasPlusScopes: false,
9644
9645 /**
9646 * array of <google-signin-aware>
9647 * state changes are broadcast to them
9648 */
9649 signinAwares: [],
9650
9651 init: function() {
9652 this._apiLoader = document.createElement('google-js-api');
9653 this._apiLoader.addEventListener('js-api-load', this.loadAuth2.bind(this ));
9654 },
9655
9656 loadAuth2: function() {
9657 gapi.load('auth2', this.initAuth2.bind(this));
9658 },
9659
9660 initAuth2: function() {
9661 if (!('gapi' in window) || !('auth2' in window.gapi) || !this.clientId) {
9662 return;
9663 }
9664 var auth = gapi.auth2.init({
9665 'client_id': this.clientId,
9666 'cookie_policy': this.cookiePolicy,
9667 'scope': this.requestedScopes,
9668 'hosted_domain': this.hostedDomain
9669 });
9670
9671 auth['currentUser'].listen(this.handleUserUpdate.bind(this));
9672
9673 auth.then(
9674 function onFulfilled() {
9675 // Let the current user listener trigger the changes.
9676 },
9677 function onRejected(error) {
9678 console.error(error);
9679 }
9680 );
9681 },
9682
9683 handleUserUpdate: function(newPrimaryUser) {
9684 // update and broadcast currentUser
9685 var isSignedIn = newPrimaryUser.isSignedIn();
9686 if (isSignedIn != this._signedIn) {
9687 this._signedIn = isSignedIn;
9688 for (var i=0; i<this.signinAwares.length; i++) {
9689 this.signinAwares[i]._setSignedIn(isSignedIn);
9690 }
9691 }
9692
9693 // update granted scopes
9694 this._grantedScopeArray = this.strToScopeArray(
9695 newPrimaryUser.getGrantedScopes());
9696 // console.log(this._grantedScopeArray);
9697 this.updateAdditionalAuth();
9698
9699 var response = newPrimaryUser.getAuthResponse();
9700 for (var i=0; i<this.signinAwares.length; i++) {
9701 this.signinAwares[i]._updateScopeStatus(response);
9702 }
9703 },
9704
9705 setOfflineCode: function(code) {
9706 for (var i=0; i<this.signinAwares.length; i++) {
9707 this.signinAwares[i]._updateOfflineCode(code);
9708 }
9709 },
9710
9711 /** convert scope string to scope array */
9712 strToScopeArray: function(str) {
9713 if (!str) {
9714 return [];
9715 }
9716 // remove extra spaces, then split
9717 var scopes = str.replace(/\ +/g, ' ').trim().split(' ');
9718 for (var i=0; i<scopes.length; i++) {
9719 scopes[i] = scopes[i].toLowerCase();
9720 // Handle scopes that will be deprecated but are still returned with their old value
9721 if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.profile') {
9722 scopes[i] = 'profile';
9723 }
9724 if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.email') {
9725 scopes[i] = 'email';
9726 }
9727 }
9728 // return with duplicates filtered out
9729 return scopes.filter( function(value, index, self) {
9730 return self.indexOf(value) === index;
9731 });
9732 },
9733
9734 /** true if scopes have google+ scopes */
9735 isPlusScope: function(scope) {
9736 return (scope.indexOf('/auth/games') > -1)
9737 || (scope.indexOf('auth/plus.') > -1 && scope.indexOf('auth/plus.me' ) < 0);
9738 },
9739
9740 /** true if scopes have been granted */
9741 hasGrantedScopes: function(scopeStr) {
9742 var scopes = this.strToScopeArray(scopeStr);
9743 for (var i=0; i< scopes.length; i++) {
9744 if (this._grantedScopeArray.indexOf(scopes[i]) === -1)
9745 return false;
9746 }
9747 return true;
9748 },
9749
9750 /** request additional scopes */
9751 requestScopes: function(newScopeStr) {
9752 var newScopes = this.strToScopeArray(newScopeStr);
9753 var scopesUpdated = false;
9754 for (var i=0; i<newScopes.length; i++) {
9755 if (this._requestedScopeArray.indexOf(newScopes[i]) === -1) {
9756 this._requestedScopeArray.push(newScopes[i]);
9757 scopesUpdated = true;
9758 }
9759 }
9760 if (scopesUpdated) {
9761 this.updateAdditionalAuth();
9762 this.updatePlusScopes();
9763 }
9764 },
9765
9766 /** update status of _needAdditionalAuth */
9767 updateAdditionalAuth: function() {
9768 var needMoreAuth = false;
9769 if ((this.offlineAlwaysPrompt || this.offline ) && !this.offlineGranted) {
9770 needMoreAuth = true;
9771 } else {
9772 for (var i=0; i<this._requestedScopeArray.length; i++) {
9773 if (this._grantedScopeArray.indexOf(this._requestedScopeArray[i]) == = -1) {
9774 needMoreAuth = true;
9775 break;
9776 }
9777 }
9778 }
9779 if (this._needAdditionalAuth != needMoreAuth) {
9780 this._needAdditionalAuth = needMoreAuth;
9781 // broadcast new value
9782 for (var i=0; i<this.signinAwares.length; i++) {
9783 this.signinAwares[i]._setNeedAdditionalAuth(needMoreAuth);
9784 }
9785 }
9786 },
9787
9788 updatePlusScopes: function() {
9789 var hasPlusScopes = false;
9790 for (var i = 0; i < this._requestedScopeArray.length; i++) {
9791 if (this.isPlusScope(this._requestedScopeArray[i])) {
9792 hasPlusScopes = true;
9793 break;
9794 }
9795 }
9796 if (this._hasPlusScopes != hasPlusScopes) {
9797 this._hasPlusScopes = hasPlusScopes;
9798 for (var i=0; i<this.signinAwares.length; i++) {
9799 this.signinAwares[i]._setHasPlusScopes(hasPlusScopes);
9800 }
9801 }
9802 },
9803 /**
9804 * attached <google-signin-aware>
9805 * @param {!GoogleSigninAwareElement} aware element to add
9806 */
9807 attachSigninAware: function(aware) {
9808 if (this.signinAwares.indexOf(aware) == -1) {
9809 this.signinAwares.push(aware);
9810 // Initialize aware properties
9811 aware._setNeedAdditionalAuth(this._needAdditionalAuth);
9812 aware._setSignedIn(this._signedIn);
9813 aware._setHasPlusScopes(this._hasPlusScopes);
9814 } else {
9815 console.warn('signinAware attached more than once', aware);
9816 }
9817 },
9818
9819 detachSigninAware: function(aware) {
9820 var index = this.signinAwares.indexOf(aware);
9821 if (index != -1) {
9822 this.signinAwares.splice(index, 1);
9823 } else {
9824 console.warn('Trying to detach unattached signin-aware');
9825 }
9826 },
9827
9828 /** returns scopes not granted */
9829 getMissingScopes: function() {
9830 return this._requestedScopeArray.filter( function(scope) {
9831 return this._grantedScopeArray.indexOf(scope) === -1;
9832 }.bind(this)).join(' ');
9833 },
9834
9835 assertAuthInitialized: function() {
9836 if (!this.clientId) {
9837 throw new Error("AuthEngine not initialized. clientId has not been con figured.");
9838 }
9839 if (!('gapi' in window)) {
9840 throw new Error("AuthEngine not initialized. gapi has not loaded.");
9841 }
9842 if (!('auth2' in window.gapi)) {
9843 throw new Error("AuthEngine not initialized. auth2 not loaded.");
9844 }
9845 },
9846
9847 /** pops up sign-in dialog */
9848 signIn: function() {
9849 this.assertAuthInitialized();
9850 var params = {
9851 'scope': this.getMissingScopes()
9852 };
9853
9854 // Proxy specific attributes through to the signIn options.
9855 Object.keys(ProxyLoginAttributes).forEach(function(key) {
9856 if (this[key] && this[key] !== '') {
9857 params[ProxyLoginAttributes[key]] = this[key];
9858 }
9859 }, this);
9860
9861 var promise;
9862 var user = gapi.auth2.getAuthInstance()['currentUser'].get();
9863 if (!(this.offline || this.offlineAlwaysPrompt)) {
9864 if (user.getGrantedScopes()) {
9865 // additional auth, skip multiple account dialog
9866 promise = user.grant(params);
9867 } else {
9868 // initial signin
9869 promise = gapi.auth2.getAuthInstance().signIn(params);
9870 }
9871 } else {
9872 params.redirect_uri = 'postmessage';
9873 if (this.offlineAlwaysPrompt) {
9874 params.approval_prompt = 'force';
9875 }
9876
9877 // Despite being documented at https://goo.gl/tiO0Bk
9878 // It doesn't seem like user.grantOfflineAccess() actually exists in
9879 // the current version of the Google Sign-In JS client we're using
9880 // through GoogleWebComponents. So in the offline case, we will not
9881 // distinguish between a first auth and an additional one.
9882 promise = gapi.auth2.getAuthInstance().grantOfflineAccess(params);
9883 }
9884 promise.then(
9885 function onFulfilled(response) {
9886 // If login was offline, response contains one string "code"
9887 // Otherwise it contains the user object already
9888 var newUser;
9889 if (response.code) {
9890 AuthEngine.offlineGranted = true;
9891 newUser = gapi.auth2.getAuthInstance()['currentUser'].get();
9892 AuthEngine.setOfflineCode(response.code);
9893 } else {
9894 newUser = response;
9895 }
9896
9897 var authResponse = newUser.getAuthResponse();
9898 // Let the current user listener trigger the changes.
9899 },
9900 function onRejected(error) {
9901 // Access denied is not an error, user hit cancel
9902 if ("Access denied." !== error.reason) {
9903 this.signinAwares.forEach(function(awareInstance) {
9904 awareInstance.errorNotify(error);
9905 });
9906 }
9907 }.bind(this)
9908 );
9909 },
9910
9911 /** signs user out */
9912 signOut: function() {
9913 this.assertAuthInitialized();
9914 gapi.auth2.getAuthInstance().signOut().then(
9915 function onFulfilled() {
9916 // Let the current user listener trigger the changes.
9917 },
9918 function onRejected(error) {
9919 console.error(error);
9920 }
9921 );
9922 }
9923 };
9924
9925 AuthEngine.init();
9926
9927 /**
9928 `google-signin-aware` is used to enable authentication in custom elements by
9929 interacting with a google-signin element that needs to be present somewhere
9930 on the page.
9931
9932 The `scopes` attribute allows you to specify which scope permissions are require d
9933 (e.g do you want to allow interaction with the Google Drive API).
9934
9935 The `google-signin-aware-success` event is triggered when a user successfully
9936 authenticates. If either `offline` or `offlineAlwaysPrompt` is set to true, succ essful
9937 authentication will also trigger the `google-signin-offline-success`event.
9938 The `google-signin-aware-signed-out` event is triggered when a user explicitly
9939 signs out via the google-signin element.
9940
9941 You can bind to `isAuthorized` property to monitor authorization state.
9942 ##### Example
9943
9944 <google-signin-aware scopes="https://www.googleapis.com/auth/drive"></google -signin-aware>
9945
9946
9947 ##### Example with offline
9948 <template id="awareness" is="dom-bind">
9949 <google-signin-aware
9950 scopes="https://www.googleapis.com/auth/drive"
9951 offline
9952 on-google-signin-aware-success="handleSignin"
9953 on-google-signin-offline-success="handleOffline"></google-signin-aware >
9954 <\/template>
9955 <script>
9956 var aware = document.querySelector('#awareness');
9957 aware.handleSignin = function(response) {
9958 var user = gapi.auth2.getAuthInstance()['currentUser'].get();
9959 console.log('User name: ' + user.getBasicProfile().getName());
9960 };
9961 aware.handleOffline = function(response) {
9962 console.log('Offline code received: ' + response.detail.code);
9963 // Here you would POST response.detail.code to your webserver, which can
9964 // exchange the authorization code for an access token. More info at:
9965 // https://developers.google.com/identity/protocols/OAuth2WebServer
9966 };
9967 <\/script>
9968 */
9969 Polymer({
9970
9971 is: 'google-signin-aware',
9972
9973 /**
9974 * Fired when this scope has been authorized
9975 * @param {Object} result Authorization result.
9976 * @event google-signin-aware-success
9977 */
9978
9979 /**
9980 * Fired when an offline authorization is successful.
9981 * @param {{code: string}} detail -
9982 * code: The one-time authorization code from Google.
9983 * Your application can exchange this for an `access_token` and `r efresh_token`
9984 * @event google-signin-offline-success
9985 */
9986
9987 /**
9988 * Fired when this scope is not authorized
9989 * @event google-signin-aware-signed-out
9990 */
9991
9992 /**
9993 * Fired when there is an error during the signin flow.
9994 * @param {Object} detail The error object returned from the OAuth 2 flow.
9995 * @event google-signin-aware-error
9996 */
9997
9998 /**
9999 * This block is needed so the previous @param is not assigned to the next property.
10000 */
10001
10002 properties: {
10003 /**
10004 * App package name for android over-the-air installs.
10005 * See the relevant [docs](https://developers.google.com/+/web/signin/an droid-app-installs)
10006 */
10007 appPackageName: {
10008 type: String,
10009 observer: '_appPackageNameChanged'
10010 },
10011
10012 /**
10013 * a Google Developers clientId reference
10014 */
10015 clientId: {
10016 type: String,
10017 observer: '_clientIdChanged'
10018 },
10019
10020 /**
10021 * The cookie policy defines what URIs have access to the session cookie
10022 * remembering the user's sign-in state.
10023 * See the relevant [docs](https://developers.google.com/+/web/signin/re ference#determining_a_value_for_cookie_policy) for more information.
10024 * @default 'single_host_origin'
10025 */
10026 cookiePolicy: {
10027 type: String,
10028 observer: '_cookiePolicyChanged'
10029 },
10030
10031 /**
10032 * The app activity types you want to write on behalf of the user
10033 * (e.g http://schemas.google.com/AddActivity)
10034 *
10035 */
10036 requestVisibleActions: {
10037 type: String,
10038 observer: '_requestVisibleActionsChanged'
10039 },
10040
10041 /**
10042 * The Google Apps domain to which users must belong to sign in.
10043 * See the relevant [docs](https://developers.google.com/identity/sign-i n/web/reference) for more information.
10044 */
10045 hostedDomain: {
10046 type: String,
10047 observer: '_hostedDomainChanged'
10048 },
10049
10050 /**
10051 * Allows for offline `access_token` retrieval during the signin process .
10052 * See also `offlineAlwaysPrompt`. You only need to set one of the two; if both
10053 * are set, the behavior of `offlineAlwaysPrompt` will override `offline `.
10054 */
10055 offline: {
10056 type: Boolean,
10057 value: false,
10058 observer: '_offlineChanged'
10059 },
10060
10061 /**
10062 * Works the same as `offline` with the addition that it will always
10063 * force a re-prompt to the user, guaranteeing that you will get a
10064 * refresh_token even if the user has already granted offline access to
10065 * this application. You only need to set one of `offline` or
10066 * `offlineAlwaysPrompt`, not both.
10067 */
10068 offlineAlwaysPrompt: {
10069 type: Boolean,
10070 value: false,
10071 observer: '_offlineAlwaysPromptChanged'
10072 },
10073
10074 /**
10075 * The scopes to provide access to (e.g https://www.googleapis.com/auth/ drive)
10076 * and should be space-delimited.
10077 */
10078 scopes: {
10079 type: String,
10080 value: 'profile',
10081 observer: '_scopesChanged'
10082 },
10083
10084 /**
10085 * Space-delimited, case-sensitive list of strings that
10086 * specifies whether the the user is prompted for reauthentication
10087 * and/or consent. The defined values are:
10088 * none: do not display authentication or consent pages.
10089 * This value is mutually exclusive with the rest.
10090 * login: always prompt the user for reauthentication.
10091 * consent: always show consent screen.
10092 * select_account: always show account selection page.
10093 * This enables a user who has multiple accounts to select amongst
10094 * the multiple accounts that they might have current sessions for.
10095 * For more information, see "prompt" parameter description in
10096 * https://openid.net/specs/openid-connect-basic-1_0.html#RequestParamet ers
10097 */
10098 openidPrompt: {
10099 type: String,
10100 value: '',
10101 observer: '_openidPromptChanged'
10102 },
10103
10104 /**
10105 * True if user is signed in
10106 */
10107 signedIn: {
10108 type: Boolean,
10109 notify: true,
10110 readOnly: true
10111 },
10112
10113 /**
10114 * True if authorizations for *this* element have been granted
10115 */
10116 isAuthorized: {
10117 type: Boolean,
10118 notify: true,
10119 readOnly: true,
10120 value: false
10121 },
10122
10123 /**
10124 * True if additional authorizations for *any* element are required
10125 */
10126 needAdditionalAuth: {
10127 type: Boolean,
10128 notify: true,
10129 readOnly: true
10130 },
10131
10132 /**
10133 * True if *any* element has google+ scopes
10134 */
10135 hasPlusScopes: {
10136 type: Boolean,
10137 value: false,
10138 notify: true,
10139 readOnly: true
10140 }
10141 },
10142
10143 attached: function() {
10144 AuthEngine.attachSigninAware(this);
10145 },
10146
10147 detached: function() {
10148 AuthEngine.detachSigninAware(this);
10149 },
10150
10151 /** pops up the authorization dialog */
10152 signIn: function() {
10153 AuthEngine.signIn();
10154 },
10155
10156 /** signs user out */
10157 signOut: function() {
10158 AuthEngine.signOut();
10159 },
10160
10161 errorNotify: function(error) {
10162 this.fire('google-signin-aware-error', error);
10163 },
10164
10165 _appPackageNameChanged: function(newName, oldName) {
10166 AuthEngine.appPackageName = newName;
10167 },
10168
10169 _clientIdChanged: function(newId, oldId) {
10170 AuthEngine.clientId = newId;
10171 },
10172
10173 _cookiePolicyChanged: function(newPolicy, oldPolicy) {
10174 AuthEngine.cookiePolicy = newPolicy;
10175 },
10176
10177 _requestVisibleActionsChanged: function(newVal, oldVal) {
10178 AuthEngine.requestVisibleActions = newVal;
10179 },
10180
10181 _hostedDomainChanged: function(newVal, oldVal) {
10182 AuthEngine.hostedDomain = newVal;
10183 },
10184
10185 _offlineChanged: function(newVal, oldVal) {
10186 AuthEngine.offline = newVal;
10187 },
10188
10189 _offlineAlwaysPromptChanged: function(newVal, oldVal) {
10190 AuthEngine.offlineAlwaysPrompt = newVal;
10191 },
10192
10193 _scopesChanged: function(newVal, oldVal) {
10194 AuthEngine.requestScopes(newVal);
10195 this._updateScopeStatus(undefined);
10196 },
10197
10198 _openidPromptChanged: function(newVal, oldVal) {
10199 AuthEngine.openidPrompt = newVal;
10200 },
10201
10202 _updateScopeStatus: function(user) {
10203 var newAuthorized = this.signedIn && AuthEngine.hasGrantedScopes(this.sc opes);
10204 if (newAuthorized !== this.isAuthorized) {
10205 this._setIsAuthorized(newAuthorized);
10206 if (newAuthorized) {
10207 this.fire('google-signin-aware-success', user);
10208 }
10209 else {
10210 this.fire('google-signin-aware-signed-out', user);
10211 }
10212 }
10213 },
10214
10215 _updateOfflineCode: function(code) {
10216 if (code) {
10217 this.fire('google-signin-offline-success', {code: code});
10218 }
10219 }
10220 });
10221 })();
10222 </script>
10223 <dom-module id="auth-signin" assetpath="imp/common/">
10224 <template>
10225 <style>
10226 #avatar {
10227 border-radius: 5px;
10228 }
10229 #signinContainer {
10230 margin-top: 14px;
10231 }
10232 </style>
10233
10234 <google-signin-aware id="aware" client-id="[[clientId]]" scopes="email" on-g oogle-signin-aware-success="_onSignin" on-google-signin-aware-signed-out="_onSig nout">
10235 </google-signin-aware>
10236
10237 <template is="dom-if" if="[[!signedIn]]">
10238 <div id="signinContainer">
10239 <a on-tap="signIn" href="#">Sign in</a>
10240 </div>
10241 </template>
10242
10243 <template is="dom-if" if="[[signedIn]]">
10244 <img id="avatar" src="[[profile.imageUrl]]" width="30" height="30">
10245 <span>[[profile.email]]</span>
10246 <span>|</span>
10247 <a on-tap="signOut" href="#">Sign out</a>
10248 </template>
10249 </template>
10250 <script>
10251 'use strict';
10252 Polymer({
10253 is: 'auth-signin',
10254 properties: {
10255 authHeaders: {
10256 type: Object,
10257 computed: "_makeHeader(authResponse)",
10258 notify: true,
10259 },
10260 authResponse: {
10261 type: Object,
10262 notify: true,
10263 },
10264 clientId: {
10265 type: String,
10266 },
10267 profile: {
10268 type: Object,
10269 readOnly: true
10270 },
10271 signedIn: {
10272 type: Boolean,
10273 readOnly: true,
10274 value: false
10275 }
10276 },
10277
10278 _onSignin: function(e) {
10279 this._setSignedIn(true);
10280 var user = gapi.auth2.getAuthInstance().currentUser.get();
10281 var profile = user.getBasicProfile();
10282 this._setProfile({
10283 email: profile.getEmail(),
10284 imageUrl: profile.getImageUrl()
10285 });
10286 this.set("authResponse", user.getAuthResponse());
10287 this.fire("auth-signin");
10288 },
10289
10290 _onSignout: function(e) {
10291 this._setSignedIn(false);
10292 this._setProfile(null);
10293 },
10294
10295 _makeHeader: function(authResponse) {
10296 if (!authResponse) {
10297 return {};
10298 }
10299 return {
10300 "authorization": authResponse.token_type + " " + authResponse.access_t oken
10301 };
10302 },
10303
10304 signIn: function() {
10305 this.$.aware.signIn();
10306 },
10307
10308 signOut: function() {
10309 this.$.aware.signOut();
10310 }
10311 });
10312 </script>
10313 </dom-module><dom-module id="swarming-index" assetpath="imp/index/">
10314 <template>
10315 <style>
10316 :host {
10317 display: block;
10318 }
10319 </style>
10320
10321 <h1>HELLO WORLD</h1><h1>
10322
10323
10324 <auth-signin auth-headers="{{auth}}" client-id="20770472288-t5smpbpjptka4nd8 88fv0ctd23ftba2o.apps.googleusercontent.com" on-auth-signin="signIn">
10325 </auth-signin>
10326
10327 <iron-ajax id="request" url="/_ah/api/swarming/v1/server/details" headers="[ [auth]]" handle-as="json" on-response="handleResponse">
10328 </iron-ajax>
10329
10330 </h1></template>
10331 <script>
10332 Polymer({
10333 is: 'swarming-index',
10334
10335 signIn: function(){
10336 this.$.request.generateRequest();
10337 },
10338
10339 handleResponse: function(a,b){
10340 console.log(this.$.request.lastResponse);
10341 }
10342 });
10343 </script>
10344 </dom-module></div>
10345 <swarming-index></swarming-index>
10346
10347
10348 </body></html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698