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

Side by Side Diff: appengine/swarming/elements/build/elements.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: Address feedback and introduce new res/ layer of direction 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
1 <!DOCTYPE html><html><head><!-- 1 <!DOCTYPE html><html><head><!--
2 @license 2 @license
3 Copyright (c) 2016 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
3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 11 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 12 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 13 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 14 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 15 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 16 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
9 --><!-- 17 --><!--
10 @license 18 @license
11 Copyright (c) 2014 The Polymer Project Authors. All rights reserved. 19 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 20 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 21 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 22 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 23 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 24 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
17 --> 25 --><meta charset="UTF-8">
18 <title>Many World, wow such hello</title> 26
19 <meta charset="utf-8"> 27
20 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 28 </head><body><div hidden="" by-vulcanize=""><script>(function () {
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() { 29 function resolve() {
39 document.body.removeAttribute('unresolved'); 30 document.body.removeAttribute('unresolved');
40 } 31 }
41 if (window.WebComponents) { 32 if (window.WebComponents) {
42 addEventListener('WebComponentsReady', resolve); 33 addEventListener('WebComponentsReady', resolve);
43 } else { 34 } else {
44 if (document.readyState === 'interactive' || document.readyState === 'complete') { 35 if (document.readyState === 'interactive' || document.readyState === 'complete') {
45 resolve(); 36 resolve();
46 } else { 37 } else {
47 addEventListener('DOMContentLoaded', resolve); 38 addEventListener('DOMContentLoaded', resolve);
(...skipping 9104 matching lines...) Expand 10 before | Expand all | Expand 10 after
9152 this.generateRequest(); 9143 this.generateRequest();
9153 } 9144 }
9154 }, this.debounceDuration); 9145 }, this.debounceDuration);
9155 }, 9146 },
9156 9147
9157 }); 9148 });
9158 </script> 9149 </script>
9159 9150
9160 9151
9161 <script> 9152 <script>
9153 Polymer.AppLayout = Polymer.AppLayout || {};
9154
9155 Polymer.AppLayout._scrollEffects = Polymer.AppLayout._scrollEffects || {};
9156
9157 Polymer.AppLayout.scrollTimingFunction = function easeOutQuad(t, b, c, d) {
9158 t /= d;
9159 return -c * t*(t-2) + b;
9160 };
9161
9162 /**
9163 * Registers a scroll effect to be used in elements that implement the
9164 * `Polymer.AppScrollEffectsBehavior` behavior.
9165 *
9166 * @param {string} effectName The effect name.
9167 * @param {Object} effectDef The effect definition.
9168 */
9169 Polymer.AppLayout.registerEffect = function registerEffect(effectName, effectD ef) {
9170 if (Polymer.AppLayout._scrollEffects[effectName] != null) {
9171 throw new Error('effect `'+ effectName + '` is already registered.');
9172 }
9173 Polymer.AppLayout._scrollEffects[effectName] = effectDef;
9174 };
9175
9176 /**
9177 * Scrolls to a particular set of coordinates in a scroll target.
9178 * If the scroll target is not defined, then it would use the main document as the target.
9179 *
9180 * To scroll in a smooth fashion, you can set the option `behavior: 'smooth'`. e.g.
9181 *
9182 * ```js
9183 * Polymer.AppLayout.scroll({top: 0, behavior: 'smooth'});
9184 * ```
9185 *
9186 * To scroll in a silent mode, without notifying scroll changes to any app-lay out elements,
9187 * you can set the option `behavior: 'silent'`. This is particularly useful we you are using
9188 * `app-header` and you desire to scroll to the top of a scrolling region with out running
9189 * scroll effects. e.g.
9190 *
9191 * ```js
9192 * Polymer.AppLayout.scroll({top: 0, behavior: 'silent'});
9193 * ```
9194 *
9195 * @param {Object} options {top: Number, left: Number, behavior: String(smooth | silent)}
9196 */
9197 Polymer.AppLayout.scroll = function scroll(options) {
9198 options = options || {};
9199
9200 var docEl = document.documentElement;
9201 var target = options.target || docEl;
9202 var hasNativeScrollBehavior = 'scrollBehavior' in target.style && target.scr oll;
9203 var scrollClassName = 'app-layout-silent-scroll';
9204 var scrollTop = options.top || 0;
9205 var scrollLeft = options.left || 0;
9206 var scrollTo = target === docEl ? window.scrollTo :
9207 function scrollTo(scrollLeft, scrollTop) {
9208 target.scrollLeft = scrollLeft;
9209 target.scrollTop = scrollTop;
9210 };
9211
9212 if (options.behavior === 'smooth') {
9213
9214 if (hasNativeScrollBehavior) {
9215
9216 target.scroll(options);
9217
9218 } else {
9219
9220 var timingFn = Polymer.AppLayout.scrollTimingFunction;
9221 var startTime = Date.now();
9222 var currentScrollTop = target === docEl ? window.pageYOffset : target.sc rollTop;
9223 var currentScrollLeft = target === docEl ? window.pageXOffset : target.s crollLeft;
9224 var deltaScrollTop = scrollTop - currentScrollTop;
9225 var deltaScrollLeft = scrollLeft - currentScrollLeft;
9226 var duration = 300;
9227 var updateFrame = (function updateFrame() {
9228 var now = Date.now();
9229 var elapsedTime = now - startTime;
9230
9231 if (elapsedTime < duration) {
9232 scrollTo(timingFn(elapsedTime, currentScrollLeft, deltaScrollLeft, d uration),
9233 timingFn(elapsedTime, currentScrollTop, deltaScrollTop, duration ));
9234 requestAnimationFrame(updateFrame);
9235 } else {
9236 scrollTo(scrollLeft, scrollTop);
9237 }
9238 }).bind(this);
9239
9240 updateFrame();
9241 }
9242
9243 } else if (options.behavior === 'silent') {
9244
9245 docEl.classList.add(scrollClassName);
9246
9247 // Browsers keep the scroll momentum even if the bottom of the scrolling c ontent
9248 // was reached. This means that calling scroll({top: 0, behavior: 'silent' }) when
9249 // the momentum is still going will result in more scroll events and thus scroll effects.
9250 // This seems to only apply when using document scrolling.
9251 // Therefore, when should we remove the class from the document element?
9252
9253 clearInterval(Polymer.AppLayout._scrollTimer);
9254
9255 Polymer.AppLayout._scrollTimer = setTimeout(function() {
9256 docEl.classList.remove(scrollClassName);
9257 Polymer.AppLayout._scrollTimer = null;
9258 }, 100);
9259
9260 scrollTo(scrollLeft, scrollTop);
9261
9262 } else {
9263
9264 scrollTo(scrollLeft, scrollTop);
9265
9266 }
9267 };
9268
9269 </script>
9270
9271
9272 <style>
9273 /* IE 10 support for HTML5 hidden attr */
9274 [hidden] {
9275 display: none !important;
9276 }
9277 </style>
9278
9279 <style is="custom-style">
9280 :root {
9281
9282 --layout: {
9283 display: -ms-flexbox;
9284 display: -webkit-flex;
9285 display: flex;
9286 };
9287
9288 --layout-inline: {
9289 display: -ms-inline-flexbox;
9290 display: -webkit-inline-flex;
9291 display: inline-flex;
9292 };
9293
9294 --layout-horizontal: {
9295 @apply(--layout);
9296
9297 -ms-flex-direction: row;
9298 -webkit-flex-direction: row;
9299 flex-direction: row;
9300 };
9301
9302 --layout-horizontal-reverse: {
9303 @apply(--layout);
9304
9305 -ms-flex-direction: row-reverse;
9306 -webkit-flex-direction: row-reverse;
9307 flex-direction: row-reverse;
9308 };
9309
9310 --layout-vertical: {
9311 @apply(--layout);
9312
9313 -ms-flex-direction: column;
9314 -webkit-flex-direction: column;
9315 flex-direction: column;
9316 };
9317
9318 --layout-vertical-reverse: {
9319 @apply(--layout);
9320
9321 -ms-flex-direction: column-reverse;
9322 -webkit-flex-direction: column-reverse;
9323 flex-direction: column-reverse;
9324 };
9325
9326 --layout-wrap: {
9327 -ms-flex-wrap: wrap;
9328 -webkit-flex-wrap: wrap;
9329 flex-wrap: wrap;
9330 };
9331
9332 --layout-wrap-reverse: {
9333 -ms-flex-wrap: wrap-reverse;
9334 -webkit-flex-wrap: wrap-reverse;
9335 flex-wrap: wrap-reverse;
9336 };
9337
9338 --layout-flex-auto: {
9339 -ms-flex: 1 1 auto;
9340 -webkit-flex: 1 1 auto;
9341 flex: 1 1 auto;
9342 };
9343
9344 --layout-flex-none: {
9345 -ms-flex: none;
9346 -webkit-flex: none;
9347 flex: none;
9348 };
9349
9350 --layout-flex: {
9351 -ms-flex: 1 1 0.000000001px;
9352 -webkit-flex: 1;
9353 flex: 1;
9354 -webkit-flex-basis: 0.000000001px;
9355 flex-basis: 0.000000001px;
9356 };
9357
9358 --layout-flex-2: {
9359 -ms-flex: 2;
9360 -webkit-flex: 2;
9361 flex: 2;
9362 };
9363
9364 --layout-flex-3: {
9365 -ms-flex: 3;
9366 -webkit-flex: 3;
9367 flex: 3;
9368 };
9369
9370 --layout-flex-4: {
9371 -ms-flex: 4;
9372 -webkit-flex: 4;
9373 flex: 4;
9374 };
9375
9376 --layout-flex-5: {
9377 -ms-flex: 5;
9378 -webkit-flex: 5;
9379 flex: 5;
9380 };
9381
9382 --layout-flex-6: {
9383 -ms-flex: 6;
9384 -webkit-flex: 6;
9385 flex: 6;
9386 };
9387
9388 --layout-flex-7: {
9389 -ms-flex: 7;
9390 -webkit-flex: 7;
9391 flex: 7;
9392 };
9393
9394 --layout-flex-8: {
9395 -ms-flex: 8;
9396 -webkit-flex: 8;
9397 flex: 8;
9398 };
9399
9400 --layout-flex-9: {
9401 -ms-flex: 9;
9402 -webkit-flex: 9;
9403 flex: 9;
9404 };
9405
9406 --layout-flex-10: {
9407 -ms-flex: 10;
9408 -webkit-flex: 10;
9409 flex: 10;
9410 };
9411
9412 --layout-flex-11: {
9413 -ms-flex: 11;
9414 -webkit-flex: 11;
9415 flex: 11;
9416 };
9417
9418 --layout-flex-12: {
9419 -ms-flex: 12;
9420 -webkit-flex: 12;
9421 flex: 12;
9422 };
9423
9424 /* alignment in cross axis */
9425
9426 --layout-start: {
9427 -ms-flex-align: start;
9428 -webkit-align-items: flex-start;
9429 align-items: flex-start;
9430 };
9431
9432 --layout-center: {
9433 -ms-flex-align: center;
9434 -webkit-align-items: center;
9435 align-items: center;
9436 };
9437
9438 --layout-end: {
9439 -ms-flex-align: end;
9440 -webkit-align-items: flex-end;
9441 align-items: flex-end;
9442 };
9443
9444 --layout-baseline: {
9445 -ms-flex-align: baseline;
9446 -webkit-align-items: baseline;
9447 align-items: baseline;
9448 };
9449
9450 /* alignment in main axis */
9451
9452 --layout-start-justified: {
9453 -ms-flex-pack: start;
9454 -webkit-justify-content: flex-start;
9455 justify-content: flex-start;
9456 };
9457
9458 --layout-center-justified: {
9459 -ms-flex-pack: center;
9460 -webkit-justify-content: center;
9461 justify-content: center;
9462 };
9463
9464 --layout-end-justified: {
9465 -ms-flex-pack: end;
9466 -webkit-justify-content: flex-end;
9467 justify-content: flex-end;
9468 };
9469
9470 --layout-around-justified: {
9471 -ms-flex-pack: distribute;
9472 -webkit-justify-content: space-around;
9473 justify-content: space-around;
9474 };
9475
9476 --layout-justified: {
9477 -ms-flex-pack: justify;
9478 -webkit-justify-content: space-between;
9479 justify-content: space-between;
9480 };
9481
9482 --layout-center-center: {
9483 @apply(--layout-center);
9484 @apply(--layout-center-justified);
9485 };
9486
9487 /* self alignment */
9488
9489 --layout-self-start: {
9490 -ms-align-self: flex-start;
9491 -webkit-align-self: flex-start;
9492 align-self: flex-start;
9493 };
9494
9495 --layout-self-center: {
9496 -ms-align-self: center;
9497 -webkit-align-self: center;
9498 align-self: center;
9499 };
9500
9501 --layout-self-end: {
9502 -ms-align-self: flex-end;
9503 -webkit-align-self: flex-end;
9504 align-self: flex-end;
9505 };
9506
9507 --layout-self-stretch: {
9508 -ms-align-self: stretch;
9509 -webkit-align-self: stretch;
9510 align-self: stretch;
9511 };
9512
9513 --layout-self-baseline: {
9514 -ms-align-self: baseline;
9515 -webkit-align-self: baseline;
9516 align-self: baseline;
9517 };
9518
9519 /* multi-line alignment in main axis */
9520
9521 --layout-start-aligned: {
9522 -ms-flex-line-pack: start; /* IE10 */
9523 -ms-align-content: flex-start;
9524 -webkit-align-content: flex-start;
9525 align-content: flex-start;
9526 };
9527
9528 --layout-end-aligned: {
9529 -ms-flex-line-pack: end; /* IE10 */
9530 -ms-align-content: flex-end;
9531 -webkit-align-content: flex-end;
9532 align-content: flex-end;
9533 };
9534
9535 --layout-center-aligned: {
9536 -ms-flex-line-pack: center; /* IE10 */
9537 -ms-align-content: center;
9538 -webkit-align-content: center;
9539 align-content: center;
9540 };
9541
9542 --layout-between-aligned: {
9543 -ms-flex-line-pack: justify; /* IE10 */
9544 -ms-align-content: space-between;
9545 -webkit-align-content: space-between;
9546 align-content: space-between;
9547 };
9548
9549 --layout-around-aligned: {
9550 -ms-flex-line-pack: distribute; /* IE10 */
9551 -ms-align-content: space-around;
9552 -webkit-align-content: space-around;
9553 align-content: space-around;
9554 };
9555
9556 /*******************************
9557 Other Layout
9558 *******************************/
9559
9560 --layout-block: {
9561 display: block;
9562 };
9563
9564 --layout-invisible: {
9565 visibility: hidden !important;
9566 };
9567
9568 --layout-relative: {
9569 position: relative;
9570 };
9571
9572 --layout-fit: {
9573 position: absolute;
9574 top: 0;
9575 right: 0;
9576 bottom: 0;
9577 left: 0;
9578 };
9579
9580 --layout-scroll: {
9581 -webkit-overflow-scrolling: touch;
9582 overflow: auto;
9583 };
9584
9585 --layout-fullbleed: {
9586 margin: 0;
9587 height: 100vh;
9588 };
9589
9590 /* fixed position */
9591
9592 --layout-fixed-top: {
9593 position: fixed;
9594 top: 0;
9595 left: 0;
9596 right: 0;
9597 };
9598
9599 --layout-fixed-right: {
9600 position: fixed;
9601 top: 0;
9602 right: 0;
9603 bottom: 0;
9604 };
9605
9606 --layout-fixed-bottom: {
9607 position: fixed;
9608 right: 0;
9609 bottom: 0;
9610 left: 0;
9611 };
9612
9613 --layout-fixed-left: {
9614 position: fixed;
9615 top: 0;
9616 bottom: 0;
9617 left: 0;
9618 };
9619
9620 }
9621
9622 </style>
9623
9624
9625 <dom-module id="app-drawer" assetpath="/res/imp/bower_components/app-layout/app- drawer/">
9626 <template>
9627 <style>
9628 :host {
9629 position: fixed;
9630 top: -120px;
9631 right: 0;
9632 bottom: -120px;
9633 left: 0;
9634
9635 visibility: hidden;
9636
9637 transition: visibility 0.2s ease;
9638 }
9639
9640 :host([opened]) {
9641 visibility: visible;
9642 }
9643
9644 :host([persistent]) {
9645 width: var(--app-drawer-width, 256px);
9646 }
9647
9648 :host([persistent][position=left]) {
9649 right: auto;
9650 }
9651
9652 :host([persistent][position=right]) {
9653 left: auto;
9654 }
9655
9656 #contentContainer {
9657 position: absolute;
9658 top: 0;
9659 bottom: 0;
9660 left: 0;
9661
9662 width: var(--app-drawer-width, 256px);
9663 padding: 120px 0;
9664
9665 transition: 0.2s ease;
9666 transition-property: -webkit-transform;
9667 transition-property: transform;
9668 -webkit-transform: translate3d(-100%, 0, 0);
9669 transform: translate3d(-100%, 0, 0);
9670
9671 background-color: #FFF;
9672
9673 @apply(--app-drawer-content-container);
9674 }
9675
9676 :host([position=right]) > #contentContainer {
9677 right: 0;
9678 left: auto;
9679
9680 -webkit-transform: translate3d(100%, 0, 0);
9681 transform: translate3d(100%, 0, 0);
9682 }
9683
9684 :host([swipe-open]) > #contentContainer::after {
9685 position: fixed;
9686 top: 0;
9687 bottom: 0;
9688 left: 100%;
9689
9690 visibility: visible;
9691
9692 width: 20px;
9693
9694 content: '';
9695 }
9696
9697 :host([swipe-open][position=right]) > #contentContainer::after {
9698 right: 100%;
9699 left: auto;
9700 }
9701
9702 :host([opened]) > #contentContainer {
9703 -webkit-transform: translate3d(0, 0, 0);
9704 transform: translate3d(0, 0, 0);
9705 }
9706
9707 #scrim {
9708 position: absolute;
9709 top: 0;
9710 right: 0;
9711 bottom: 0;
9712 left: 0;
9713
9714 transition: opacity 0.2s ease;
9715 -webkit-transform: translateZ(0);
9716 transform: translateZ(0);
9717
9718 opacity: 0;
9719 background: var(--app-drawer-scrim-background, rgba(0, 0, 0, 0.5));
9720 }
9721
9722 :host([opened]) > #scrim {
9723 opacity: 1;
9724 }
9725
9726 :host([opened][persistent]) > #scrim {
9727 visibility: hidden;
9728 /**
9729 * NOTE(keanulee): Keep both opacity: 0 and visibility: hidden to preven t the
9730 * scrim from showing when toggling between closed and opened/persistent .
9731 */
9732
9733 opacity: 0;
9734 }
9735 </style>
9736
9737 <div id="scrim" on-tap="close"></div>
9738
9739 <div id="contentContainer">
9740 <content></content>
9741 </div>
9742 </template>
9743
9744 <script>
9745
9746 Polymer({
9747 is: 'app-drawer',
9748
9749 properties: {
9750 /**
9751 * The opened state of the drawer.
9752 */
9753 opened: {
9754 type: Boolean,
9755 value: false,
9756 notify: true,
9757 reflectToAttribute: true
9758 },
9759
9760 /**
9761 * The drawer does not have a scrim and cannot be swiped close.
9762 */
9763 persistent: {
9764 type: Boolean,
9765 value: false,
9766 reflectToAttribute: true
9767 },
9768
9769 /**
9770 * The alignment of the drawer on the screen ('left', 'right', 'start' o r 'end').
9771 * 'start' computes to left and 'end' to right in LTR layout and vice ve rsa in RTL
9772 * layout.
9773 */
9774 align: {
9775 type: String,
9776 value: 'left'
9777 },
9778
9779 /**
9780 * The computed, read-only position of the drawer on the screen ('left' or 'right').
9781 */
9782 position: {
9783 type: String,
9784 readOnly: true,
9785 reflectToAttribute: true
9786 },
9787
9788 /**
9789 * Create an area at the edge of the screen to swipe open the drawer.
9790 */
9791 swipeOpen: {
9792 type: Boolean,
9793 value: false,
9794 reflectToAttribute: true
9795 },
9796
9797 /**
9798 * Trap keyboard focus when the drawer is opened and not persistent.
9799 */
9800 noFocusTrap: {
9801 type: Boolean,
9802 value: false
9803 }
9804 },
9805
9806 observers: [
9807 'resetLayout(position, isAttached)',
9808 '_resetPosition(align, isAttached)'
9809 ],
9810
9811 _translateOffset: 0,
9812
9813 _trackDetails: null,
9814
9815 _drawerState: 0,
9816
9817 _boundEscKeydownHandler: null,
9818
9819 _firstTabStop: null,
9820
9821 _lastTabStop: null,
9822
9823 ready: function() {
9824 // Only transition the drawer after its first render (e.g. app-drawer-la yout
9825 // may need to set the initial opened state which should not be transiti oned).
9826 this._setTransitionDuration('0s');
9827 },
9828
9829 attached: function() {
9830 // Only transition the drawer after its first render (e.g. app-drawer-la yout
9831 // may need to set the initial opened state which should not be transiti oned).
9832 Polymer.RenderStatus.afterNextRender(this, function() {
9833 this._setTransitionDuration('');
9834 this._boundEscKeydownHandler = this._escKeydownHandler.bind(this);
9835 this._resetDrawerState();
9836
9837 this.addEventListener('transitionend', this._transitionend.bind(this)) ;
9838 this.addEventListener('keydown', this._tabKeydownHandler.bind(this))
9839
9840 // Only listen for horizontal track so you can vertically scroll insid e the drawer.
9841 this.listen(this, 'track', '_track');
9842 this.setScrollDirection('y');
9843 });
9844 },
9845
9846 detached: function() {
9847 document.removeEventListener('keydown', this._boundEscKeydownHandler);
9848 },
9849
9850 /**
9851 * Opens the drawer.
9852 */
9853 open: function() {
9854 this.opened = true;
9855 },
9856
9857 /**
9858 * Closes the drawer.
9859 */
9860 close: function() {
9861 this.opened = false;
9862 },
9863
9864 /**
9865 * Toggles the drawer open and close.
9866 */
9867 toggle: function() {
9868 this.opened = !this.opened;
9869 },
9870
9871 /**
9872 * Gets the width of the drawer.
9873 *
9874 * @return {number} The width of the drawer in pixels.
9875 */
9876 getWidth: function() {
9877 return this.$.contentContainer.offsetWidth;
9878 },
9879
9880 /**
9881 * Resets the layout. The event fired is used by app-drawer-layout to posi tion the
9882 * content.
9883 *
9884 * @method resetLayout
9885 */
9886 resetLayout: function() {
9887 this.fire('app-drawer-reset-layout');
9888 },
9889
9890 _isRTL: function() {
9891 return window.getComputedStyle(this).direction === 'rtl';
9892 },
9893
9894 _resetPosition: function() {
9895 switch (this.align) {
9896 case 'start':
9897 this._setPosition(this._isRTL() ? 'right' : 'left');
9898 return;
9899 case 'end':
9900 this._setPosition(this._isRTL() ? 'left' : 'right');
9901 return;
9902 }
9903 this._setPosition(this.align);
9904 },
9905
9906 _escKeydownHandler: function(event) {
9907 var ESC_KEYCODE = 27;
9908 if (event.keyCode === ESC_KEYCODE) {
9909 // Prevent any side effects if app-drawer closes.
9910 event.preventDefault();
9911 this.close();
9912 }
9913 },
9914
9915 _track: function(event) {
9916 if (this.persistent) {
9917 return;
9918 }
9919
9920 // Disable user selection on desktop.
9921 event.preventDefault();
9922
9923 switch (event.detail.state) {
9924 case 'start':
9925 this._trackStart(event);
9926 break;
9927 case 'track':
9928 this._trackMove(event);
9929 break;
9930 case 'end':
9931 this._trackEnd(event);
9932 break;
9933 }
9934 },
9935
9936 _trackStart: function(event) {
9937 this._drawerState = this._DRAWER_STATE.TRACKING;
9938
9939 // Disable transitions since style attributes will reflect user track ev ents.
9940 this._setTransitionDuration('0s');
9941 this.style.visibility = 'visible';
9942
9943 var rect = this.$.contentContainer.getBoundingClientRect();
9944 if (this.position === 'left') {
9945 this._translateOffset = rect.left;
9946 } else {
9947 this._translateOffset = rect.right - window.innerWidth;
9948 }
9949
9950 this._trackDetails = [];
9951 },
9952
9953 _trackMove: function(event) {
9954 this._translateDrawer(event.detail.dx + this._translateOffset);
9955
9956 // Use Date.now() since event.timeStamp is inconsistent across browsers (e.g. most
9957 // browsers use milliseconds but FF 44 uses microseconds).
9958 this._trackDetails.push({
9959 dx: event.detail.dx,
9960 timeStamp: Date.now()
9961 });
9962 },
9963
9964 _trackEnd: function(event) {
9965 var x = event.detail.dx + this._translateOffset;
9966 var drawerWidth = this.getWidth();
9967 var isPositionLeft = this.position === 'left';
9968 var isInEndState = isPositionLeft ? (x >= 0 || x <= -drawerWidth) :
9969 (x <= 0 || x >= drawerWidth);
9970
9971 if (!isInEndState) {
9972 // No longer need the track events after this method returns - allow t hem to be GC'd.
9973 var trackDetails = this._trackDetails;
9974 this._trackDetails = null;
9975
9976 this._flingDrawer(event, trackDetails);
9977 if (this._drawerState === this._DRAWER_STATE.FLINGING) {
9978 return;
9979 }
9980 }
9981
9982 // If the drawer is not flinging, toggle the opened state based on the p osition of
9983 // the drawer.
9984 var halfWidth = drawerWidth / 2;
9985 if (event.detail.dx < -halfWidth) {
9986 this.opened = this.position === 'right';
9987 } else if (event.detail.dx > halfWidth) {
9988 this.opened = this.position === 'left';
9989 }
9990
9991 // Trigger app-drawer-transitioned now since there will be no transition end event.
9992 if (isInEndState) {
9993 this._resetDrawerState();
9994 }
9995
9996 this._setTransitionDuration('');
9997 this._resetDrawerTranslate();
9998 this.style.visibility = '';
9999 },
10000
10001 _calculateVelocity: function(event, trackDetails) {
10002 // Find the oldest track event that is within 100ms using binary search.
10003 var now = Date.now();
10004 var timeLowerBound = now - 100;
10005 var trackDetail;
10006 var min = 0;
10007 var max = trackDetails.length - 1;
10008
10009 while (min <= max) {
10010 // Floor of average of min and max.
10011 var mid = (min + max) >> 1;
10012 var d = trackDetails[mid];
10013 if (d.timeStamp >= timeLowerBound) {
10014 trackDetail = d;
10015 max = mid - 1;
10016 } else {
10017 min = mid + 1;
10018 }
10019 }
10020
10021 if (trackDetail) {
10022 var dx = event.detail.dx - trackDetail.dx;
10023 var dt = (now - trackDetail.timeStamp) || 1;
10024 return dx / dt;
10025 }
10026 return 0;
10027 },
10028
10029 _flingDrawer: function(event, trackDetails) {
10030 var velocity = this._calculateVelocity(event, trackDetails);
10031
10032 // Do not fling if velocity is not above a threshold.
10033 if (Math.abs(velocity) < this._MIN_FLING_THRESHOLD) {
10034 return;
10035 }
10036
10037 this._drawerState = this._DRAWER_STATE.FLINGING;
10038
10039 var x = event.detail.dx + this._translateOffset;
10040 var drawerWidth = this.getWidth();
10041 var isPositionLeft = this.position === 'left';
10042 var isVelocityPositive = velocity > 0;
10043 var isClosingLeft = !isVelocityPositive && isPositionLeft;
10044 var isClosingRight = isVelocityPositive && !isPositionLeft;
10045 var dx;
10046 if (isClosingLeft) {
10047 dx = -(x + drawerWidth);
10048 } else if (isClosingRight) {
10049 dx = (drawerWidth - x);
10050 } else {
10051 dx = -x;
10052 }
10053
10054 // Enforce a minimum transition velocity to make the drawer feel snappy.
10055 if (isVelocityPositive) {
10056 velocity = Math.max(velocity, this._MIN_TRANSITION_VELOCITY);
10057 this.opened = this.position === 'left';
10058 } else {
10059 velocity = Math.min(velocity, -this._MIN_TRANSITION_VELOCITY);
10060 this.opened = this.position === 'right';
10061 }
10062
10063 // Calculate the amount of time needed to finish the transition based on the
10064 // initial slope of the timing function.
10065 this._setTransitionDuration((this._FLING_INITIAL_SLOPE * dx / velocity) + 'ms');
10066 this._setTransitionTimingFunction(this._FLING_TIMING_FUNCTION);
10067
10068 this._resetDrawerTranslate();
10069 },
10070
10071 _transitionend: function(event) {
10072 // contentContainer will transition on opened state changed, and scrim w ill
10073 // transition on persistent state changed when opened - these are the
10074 // transitions we are interested in.
10075 var target = Polymer.dom(event).rootTarget;
10076 if (target === this.$.contentContainer || target === this.$.scrim) {
10077
10078 // If the drawer was flinging, we need to reset the style attributes.
10079 if (this._drawerState === this._DRAWER_STATE.FLINGING) {
10080 this._setTransitionDuration('');
10081 this._setTransitionTimingFunction('');
10082 this.style.visibility = '';
10083 }
10084
10085 this._resetDrawerState();
10086 }
10087 },
10088
10089 _setTransitionDuration: function(duration) {
10090 this.$.contentContainer.style.transitionDuration = duration;
10091 this.$.scrim.style.transitionDuration = duration;
10092 },
10093
10094 _setTransitionTimingFunction: function(timingFunction) {
10095 this.$.contentContainer.style.transitionTimingFunction = timingFunction;
10096 this.$.scrim.style.transitionTimingFunction = timingFunction;
10097 },
10098
10099 _translateDrawer: function(x) {
10100 var drawerWidth = this.getWidth();
10101
10102 if (this.position === 'left') {
10103 x = Math.max(-drawerWidth, Math.min(x, 0));
10104 this.$.scrim.style.opacity = 1 + x / drawerWidth;
10105 } else {
10106 x = Math.max(0, Math.min(x, drawerWidth));
10107 this.$.scrim.style.opacity = 1 - x / drawerWidth;
10108 }
10109
10110 this.translate3d(x + 'px', '0', '0', this.$.contentContainer);
10111 },
10112
10113 _resetDrawerTranslate: function() {
10114 this.$.scrim.style.opacity = '';
10115 this.transform('', this.$.contentContainer);
10116 },
10117
10118 _resetDrawerState: function() {
10119 var oldState = this._drawerState;
10120 if (this.opened) {
10121 this._drawerState = this.persistent ?
10122 this._DRAWER_STATE.OPENED_PERSISTENT : this._DRAWER_STATE.OPENED;
10123 } else {
10124 this._drawerState = this._DRAWER_STATE.CLOSED;
10125 }
10126
10127 if (oldState !== this._drawerState) {
10128 if (this._drawerState === this._DRAWER_STATE.OPENED) {
10129 this._setKeyboardFocusTrap();
10130 document.addEventListener('keydown', this._boundEscKeydownHandler);
10131 document.body.style.overflow = 'hidden';
10132 } else {
10133 document.removeEventListener('keydown', this._boundEscKeydownHandler );
10134 document.body.style.overflow = '';
10135 }
10136
10137 // Don't fire the event on initial load.
10138 if (oldState !== this._DRAWER_STATE.INIT) {
10139 this.fire('app-drawer-transitioned');
10140 }
10141 }
10142 },
10143
10144 _setKeyboardFocusTrap: function() {
10145 if (this.noFocusTrap) {
10146 return;
10147 }
10148
10149 // NOTE: Unless we use /deep/ (which we shouldn't since it's deprecated) , this will
10150 // not select focusable elements inside shadow roots.
10151 var focusableElementsSelector = [
10152 'a[href]:not([tabindex="-1"])',
10153 'area[href]:not([tabindex="-1"])',
10154 'input:not([disabled]):not([tabindex="-1"])',
10155 'select:not([disabled]):not([tabindex="-1"])',
10156 'textarea:not([disabled]):not([tabindex="-1"])',
10157 'button:not([disabled]):not([tabindex="-1"])',
10158 'iframe:not([tabindex="-1"])',
10159 '[tabindex]:not([tabindex="-1"])',
10160 '[contentEditable=true]:not([tabindex="-1"])'
10161 ].join(',');
10162 var focusableElements = Polymer.dom(this).querySelectorAll(focusableElem entsSelector);
10163
10164 if (focusableElements.length > 0) {
10165 this._firstTabStop = focusableElements[0];
10166 this._lastTabStop = focusableElements[focusableElements.length - 1];
10167 } else {
10168 // Reset saved tab stops when there are no focusable elements in the d rawer.
10169 this._firstTabStop = null;
10170 this._lastTabStop = null;
10171 }
10172
10173 // Focus on app-drawer if it has non-zero tabindex. Otherwise, focus the first focusable
10174 // element in the drawer, if it exists. Use the tabindex attribute since the this.tabIndex
10175 // property in IE/Edge returns 0 (instead of -1) when the attribute is n ot set.
10176 var tabindex = this.getAttribute('tabindex');
10177 if (tabindex && parseInt(tabindex, 10) > -1) {
10178 this.focus();
10179 } else if (this._firstTabStop) {
10180 this._firstTabStop.focus();
10181 }
10182 },
10183
10184 _tabKeydownHandler: function(event) {
10185 if (this.noFocusTrap) {
10186 return;
10187 }
10188
10189 var TAB_KEYCODE = 9;
10190 if (this._drawerState === this._DRAWER_STATE.OPENED && event.keyCode === TAB_KEYCODE) {
10191 if (event.shiftKey) {
10192 if (this._firstTabStop && Polymer.dom(event).localTarget === this._f irstTabStop) {
10193 event.preventDefault();
10194 this._lastTabStop.focus();
10195 }
10196 } else {
10197 if (this._lastTabStop && Polymer.dom(event).localTarget === this._la stTabStop) {
10198 event.preventDefault();
10199 this._firstTabStop.focus();
10200 }
10201 }
10202 }
10203 },
10204
10205 _MIN_FLING_THRESHOLD: 0.2,
10206
10207 _MIN_TRANSITION_VELOCITY: 1.2,
10208
10209 _FLING_TIMING_FUNCTION: 'cubic-bezier(0.667, 1, 0.667, 1)',
10210
10211 _FLING_INITIAL_SLOPE: 1.5,
10212
10213 _DRAWER_STATE: {
10214 INIT: 0,
10215 OPENED: 1,
10216 OPENED_PERSISTENT: 2,
10217 CLOSED: 3,
10218 TRACKING: 4,
10219 FLINGING: 5
10220 }
10221
10222 /**
10223 * Fired when the layout of app-drawer has changed.
10224 *
10225 * @event app-drawer-reset-layout
10226 */
10227
10228 /**
10229 * Fired when app-drawer has finished transitioning.
10230 *
10231 * @event app-drawer-transitioned
10232 */
10233 });
10234 </script>
10235 </dom-module>
10236
10237
10238 <script>
10239
10240 Polymer({
10241
10242 is: 'iron-media-query',
10243
10244 properties: {
10245
10246 /**
10247 * The Boolean return value of the media query.
10248 */
10249 queryMatches: {
10250 type: Boolean,
10251 value: false,
10252 readOnly: true,
10253 notify: true
10254 },
10255
10256 /**
10257 * The CSS media query to evaluate.
10258 */
10259 query: {
10260 type: String,
10261 observer: 'queryChanged'
10262 },
10263
10264 /**
10265 * If true, the query attribute is assumed to be a complete media query
10266 * string rather than a single media feature.
10267 */
10268 full: {
10269 type: Boolean,
10270 value: false
10271 },
10272
10273 /**
10274 * @type {function(MediaQueryList)}
10275 */
10276 _boundMQHandler: {
10277 value: function() {
10278 return this.queryHandler.bind(this);
10279 }
10280 },
10281
10282 /**
10283 * @type {MediaQueryList}
10284 */
10285 _mq: {
10286 value: null
10287 }
10288 },
10289
10290 attached: function() {
10291 this.style.display = 'none';
10292 this.queryChanged();
10293 },
10294
10295 detached: function() {
10296 this._remove();
10297 },
10298
10299 _add: function() {
10300 if (this._mq) {
10301 this._mq.addListener(this._boundMQHandler);
10302 }
10303 },
10304
10305 _remove: function() {
10306 if (this._mq) {
10307 this._mq.removeListener(this._boundMQHandler);
10308 }
10309 this._mq = null;
10310 },
10311
10312 queryChanged: function() {
10313 this._remove();
10314 var query = this.query;
10315 if (!query) {
10316 return;
10317 }
10318 if (!this.full && query[0] !== '(') {
10319 query = '(' + query + ')';
10320 }
10321 this._mq = window.matchMedia(query);
10322 this._add();
10323 this.queryHandler(this._mq);
10324 },
10325
10326 queryHandler: function(mq) {
10327 this._setQueryMatches(mq.matches);
10328 }
10329
10330 });
10331
10332 </script>
10333 <script>
10334 /**
10335 * `IronResizableBehavior` is a behavior that can be used in Polymer elements to
10336 * coordinate the flow of resize events between "resizers" (elements that cont rol the
10337 * size or hidden state of their children) and "resizables" (elements that nee d to be
10338 * notified when they are resized or un-hidden by their parents in order to ta ke
10339 * action on their new measurements).
10340 *
10341 * Elements that perform measurement should add the `IronResizableBehavior` be havior to
10342 * their element definition and listen for the `iron-resize` event on themselv es.
10343 * This event will be fired when they become showing after having been hidden,
10344 * when they are resized explicitly by another resizable, or when the window h as been
10345 * resized.
10346 *
10347 * Note, the `iron-resize` event is non-bubbling.
10348 *
10349 * @polymerBehavior Polymer.IronResizableBehavior
10350 * @demo demo/index.html
10351 **/
10352 Polymer.IronResizableBehavior = {
10353 properties: {
10354 /**
10355 * The closest ancestor element that implements `IronResizableBehavior`.
10356 */
10357 _parentResizable: {
10358 type: Object,
10359 observer: '_parentResizableChanged'
10360 },
10361
10362 /**
10363 * True if this element is currently notifying its descedant elements of
10364 * resize.
10365 */
10366 _notifyingDescendant: {
10367 type: Boolean,
10368 value: false
10369 }
10370 },
10371
10372 listeners: {
10373 'iron-request-resize-notifications': '_onIronRequestResizeNotifications'
10374 },
10375
10376 created: function() {
10377 // We don't really need property effects on these, and also we want them
10378 // to be created before the `_parentResizable` observer fires:
10379 this._interestedResizables = [];
10380 this._boundNotifyResize = this.notifyResize.bind(this);
10381 },
10382
10383 attached: function() {
10384 this.fire('iron-request-resize-notifications', null, {
10385 node: this,
10386 bubbles: true,
10387 cancelable: true
10388 });
10389
10390 if (!this._parentResizable) {
10391 window.addEventListener('resize', this._boundNotifyResize);
10392 this.notifyResize();
10393 }
10394 },
10395
10396 detached: function() {
10397 if (this._parentResizable) {
10398 this._parentResizable.stopResizeNotificationsFor(this);
10399 } else {
10400 window.removeEventListener('resize', this._boundNotifyResize);
10401 }
10402
10403 this._parentResizable = null;
10404 },
10405
10406 /**
10407 * Can be called to manually notify a resizable and its descendant
10408 * resizables of a resize change.
10409 */
10410 notifyResize: function() {
10411 if (!this.isAttached) {
10412 return;
10413 }
10414
10415 this._interestedResizables.forEach(function(resizable) {
10416 if (this.resizerShouldNotify(resizable)) {
10417 this._notifyDescendant(resizable);
10418 }
10419 }, this);
10420
10421 this._fireResize();
10422 },
10423
10424 /**
10425 * Used to assign the closest resizable ancestor to this resizable
10426 * if the ancestor detects a request for notifications.
10427 */
10428 assignParentResizable: function(parentResizable) {
10429 this._parentResizable = parentResizable;
10430 },
10431
10432 /**
10433 * Used to remove a resizable descendant from the list of descendants
10434 * that should be notified of a resize change.
10435 */
10436 stopResizeNotificationsFor: function(target) {
10437 var index = this._interestedResizables.indexOf(target);
10438
10439 if (index > -1) {
10440 this._interestedResizables.splice(index, 1);
10441 this.unlisten(target, 'iron-resize', '_onDescendantIronResize');
10442 }
10443 },
10444
10445 /**
10446 * This method can be overridden to filter nested elements that should or
10447 * should not be notified by the current element. Return true if an element
10448 * should be notified, or false if it should not be notified.
10449 *
10450 * @param {HTMLElement} element A candidate descendant element that
10451 * implements `IronResizableBehavior`.
10452 * @return {boolean} True if the `element` should be notified of resize.
10453 */
10454 resizerShouldNotify: function(element) { return true; },
10455
10456 _onDescendantIronResize: function(event) {
10457 if (this._notifyingDescendant) {
10458 event.stopPropagation();
10459 return;
10460 }
10461
10462 // NOTE(cdata): In ShadowDOM, event retargetting makes echoing of the
10463 // otherwise non-bubbling event "just work." We do it manually here for
10464 // the case where Polymer is not using shadow roots for whatever reason:
10465 if (!Polymer.Settings.useShadow) {
10466 this._fireResize();
10467 }
10468 },
10469
10470 _fireResize: function() {
10471 this.fire('iron-resize', null, {
10472 node: this,
10473 bubbles: false
10474 });
10475 },
10476
10477 _onIronRequestResizeNotifications: function(event) {
10478 var target = event.path ? event.path[0] : event.target;
10479
10480 if (target === this) {
10481 return;
10482 }
10483
10484 if (this._interestedResizables.indexOf(target) === -1) {
10485 this._interestedResizables.push(target);
10486 this.listen(target, 'iron-resize', '_onDescendantIronResize');
10487 }
10488
10489 target.assignParentResizable(this);
10490 this._notifyDescendant(target);
10491
10492 event.stopPropagation();
10493 },
10494
10495 _parentResizableChanged: function(parentResizable) {
10496 if (parentResizable) {
10497 window.removeEventListener('resize', this._boundNotifyResize);
10498 }
10499 },
10500
10501 _notifyDescendant: function(descendant) {
10502 // NOTE(cdata): In IE10, attached is fired on children first, so it's
10503 // important not to notify them if the parent is not attached yet (or
10504 // else they will get redundantly notified when the parent attaches).
10505 if (!this.isAttached) {
10506 return;
10507 }
10508
10509 this._notifyingDescendant = true;
10510 descendant.notifyResize();
10511 this._notifyingDescendant = false;
10512 }
10513 };
10514 </script>
10515
10516
10517
10518 <dom-module id="app-drawer-layout" assetpath="/res/imp/bower_components/app-layo ut/app-drawer-layout/">
10519 <template>
10520 <style>
10521 :host {
10522 display: block;
10523 }
10524
10525 :host([fullbleed]) {
10526 @apply(--layout-fit);
10527 }
10528
10529 #contentContainer {
10530 position: relative;
10531
10532 height: 100%;
10533
10534 transition: var(--app-drawer-layout-content-transition, none);
10535 }
10536
10537 #contentContainer:not(.narrow) > ::content [drawer-toggle] {
10538 display: none;
10539 }
10540 </style>
10541
10542 <div id="contentContainer">
10543 <content select=":not(app-drawer)"></content>
10544 </div>
10545
10546 <content id="drawerContent" select="app-drawer"></content>
10547
10548 <iron-media-query query="[[_computeMediaQuery(forceNarrow, responsiveWidth)] ]" on-query-matches-changed="_onQueryMatchesChanged"></iron-media-query>
10549 </template>
10550
10551 <script>
10552 Polymer({
10553 is: 'app-drawer-layout',
10554
10555 behaviors: [
10556 Polymer.IronResizableBehavior
10557 ],
10558
10559 properties: {
10560 /**
10561 * If true, ignore `responsiveWidth` setting and force the narrow layout .
10562 */
10563 forceNarrow: {
10564 type: Boolean,
10565 value: false
10566 },
10567
10568 /**
10569 * If the viewport's width is smaller than this value, the panel will ch ange to narrow
10570 * layout. In the mode the drawer will be closed.
10571 */
10572 responsiveWidth: {
10573 type: String,
10574 value: '640px'
10575 },
10576
10577 /**
10578 * Returns true if it is in narrow layout. This is useful if you need to show/hide
10579 * elements based on the layout.
10580 */
10581 narrow: {
10582 type: Boolean,
10583 readOnly: true,
10584 notify: true
10585 }
10586 },
10587
10588 listeners: {
10589 'tap': '_tapHandler',
10590 'app-drawer-reset-layout': 'resetLayout'
10591 },
10592
10593 observers: [
10594 'resetLayout(narrow, isAttached)'
10595 ],
10596
10597 /**
10598 * A reference to the app-drawer element.
10599 *
10600 * @property drawer
10601 */
10602 get drawer() {
10603 return Polymer.dom(this.$.drawerContent).getDistributedNodes()[0];
10604 },
10605
10606 _tapHandler: function(e) {
10607 var target = Polymer.dom(e).localTarget;
10608 if (target && target.hasAttribute('drawer-toggle')) {
10609 this.drawer.toggle();
10610 }
10611 },
10612
10613 resetLayout: function() {
10614 this.debounce('_resetLayout', function() {
10615 var drawer = this.drawer;
10616 var contentContainer = this.$.contentContainer;
10617
10618 if (this.narrow) {
10619 drawer.opened = drawer.persistent = false;
10620 contentContainer.classList.add('narrow');
10621
10622 contentContainer.style.marginLeft = '';
10623 contentContainer.style.marginRight = '';
10624 } else {
10625 drawer.opened = drawer.persistent = true;
10626 contentContainer.classList.remove('narrow');
10627
10628 var drawerWidth = this.drawer.getWidth();
10629 if (drawer.position == 'right') {
10630 contentContainer.style.marginLeft = '';
10631 contentContainer.style.marginRight = drawerWidth + 'px';
10632 } else {
10633 contentContainer.style.marginLeft = drawerWidth + 'px';
10634 contentContainer.style.marginRight = '';
10635 }
10636 }
10637
10638 this.notifyResize();
10639 });
10640 },
10641
10642 _onQueryMatchesChanged: function(event) {
10643 this._setNarrow(event.detail.value);
10644 },
10645
10646 _computeMediaQuery: function(forceNarrow, responsiveWidth) {
10647 return forceNarrow ? '(min-width: 0px)' : '(max-width: ' + responsiveWid th + ')';
10648 }
10649 });
10650 </script>
10651 </dom-module>
10652
10653
10654 <dom-module id="app-grid-style" assetpath="/res/imp/bower_components/app-layout/ app-grid/">
10655 <template>
10656 <style>
10657
10658 :host {
10659 /**
10660 * The width for the expandible item is:
10661 * ((100% - subPixelAdjustment) / columns * itemColumns - gutter * (colu mns - itemColumns)
10662 *
10663 * - subPixelAdjustment: 0.1px (Required for IE 11)
10664 * - gutter: var(--app-grid-gutter)
10665 * - columns: var(--app-grid-columns)
10666 * - itemColumn: var(--app-grid-expandible-item-columns)
10667 */
10668 --app-grid-expandible-item: {
10669 -webkit-flex-basis: calc((100% - 0.1px) / var(--app-grid-columns, 1) * var(--app-grid-expandible-item-columns, 1) - (var(--app-grid-gutter, 0px) * (va r(--app-grid-columns, 1) - var(--app-grid-expandible-item-columns, 1)))) !import ant;
10670 flex-basis: calc((100% - 0.1px) / var(--app-grid-columns, 1) * var(--a pp-grid-expandible-item-columns, 1) - (var(--app-grid-gutter, 0px) * (var(--app- grid-columns, 1) - var(--app-grid-expandible-item-columns, 1)))) !important;
10671 max-width: calc((100% - 0.1px) / var(--app-grid-columns, 1) * var(--ap p-grid-expandible-item-columns, 1) - (var(--app-grid-gutter, 0px) * (var(--app-g rid-columns, 1) - var(--app-grid-expandible-item-columns, 1)))) !important;
10672
10673 };
10674 }
10675
10676 .app-grid {
10677 display: -ms-flexbox;
10678 display: -webkit-flex;
10679 display: flex;
10680
10681 -ms-flex-direction: row;
10682 -webkit-flex-direction: row;
10683 flex-direction: row;
10684
10685 -ms-flex-wrap: wrap;
10686 -webkit-flex-wrap: wrap;
10687 flex-wrap: wrap;
10688
10689 margin-top: var(--app-grid-gutter, 0px);
10690 margin-left: var(--app-grid-gutter, 0px);
10691 }
10692
10693 .app-grid > * {
10694 /* Required for IE 10 */
10695 -ms-flex: 1 1 100%;
10696 -webkit-flex: 1;
10697 flex: 1;
10698
10699 /* The width for an item is: (100% - subPixelAdjustment - gutter * colum ns) / columns */
10700 -webkit-flex-basis: calc((100% - 0.1px - (var(--app-grid-gutter, 0px) * var(--app-grid-columns, 1))) / var(--app-grid-columns, 1));
10701 flex-basis: calc((100% - 0.1px - (var(--app-grid-gutter, 0px) * var(--ap p-grid-columns, 1))) / var(--app-grid-columns, 1));
10702
10703 max-width: calc((100% - 0.1px - (var(--app-grid-gutter, 0px) * var(--app -grid-columns, 1))) / var(--app-grid-columns, 1));
10704 margin-bottom: var(--app-grid-gutter, 0px);
10705 margin-right: var(--app-grid-gutter, 0px);
10706 height: var(--app-grid-item-height);
10707 box-sizing: border-box;
10708 }
10709
10710 .app-grid[has-aspect-ratio] > * {
10711 position: relative;
10712 }
10713
10714 .app-grid[has-aspect-ratio] > *::before {
10715 display: block;
10716 content: "";
10717 padding-top: var(--app-grid-item-height, 100%);
10718 }
10719
10720 .app-grid[has-aspect-ratio] > * > * {
10721 position: absolute;
10722 top: 0;
10723 right: 0;
10724 bottom: 0;
10725 left: 0;
10726 }
10727
10728 </style>
10729 </template>
10730 </dom-module>
10731 <script>
10732
10733 /**
10734 * `Polymer.IronScrollTargetBehavior` allows an element to respond to scroll e vents from a
10735 * designated scroll target.
10736 *
10737 * Elements that consume this behavior can override the `_scrollHandler`
10738 * method to add logic on the scroll event.
10739 *
10740 * @demo demo/scrolling-region.html Scrolling Region
10741 * @demo demo/document.html Document Element
10742 * @polymerBehavior
10743 */
10744 Polymer.IronScrollTargetBehavior = {
10745
10746 properties: {
10747
10748 /**
10749 * Specifies the element that will handle the scroll event
10750 * on the behalf of the current element. This is typically a reference to an element,
10751 * but there are a few more posibilities:
10752 *
10753 * ### Elements id
10754 *
10755 *```html
10756 * <div id="scrollable-element" style="overflow: auto;">
10757 * <x-element scroll-target="scrollable-element">
10758 * <!-- Content-->
10759 * </x-element>
10760 * </div>
10761 *```
10762 * In this case, the `scrollTarget` will point to the outer div element.
10763 *
10764 * ### Document scrolling
10765 *
10766 * For document scrolling, you can use the reserved word `document`:
10767 *
10768 *```html
10769 * <x-element scroll-target="document">
10770 * <!-- Content -->
10771 * </x-element>
10772 *```
10773 *
10774 * ### Elements reference
10775 *
10776 *```js
10777 * appHeader.scrollTarget = document.querySelector('#scrollable-element');
10778 *```
10779 *
10780 * @type {HTMLElement}
10781 */
10782 scrollTarget: {
10783 type: HTMLElement,
10784 value: function() {
10785 return this._defaultScrollTarget;
10786 }
10787 }
10788 },
10789
10790 observers: [
10791 '_scrollTargetChanged(scrollTarget, isAttached)'
10792 ],
10793
10794 _scrollTargetChanged: function(scrollTarget, isAttached) {
10795 var eventTarget;
10796
10797 if (this._oldScrollTarget) {
10798 eventTarget = this._oldScrollTarget === this._doc ? window : this._oldSc rollTarget;
10799 eventTarget.removeEventListener('scroll', this._boundScrollHandler);
10800 this._oldScrollTarget = null;
10801 }
10802
10803 if (!isAttached) {
10804 return;
10805 }
10806 // Support element id references
10807 if (scrollTarget === 'document') {
10808
10809 this.scrollTarget = this._doc;
10810
10811 } else if (typeof scrollTarget === 'string') {
10812
10813 this.scrollTarget = this.domHost ? this.domHost.$[scrollTarget] :
10814 Polymer.dom(this.ownerDocument).querySelector('#' + scrollTarget);
10815
10816 } else if (this._isValidScrollTarget()) {
10817
10818 eventTarget = scrollTarget === this._doc ? window : scrollTarget;
10819 this._boundScrollHandler = this._boundScrollHandler || this._scrollHandl er.bind(this);
10820 this._oldScrollTarget = scrollTarget;
10821
10822 eventTarget.addEventListener('scroll', this._boundScrollHandler);
10823 }
10824 },
10825
10826 /**
10827 * Runs on every scroll event. Consumer of this behavior may override this m ethod.
10828 *
10829 * @protected
10830 */
10831 _scrollHandler: function scrollHandler() {},
10832
10833 /**
10834 * The default scroll target. Consumers of this behavior may want to customi ze
10835 * the default scroll target.
10836 *
10837 * @type {Element}
10838 */
10839 get _defaultScrollTarget() {
10840 return this._doc;
10841 },
10842
10843 /**
10844 * Shortcut for the document element
10845 *
10846 * @type {Element}
10847 */
10848 get _doc() {
10849 return this.ownerDocument.documentElement;
10850 },
10851
10852 /**
10853 * Gets the number of pixels that the content of an element is scrolled upwa rd.
10854 *
10855 * @type {number}
10856 */
10857 get _scrollTop() {
10858 if (this._isValidScrollTarget()) {
10859 return this.scrollTarget === this._doc ? window.pageYOffset : this.scrol lTarget.scrollTop;
10860 }
10861 return 0;
10862 },
10863
10864 /**
10865 * Gets the number of pixels that the content of an element is scrolled to t he left.
10866 *
10867 * @type {number}
10868 */
10869 get _scrollLeft() {
10870 if (this._isValidScrollTarget()) {
10871 return this.scrollTarget === this._doc ? window.pageXOffset : this.scrol lTarget.scrollLeft;
10872 }
10873 return 0;
10874 },
10875
10876 /**
10877 * Sets the number of pixels that the content of an element is scrolled upwa rd.
10878 *
10879 * @type {number}
10880 */
10881 set _scrollTop(top) {
10882 if (this.scrollTarget === this._doc) {
10883 window.scrollTo(window.pageXOffset, top);
10884 } else if (this._isValidScrollTarget()) {
10885 this.scrollTarget.scrollTop = top;
10886 }
10887 },
10888
10889 /**
10890 * Sets the number of pixels that the content of an element is scrolled to t he left.
10891 *
10892 * @type {number}
10893 */
10894 set _scrollLeft(left) {
10895 if (this.scrollTarget === this._doc) {
10896 window.scrollTo(left, window.pageYOffset);
10897 } else if (this._isValidScrollTarget()) {
10898 this.scrollTarget.scrollLeft = left;
10899 }
10900 },
10901
10902 /**
10903 * Scrolls the content to a particular place.
10904 *
10905 * @method scroll
10906 * @param {number} left The left position
10907 * @param {number} top The top position
10908 */
10909 scroll: function(left, top) {
10910 if (this.scrollTarget === this._doc) {
10911 window.scrollTo(left, top);
10912 } else if (this._isValidScrollTarget()) {
10913 this.scrollTarget.scrollLeft = left;
10914 this.scrollTarget.scrollTop = top;
10915 }
10916 },
10917
10918 /**
10919 * Gets the width of the scroll target.
10920 *
10921 * @type {number}
10922 */
10923 get _scrollTargetWidth() {
10924 if (this._isValidScrollTarget()) {
10925 return this.scrollTarget === this._doc ? window.innerWidth : this.scroll Target.offsetWidth;
10926 }
10927 return 0;
10928 },
10929
10930 /**
10931 * Gets the height of the scroll target.
10932 *
10933 * @type {number}
10934 */
10935 get _scrollTargetHeight() {
10936 if (this._isValidScrollTarget()) {
10937 return this.scrollTarget === this._doc ? window.innerHeight : this.scrol lTarget.offsetHeight;
10938 }
10939 return 0;
10940 },
10941
10942 /**
10943 * Returns true if the scroll target is a valid HTMLElement.
10944 *
10945 * @return {boolean}
10946 */
10947 _isValidScrollTarget: function() {
10948 return this.scrollTarget instanceof HTMLElement;
10949 }
10950 };
10951
10952 </script>
10953 <script>
10954 /**
10955 * `Polymer.AppScrollEffectsBehavior` provides an interface that allows an ele ment to use scrolls effects.
10956 *
10957 * ### Importing the app-layout effects
10958 *
10959 * app-layout provides a set of scroll effects that can be used by explicitly importing
10960 * `app-scroll-effects.html`:
10961 *
10962 * ```html
10963 * <link rel="import" href="/bower_components/app-layout/app-scroll-effects/ap p-scroll-effects.html">
10964 * ```
10965 *
10966 * The scroll effects can also be used by individually importing
10967 * `app-layout/app-scroll-effects/effects/[effectName].html`. For example:
10968 *
10969 * ```html
10970 * <link rel="import" href="/bower_components/app-layout/app-scroll-effects/e ffects/waterfall.html">
10971 * ```
10972 *
10973 * ### Consuming effects
10974 *
10975 * Effects can be consumed via the `effects` property. For example:
10976 *
10977 * ```html
10978 * <app-header effects="waterfall"></app-header>
10979 * ```
10980 *
10981 * ### Creating scroll effects
10982 *
10983 * You may want to create a custom scroll effect if you need to modify the CSS of an element
10984 * based on the scroll position.
10985 *
10986 * A scroll effect definition is an object with `setUp()`, `tearDown()` and `r un()` functions.
10987 *
10988 * To register the effect, you can use `Polymer.AppLayout.registerEffect(effec tName, effectDef)`
10989 * For example, let's define an effect that resizes the header's logo:
10990 *
10991 * ```js
10992 * Polymer.AppLayout.registerEffect('resizable-logo', {
10993 * setUp: function(config) {
10994 * // the effect's config is passed to the setUp.
10995 * this._fxResizeLogo = { logo: Polymer.dom(this).querySelector('[logo]') };
10996 * },
10997 *
10998 * run: function(progress) {
10999 * // the progress of the effect
11000 * this.transform('scale3d(' + progress + ', '+ progress +', 1)', this._ fxResizeLogo.logo);
11001 * },
11002 *
11003 * tearDown: function() {
11004 * // clean up and reset of states
11005 * delete this._fxResizeLogo;
11006 * }
11007 * });
11008 * ```
11009 * Now, you can consume the effect:
11010 *
11011 * ```html
11012 * <app-header id="appHeader" effects="resizable-logo">
11013 * <img logo src="logo.svg">
11014 * </app-header>
11015 * ```
11016 *
11017 * ### Imperative API
11018 *
11019 * ```js
11020 * var logoEffect = appHeader.createEffect('resizable-logo', effectConfig);
11021 * // run the effect: logoEffect.run(progress);
11022 * // tear down the effect: logoEffect.tearDown();
11023 * ```
11024 *
11025 * ### Configuring effects
11026 *
11027 * For effects installed via the `effects` property, their configuration can b e set
11028 * via the `effectsConfig` property. For example:
11029 *
11030 * ```html
11031 * <app-header effects="waterfall"
11032 * effects-config='{"waterfall": {"startsAt": 0, "endsAt": 0.5}}'>
11033 * </app-header>
11034 * ```
11035 *
11036 * All effects have a `startsAt` and `endsAt` config property. They specify at what
11037 * point the effect should start and end. This value goes from 0 to 1 inclusiv e.
11038 *
11039 * @polymerBehavior
11040 */
11041 Polymer.AppScrollEffectsBehavior = [
11042 Polymer.IronScrollTargetBehavior,
11043 {
11044
11045 properties: {
11046
11047 /**
11048 * A space-separated list of the effects names that will be triggered when the user scrolls.
11049 * e.g. `waterfall parallax-background` installs the `waterfall` and `para llax-background`.
11050 */
11051 effects: {
11052 type: String
11053 },
11054
11055 /**
11056 * An object that configurates the effects installed via the `effects` pro perty. e.g.
11057 * ```js
11058 * element.effectsConfig = {
11059 * "blend-background": {
11060 * "startsAt": 0.5
11061 * }
11062 * };
11063 * ```
11064 * Every effect has at least two config properties: `startsAt` and `endsAt `.
11065 * These properties indicate when the event should start and end respectiv ely
11066 * and relative to the overall element progress. So for example, if `blend -background`
11067 * starts at `0.5`, the effect will only start once the current element re aches 0.5
11068 * of its progress. In this context, the progress is a value in the range of `[0, 1]`
11069 * that indicates where this element is on the screen relative to the view port.
11070 */
11071 effectsConfig: {
11072 type: Object,
11073 value: function() {
11074 return {};
11075 }
11076 },
11077
11078 /**
11079 * Disables CSS transitions and scroll effects on the element.
11080 */
11081 disabled: {
11082 type: Boolean,
11083 reflectToAttribute: true,
11084 value: false
11085 }
11086 },
11087
11088 observers: [
11089 '_effectsChanged(effects, effectsConfig, isAttached)'
11090 ],
11091
11092 /**
11093 * Updates the scroll state. This method should be overridden
11094 * by the consumer of this behavior.
11095 *
11096 * @method _updateScrollState
11097 */
11098 _updateScrollState: function() {},
11099
11100 /**
11101 * Returns true if the current element is on the screen.
11102 * That is, visible in the current viewport. This method should be
11103 * overridden by the consumer of this behavior.
11104 *
11105 * @method isOnScreen
11106 * @return {boolean}
11107 */
11108 isOnScreen: function() {
11109 return false;
11110 },
11111
11112 /**
11113 * Returns true if there's content below the current element. This method
11114 * should be overridden by the consumer of this behavior.
11115 *
11116 * @method isContentBelow
11117 * @return {boolean}
11118 */
11119 isContentBelow: function() {
11120 return false;
11121 },
11122
11123 /**
11124 * List of effects handlers that will take place during scroll.
11125 *
11126 * @type {Array<Function>}
11127 */
11128 _effectsRunFn: null,
11129
11130 /**
11131 * List of the effects definitions installed via the `effects` property.
11132 *
11133 * @type {Array<Object>}
11134 */
11135 _effects: null,
11136
11137 /**
11138 * The clamped value of `_scrollTop`.
11139 * @type number
11140 */
11141 get _clampedScrollTop() {
11142 return Math.max(0, this._scrollTop);
11143 },
11144
11145 detached: function() {
11146 this._tearDownEffects();
11147 },
11148
11149 /**
11150 * Creates an effect object from an effect's name that can be used to run
11151 * effects programmatically.
11152 *
11153 * @method createEffect
11154 * @param {string} effectName The effect's name registered via `Polymer.AppL ayout.registerEffect`.
11155 * @param {Object=} effectConfig The effect config object. (Optional)
11156 * @return {Object} An effect object with the following functions:
11157 *
11158 * * `effect.setUp()`, Sets up the requirements for the effect.
11159 * This function is called automatically before the `effect` function returns.
11160 * * `effect.run(progress, y)`, Runs the effect given a `progress`.
11161 * * `effect.tearDown()`, Cleans up any DOM nodes or element references use d by the effect.
11162 *
11163 * Example:
11164 * ```js
11165 * var parallax = element.createEffect('parallax-background');
11166 * // runs the effect
11167 * parallax.run(0.5, 0);
11168 * ```
11169 */
11170 createEffect: function(effectName, effectConfig) {
11171 var effectDef = Polymer.AppLayout._scrollEffects[effectName];
11172 if (!effectDef) {
11173 throw new ReferenceError(this._getUndefinedMsg(effectName));
11174 }
11175 var prop = this._boundEffect(effectDef, effectConfig || {});
11176 prop.setUp();
11177 return prop;
11178 },
11179
11180 /**
11181 * Called when `effects` or `effectsConfig` changes.
11182 */
11183 _effectsChanged: function(effects, effectsConfig, isAttached) {
11184 this._tearDownEffects();
11185
11186 if (effects === '' || !isAttached) {
11187 return;
11188 }
11189 effects.split(' ').forEach(function(effectName) {
11190 var effectDef;
11191 if (effectName !== '') {
11192 if ((effectDef = Polymer.AppLayout._scrollEffects[effectName])) {
11193 this._effects.push(this._boundEffect(effectDef, effectsConfig[effect Name]));
11194 } else {
11195 this._warn(this._logf('_effectsChanged', this._getUndefinedMsg(effec tName)));
11196 }
11197 }
11198 }, this);
11199
11200 this._setUpEffect();
11201 },
11202
11203 /**
11204 * Forces layout
11205 */
11206 _layoutIfDirty: function() {
11207 return this.offsetWidth;
11208 },
11209
11210 /**
11211 * Returns an effect object bound to the current context.
11212 *
11213 * @param {Object} effectDef
11214 * @param {Object=} effectsConfig The effect config object if the effect acc epts config values. (Optional)
11215 */
11216 _boundEffect: function(effectDef, effectsConfig) {
11217 effectsConfig = effectsConfig || {};
11218 var startsAt = parseFloat(effectsConfig.startsAt || 0);
11219 var endsAt = parseFloat(effectsConfig.endsAt || 1);
11220 var deltaS = endsAt - startsAt;
11221 var noop = Function();
11222 // fast path if possible
11223 var runFn = (startsAt === 0 && endsAt === 1) ? effectDef.run :
11224 function(progress, y) {
11225 effectDef.run.call(this,
11226 Math.max(0, (progress - startsAt) / deltaS), y);
11227 };
11228 return {
11229 setUp: effectDef.setUp ? effectDef.setUp.bind(this, effectsConfig) : noo p,
11230 run: effectDef.run ? runFn.bind(this) : noop,
11231 tearDown: effectDef.tearDown ? effectDef.tearDown.bind(this) : noop
11232 };
11233 },
11234
11235 /**
11236 * Sets up the effects.
11237 */
11238 _setUpEffect: function() {
11239 if (this.isAttached && this._effects) {
11240 this._effectsRunFn = [];
11241 this._effects.forEach(function(effectDef) {
11242 // install the effect only if no error was reported
11243 if (effectDef.setUp() !== false) {
11244 this._effectsRunFn.push(effectDef.run);
11245 }
11246 }, this);
11247 }
11248 },
11249
11250 /**
11251 * Tears down the effects.
11252 */
11253 _tearDownEffects: function() {
11254 if (this._effects) {
11255 this._effects.forEach(function(effectDef) {
11256 effectDef.tearDown();
11257 });
11258 }
11259 this._effectsRunFn = [];
11260 this._effects = [];
11261 },
11262
11263 /**
11264 * Runs the effects.
11265 *
11266 * @param {number} p The progress
11267 * @param {number} y The top position of the current element relative to the viewport.
11268 */
11269 _runEffects: function(p, y) {
11270 if (this._effectsRunFn) {
11271 this._effectsRunFn.forEach(function(run) {
11272 run(p, y);
11273 });
11274 }
11275 },
11276
11277 /**
11278 * Overrides the `_scrollHandler`.
11279 */
11280 _scrollHandler: function() {
11281 if (!this.disabled) {
11282 this._updateScrollState(this._clampedScrollTop);
11283 }
11284 },
11285
11286 /**
11287 * Override this method to return a reference to a node in the local DOM.
11288 * The node is consumed by a scroll effect.
11289 *
11290 * @param {string} id The id for the node.
11291 */
11292 _getDOMRef: function(id) {
11293 this._warn(this._logf('_getDOMRef', '`'+ id +'` is undefined'));
11294 },
11295
11296 _getUndefinedMsg: function(effectName) {
11297 return 'Scroll effect `' + effectName + '` is undefined. ' +
11298 'Did you forget to import app-layout/app-scroll-effects/effects/' + ef fectName + '.html ?';
11299 }
11300
11301 }];
11302
11303 </script>
11304
11305
11306 <dom-module id="app-header" assetpath="/res/imp/bower_components/app-layout/app- header/">
11307 <template>
11308 <style>
11309 :host {
11310 position: relative;
11311 display: block;
11312 transition-timing-function: linear;
11313 transition-property: -webkit-transform;
11314 transition-property: transform;
11315 }
11316
11317 :host::after {
11318 position: absolute;
11319 right: 0px;
11320 bottom: -5px;
11321 left: 0px;
11322 width: 100%;
11323 height: 5px;
11324 content: "";
11325 transition: opacity 0.4s;
11326 pointer-events: none;
11327 opacity: 0;
11328 box-shadow: inset 0px 5px 6px -3px rgba(0, 0, 0, 0.4);
11329 will-change: opacity;
11330 @apply(--app-header-shadow);
11331 }
11332
11333 :host([shadow])::after {
11334 opacity: 1;
11335 }
11336
11337 #contentContainer > ::content [condensed-title] {
11338 -webkit-transform-origin: left top;
11339 transform-origin: left top;
11340 white-space: nowrap;
11341 opacity: 0;
11342 }
11343
11344 #contentContainer > ::content [main-title] {
11345 -webkit-transform-origin: left top;
11346 transform-origin: left top;
11347 white-space: nowrap;
11348 }
11349
11350 #background {
11351 @apply(--layout-fit);
11352 overflow: hidden;
11353 }
11354
11355 #backgroundFrontLayer,
11356 #backgroundRearLayer {
11357 @apply(--layout-fit);
11358 height: 100%;
11359 pointer-events: none;
11360 background-size: cover;
11361 }
11362
11363 #backgroundFrontLayer {
11364 @apply(--app-header-background-front-layer);
11365 }
11366
11367 #backgroundRearLayer {
11368 opacity: 0;
11369 @apply(--app-header-background-rear-layer);
11370 }
11371
11372 #contentContainer {
11373 position: relative;
11374 width: 100%;
11375 height: 100%;
11376 }
11377
11378 :host([disabled]),
11379 :host([disabled])::after,
11380 :host([disabled]) #backgroundFrontLayer,
11381 :host([disabled]) #backgroundRearLayer,
11382 :host([disabled]) ::content > app-toolbar:first-of-type,
11383 :host([disabled]) ::content > [sticky],
11384 /* Silent scrolling should not run CSS transitions */
11385 :host-context(.app-layout-silent-scroll),
11386 :host-context(.app-layout-silent-scroll)::after,
11387 :host-context(.app-layout-silent-scroll) #backgroundFrontLayer,
11388 :host-context(.app-layout-silent-scroll) #backgroundRearLayer,
11389 :host-context(.app-layout-silent-scroll) ::content > app-toolbar:first-of- type,
11390 :host-context(.app-layout-silent-scroll) ::content > [sticky] {
11391 transition: none !important;
11392 }
11393 </style>
11394 <div id="contentContainer">
11395 <content id="content"></content>
11396 </div>
11397 </template>
11398
11399 <script>
11400 Polymer({
11401 is: 'app-header',
11402
11403 behaviors: [
11404 Polymer.AppScrollEffectsBehavior,
11405 Polymer.IronResizableBehavior
11406 ],
11407
11408 properties: {
11409 /**
11410 * If true, the header will automatically collapse when scrolling down.
11411 * That is, the `sticky` element remains visible when the header is full y condensed
11412 * whereas the rest of the elements will collapse below `sticky` element .
11413 *
11414 * By default, the `sticky` element is the first toolbar in the light DO M:
11415 *
11416 *```html
11417 * <app-header condenses>
11418 * <app-toolbar>This toolbar remains on top</app-toolbar>
11419 * <app-toolbar></app-toolbar>
11420 * <app-toolbar></app-toolbar>
11421 * </app-header>
11422 * ```
11423 *
11424 * Additionally, you can specify which toolbar or element remains visibl e in condensed mode
11425 * by adding the `sticky` attribute to that element. For example: if we want the last
11426 * toolbar to remain visible, we can add the `sticky` attribute to it.
11427 *
11428 *```html
11429 * <app-header condenses>
11430 * <app-toolbar></app-toolbar>
11431 * <app-toolbar></app-toolbar>
11432 * <app-toolbar sticky>This toolbar remains on top</app-toolbar>
11433 * </app-header>
11434 * ```
11435 *
11436 * Note the `sticky` element must be a direct child of `app-header`.
11437 */
11438 condenses: {
11439 type: Boolean,
11440 value: false
11441 },
11442
11443 /**
11444 * Mantains the header fixed at the top so it never moves away.
11445 */
11446 fixed: {
11447 type: Boolean,
11448 value: false
11449 },
11450
11451 /**
11452 * Slides back the header when scrolling back up.
11453 */
11454 reveals: {
11455 type: Boolean,
11456 value: false
11457 },
11458
11459 /**
11460 * Displays a shadow below the header.
11461 */
11462 shadow: {
11463 type: Boolean,
11464 reflectToAttribute: true,
11465 value: false
11466 }
11467 },
11468
11469 observers: [
11470 'resetLayout(isAttached, condenses, fixed)'
11471 ],
11472
11473 listeners: {
11474 'iron-resize': '_resizeHandler'
11475 },
11476
11477 /**
11478 * A cached offsetHeight of the current element.
11479 *
11480 * @type {number}
11481 */
11482 _height: 0,
11483
11484 /**
11485 * The distance in pixels the header will be translated to when scrolling.
11486 *
11487 * @type {number}
11488 */
11489 _dHeight: 0,
11490
11491 /**
11492 * The offsetTop of `_stickyEl`
11493 *
11494 * @type {number}
11495 */
11496 _stickyElTop: 0,
11497
11498 /**
11499 * The element that remains visible when the header condenses.
11500 *
11501 * @type {HTMLElement}
11502 */
11503 _stickyEl: null,
11504
11505 /**
11506 * The header's top value used for the `transformY`
11507 *
11508 * @type {number}
11509 */
11510 _top: 0,
11511
11512 /**
11513 * The current scroll progress.
11514 *
11515 * @type {number}
11516 */
11517 _progress: 0,
11518
11519 _wasScrollingDown: false,
11520 _initScrollTop: 0,
11521 _initTimestamp: 0,
11522 _lastTimestamp: 0,
11523 _lastScrollTop: 0,
11524
11525 /**
11526 * The distance the header is allowed to move away.
11527 *
11528 * @type {number}
11529 */
11530 get _maxHeaderTop() {
11531 return this.fixed ? this._dHeight : this._height + 5;
11532 },
11533
11534 /**
11535 * Returns a reference to the sticky element.
11536 *
11537 * @return {HTMLElement}?
11538 */
11539 _getStickyEl: function() {
11540 /** @type {HTMLElement} */
11541 var stickyEl;
11542 var nodes = Polymer.dom(this.$.content).getDistributedNodes();
11543
11544 for (var i = 0; i < nodes.length; i++) {
11545 if (nodes[i].nodeType === Node.ELEMENT_NODE) {
11546 var node = /** @type {HTMLElement} */ (nodes[i]);
11547 if (node.hasAttribute('sticky')) {
11548 stickyEl = node;
11549 break;
11550 } else if (!stickyEl) {
11551 stickyEl = node;
11552 }
11553 }
11554 }
11555 return stickyEl;
11556 },
11557
11558 /**
11559 * Resets the layout. If you changed the size of app-header via CSS
11560 * you can notify the changes by either firing the `iron-resize` event
11561 * or calling `resetLayout` directly.
11562 *
11563 * @method resetLayout
11564 */
11565 resetLayout: function() {
11566 this.fire('app-header-reset-layout');
11567
11568 this.debounce('_resetLayout', function() {
11569 // noop if the header isn't visible
11570 if (this.offsetWidth === 0 && this.offsetHeight === 0) {
11571 return;
11572 }
11573
11574 var scrollTop = this._clampedScrollTop;
11575 var firstSetup = this._height === 0 || scrollTop === 0;
11576 var currentDisabled = this.disabled;
11577
11578 this._height = this.offsetHeight;
11579 this._stickyEl = this._getStickyEl();
11580 this.disabled = true;
11581
11582 // prepare for measurement
11583 if (!firstSetup) {
11584 this._updateScrollState(0, true);
11585 }
11586
11587 if (this._mayMove()) {
11588 this._dHeight = this._stickyEl ? this._height - this._stickyEl.offse tHeight : 0;
11589 } else {
11590 this._dHeight = 0;
11591 }
11592
11593 this._stickyElTop = this._stickyEl ? this._stickyEl.offsetTop : 0;
11594 this._setUpEffect();
11595
11596 if (firstSetup) {
11597 this._updateScrollState(scrollTop, true);
11598 } else {
11599 this._updateScrollState(this._lastScrollTop, true);
11600 this._layoutIfDirty();
11601 }
11602 // restore no transition
11603 this.disabled = currentDisabled;
11604 });
11605 },
11606
11607 /**
11608 * Updates the scroll state.
11609 *
11610 * @param {number} scrollTop
11611 * @param {boolean=} forceUpdate (default: false)
11612 */
11613 _updateScrollState: function(scrollTop, forceUpdate) {
11614 if (this._height === 0) {
11615 return;
11616 }
11617
11618 var progress = 0;
11619 var top = 0;
11620 var lastTop = this._top;
11621 var lastScrollTop = this._lastScrollTop;
11622 var maxHeaderTop = this._maxHeaderTop;
11623 var dScrollTop = scrollTop - this._lastScrollTop;
11624 var absDScrollTop = Math.abs(dScrollTop);
11625 var isScrollingDown = scrollTop > this._lastScrollTop;
11626 var now = Date.now();
11627
11628 if (this._mayMove()) {
11629 top = this._clamp(this.reveals ? lastTop + dScrollTop : scrollTop, 0, maxHeaderTop);
11630 }
11631
11632 if (scrollTop >= this._dHeight) {
11633 top = this.condenses && !this.fixed ? Math.max(this._dHeight, top) : t op;
11634 this.style.transitionDuration = '0ms';
11635 }
11636
11637 if (this.reveals && !this.disabled && absDScrollTop < 100) {
11638 // set the initial scroll position
11639 if (now - this._initTimestamp > 300 || this._wasScrollingDown !== isSc rollingDown) {
11640 this._initScrollTop = scrollTop;
11641 this._initTimestamp = now;
11642 }
11643
11644 if (scrollTop >= maxHeaderTop) {
11645 // check if the header is allowed to snap
11646 if (Math.abs(this._initScrollTop - scrollTop) > 30 || absDScrollTop > 10) {
11647 if (isScrollingDown && scrollTop >= maxHeaderTop) {
11648 top = maxHeaderTop;
11649 } else if (!isScrollingDown && scrollTop >= this._dHeight) {
11650 top = this.condenses && !this.fixed ? this._dHeight : 0;
11651 }
11652 var scrollVelocity = dScrollTop / (now - this._lastTimestamp);
11653 this.style.transitionDuration = this._clamp((top - lastTop) / scro llVelocity, 0, 300) + 'ms';
11654 } else {
11655 top = this._top;
11656 }
11657 }
11658 }
11659
11660 if (this._dHeight === 0) {
11661 progress = scrollTop > 0 ? 1 : 0;
11662 } else {
11663 progress = top / this._dHeight;
11664 }
11665
11666 if (!forceUpdate) {
11667 this._lastScrollTop = scrollTop;
11668 this._top = top;
11669 this._wasScrollingDown = isScrollingDown;
11670 this._lastTimestamp = now;
11671 }
11672
11673 if (forceUpdate || progress !== this._progress || lastTop !== top || scr ollTop === 0) {
11674 this._progress = progress;
11675 this._runEffects(progress, top);
11676 this._transformHeader(top);
11677 }
11678 },
11679
11680 /**
11681 * Returns true if the current header is allowed to move as the user scrol ls.
11682 *
11683 * @return {boolean}
11684 */
11685 _mayMove: function() {
11686 return this.condenses || !this.fixed;
11687 },
11688
11689 /**
11690 * Returns true if the current header will condense based on the size of t he header
11691 * and the `consenses` property.
11692 *
11693 * @return {boolean}
11694 */
11695 willCondense: function() {
11696 return this._dHeight > 0 && this.condenses;
11697 },
11698
11699 /**
11700 * Returns true if the current element is on the screen.
11701 * That is, visible in the current viewport.
11702 *
11703 * @method isOnScreen
11704 * @return {boolean}
11705 */
11706 isOnScreen: function() {
11707 return this._height !== 0 && this._top < this._height;
11708 },
11709
11710 /**
11711 * Returns true if there's content below the current element.
11712 *
11713 * @method isContentBelow
11714 * @return {boolean}
11715 */
11716 isContentBelow: function() {
11717 if (this._top === 0) {
11718 return this._clampedScrollTop > 0;
11719 }
11720 return this._clampedScrollTop - this._maxHeaderTop >= 0;
11721 },
11722
11723 /**
11724 * Transforms the header.
11725 *
11726 * @param {number} y
11727 */
11728 _transformHeader: function(y) {
11729 this.translate3d(0, (-y) + 'px', 0);
11730 if (this._stickyEl && this.condenses && y >= this._stickyElTop) {
11731 this.translate3d(0, (Math.min(y, this._dHeight) - this._stickyElTop) + 'px', 0,
11732 this._stickyEl);
11733 }
11734 },
11735
11736 _resizeHandler: function() {
11737 this.resetLayout();
11738 },
11739
11740 _clamp: function(v, min, max) {
11741 return Math.min(max, Math.max(min, v));
11742 },
11743
11744 _ensureBgContainers: function() {
11745 if (!this._bgContainer) {
11746 this._bgContainer = document.createElement('div');
11747 this._bgContainer.id = 'background';
11748
11749 this._bgRear = document.createElement('div');
11750 this._bgRear.id = 'backgroundRearLayer';
11751 this._bgContainer.appendChild(this._bgRear);
11752
11753 this._bgFront = document.createElement('div');
11754 this._bgFront.id = 'backgroundFrontLayer';
11755 this._bgContainer.appendChild(this._bgFront);
11756
11757 Polymer.dom(this.root).insertBefore(this._bgContainer, this.$.contentC ontainer);
11758 }
11759 },
11760
11761 _getDOMRef: function(id) {
11762 switch (id) {
11763 case 'backgroundFrontLayer':
11764 this._ensureBgContainers();
11765 return this._bgFront;
11766 case 'backgroundRearLayer':
11767 this._ensureBgContainers();
11768 return this._bgRear;
11769 case 'background':
11770 this._ensureBgContainers();
11771 return this._bgContainer;
11772 case 'mainTitle':
11773 return Polymer.dom(this).querySelector('[main-title]');
11774 case 'condensedTitle':
11775 return Polymer.dom(this).querySelector('[condensed-title]');
11776 }
11777 return null;
11778 },
11779
11780 /**
11781 * Returns an object containing the progress value of the scroll effects
11782 * and the top position of the header.
11783 *
11784 * @method getScrollState
11785 * @return {Object}
11786 */
11787 getScrollState: function() {
11788 return { progress: this._progress, top: this._top };
11789 }
11790
11791 /**
11792 * Fires when the layout of `app-header` changed.
11793 *
11794 * @event app-header-reset-layout
11795 */
11796 });
11797 </script>
11798 </dom-module>
11799
11800
11801 <dom-module id="app-header-layout" assetpath="/res/imp/bower_components/app-layo ut/app-header-layout/">
11802 <template>
11803 <style>
11804 :host {
11805 display: block;
11806 /**
11807 * Force app-header-layout to have its own stacking context so that its parent can
11808 * control the stacking of it relative to other elements (e.g. app-drawe r-layout).
11809 * This could be done using `isolation: isolate`, but that's not well su pported
11810 * across browsers.
11811 */
11812 position: relative;
11813 z-index: 0;
11814 }
11815
11816 :host > ::content > app-header {
11817 @apply(--layout-fixed-top);
11818 z-index: 1;
11819 }
11820
11821 :host([has-scrolling-region]) {
11822 height: 100%;
11823 }
11824
11825 :host([has-scrolling-region]) > ::content > app-header {
11826 position: absolute;
11827 }
11828
11829 :host([has-scrolling-region]) > #contentContainer {
11830 @apply(--layout-fit);
11831 overflow-y: auto;
11832 -webkit-overflow-scrolling: touch;
11833 }
11834
11835 :host([fullbleed]) {
11836 @apply(--layout-vertical);
11837 @apply(--layout-fit);
11838 }
11839
11840 :host([fullbleed]) > #contentContainer {
11841 @apply(--layout-vertical);
11842 @apply(--layout-flex);
11843 }
11844
11845 #contentContainer {
11846 /* Create a stacking context here so that all children appear below the header. */
11847 position: relative;
11848 z-index: 0;
11849 }
11850
11851 </style>
11852
11853 <content id="header" select="app-header"></content>
11854
11855 <div id="contentContainer">
11856 <content></content>
11857 </div>
11858
11859 </template>
11860
11861 <script>
11862 Polymer({
11863 is: 'app-header-layout',
11864
11865 behaviors: [
11866 Polymer.IronResizableBehavior
11867 ],
11868
11869 properties: {
11870 /**
11871 * If true, the current element will have its own scrolling region.
11872 * Otherwise, it will use the document scroll to control the header.
11873 */
11874 hasScrollingRegion: {
11875 type: Boolean,
11876 value: false,
11877 reflectToAttribute: true
11878 }
11879 },
11880
11881 listeners: {
11882 'iron-resize': '_resizeHandler',
11883 'app-header-reset-layout': 'resetLayout'
11884 },
11885
11886 observers: [
11887 'resetLayout(isAttached, hasScrollingRegion)'
11888 ],
11889
11890 /**
11891 * A reference to the app-header element.
11892 *
11893 * @property header
11894 */
11895 get header() {
11896 return Polymer.dom(this.$.header).getDistributedNodes()[0];
11897 },
11898
11899 /**
11900 * Resets the layout. This method is automatically called when the element is attached
11901 * to the DOM.
11902 *
11903 * @method resetLayout
11904 */
11905 resetLayout: function() {
11906 this._updateScroller();
11907 this.debounce('_resetLayout', this._updateContentPosition);
11908 },
11909
11910 _updateContentPosition: function() {
11911 var header = this.header;
11912 if (!this.isAttached || !header) {
11913 return;
11914 }
11915 // Get header height here so that style reads are batched together befor e style writes
11916 // (i.e. getBoundingClientRect() below).
11917 var headerHeight = header.offsetHeight;
11918 // Update the header position.
11919 if (!this.hasScrollingRegion) {
11920 var rect = this.getBoundingClientRect();
11921 var rightOffset = document.documentElement.clientWidth - rect.right;
11922 header.style.left = rect.left + 'px';
11923 header.style.right = rightOffset + 'px';
11924 } else {
11925 header.style.left = '';
11926 header.style.right = '';
11927 }
11928 // Update the content container position.
11929 var containerStyle = this.$.contentContainer.style;
11930 if (header.fixed && !header.willCondense() && this.hasScrollingRegion) {
11931 // If the header size does not change and we're using a scrolling regi on, exclude
11932 // the header area from the scrolling region so that the header doesn' t overlap
11933 // the scrollbar.
11934 containerStyle.marginTop = headerHeight + 'px';
11935 containerStyle.paddingTop = '';
11936 } else {
11937 containerStyle.paddingTop = headerHeight + 'px';
11938 containerStyle.marginTop = '';
11939 }
11940 },
11941
11942 _updateScroller: function() {
11943 if (!this.isAttached) {
11944 return;
11945 }
11946 var header = this.header;
11947 if (header) {
11948 header.scrollTarget = this.hasScrollingRegion ?
11949 this.$.contentContainer : this.ownerDocument.documentElement;
11950 }
11951 },
11952
11953 _resizeHandler: function() {
11954 this.resetLayout();
11955 }
11956 });
11957 </script>
11958 </dom-module>
11959
11960
11961 <dom-module id="app-scrollpos-control" assetpath="/res/imp/bower_components/app- layout/app-scrollpos-control/">
11962 <script>
11963 Polymer({
11964 is: 'app-scrollpos-control',
11965
11966 behaviors: [
11967 Polymer.IronScrollTargetBehavior
11968 ],
11969
11970 properties: {
11971 /**
11972 * The selected page.
11973 */
11974 selected: {
11975 type: String,
11976 observer: '_selectedChanged'
11977 },
11978
11979 /**
11980 * Reset the scroll position to 0.
11981 */
11982 reset: {
11983 type: Boolean,
11984 value: false
11985 }
11986 },
11987
11988 observers: [
11989 '_updateScrollPos(selected, reset)'
11990 ],
11991
11992 created: function() {
11993 this._scrollposMap = {};
11994 },
11995
11996 _selectedChanged: function(selected, old) {
11997 if (old != null) {
11998 this._scrollposMap[old] = {x: this._scrollLeft, y: this._scrollTop};
11999 }
12000 },
12001
12002 _updateScrollPos: function(selected, reset) {
12003 this.debounce('_updateScrollPos', function() {
12004 var pos = this._scrollposMap[this.selected];
12005 if (pos != null && !this.reset) {
12006 this.scroll(pos.x, pos.y);
12007 } else {
12008 this.scroll(0, 0);
12009 }
12010 });
12011 }
12012 });
12013 </script>
12014 </dom-module>
12015
12016
12017 <dom-module id="app-toolbar" assetpath="/res/imp/bower_components/app-layout/app -toolbar/">
12018 <template>
12019 <style>
12020 :host {
12021 position: relative;
12022
12023 @apply(--layout-horizontal);
12024 @apply(--layout-center);
12025
12026 height: 64px;
12027 padding: 0 16px;
12028
12029 pointer-events: none;
12030
12031 font-size: var(--app-toolbar-font-size, 20px);
12032 }
12033
12034 :host > ::content > * {
12035 pointer-events: auto;
12036 }
12037
12038 :host > ::content > paper-icon-button {
12039 /* paper-icon-button/issues/33 */
12040 font-size: 0;
12041 }
12042
12043 :host > ::content > [main-title],
12044 :host > ::content > [condensed-title] {
12045 pointer-events: none;
12046 @apply(--layout-flex);
12047 }
12048
12049 :host > ::content > [bottom-item] {
12050 position: absolute;
12051 right: 0;
12052 bottom: 0;
12053 left: 0;
12054 }
12055
12056 :host > ::content > [top-item] {
12057 position: absolute;
12058 top: 0;
12059 right: 0;
12060 left: 0;
12061 }
12062
12063 :host > ::content > [spacer] {
12064 margin-left: 64px;
12065 }
12066 </style>
12067
12068 <content></content>
12069 </template>
12070
12071 <script>
12072 Polymer({
12073 is: 'app-toolbar'
12074 });
12075 </script>
12076 </dom-module>
12077
12078
12079 <dom-module id="app-box" assetpath="/res/imp/bower_components/app-layout/app-box /">
12080 <template>
12081 <style>
12082 :host {
12083 position: relative;
12084
12085 display: block;
12086 }
12087
12088 #background {
12089 @apply(--layout-fit);
12090
12091 overflow: hidden;
12092
12093 height: 100%;
12094 }
12095
12096 #backgroundFrontLayer {
12097 min-height: 100%;
12098
12099 pointer-events: none;
12100
12101 background-size: cover;
12102
12103 @apply(--app-box-background-front-layer);
12104 }
12105
12106 #contentContainer {
12107 position: relative;
12108
12109 width: 100%;
12110 height: 100%;
12111 }
12112
12113 :host([disabled]),
12114 :host([disabled]) #backgroundFrontLayer {
12115 transition: none !important;
12116 }
12117 </style>
12118
12119 <div id="background">
12120 <div id="backgroundFrontLayer">
12121 <content select="[background]"></content>
12122 </div>
12123 </div>
12124 <div id="contentContainer">
12125 <content id="content"></content>
12126 </div>
12127 </template>
12128
12129 <script>
12130 Polymer({
12131 is: 'app-box',
12132
12133 behaviors: [
12134 Polymer.AppScrollEffectsBehavior,
12135 Polymer.IronResizableBehavior
12136 ],
12137
12138 listeners: {
12139 'iron-resize': '_resizeHandler'
12140 },
12141
12142 /**
12143 * The current scroll progress.
12144 *
12145 * @type {number}
12146 */
12147 _progress: 0,
12148
12149 attached: function() {
12150 this.resetLayout();
12151 },
12152
12153 /**
12154 * Resets the layout. This method is automatically called when the element is attached to the DOM.
12155 *
12156 * @method resetLayout
12157 */
12158 resetLayout: function() {
12159 this.debounce('_resetLayout', function() {
12160 // noop if the box isn't in the rendered tree
12161 if (this.offsetWidth === 0 && this.offsetHeight === 0) {
12162 return;
12163 }
12164
12165 var scrollTop = this._clampedScrollTop;
12166 var savedDisabled = this.disabled;
12167
12168 this.disabled = true;
12169 this._elementTop = this._getElementTop();
12170 this._elementHeight = this.offsetHeight;
12171 this._cachedScrollTargetHeight = this._scrollTargetHeight;
12172 this._setUpEffect();
12173 this._updateScrollState(scrollTop);
12174 this.disabled = savedDisabled;
12175 }, 1);
12176 },
12177
12178 _getElementTop: function() {
12179 var currentNode = this;
12180 var top = 0;
12181
12182 while (currentNode && currentNode !== this.scrollTarget) {
12183 top += currentNode.offsetTop;
12184 currentNode = currentNode.offsetParent;
12185 }
12186 return top;
12187 },
12188
12189 _updateScrollState: function(scrollTop) {
12190 if (this.isOnScreen()) {
12191 var viewportTop = this._elementTop - scrollTop;
12192 this._progress = 1 - (viewportTop + this._elementHeight) / this._cache dScrollTargetHeight;
12193 this._runEffects(this._progress, scrollTop);
12194 }
12195 },
12196
12197 /**
12198 * Returns true if this app-box is on the screen.
12199 * That is, visible in the current viewport.
12200 *
12201 * @method isOnScreen
12202 * @return {boolean}
12203 */
12204 isOnScreen: function() {
12205 return this._elementTop < this._scrollTop + this._cachedScrollTargetHeig ht
12206 && this._elementTop + this._elementHeight > this._scrollTop;
12207 },
12208
12209 _resizeHandler: function() {
12210 this.resetLayout();
12211 },
12212
12213 _getDOMRef: function(id) {
12214 if (id === 'background') {
12215 return this.$.background;
12216 }
12217 if (id === 'backgroundFrontLayer') {
12218 return this.$.backgroundFrontLayer;
12219 }
12220 },
12221
12222 /**
12223 * Returns an object containing the progress value of the scroll effects.
12224 *
12225 * @method getScrollState
12226 * @return {Object}
12227 */
12228 getScrollState: function() {
12229 return { progress: this._progress };
12230 }
12231 });
12232 </script>
12233 </dom-module>
12234 <style is="custom-style">
12235
12236 :root {
12237
12238 /* Material Design color palette for Google products */
12239
12240 --google-red-100: #f4c7c3;
12241 --google-red-300: #e67c73;
12242 --google-red-500: #db4437;
12243 --google-red-700: #c53929;
12244
12245 --google-blue-100: #c6dafc;
12246 --google-blue-300: #7baaf7;
12247 --google-blue-500: #4285f4;
12248 --google-blue-700: #3367d6;
12249
12250 --google-green-100: #b7e1cd;
12251 --google-green-300: #57bb8a;
12252 --google-green-500: #0f9d58;
12253 --google-green-700: #0b8043;
12254
12255 --google-yellow-100: #fce8b2;
12256 --google-yellow-300: #f7cb4d;
12257 --google-yellow-500: #f4b400;
12258 --google-yellow-700: #f09300;
12259
12260 --google-grey-100: #f5f5f5;
12261 --google-grey-300: #e0e0e0;
12262 --google-grey-500: #9e9e9e;
12263 --google-grey-700: #616161;
12264
12265 /* Material Design color palette from online spec document */
12266
12267 --paper-red-50: #ffebee;
12268 --paper-red-100: #ffcdd2;
12269 --paper-red-200: #ef9a9a;
12270 --paper-red-300: #e57373;
12271 --paper-red-400: #ef5350;
12272 --paper-red-500: #f44336;
12273 --paper-red-600: #e53935;
12274 --paper-red-700: #d32f2f;
12275 --paper-red-800: #c62828;
12276 --paper-red-900: #b71c1c;
12277 --paper-red-a100: #ff8a80;
12278 --paper-red-a200: #ff5252;
12279 --paper-red-a400: #ff1744;
12280 --paper-red-a700: #d50000;
12281
12282 --paper-pink-50: #fce4ec;
12283 --paper-pink-100: #f8bbd0;
12284 --paper-pink-200: #f48fb1;
12285 --paper-pink-300: #f06292;
12286 --paper-pink-400: #ec407a;
12287 --paper-pink-500: #e91e63;
12288 --paper-pink-600: #d81b60;
12289 --paper-pink-700: #c2185b;
12290 --paper-pink-800: #ad1457;
12291 --paper-pink-900: #880e4f;
12292 --paper-pink-a100: #ff80ab;
12293 --paper-pink-a200: #ff4081;
12294 --paper-pink-a400: #f50057;
12295 --paper-pink-a700: #c51162;
12296
12297 --paper-purple-50: #f3e5f5;
12298 --paper-purple-100: #e1bee7;
12299 --paper-purple-200: #ce93d8;
12300 --paper-purple-300: #ba68c8;
12301 --paper-purple-400: #ab47bc;
12302 --paper-purple-500: #9c27b0;
12303 --paper-purple-600: #8e24aa;
12304 --paper-purple-700: #7b1fa2;
12305 --paper-purple-800: #6a1b9a;
12306 --paper-purple-900: #4a148c;
12307 --paper-purple-a100: #ea80fc;
12308 --paper-purple-a200: #e040fb;
12309 --paper-purple-a400: #d500f9;
12310 --paper-purple-a700: #aa00ff;
12311
12312 --paper-deep-purple-50: #ede7f6;
12313 --paper-deep-purple-100: #d1c4e9;
12314 --paper-deep-purple-200: #b39ddb;
12315 --paper-deep-purple-300: #9575cd;
12316 --paper-deep-purple-400: #7e57c2;
12317 --paper-deep-purple-500: #673ab7;
12318 --paper-deep-purple-600: #5e35b1;
12319 --paper-deep-purple-700: #512da8;
12320 --paper-deep-purple-800: #4527a0;
12321 --paper-deep-purple-900: #311b92;
12322 --paper-deep-purple-a100: #b388ff;
12323 --paper-deep-purple-a200: #7c4dff;
12324 --paper-deep-purple-a400: #651fff;
12325 --paper-deep-purple-a700: #6200ea;
12326
12327 --paper-indigo-50: #e8eaf6;
12328 --paper-indigo-100: #c5cae9;
12329 --paper-indigo-200: #9fa8da;
12330 --paper-indigo-300: #7986cb;
12331 --paper-indigo-400: #5c6bc0;
12332 --paper-indigo-500: #3f51b5;
12333 --paper-indigo-600: #3949ab;
12334 --paper-indigo-700: #303f9f;
12335 --paper-indigo-800: #283593;
12336 --paper-indigo-900: #1a237e;
12337 --paper-indigo-a100: #8c9eff;
12338 --paper-indigo-a200: #536dfe;
12339 --paper-indigo-a400: #3d5afe;
12340 --paper-indigo-a700: #304ffe;
12341
12342 --paper-blue-50: #e3f2fd;
12343 --paper-blue-100: #bbdefb;
12344 --paper-blue-200: #90caf9;
12345 --paper-blue-300: #64b5f6;
12346 --paper-blue-400: #42a5f5;
12347 --paper-blue-500: #2196f3;
12348 --paper-blue-600: #1e88e5;
12349 --paper-blue-700: #1976d2;
12350 --paper-blue-800: #1565c0;
12351 --paper-blue-900: #0d47a1;
12352 --paper-blue-a100: #82b1ff;
12353 --paper-blue-a200: #448aff;
12354 --paper-blue-a400: #2979ff;
12355 --paper-blue-a700: #2962ff;
12356
12357 --paper-light-blue-50: #e1f5fe;
12358 --paper-light-blue-100: #b3e5fc;
12359 --paper-light-blue-200: #81d4fa;
12360 --paper-light-blue-300: #4fc3f7;
12361 --paper-light-blue-400: #29b6f6;
12362 --paper-light-blue-500: #03a9f4;
12363 --paper-light-blue-600: #039be5;
12364 --paper-light-blue-700: #0288d1;
12365 --paper-light-blue-800: #0277bd;
12366 --paper-light-blue-900: #01579b;
12367 --paper-light-blue-a100: #80d8ff;
12368 --paper-light-blue-a200: #40c4ff;
12369 --paper-light-blue-a400: #00b0ff;
12370 --paper-light-blue-a700: #0091ea;
12371
12372 --paper-cyan-50: #e0f7fa;
12373 --paper-cyan-100: #b2ebf2;
12374 --paper-cyan-200: #80deea;
12375 --paper-cyan-300: #4dd0e1;
12376 --paper-cyan-400: #26c6da;
12377 --paper-cyan-500: #00bcd4;
12378 --paper-cyan-600: #00acc1;
12379 --paper-cyan-700: #0097a7;
12380 --paper-cyan-800: #00838f;
12381 --paper-cyan-900: #006064;
12382 --paper-cyan-a100: #84ffff;
12383 --paper-cyan-a200: #18ffff;
12384 --paper-cyan-a400: #00e5ff;
12385 --paper-cyan-a700: #00b8d4;
12386
12387 --paper-teal-50: #e0f2f1;
12388 --paper-teal-100: #b2dfdb;
12389 --paper-teal-200: #80cbc4;
12390 --paper-teal-300: #4db6ac;
12391 --paper-teal-400: #26a69a;
12392 --paper-teal-500: #009688;
12393 --paper-teal-600: #00897b;
12394 --paper-teal-700: #00796b;
12395 --paper-teal-800: #00695c;
12396 --paper-teal-900: #004d40;
12397 --paper-teal-a100: #a7ffeb;
12398 --paper-teal-a200: #64ffda;
12399 --paper-teal-a400: #1de9b6;
12400 --paper-teal-a700: #00bfa5;
12401
12402 --paper-green-50: #e8f5e9;
12403 --paper-green-100: #c8e6c9;
12404 --paper-green-200: #a5d6a7;
12405 --paper-green-300: #81c784;
12406 --paper-green-400: #66bb6a;
12407 --paper-green-500: #4caf50;
12408 --paper-green-600: #43a047;
12409 --paper-green-700: #388e3c;
12410 --paper-green-800: #2e7d32;
12411 --paper-green-900: #1b5e20;
12412 --paper-green-a100: #b9f6ca;
12413 --paper-green-a200: #69f0ae;
12414 --paper-green-a400: #00e676;
12415 --paper-green-a700: #00c853;
12416
12417 --paper-light-green-50: #f1f8e9;
12418 --paper-light-green-100: #dcedc8;
12419 --paper-light-green-200: #c5e1a5;
12420 --paper-light-green-300: #aed581;
12421 --paper-light-green-400: #9ccc65;
12422 --paper-light-green-500: #8bc34a;
12423 --paper-light-green-600: #7cb342;
12424 --paper-light-green-700: #689f38;
12425 --paper-light-green-800: #558b2f;
12426 --paper-light-green-900: #33691e;
12427 --paper-light-green-a100: #ccff90;
12428 --paper-light-green-a200: #b2ff59;
12429 --paper-light-green-a400: #76ff03;
12430 --paper-light-green-a700: #64dd17;
12431
12432 --paper-lime-50: #f9fbe7;
12433 --paper-lime-100: #f0f4c3;
12434 --paper-lime-200: #e6ee9c;
12435 --paper-lime-300: #dce775;
12436 --paper-lime-400: #d4e157;
12437 --paper-lime-500: #cddc39;
12438 --paper-lime-600: #c0ca33;
12439 --paper-lime-700: #afb42b;
12440 --paper-lime-800: #9e9d24;
12441 --paper-lime-900: #827717;
12442 --paper-lime-a100: #f4ff81;
12443 --paper-lime-a200: #eeff41;
12444 --paper-lime-a400: #c6ff00;
12445 --paper-lime-a700: #aeea00;
12446
12447 --paper-yellow-50: #fffde7;
12448 --paper-yellow-100: #fff9c4;
12449 --paper-yellow-200: #fff59d;
12450 --paper-yellow-300: #fff176;
12451 --paper-yellow-400: #ffee58;
12452 --paper-yellow-500: #ffeb3b;
12453 --paper-yellow-600: #fdd835;
12454 --paper-yellow-700: #fbc02d;
12455 --paper-yellow-800: #f9a825;
12456 --paper-yellow-900: #f57f17;
12457 --paper-yellow-a100: #ffff8d;
12458 --paper-yellow-a200: #ffff00;
12459 --paper-yellow-a400: #ffea00;
12460 --paper-yellow-a700: #ffd600;
12461
12462 --paper-amber-50: #fff8e1;
12463 --paper-amber-100: #ffecb3;
12464 --paper-amber-200: #ffe082;
12465 --paper-amber-300: #ffd54f;
12466 --paper-amber-400: #ffca28;
12467 --paper-amber-500: #ffc107;
12468 --paper-amber-600: #ffb300;
12469 --paper-amber-700: #ffa000;
12470 --paper-amber-800: #ff8f00;
12471 --paper-amber-900: #ff6f00;
12472 --paper-amber-a100: #ffe57f;
12473 --paper-amber-a200: #ffd740;
12474 --paper-amber-a400: #ffc400;
12475 --paper-amber-a700: #ffab00;
12476
12477 --paper-orange-50: #fff3e0;
12478 --paper-orange-100: #ffe0b2;
12479 --paper-orange-200: #ffcc80;
12480 --paper-orange-300: #ffb74d;
12481 --paper-orange-400: #ffa726;
12482 --paper-orange-500: #ff9800;
12483 --paper-orange-600: #fb8c00;
12484 --paper-orange-700: #f57c00;
12485 --paper-orange-800: #ef6c00;
12486 --paper-orange-900: #e65100;
12487 --paper-orange-a100: #ffd180;
12488 --paper-orange-a200: #ffab40;
12489 --paper-orange-a400: #ff9100;
12490 --paper-orange-a700: #ff6500;
12491
12492 --paper-deep-orange-50: #fbe9e7;
12493 --paper-deep-orange-100: #ffccbc;
12494 --paper-deep-orange-200: #ffab91;
12495 --paper-deep-orange-300: #ff8a65;
12496 --paper-deep-orange-400: #ff7043;
12497 --paper-deep-orange-500: #ff5722;
12498 --paper-deep-orange-600: #f4511e;
12499 --paper-deep-orange-700: #e64a19;
12500 --paper-deep-orange-800: #d84315;
12501 --paper-deep-orange-900: #bf360c;
12502 --paper-deep-orange-a100: #ff9e80;
12503 --paper-deep-orange-a200: #ff6e40;
12504 --paper-deep-orange-a400: #ff3d00;
12505 --paper-deep-orange-a700: #dd2c00;
12506
12507 --paper-brown-50: #efebe9;
12508 --paper-brown-100: #d7ccc8;
12509 --paper-brown-200: #bcaaa4;
12510 --paper-brown-300: #a1887f;
12511 --paper-brown-400: #8d6e63;
12512 --paper-brown-500: #795548;
12513 --paper-brown-600: #6d4c41;
12514 --paper-brown-700: #5d4037;
12515 --paper-brown-800: #4e342e;
12516 --paper-brown-900: #3e2723;
12517
12518 --paper-grey-50: #fafafa;
12519 --paper-grey-100: #f5f5f5;
12520 --paper-grey-200: #eeeeee;
12521 --paper-grey-300: #e0e0e0;
12522 --paper-grey-400: #bdbdbd;
12523 --paper-grey-500: #9e9e9e;
12524 --paper-grey-600: #757575;
12525 --paper-grey-700: #616161;
12526 --paper-grey-800: #424242;
12527 --paper-grey-900: #212121;
12528
12529 --paper-blue-grey-50: #eceff1;
12530 --paper-blue-grey-100: #cfd8dc;
12531 --paper-blue-grey-200: #b0bec5;
12532 --paper-blue-grey-300: #90a4ae;
12533 --paper-blue-grey-400: #78909c;
12534 --paper-blue-grey-500: #607d8b;
12535 --paper-blue-grey-600: #546e7a;
12536 --paper-blue-grey-700: #455a64;
12537 --paper-blue-grey-800: #37474f;
12538 --paper-blue-grey-900: #263238;
12539
12540 /* opacity for dark text on a light background */
12541 --dark-divider-opacity: 0.12;
12542 --dark-disabled-opacity: 0.38; /* or hint text or icon */
12543 --dark-secondary-opacity: 0.54;
12544 --dark-primary-opacity: 0.87;
12545
12546 /* opacity for light text on a dark background */
12547 --light-divider-opacity: 0.12;
12548 --light-disabled-opacity: 0.3; /* or hint text or icon */
12549 --light-secondary-opacity: 0.7;
12550 --light-primary-opacity: 1.0;
12551
12552 }
12553
12554 </style>
12555 <script>
12556
12557 /** @polymerBehavior */
12558 Polymer.PaperSpinnerBehavior = {
12559
12560 listeners: {
12561 'animationend': '__reset',
12562 'webkitAnimationEnd': '__reset'
12563 },
12564
12565 properties: {
12566 /**
12567 * Displays the spinner.
12568 */
12569 active: {
12570 type: Boolean,
12571 value: false,
12572 reflectToAttribute: true,
12573 observer: '__activeChanged'
12574 },
12575
12576 /**
12577 * Alternative text content for accessibility support.
12578 * If alt is present, it will add an aria-label whose content matches alt when active.
12579 * If alt is not present, it will default to 'loading' as the alt value.
12580 */
12581 alt: {
12582 type: String,
12583 value: 'loading',
12584 observer: '__altChanged'
12585 },
12586
12587 __coolingDown: {
12588 type: Boolean,
12589 value: false
12590 }
12591 },
12592
12593 __computeContainerClasses: function(active, coolingDown) {
12594 return [
12595 active || coolingDown ? 'active' : '',
12596 coolingDown ? 'cooldown' : ''
12597 ].join(' ');
12598 },
12599
12600 __activeChanged: function(active, old) {
12601 this.__setAriaHidden(!active);
12602 this.__coolingDown = !active && old;
12603 },
12604
12605 __altChanged: function(alt) {
12606 // user-provided `aria-label` takes precedence over prototype default
12607 if (alt === this.getPropertyInfo('alt').value) {
12608 this.alt = this.getAttribute('aria-label') || alt;
12609 } else {
12610 this.__setAriaHidden(alt==='');
12611 this.setAttribute('aria-label', alt);
12612 }
12613 },
12614
12615 __setAriaHidden: function(hidden) {
12616 var attr = 'aria-hidden';
12617 if (hidden) {
12618 this.setAttribute(attr, 'true');
12619 } else {
12620 this.removeAttribute(attr);
12621 }
12622 },
12623
12624 __reset: function() {
12625 this.active = false;
12626 this.__coolingDown = false;
12627 }
12628 };
12629 </script>
12630 <dom-module id="paper-spinner-styles" assetpath="/res/imp/bower_components/paper -spinner/">
12631 <template>
12632 <style>
12633 /*
12634 /**************************/
12635 /* STYLES FOR THE SPINNER */
12636 /**************************/
12637
12638 /*
12639 * Constants:
12640 * ARCSIZE = 270 degrees (amount of circle the arc takes up)
12641 * ARCTIME = 1333ms (time it takes to expand and contract arc)
12642 * ARCSTARTROT = 216 degrees (how much the start location of the arc
12643 * should rotate each time, 216 gives us a
12644 * 5 pointed star shape (it's 360/5 * 3).
12645 * For a 7 pointed star, we might do
12646 * 360/7 * 3 = 154.286)
12647 * SHRINK_TIME = 400ms
12648 */
12649
12650 :host {
12651 display: inline-block;
12652 position: relative;
12653 width: 28px;
12654 height: 28px;
12655
12656 /* 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
12657 --paper-spinner-container-rotation-duration: 1568ms;
12658
12659 /* ARCTIME */
12660 --paper-spinner-expand-contract-duration: 1333ms;
12661
12662 /* 4 * ARCTIME */
12663 --paper-spinner-full-cycle-duration: 5332ms;
12664
12665 /* SHRINK_TIME */
12666 --paper-spinner-cooldown-duration: 400ms;
12667 }
12668
12669 #spinnerContainer {
12670 width: 100%;
12671 height: 100%;
12672
12673 /* The spinner does not have any contents that would have to be
12674 * flipped if the direction changes. Always use ltr so that the
12675 * style works out correctly in both cases. */
12676 direction: ltr;
12677 }
12678
12679 #spinnerContainer.active {
12680 -webkit-animation: container-rotate var(--paper-spinner-container-rotati on-duration) linear infinite;
12681 animation: container-rotate var(--paper-spinner-container-rotation-durat ion) linear infinite;
12682 }
12683
12684 @-webkit-keyframes container-rotate {
12685 to { -webkit-transform: rotate(360deg) }
12686 }
12687
12688 @keyframes container-rotate {
12689 to { transform: rotate(360deg) }
12690 }
12691
12692 .spinner-layer {
12693 position: absolute;
12694 width: 100%;
12695 height: 100%;
12696 opacity: 0;
12697 white-space: nowrap;
12698 border-color: var(--paper-spinner-color, --google-blue-500);
12699 }
12700
12701 .layer-1 {
12702 border-color: var(--paper-spinner-layer-1-color, --google-blue-500);
12703 }
12704
12705 .layer-2 {
12706 border-color: var(--paper-spinner-layer-2-color, --google-red-500);
12707 }
12708
12709 .layer-3 {
12710 border-color: var(--paper-spinner-layer-3-color, --google-yellow-500);
12711 }
12712
12713 .layer-4 {
12714 border-color: var(--paper-spinner-layer-4-color, --google-green-500);
12715 }
12716
12717 /**
12718 * IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
12719 *
12720 * iOS Safari (tested on iOS 8.1) does not handle animation-delay very wel l - it doesn't
12721 * guarantee that the animation will start _exactly_ after that value. So we avoid using
12722 * animation-delay and instead set custom keyframes for each color (as lay er-2undant as it
12723 * seems).
12724 */
12725 .active .spinner-layer {
12726 -webkit-animation-name: fill-unfill-rotate;
12727 -webkit-animation-duration: var(--paper-spinner-full-cycle-duration);
12728 -webkit-animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
12729 -webkit-animation-iteration-count: infinite;
12730 animation-name: fill-unfill-rotate;
12731 animation-duration: var(--paper-spinner-full-cycle-duration);
12732 animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
12733 animation-iteration-count: infinite;
12734 opacity: 1;
12735 }
12736
12737 .active .spinner-layer.layer-1 {
12738 -webkit-animation-name: fill-unfill-rotate, layer-1-fade-in-out;
12739 animation-name: fill-unfill-rotate, layer-1-fade-in-out;
12740 }
12741
12742 .active .spinner-layer.layer-2 {
12743 -webkit-animation-name: fill-unfill-rotate, layer-2-fade-in-out;
12744 animation-name: fill-unfill-rotate, layer-2-fade-in-out;
12745 }
12746
12747 .active .spinner-layer.layer-3 {
12748 -webkit-animation-name: fill-unfill-rotate, layer-3-fade-in-out;
12749 animation-name: fill-unfill-rotate, layer-3-fade-in-out;
12750 }
12751
12752 .active .spinner-layer.layer-4 {
12753 -webkit-animation-name: fill-unfill-rotate, layer-4-fade-in-out;
12754 animation-name: fill-unfill-rotate, layer-4-fade-in-out;
12755 }
12756
12757 @-webkit-keyframes fill-unfill-rotate {
12758 12.5% { -webkit-transform: rotate(135deg) } /* 0.5 * ARCSIZE */
12759 25% { -webkit-transform: rotate(270deg) } /* 1 * ARCSIZE */
12760 37.5% { -webkit-transform: rotate(405deg) } /* 1.5 * ARCSIZE */
12761 50% { -webkit-transform: rotate(540deg) } /* 2 * ARCSIZE */
12762 62.5% { -webkit-transform: rotate(675deg) } /* 2.5 * ARCSIZE */
12763 75% { -webkit-transform: rotate(810deg) } /* 3 * ARCSIZE */
12764 87.5% { -webkit-transform: rotate(945deg) } /* 3.5 * ARCSIZE */
12765 to { -webkit-transform: rotate(1080deg) } /* 4 * ARCSIZE */
12766 }
12767
12768 @keyframes fill-unfill-rotate {
12769 12.5% { transform: rotate(135deg) } /* 0.5 * ARCSIZE */
12770 25% { transform: rotate(270deg) } /* 1 * ARCSIZE */
12771 37.5% { transform: rotate(405deg) } /* 1.5 * ARCSIZE */
12772 50% { transform: rotate(540deg) } /* 2 * ARCSIZE */
12773 62.5% { transform: rotate(675deg) } /* 2.5 * ARCSIZE */
12774 75% { transform: rotate(810deg) } /* 3 * ARCSIZE */
12775 87.5% { transform: rotate(945deg) } /* 3.5 * ARCSIZE */
12776 to { transform: rotate(1080deg) } /* 4 * ARCSIZE */
12777 }
12778
12779 @-webkit-keyframes layer-1-fade-in-out {
12780 0% { opacity: 1 }
12781 25% { opacity: 1 }
12782 26% { opacity: 0 }
12783 89% { opacity: 0 }
12784 90% { opacity: 1 }
12785 to { opacity: 1 }
12786 }
12787
12788 @keyframes layer-1-fade-in-out {
12789 0% { opacity: 1 }
12790 25% { opacity: 1 }
12791 26% { opacity: 0 }
12792 89% { opacity: 0 }
12793 90% { opacity: 1 }
12794 to { opacity: 1 }
12795 }
12796
12797 @-webkit-keyframes layer-2-fade-in-out {
12798 0% { opacity: 0 }
12799 15% { opacity: 0 }
12800 25% { opacity: 1 }
12801 50% { opacity: 1 }
12802 51% { opacity: 0 }
12803 to { opacity: 0 }
12804 }
12805
12806 @keyframes layer-2-fade-in-out {
12807 0% { opacity: 0 }
12808 15% { opacity: 0 }
12809 25% { opacity: 1 }
12810 50% { opacity: 1 }
12811 51% { opacity: 0 }
12812 to { opacity: 0 }
12813 }
12814
12815 @-webkit-keyframes layer-3-fade-in-out {
12816 0% { opacity: 0 }
12817 40% { opacity: 0 }
12818 50% { opacity: 1 }
12819 75% { opacity: 1 }
12820 76% { opacity: 0 }
12821 to { opacity: 0 }
12822 }
12823
12824 @keyframes layer-3-fade-in-out {
12825 0% { opacity: 0 }
12826 40% { opacity: 0 }
12827 50% { opacity: 1 }
12828 75% { opacity: 1 }
12829 76% { opacity: 0 }
12830 to { opacity: 0 }
12831 }
12832
12833 @-webkit-keyframes layer-4-fade-in-out {
12834 0% { opacity: 0 }
12835 65% { opacity: 0 }
12836 75% { opacity: 1 }
12837 90% { opacity: 1 }
12838 to { opacity: 0 }
12839 }
12840
12841 @keyframes layer-4-fade-in-out {
12842 0% { opacity: 0 }
12843 65% { opacity: 0 }
12844 75% { opacity: 1 }
12845 90% { opacity: 1 }
12846 to { opacity: 0 }
12847 }
12848
12849 .circle-clipper {
12850 display: inline-block;
12851 position: relative;
12852 width: 50%;
12853 height: 100%;
12854 overflow: hidden;
12855 border-color: inherit;
12856 }
12857
12858 /**
12859 * Patch the gap that appear between the two adjacent div.circle-clipper w hile the
12860 * spinner is rotating (appears on Chrome 50, Safari 9.1.1, and Edge).
12861 */
12862 .spinner-layer::after {
12863 left: 45%;
12864 width: 10%;
12865 border-top-style: solid;
12866 }
12867
12868 .spinner-layer::after,
12869 .circle-clipper::after {
12870 content: '';
12871 box-sizing: border-box;
12872 position: absolute;
12873 top: 0;
12874 border-width: var(--paper-spinner-stroke-width, 3px);
12875 border-color: inherit;
12876 border-radius: 50%;
12877 }
12878
12879 .circle-clipper::after {
12880 bottom: 0;
12881 width: 200%;
12882 border-style: solid;
12883 border-bottom-color: transparent !important;
12884 }
12885
12886 .circle-clipper.left::after {
12887 left: 0;
12888 border-right-color: transparent !important;
12889 -webkit-transform: rotate(129deg);
12890 transform: rotate(129deg);
12891 }
12892
12893 .circle-clipper.right::after {
12894 left: -100%;
12895 border-left-color: transparent !important;
12896 -webkit-transform: rotate(-129deg);
12897 transform: rotate(-129deg);
12898 }
12899
12900 .active .gap-patch::after,
12901 .active .circle-clipper::after {
12902 -webkit-animation-duration: var(--paper-spinner-expand-contract-duration );
12903 -webkit-animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
12904 -webkit-animation-iteration-count: infinite;
12905 animation-duration: var(--paper-spinner-expand-contract-duration);
12906 animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1);
12907 animation-iteration-count: infinite;
12908 }
12909
12910 .active .circle-clipper.left::after {
12911 -webkit-animation-name: left-spin;
12912 animation-name: left-spin;
12913 }
12914
12915 .active .circle-clipper.right::after {
12916 -webkit-animation-name: right-spin;
12917 animation-name: right-spin;
12918 }
12919
12920 @-webkit-keyframes left-spin {
12921 0% { -webkit-transform: rotate(130deg) }
12922 50% { -webkit-transform: rotate(-5deg) }
12923 to { -webkit-transform: rotate(130deg) }
12924 }
12925
12926 @keyframes left-spin {
12927 0% { transform: rotate(130deg) }
12928 50% { transform: rotate(-5deg) }
12929 to { transform: rotate(130deg) }
12930 }
12931
12932 @-webkit-keyframes right-spin {
12933 0% { -webkit-transform: rotate(-130deg) }
12934 50% { -webkit-transform: rotate(5deg) }
12935 to { -webkit-transform: rotate(-130deg) }
12936 }
12937
12938 @keyframes right-spin {
12939 0% { transform: rotate(-130deg) }
12940 50% { transform: rotate(5deg) }
12941 to { transform: rotate(-130deg) }
12942 }
12943
12944 #spinnerContainer.cooldown {
12945 -webkit-animation: container-rotate var(--paper-spinner-container-rotati on-duration) linear infinite, fade-out var(--paper-spinner-cooldown-duration) cu bic-bezier(0.4, 0.0, 0.2, 1);
12946 animation: container-rotate var(--paper-spinner-container-rotation-durat ion) linear infinite, fade-out var(--paper-spinner-cooldown-duration) cubic-bezi er(0.4, 0.0, 0.2, 1);
12947 }
12948
12949 @-webkit-keyframes fade-out {
12950 0% { opacity: 1 }
12951 to { opacity: 0 }
12952 }
12953
12954 @keyframes fade-out {
12955 0% { opacity: 1 }
12956 to { opacity: 0 }
12957 }
12958 </style>
12959 </template>
12960 </dom-module>
12961
12962
12963 <dom-module id="paper-spinner-lite" assetpath="/res/imp/bower_components/paper-s pinner/">
12964 <template strip-whitespace="">
12965 <style include="paper-spinner-styles"></style>
12966
12967 <div id="spinnerContainer" class-name="[[__computeContainerClasses(active, _ _coolingDown)]]">
12968 <div class="spinner-layer">
12969 <div class="circle-clipper left"></div>
12970 <div class="circle-clipper right"></div>
12971 </div>
12972 </div>
12973 </template>
12974
12975 <script>
12976 Polymer({
12977 is: 'paper-spinner-lite',
12978
12979 behaviors: [
12980 Polymer.PaperSpinnerBehavior
12981 ]
12982 });
12983 </script>
12984 </dom-module>
12985
12986 <dom-module id="iron-flex" assetpath="/res/imp/bower_components/iron-flex-layout /">
12987 <template>
12988 <style>
12989 .layout.horizontal,
12990 .layout.vertical {
12991 display: -ms-flexbox;
12992 display: -webkit-flex;
12993 display: flex;
12994 }
12995
12996 .layout.inline {
12997 display: -ms-inline-flexbox;
12998 display: -webkit-inline-flex;
12999 display: inline-flex;
13000 }
13001
13002 .layout.horizontal {
13003 -ms-flex-direction: row;
13004 -webkit-flex-direction: row;
13005 flex-direction: row;
13006 }
13007
13008 .layout.vertical {
13009 -ms-flex-direction: column;
13010 -webkit-flex-direction: column;
13011 flex-direction: column;
13012 }
13013
13014 .layout.wrap {
13015 -ms-flex-wrap: wrap;
13016 -webkit-flex-wrap: wrap;
13017 flex-wrap: wrap;
13018 }
13019
13020 .layout.center,
13021 .layout.center-center {
13022 -ms-flex-align: center;
13023 -webkit-align-items: center;
13024 align-items: center;
13025 }
13026
13027 .layout.center-justified,
13028 .layout.center-center {
13029 -ms-flex-pack: center;
13030 -webkit-justify-content: center;
13031 justify-content: center;
13032 }
13033
13034 .flex {
13035 -ms-flex: 1 1 0.000000001px;
13036 -webkit-flex: 1;
13037 flex: 1;
13038 -webkit-flex-basis: 0.000000001px;
13039 flex-basis: 0.000000001px;
13040 }
13041
13042 .flex-auto {
13043 -ms-flex: 1 1 auto;
13044 -webkit-flex: 1 1 auto;
13045 flex: 1 1 auto;
13046 }
13047
13048 .flex-none {
13049 -ms-flex: none;
13050 -webkit-flex: none;
13051 flex: none;
13052 }
13053 </style>
13054 </template>
13055 </dom-module>
13056
13057
13058 <dom-module id="iron-flex-reverse" assetpath="/res/imp/bower_components/iron-fle x-layout/">
13059 <template>
13060 <style>
13061 .layout.horizontal-reverse,
13062 .layout.vertical-reverse {
13063 display: -ms-flexbox;
13064 display: -webkit-flex;
13065 display: flex;
13066 }
13067
13068 .layout.horizontal-reverse {
13069 -ms-flex-direction: row-reverse;
13070 -webkit-flex-direction: row-reverse;
13071 flex-direction: row-reverse;
13072 }
13073
13074 .layout.vertical-reverse {
13075 -ms-flex-direction: column-reverse;
13076 -webkit-flex-direction: column-reverse;
13077 flex-direction: column-reverse;
13078 }
13079
13080 .layout.wrap-reverse {
13081 -ms-flex-wrap: wrap-reverse;
13082 -webkit-flex-wrap: wrap-reverse;
13083 flex-wrap: wrap-reverse;
13084 }
13085 </style>
13086 </template>
13087 </dom-module>
13088
13089
13090 <dom-module id="iron-flex-alignment" assetpath="/res/imp/bower_components/iron-f lex-layout/">
13091 <template>
13092 <style>
13093 /**
13094 * Alignment in cross axis.
13095 */
13096 .layout.start {
13097 -ms-flex-align: start;
13098 -webkit-align-items: flex-start;
13099 align-items: flex-start;
13100 }
13101
13102 .layout.center,
13103 .layout.center-center {
13104 -ms-flex-align: center;
13105 -webkit-align-items: center;
13106 align-items: center;
13107 }
13108
13109 .layout.end {
13110 -ms-flex-align: end;
13111 -webkit-align-items: flex-end;
13112 align-items: flex-end;
13113 }
13114
13115 .layout.baseline {
13116 -ms-flex-align: baseline;
13117 -webkit-align-items: baseline;
13118 align-items: baseline;
13119 }
13120
13121 /**
13122 * Alignment in main axis.
13123 */
13124 .layout.start-justified {
13125 -ms-flex-pack: start;
13126 -webkit-justify-content: flex-start;
13127 justify-content: flex-start;
13128 }
13129
13130 .layout.center-justified,
13131 .layout.center-center {
13132 -ms-flex-pack: center;
13133 -webkit-justify-content: center;
13134 justify-content: center;
13135 }
13136
13137 .layout.end-justified {
13138 -ms-flex-pack: end;
13139 -webkit-justify-content: flex-end;
13140 justify-content: flex-end;
13141 }
13142
13143 .layout.around-justified {
13144 -ms-flex-pack: distribute;
13145 -webkit-justify-content: space-around;
13146 justify-content: space-around;
13147 }
13148
13149 .layout.justified {
13150 -ms-flex-pack: justify;
13151 -webkit-justify-content: space-between;
13152 justify-content: space-between;
13153 }
13154
13155 /**
13156 * Self alignment.
13157 */
13158 .self-start {
13159 -ms-align-self: flex-start;
13160 -webkit-align-self: flex-start;
13161 align-self: flex-start;
13162 }
13163
13164 .self-center {
13165 -ms-align-self: center;
13166 -webkit-align-self: center;
13167 align-self: center;
13168 }
13169
13170 .self-end {
13171 -ms-align-self: flex-end;
13172 -webkit-align-self: flex-end;
13173 align-self: flex-end;
13174 }
13175
13176 .self-stretch {
13177 -ms-align-self: stretch;
13178 -webkit-align-self: stretch;
13179 align-self: stretch;
13180 }
13181
13182 .self-baseline {
13183 -ms-align-self: baseline;
13184 -webkit-align-self: baseline;
13185 align-self: baseline;
13186 };
13187
13188 /**
13189 * multi-line alignment in main axis.
13190 */
13191 .layout.start-aligned {
13192 -ms-flex-line-pack: start; /* IE10 */
13193 -ms-align-content: flex-start;
13194 -webkit-align-content: flex-start;
13195 align-content: flex-start;
13196 }
13197
13198 .layout.end-aligned {
13199 -ms-flex-line-pack: end; /* IE10 */
13200 -ms-align-content: flex-end;
13201 -webkit-align-content: flex-end;
13202 align-content: flex-end;
13203 }
13204
13205 .layout.center-aligned {
13206 -ms-flex-line-pack: center; /* IE10 */
13207 -ms-align-content: center;
13208 -webkit-align-content: center;
13209 align-content: center;
13210 }
13211
13212 .layout.between-aligned {
13213 -ms-flex-line-pack: justify; /* IE10 */
13214 -ms-align-content: space-between;
13215 -webkit-align-content: space-between;
13216 align-content: space-between;
13217 }
13218
13219 .layout.around-aligned {
13220 -ms-flex-line-pack: distribute; /* IE10 */
13221 -ms-align-content: space-around;
13222 -webkit-align-content: space-around;
13223 align-content: space-around;
13224 }
13225 </style>
13226 </template>
13227 </dom-module>
13228
13229 <dom-module id="iron-flex-factors" assetpath="/res/imp/bower_components/iron-fle x-layout/">
13230 <template>
13231 <style>
13232 .flex,
13233 .flex-1 {
13234 -ms-flex: 1 1 0.000000001px;
13235 -webkit-flex: 1;
13236 flex: 1;
13237 -webkit-flex-basis: 0.000000001px;
13238 flex-basis: 0.000000001px;
13239 }
13240
13241 .flex-2 {
13242 -ms-flex: 2;
13243 -webkit-flex: 2;
13244 flex: 2;
13245 }
13246
13247 .flex-3 {
13248 -ms-flex: 3;
13249 -webkit-flex: 3;
13250 flex: 3;
13251 }
13252
13253 .flex-4 {
13254 -ms-flex: 4;
13255 -webkit-flex: 4;
13256 flex: 4;
13257 }
13258
13259 .flex-5 {
13260 -ms-flex: 5;
13261 -webkit-flex: 5;
13262 flex: 5;
13263 }
13264
13265 .flex-6 {
13266 -ms-flex: 6;
13267 -webkit-flex: 6;
13268 flex: 6;
13269 }
13270
13271 .flex-7 {
13272 -ms-flex: 7;
13273 -webkit-flex: 7;
13274 flex: 7;
13275 }
13276
13277 .flex-8 {
13278 -ms-flex: 8;
13279 -webkit-flex: 8;
13280 flex: 8;
13281 }
13282
13283 .flex-9 {
13284 -ms-flex: 9;
13285 -webkit-flex: 9;
13286 flex: 9;
13287 }
13288
13289 .flex-10 {
13290 -ms-flex: 10;
13291 -webkit-flex: 10;
13292 flex: 10;
13293 }
13294
13295 .flex-11 {
13296 -ms-flex: 11;
13297 -webkit-flex: 11;
13298 flex: 11;
13299 }
13300
13301 .flex-12 {
13302 -ms-flex: 12;
13303 -webkit-flex: 12;
13304 flex: 12;
13305 }
13306 </style>
13307 </template>
13308 </dom-module>
13309
13310
13311 <dom-module id="iron-positioning" assetpath="/res/imp/bower_components/iron-flex -layout/">
13312 <template>
13313 <style>
13314 .block {
13315 display: block;
13316 }
13317
13318 /* IE 10 support for HTML5 hidden attr */
13319 [hidden] {
13320 display: none !important;
13321 }
13322
13323 .invisible {
13324 visibility: hidden !important;
13325 }
13326
13327 .relative {
13328 position: relative;
13329 }
13330
13331 .fit {
13332 position: absolute;
13333 top: 0;
13334 right: 0;
13335 bottom: 0;
13336 left: 0;
13337 }
13338
13339 body.fullbleed {
13340 margin: 0;
13341 height: 100vh;
13342 }
13343
13344 .scroll {
13345 -webkit-overflow-scrolling: touch;
13346 overflow: auto;
13347 }
13348
13349 /* fixed position */
13350 .fixed-bottom,
13351 .fixed-left,
13352 .fixed-right,
13353 .fixed-top {
13354 position: fixed;
13355 }
13356
13357 .fixed-top {
13358 top: 0;
13359 left: 0;
13360 right: 0;
13361 }
13362
13363 .fixed-right {
13364 top: 0;
13365 right: 0;
13366 bottom: 0;
13367 }
13368
13369 .fixed-bottom {
13370 right: 0;
13371 bottom: 0;
13372 left: 0;
13373 }
13374
13375 .fixed-left {
13376 top: 0;
13377 bottom: 0;
13378 left: 0;
13379 }
13380 </style>
13381 </template>
13382 </dom-module>
13383 <script>
9162 (function() { 13384 (function() {
9163 "use strict"; 13385 "use strict";
9164 /** 13386 /**
9165 `Polymer.IronJsonpLibraryBehavior` loads a jsonp library. 13387 `Polymer.IronJsonpLibraryBehavior` loads a jsonp library.
9166 Multiple components can request same library, only one copy will load. 13388 Multiple components can request same library, only one copy will load.
9167 13389
9168 Some libraries require a specific global function be defined. 13390 Some libraries require a specific global function be defined.
9169 If this is the case, specify the `callbackName` property. 13391 If this is the case, specify the `callbackName` property.
9170 13392
9171 You should use an HTML Import to load library dependencies 13393 You should use an HTML Import to load library dependencies
(...skipping 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after
10213 }, 14435 },
10214 14436
10215 _updateOfflineCode: function(code) { 14437 _updateOfflineCode: function(code) {
10216 if (code) { 14438 if (code) {
10217 this.fire('google-signin-offline-success', {code: code}); 14439 this.fire('google-signin-offline-success', {code: code});
10218 } 14440 }
10219 } 14441 }
10220 }); 14442 });
10221 })(); 14443 })();
10222 </script> 14444 </script>
10223 <dom-module id="auth-signin" assetpath="imp/common/"> 14445 <dom-module id="auth-signin" assetpath="/res/imp/common/">
10224 <template> 14446 <template>
10225 <style> 14447 <style>
10226 #avatar { 14448 #avatar {
10227 border-radius: 5px; 14449 border-radius: 5px;
10228 } 14450 }
10229 #signinContainer { 14451 a {
10230 margin-top: 14px; 14452 color: white;
14453 }
14454 .center {
14455 vertical-align: middle;
10231 } 14456 }
10232 </style> 14457 </style>
10233 14458
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"> 14459 <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> 14460 </google-signin-aware>
10236 14461
10237 <template is="dom-if" if="[[!signedIn]]"> 14462 <template is="dom-if" if="[[!signedIn]]">
10238 <div id="signinContainer"> 14463 <div id="signinContainer">
10239 <a on-tap="signIn" href="#">Sign in</a> 14464 <a on-tap="signIn" href="#">Sign in</a>
10240 </div> 14465 </div>
10241 </template> 14466 </template>
10242 14467
10243 <template is="dom-if" if="[[signedIn]]"> 14468 <template is="dom-if" if="[[signedIn]]">
10244 <img id="avatar" src="[[profile.imageUrl]]" width="30" height="30"> 14469 <img class="center" id="avatar" src="[[profile.imageUrl]]" width="30" heig ht="30">
10245 <span>[[profile.email]]</span> 14470 <span class="center">[[profile.email]]</span>
10246 <span>|</span> 14471 <span class="center">|</span>
10247 <a on-tap="signOut" href="#">Sign out</a> 14472 <a class="center" on-tap="signOut" href="#">Sign out</a>
10248 </template> 14473 </template>
10249 </template> 14474 </template>
10250 <script> 14475 <script>
10251 'use strict'; 14476 'use strict';
10252 Polymer({ 14477 Polymer({
10253 is: 'auth-signin', 14478 is: 'auth-signin',
10254 properties: { 14479 properties: {
10255 authHeaders: { 14480 authHeaders: {
10256 type: Object, 14481 type: Object,
10257 computed: "_makeHeader(authResponse)", 14482 computed: "_makeHeader(authResponse)",
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
10303 14528
10304 signIn: function() { 14529 signIn: function() {
10305 this.$.aware.signIn(); 14530 this.$.aware.signIn();
10306 }, 14531 },
10307 14532
10308 signOut: function() { 14533 signOut: function() {
10309 this.$.aware.signOut(); 14534 this.$.aware.signOut();
10310 } 14535 }
10311 }); 14536 });
10312 </script> 14537 </script>
10313 </dom-module><dom-module id="swarming-index" assetpath="imp/index/"> 14538 </dom-module><dom-module id="swarming-app" assetpath="/res/imp/common/">
14539 <template>
14540 <style include="iron-flex">
14541 :host {
14542 position: absolute;
14543 top: 0;
14544 bottom: 0;
14545 left: 0;
14546 right: 0;
14547 }
14548
14549 app-toolbar {
14550 background-color: #4285f4;
14551 color: #fff;
14552 }
14553
14554 app-toolbar a {
14555 color: #fff;
14556 }
14557 .left {
14558 margin-right:15px;
14559 }
14560 .right {
14561 margin-left:15px;
14562 }
14563 .main-content {
14564 padding: 3px;
14565 }
14566
14567 paper-spinner-lite {
14568 --paper-spinner-color: var(--google-yellow-500);
14569 }
14570 </style>
14571 <app-header-layout>
14572 <app-header fixed="">
14573 <app-toolbar>
14574 <div class="title left">[[name]]</div>
14575 <paper-spinner-lite class="left" active="[[busy]]"></paper-spinner-lit e>
14576
14577 <a class="left" href="/newui/">Home</a>
14578 <a class="left" href="/newui/botlist">Bot List</a>
14579 <div class="flex"></div>
14580
14581 <auth-signin class="right" client-id="20770472288-t5smpbpjptka4nd888fv 0ctd23ftba2o.apps.googleusercontent.com" auth-headers="{{auth_headers}}">
14582 </auth-signin>
14583 </app-toolbar>
14584 </app-header>
14585 <div class="main-content">
14586 <content></content>
14587 </div>
14588 </app-header-layout>
14589
14590 </template>
14591 <script>
14592 Polymer({
14593 is: 'swarming-app',
14594 properties: {
14595 auth_headers: {
14596 type: Object,
14597 notify: true,
14598 },
14599 busy: {
14600 type: Boolean,
14601 },
14602 name: {
14603 type: String,
14604 },
14605 },
14606
14607 });
14608 </script>
14609 </dom-module><dom-module id="swarming-index" assetpath="/res/imp/index/">
10314 <template> 14610 <template>
10315 <style> 14611 <style>
10316 :host { 14612 :host {
10317 display: block; 14613 display: block;
10318 } 14614 }
10319 </style> 14615 </style>
10320 14616
10321 <h1>HELLO WORLD</h1><h1> 14617 <swarming-app auth_headers="{{auth_headers}}" name="Swarming" busy="[[busy]] ">
10322 14618
10323 14619 <iron-ajax id="request" url="/_ah/api/swarming/v1/server/details" headers= "[[auth_headers]]" handle-as="json" last-response="{{serverDetails}}" loading="{ {busy}}">
10324 <auth-signin auth-headers="{{auth}}" client-id="20770472288-t5smpbpjptka4nd8 88fv0ctd23ftba2o.apps.googleusercontent.com" on-auth-signin="signIn"> 14620 </iron-ajax>
10325 </auth-signin>
10326 14621
10327 <iron-ajax id="request" url="/_ah/api/swarming/v1/server/details" headers="[ [auth]]" handle-as="json" on-response="handleResponse"> 14622 <h1>HELLO WORLD</h1>
10328 </iron-ajax>
10329 14623
10330 </h1></template> 14624 <div>Server Version: [[serverDetails.server_version]]</div>
14625
14626 </swarming-app>
14627
14628 </template>
10331 <script> 14629 <script>
10332 Polymer({ 14630 Polymer({
10333 is: 'swarming-index', 14631 is: 'swarming-index',
10334 14632
14633 properties: {
14634 auth_headers: {
14635 type: Object,
14636 observer: "signIn",
14637 },
14638
14639 serverDetails: {
14640 type: String,
14641 }
14642 },
14643
10335 signIn: function(){ 14644 signIn: function(){
10336 this.$.request.generateRequest(); 14645 this.$.request.generateRequest();
10337 }, 14646 },
10338 14647
10339 handleResponse: function(a,b){
10340 console.log(this.$.request.lastResponse);
10341 }
10342 }); 14648 });
10343 </script> 14649 </script>
10344 </dom-module></div> 14650 </dom-module></div></body></html>
10345 <swarming-index></swarming-index>
10346
10347
10348 </body></html>
OLDNEW
« no previous file with comments | « appengine/swarming/elements/build/botlist-build.html ('k') | appengine/swarming/elements/build/index-build.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698