Index: appengine/swarming/ui/build/elements.html |
diff --git a/appengine/swarming/ui/build/elements.html b/appengine/swarming/ui/build/elements.html |
index 1ef36edbab9ac91fdae69640b80336d3b4c3e649..1047927984d0c5d03a4124a8ebea71ee36d884b1 100644 |
--- a/appengine/swarming/ui/build/elements.html |
+++ b/appengine/swarming/ui/build/elements.html |
@@ -115,8 +115,8 @@ delete this[t])},_configureProperties:function(e,t){for(var n in e){var r=e[n];i |
return cursor === END; |
} |
}); |
- })(); </script> </dom-module><script>Polymer({is:"iron-a11y-keys",behaviors:[Polymer.IronA11yKeysBehavior],properties:{target:{type:Object,observer:"_targetChanged"},keys:{type:String,reflectToAttribute:!0,observer:"_keysChanged"}},attached:function(){this.target||(this.target=this.parentNode)},_targetChanged:function(e){this.keyEventTarget=e},_keysChanged:function(){this.removeOwnKeyBindings(),this.addOwnKeyBinding(this.keys,"_fireKeysPressed")},_fireKeysPressed:function(e){this.fire("keys-pressed",e.detail,{})}})</script> <script>Polymer({is:"iron-selector",behaviors:[Polymer.IronMultiSelectableBehavior]})</script> <script>Polymer.IronValidatableBehaviorMeta=null,Polymer.IronValidatableBehavior={properties:{validator:{type:String},invalid:{notify:!0,reflectToAttribute:!0,type:Boolean,value:!1},_validatorMeta:{type:Object},validatorType:{type:String,value:"validator"},_validator:{type:Object,computed:"__computeValidator(validator)"}},observers:["_invalidChanged(invalid)"],registered:function(){Polymer.IronValidatableBehaviorMeta=new Polymer.IronMeta({type:"validator"})},_invalidChanged:function(){this.invalid?this.setAttribute("aria-invalid","true"):this.removeAttribute("aria-invalid")},hasValidator:function(){return null!=this._validator},validate:function(a){return this.invalid=!this._getValidity(a),!this.invalid},_getValidity:function(a){return!this.hasValidator()||this._validator.validate(a)},__computeValidator:function(){return Polymer.IronValidatableBehaviorMeta&&Polymer.IronValidatableBehaviorMeta.byKey(this.validator)}}</script> <script>Polymer.IronFormElementBehavior={properties:{name:{type:String},value:{notify:!0,type:String},required:{type:Boolean,value:!1},_parentForm:{type:Object}},attached:function(){this.fire("iron-form-element-register")},detached:function(){this._parentForm&&this._parentForm.fire("iron-form-element-unregister",{target:this})}}</script> <script>Polymer.IronCheckedElementBehaviorImpl={properties:{checked:{type:Boolean,value:!1,reflectToAttribute:!0,notify:!0,observer:"_checkedChanged"},toggles:{type:Boolean,value:!0,reflectToAttribute:!0},value:{type:String,value:"on",observer:"_valueChanged"}},observers:["_requiredChanged(required)"],created:function(){this._hasIronCheckedElementBehavior=!0},_getValidity:function(e){return this.disabled||!this.required||this.checked},_requiredChanged:function(){this.required?this.setAttribute("aria-required","true"):this.removeAttribute("aria-required")},_checkedChanged:function(){this.active=this.checked,this.fire("iron-change")},_valueChanged:function(){void 0!==this.value&&null!==this.value||(this.value="on")}},Polymer.IronCheckedElementBehavior=[Polymer.IronFormElementBehavior,Polymer.IronValidatableBehavior,Polymer.IronCheckedElementBehaviorImpl]</script> <script>Polymer.PaperCheckedElementBehaviorImpl={_checkedChanged:function(){Polymer.IronCheckedElementBehaviorImpl._checkedChanged.call(this),this.hasRipple()&&(this.checked?this._ripple.setAttribute("checked",""):this._ripple.removeAttribute("checked"))},_buttonStateChanged:function(){Polymer.PaperRippleBehavior._buttonStateChanged.call(this),this.disabled||this.isAttached&&(this.checked=this.active)}},Polymer.PaperCheckedElementBehavior=[Polymer.PaperInkyFocusBehavior,Polymer.IronCheckedElementBehavior,Polymer.PaperCheckedElementBehaviorImpl]</script> <dom-module id="paper-checkbox" assetpath="/res/imp/bower_components/paper-checkbox/"> <template strip-whitespace=""> <style>:host{display:inline-block;white-space:nowrap;cursor:pointer;--calculated-paper-checkbox-size:var(--paper-checkbox-size, 18px);--calculated-paper-checkbox-ink-size:var(--paper-checkbox-ink-size, -1px);@apply(--paper-font-common-base);line-height:0;-webkit-tap-highlight-color:transparent}:host([hidden]){display:none!important}:host(:focus){outline:0}.hidden{display:none}#checkboxContainer{display:inline-block;position:relative;width:var(--calculated-paper-checkbox-size);height:var(--calculated-paper-checkbox-size);min-width:var(--calculated-paper-checkbox-size);margin:var(--paper-checkbox-margin,initial);vertical-align:var(--paper-checkbox-vertical-align,middle);background-color:var(--paper-checkbox-unchecked-background-color,transparent)}#ink{position:absolute;top:calc(0px - (var(--calculated-paper-checkbox-ink-size) - var(--calculated-paper-checkbox-size))/ 2);left:calc(0px - (var(--calculated-paper-checkbox-ink-size) - var(--calculated-paper-checkbox-size))/ 2);width:var(--calculated-paper-checkbox-ink-size);height:var(--calculated-paper-checkbox-ink-size);color:var(--paper-checkbox-unchecked-ink-color,var(--primary-text-color));opacity:.6;pointer-events:none}:host-context([dir=rtl]) #ink{right:calc(0px - (var(--calculated-paper-checkbox-ink-size) - var(--calculated-paper-checkbox-size))/ 2);left:auto}#ink[checked]{color:var(--paper-checkbox-checked-ink-color,var(--primary-color))}#checkbox{position:relative;box-sizing:border-box;height:100%;border:solid 2px;border-color:var(--paper-checkbox-unchecked-color,var(--primary-text-color));border-radius:2px;pointer-events:none;-webkit-transition:background-color 140ms,border-color 140ms;transition:background-color 140ms,border-color 140ms}#checkbox.checked #checkmark{-webkit-animation:checkmark-expand 140ms ease-out forwards;animation:checkmark-expand 140ms ease-out forwards}@-webkit-keyframes checkmark-expand{0%{-webkit-transform:scale(0,0) rotate(45deg)}100%{-webkit-transform:scale(1,1) rotate(45deg)}}@keyframes checkmark-expand{0%{transform:scale(0,0) rotate(45deg)}100%{transform:scale(1,1) rotate(45deg)}}#checkbox.checked{background-color:var(--paper-checkbox-checked-color,var(--primary-color));border-color:var(--paper-checkbox-checked-color,var(--primary-color))}#checkmark{position:absolute;width:36%;height:70%;border-style:solid;border-top:none;border-left:none;border-right-width:calc(2/15 * var(--calculated-paper-checkbox-size));border-bottom-width:calc(2/15 * var(--calculated-paper-checkbox-size));border-color:var(--paper-checkbox-checkmark-color,#fff);-webkit-transform-origin:97% 86%;transform-origin:97% 86%;box-sizing:content-box}:host-context([dir=rtl]) #checkmark{-webkit-transform-origin:50% 14%;transform-origin:50% 14%}#checkboxLabel{position:relative;display:inline-block;vertical-align:middle;padding-left:var(--paper-checkbox-label-spacing,8px);white-space:normal;line-height:normal;color:var(--paper-checkbox-label-color,var(--primary-text-color));@apply(--paper-checkbox-label)}:host([checked]) #checkboxLabel{color:var(--paper-checkbox-label-checked-color,var(--paper-checkbox-label-color,var(--primary-text-color)));@apply(--paper-checkbox-label-checked)}:host-context([dir=rtl]) #checkboxLabel{padding-right:var(--paper-checkbox-label-spacing,8px);padding-left:0}#checkboxLabel[hidden]{display:none}:host([disabled]) #checkbox{opacity:.5;border-color:var(--paper-checkbox-unchecked-color,var(--primary-text-color))}:host([disabled][checked]) #checkbox{background-color:var(--paper-checkbox-unchecked-color,var(--primary-text-color));opacity:.5}:host([disabled]) #checkboxLabel{opacity:.65}#checkbox.invalid:not(.checked){border-color:var(--paper-checkbox-error-color,var(--error-color))}</style> <div id="checkboxContainer"> <div id="checkbox" class$="[[_computeCheckboxClass(checked, invalid)]]"> <div id="checkmark" class$="[[_computeCheckmarkClass(checked)]]"></div> </div> </div> <div id="checkboxLabel"><content></content></div> </template> <script>Polymer({is:"paper-checkbox",behaviors:[Polymer.PaperCheckedElementBehavior],hostAttributes:{role:"checkbox","aria-checked":!1,tabindex:0},properties:{ariaActiveAttribute:{type:String,value:"aria-checked"}},attached:function(){var e=this.getComputedStyleValue("--calculated-paper-checkbox-ink-size");if("-1px"===e){var t=parseFloat(this.getComputedStyleValue("--calculated-paper-checkbox-size")),a=Math.floor(8/3*t);a%2!==t%2&&a++,this.customStyle["--paper-checkbox-ink-size"]=a+"px",this.updateStyles()}},_computeCheckboxClass:function(e,t){var a="";return e&&(a+="checked "),t&&(a+="invalid"),a},_computeCheckmarkClass:function(e){return e?"":"hidden"},_createRipple:function(){return this._rippleContainer=this.$.checkboxContainer,Polymer.PaperInkyFocusBehaviorImpl._createRipple.call(this)}})</script> </dom-module> <script>Polymer({is:"iron-input",extends:"input",behaviors:[Polymer.IronValidatableBehavior],properties:{bindValue:{observer:"_bindValueChanged",type:String},preventInvalidInput:{type:Boolean},allowedPattern:{type:String,observer:"_allowedPatternChanged"},_previousValidInput:{type:String,value:""},_patternAlreadyChecked:{type:Boolean,value:!1}},listeners:{input:"_onInput",keypress:"_onKeypress"},registered:function(){this._canDispatchEventOnDisabled()||(this._origDispatchEvent=this.dispatchEvent,this.dispatchEvent=this._dispatchEventFirefoxIE)},created:function(){Polymer.IronA11yAnnouncer.requestAvailability()},_canDispatchEventOnDisabled:function(){var e=document.createElement("input"),t=!1;e.disabled=!0,e.addEventListener("feature-check-dispatch-event",function(){t=!0});try{e.dispatchEvent(new Event("feature-check-dispatch-event"))}catch(e){}return t},_dispatchEventFirefoxIE:function(){var e=this.disabled;this.disabled=!1,this._origDispatchEvent.apply(this,arguments),this.disabled=e},get _patternRegExp(){var e;if(this.allowedPattern)e=new RegExp(this.allowedPattern);else switch(this.type){case"number":e=/[0-9.,e-]/}return e},ready:function(){this.bindValue=this.value},_bindValueChanged:function(){this.value!==this.bindValue&&(this.value=this.bindValue||0===this.bindValue||this.bindValue===!1?this.bindValue:""),this.fire("bind-value-changed",{value:this.bindValue})},_allowedPatternChanged:function(){this.preventInvalidInput=!!this.allowedPattern},_onInput:function(){if(this.preventInvalidInput&&!this._patternAlreadyChecked){var e=this._checkPatternValidity();e||(this._announceInvalidCharacter("Invalid string of characters not entered."),this.value=this._previousValidInput)}this.bindValue=this.value,this._previousValidInput=this.value,this._patternAlreadyChecked=!1},_isPrintable:function(e){var t=8==e.keyCode||9==e.keyCode||13==e.keyCode||27==e.keyCode,i=19==e.keyCode||20==e.keyCode||45==e.keyCode||46==e.keyCode||144==e.keyCode||145==e.keyCode||e.keyCode>32&&e.keyCode<41||e.keyCode>111&&e.keyCode<124;return!(t||0==e.charCode&&i)},_onKeypress:function(e){if(this.preventInvalidInput||"number"===this.type){var t=this._patternRegExp;if(t&&!(e.metaKey||e.ctrlKey||e.altKey)){this._patternAlreadyChecked=!0;var i=String.fromCharCode(e.charCode);this._isPrintable(e)&&!t.test(i)&&(e.preventDefault(),this._announceInvalidCharacter("Invalid character "+i+" not entered."))}}},_checkPatternValidity:function(){var e=this._patternRegExp;if(!e)return!0;for(var t=0;t<this.value.length;t++)if(!e.test(this.value[t]))return!1;return!0},validate:function(){var e=this.checkValidity();return e&&(this.required&&""===this.value?e=!1:this.hasValidator()&&(e=Polymer.IronValidatableBehavior.validate.call(this,this.value))),this.invalid=!e,this.fire("iron-input-validate"),e},_announceInvalidCharacter:function(e){this.fire("iron-announce",{text:e})}})</script> <script>Polymer.PaperInputHelper={},Polymer.PaperInputHelper.NextLabelID=1,Polymer.PaperInputHelper.NextAddonID=1,Polymer.PaperInputBehaviorImpl={properties:{label:{type:String},value:{notify:!0,type:String},disabled:{type:Boolean,value:!1},invalid:{type:Boolean,value:!1,notify:!0},preventInvalidInput:{type:Boolean},allowedPattern:{type:String},type:{type:String},list:{type:String},pattern:{type:String},required:{type:Boolean,value:!1},errorMessage:{type:String},charCounter:{type:Boolean,value:!1},noLabelFloat:{type:Boolean,value:!1},alwaysFloatLabel:{type:Boolean,value:!1},autoValidate:{type:Boolean,value:!1},validator:{type:String},autocomplete:{type:String,value:"off"},autofocus:{type:Boolean,observer:"_autofocusChanged"},inputmode:{type:String},minlength:{type:Number},maxlength:{type:Number},min:{type:String},max:{type:String},step:{type:String},name:{type:String},placeholder:{type:String,value:""},readonly:{type:Boolean,value:!1},size:{type:Number},autocapitalize:{type:String,value:"none"},autocorrect:{type:String,value:"off"},autosave:{type:String},results:{type:Number},accept:{type:String},multiple:{type:Boolean},_ariaDescribedBy:{type:String,value:""},_ariaLabelledBy:{type:String,value:""}},listeners:{"addon-attached":"_onAddonAttached"},keyBindings:{"shift+tab:keydown":"_onShiftTabDown"},hostAttributes:{tabindex:0},get inputElement(){return this.$.input},get _focusableElement(){return this.inputElement},registered:function(){this._typesThatHaveText=["date","datetime","datetime-local","month","time","week","file"]},attached:function(){this._updateAriaLabelledBy(),this.inputElement&&this._typesThatHaveText.indexOf(this.inputElement.type)!==-1&&(this.alwaysFloatLabel=!0)},_appendStringWithSpace:function(e,t){return e=e?e+" "+t:t},_onAddonAttached:function(e){var t=e.path?e.path[0]:e.target;if(t.id)this._ariaDescribedBy=this._appendStringWithSpace(this._ariaDescribedBy,t.id);else{var a="paper-input-add-on-"+Polymer.PaperInputHelper.NextAddonID++;t.id=a,this._ariaDescribedBy=this._appendStringWithSpace(this._ariaDescribedBy,a)}},validate:function(){return this.inputElement.validate()},_focusBlurHandler:function(e){Polymer.IronControlState._focusBlurHandler.call(this,e),this.focused&&!this._shiftTabPressed&&this._focusableElement.focus()},_onShiftTabDown:function(e){var t=this.getAttribute("tabindex");this._shiftTabPressed=!0,this.setAttribute("tabindex","-1"),this.async(function(){this.setAttribute("tabindex",t),this._shiftTabPressed=!1},1)},_handleAutoValidate:function(){this.autoValidate&&this.validate()},updateValueAndPreserveCaret:function(e){try{var t=this.inputElement.selectionStart;this.value=e,this.inputElement.selectionStart=t,this.inputElement.selectionEnd=t}catch(t){this.value=e}},_computeAlwaysFloatLabel:function(e,t){return t||e},_updateAriaLabelledBy:function(){var e=Polymer.dom(this.root).querySelector("label");if(!e)return void(this._ariaLabelledBy="");var t;e.id?t=e.id:(t="paper-input-label-"+Polymer.PaperInputHelper.NextLabelID++,e.id=t),this._ariaLabelledBy=t},_onChange:function(e){this.shadowRoot&&this.fire(e.type,{sourceEvent:e},{node:this,bubbles:e.bubbles,cancelable:e.cancelable})},_autofocusChanged:function(){if(this.autofocus&&this._focusableElement){var e=document.activeElement,t=e instanceof HTMLElement,a=t&&e!==document.body&&e!==document.documentElement;a||this._focusableElement.focus()}}},Polymer.PaperInputBehavior=[Polymer.IronControlState,Polymer.IronA11yKeysBehavior,Polymer.PaperInputBehaviorImpl]</script> <script>Polymer.PaperInputAddonBehavior={hostAttributes:{"add-on":""},attached:function(){this.fire("addon-attached")},update:function(t){}}</script> <dom-module id="paper-input-char-counter" assetpath="/res/imp/bower_components/paper-input/"> <template> <style>:host{display:inline-block;float:right;@apply(--paper-font-caption);@apply(--paper-input-char-counter)}:host([hidden]){display:none!important}:host-context([dir=rtl]){float:left}</style> <span>[[_charCounterStr]]</span> </template> </dom-module> <script>Polymer({is:"paper-input-char-counter",behaviors:[Polymer.PaperInputAddonBehavior],properties:{_charCounterStr:{type:String,value:"0"}},update:function(t){if(t.inputElement){t.value=t.value||"";var e=t.value.toString().length.toString();t.inputElement.hasAttribute("maxlength")&&(e+="/"+t.inputElement.getAttribute("maxlength")),this._charCounterStr=e}}})</script> <dom-module id="paper-input-container" assetpath="/res/imp/bower_components/paper-input/"> <template> <style>:host{display:block;padding:8px 0;@apply(--paper-input-container)}:host([inline]){display:inline-block}:host([disabled]){pointer-events:none;opacity:.33;@apply(--paper-input-container-disabled)}:host([hidden]){display:none!important}.floated-label-placeholder{@apply(--paper-font-caption)}.underline{position:relative}.focused-line{@apply(--layout-fit);background:var(--paper-input-container-focus-color,--primary-color);height:2px;-webkit-transform-origin:center center;transform-origin:center center;-webkit-transform:scale3d(0,1,1);transform:scale3d(0,1,1);@apply(--paper-input-container-underline-focus)}.underline.is-highlighted .focused-line{-webkit-transform:none;transform:none;-webkit-transition:-webkit-transform .25s;transition:transform .25s;@apply(--paper-transition-easing)}.underline.is-invalid .focused-line{background:var(--paper-input-container-invalid-color,--error-color);-webkit-transform:none;transform:none;-webkit-transition:-webkit-transform .25s;transition:transform .25s;@apply(--paper-transition-easing)}.unfocused-line{@apply(--layout-fit);background:var(--paper-input-container-color,--secondary-text-color);height:1px;@apply(--paper-input-container-underline)}:host([disabled]) .unfocused-line{border-bottom:1px dashed;border-color:var(--paper-input-container-color,--secondary-text-color);background:0 0;@apply(--paper-input-container-underline-disabled)}.label-and-input-container{@apply(--layout-flex-auto);@apply(--layout-relative);width:100%;max-width:100%}.input-content{@apply(--layout-horizontal);@apply(--layout-center);position:relative}.input-content ::content .paper-input-label,.input-content ::content label{position:absolute;top:0;right:0;left:0;width:100%;font:inherit;color:var(--paper-input-container-color,--secondary-text-color);-webkit-transition:-webkit-transform .25s,width .25s;transition:transform .25s,width .25s;-webkit-transform-origin:left top;transform-origin:left top;@apply(--paper-font-common-nowrap);@apply(--paper-font-subhead);@apply(--paper-input-container-label);@apply(--paper-transition-easing)}.input-content.label-is-floating ::content .paper-input-label,.input-content.label-is-floating ::content label{-webkit-transform:translateY(-75%) scale(.75);transform:translateY(-75%) scale(.75);width:133%;@apply(--paper-input-container-label-floating)}:host-context([dir=rtl]) .input-content.label-is-floating ::content .paper-input-label,:host-context([dir=rtl]) .input-content.label-is-floating ::content label{width:100%;-webkit-transform-origin:right top;transform-origin:right top}.input-content.label-is-highlighted ::content .paper-input-label,.input-content.label-is-highlighted ::content label{color:var(--paper-input-container-focus-color,--primary-color);@apply(--paper-input-container-label-focus)}.input-content.is-invalid ::content .paper-input-label,.input-content.is-invalid ::content label{color:var(--paper-input-container-invalid-color,--error-color)}.input-content.label-is-hidden ::content .paper-input-label,.input-content.label-is-hidden ::content label{visibility:hidden}.input-content ::content .paper-input-input,.input-content ::content input,.input-content ::content iron-autogrow-textarea,.input-content ::content textarea{position:relative;outline:0;box-shadow:none;padding:0;width:100%;max-width:100%;background:0 0;border:none;color:var(--paper-input-container-input-color,--primary-text-color);-webkit-appearance:none;text-align:inherit;vertical-align:bottom;@apply(--paper-font-subhead);@apply(--paper-input-container-input)}::content [prefix]{@apply(--paper-font-subhead);@apply(--paper-input-prefix);@apply(--layout-flex-none)}::content [suffix]{@apply(--paper-font-subhead);@apply(--paper-input-suffix);@apply(--layout-flex-none)}.input-content ::content input{min-width:0}.input-content ::content textarea{resize:none}.add-on-content{position:relative}.add-on-content.is-invalid ::content *{color:var(--paper-input-container-invalid-color,--error-color)}.add-on-content.is-highlighted ::content *{color:var(--paper-input-container-focus-color,--primary-color)}</style> <template is="dom-if" if="[[!noLabelFloat]]"> <div class="floated-label-placeholder" aria-hidden="true"> </div> </template> <div class$="[[_computeInputContentClass(noLabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent)]]"> <content select="[prefix]" id="prefix"></content> <div class="label-and-input-container" id="labelAndInputContainer"> <content select=":not([add-on]):not([prefix]):not([suffix])"></content> </div> <content select="[suffix]"></content> </div> <div class$="[[_computeUnderlineClass(focused,invalid)]]"> <div class="unfocused-line"></div> <div class="focused-line"></div> </div> <div class$="[[_computeAddOnContentClass(focused,invalid)]]"> <content id="addOnContent" select="[add-on]"></content> </div> </template> </dom-module> <script>Polymer({is:"paper-input-container",properties:{noLabelFloat:{type:Boolean,value:!1},alwaysFloatLabel:{type:Boolean,value:!1},attrForValue:{type:String,value:"bind-value"},autoValidate:{type:Boolean,value:!1},invalid:{observer:"_invalidChanged",type:Boolean,value:!1},focused:{readOnly:!0,type:Boolean,value:!1,notify:!0},_addons:{type:Array},_inputHasContent:{type:Boolean,value:!1},_inputSelector:{type:String,value:"input,textarea,.paper-input-input"},_boundOnFocus:{type:Function,value:function(){return this._onFocus.bind(this)}},_boundOnBlur:{type:Function,value:function(){return this._onBlur.bind(this)}},_boundOnInput:{type:Function,value:function(){return this._onInput.bind(this)}},_boundValueChanged:{type:Function,value:function(){return this._onValueChanged.bind(this)}}},listeners:{"addon-attached":"_onAddonAttached","iron-input-validate":"_onIronInputValidate"},get _valueChangedEvent(){return this.attrForValue+"-changed"},get _propertyForValue(){return Polymer.CaseMap.dashToCamelCase(this.attrForValue)},get _inputElement(){return Polymer.dom(this).querySelector(this._inputSelector)},get _inputElementValue(){return this._inputElement[this._propertyForValue]||this._inputElement.value},ready:function(){this._addons||(this._addons=[]),this.addEventListener("focus",this._boundOnFocus,!0),this.addEventListener("blur",this._boundOnBlur,!0)},attached:function(){this.attrForValue?this._inputElement.addEventListener(this._valueChangedEvent,this._boundValueChanged):this.addEventListener("input",this._onInput),""!=this._inputElementValue?this._handleValueAndAutoValidate(this._inputElement):this._handleValue(this._inputElement)},_onAddonAttached:function(t){this._addons||(this._addons=[]);var n=t.target;this._addons.indexOf(n)===-1&&(this._addons.push(n),this.isAttached&&this._handleValue(this._inputElement))},_onFocus:function(){this._setFocused(!0)},_onBlur:function(){this._setFocused(!1),this._handleValueAndAutoValidate(this._inputElement)},_onInput:function(t){this._handleValueAndAutoValidate(t.target)},_onValueChanged:function(t){this._handleValueAndAutoValidate(t.target)},_handleValue:function(t){var n=this._inputElementValue;n||0===n||"number"===t.type&&!t.checkValidity()?this._inputHasContent=!0:this._inputHasContent=!1,this.updateAddons({inputElement:t,value:n,invalid:this.invalid})},_handleValueAndAutoValidate:function(t){if(this.autoValidate){var n;n=t.validate?t.validate(this._inputElementValue):t.checkValidity(),this.invalid=!n}this._handleValue(t)},_onIronInputValidate:function(t){this.invalid=this._inputElement.invalid},_invalidChanged:function(){this._addons&&this.updateAddons({invalid:this.invalid})},updateAddons:function(t){for(var n,e=0;n=this._addons[e];e++)n.update(t)},_computeInputContentClass:function(t,n,e,i,a){var u="input-content";if(t)a&&(u+=" label-is-hidden");else{var o=this.querySelector("label");n||a?(u+=" label-is-floating",this.$.labelAndInputContainer.style.position="static",i?u+=" is-invalid":e&&(u+=" label-is-highlighted")):o&&(this.$.labelAndInputContainer.style.position="relative")}return u},_computeUnderlineClass:function(t,n){var e="underline";return n?e+=" is-invalid":t&&(e+=" is-highlighted"),e},_computeAddOnContentClass:function(t,n){var e="add-on-content";return n?e+=" is-invalid":t&&(e+=" is-highlighted"),e}})</script> <dom-module id="paper-input-error" assetpath="/res/imp/bower_components/paper-input/"> <template> <style>:host{display:inline-block;visibility:hidden;color:var(--paper-input-container-invalid-color,--error-color);@apply(--paper-font-caption);@apply(--paper-input-error);position:absolute;left:0;right:0}:host([invalid]){visibility:visible};</style> <content></content> </template> </dom-module> <script>Polymer({is:"paper-input-error",behaviors:[Polymer.PaperInputAddonBehavior],properties:{invalid:{readOnly:!0,reflectToAttribute:!0,type:Boolean}},update:function(e){this._setInvalid(e.invalid)}})</script> <dom-module id="paper-input" assetpath="/res/imp/bower_components/paper-input/"> <template> <style>:host{display:block}:host([focused]){outline:0}:host([hidden]){display:none!important}input::-webkit-input-placeholder{color:var(--paper-input-container-color,--secondary-text-color)}input:-moz-placeholder{color:var(--paper-input-container-color,--secondary-text-color)}input::-moz-placeholder{color:var(--paper-input-container-color,--secondary-text-color)}input:-ms-input-placeholder{color:var(--paper-input-container-color,--secondary-text-color)}label{pointer-events:none}</style> <paper-input-container no-label-float="[[noLabelFloat]]" always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]" auto-validate$="[[autoValidate]]" disabled$="[[disabled]]" invalid="[[invalid]]"> <content select="[prefix]"></content> <label hidden$="[[!label]]" aria-hidden="true" for="input">[[label]]</label> <input is="iron-input" id="input" aria-labelledby$="[[_ariaLabelledBy]]" aria-describedby$="[[_ariaDescribedBy]]" disabled$="[[disabled]]" title$="[[title]]" bind-value="{{value}}" invalid="{{invalid}}" prevent-invalid-input="[[preventInvalidInput]]" allowed-pattern="[[allowedPattern]]" validator="[[validator]]" type$="[[type]]" pattern$="[[pattern]]" required$="[[required]]" autocomplete$="[[autocomplete]]" autofocus$="[[autofocus]]" inputmode$="[[inputmode]]" minlength$="[[minlength]]" maxlength$="[[maxlength]]" min$="[[min]]" max$="[[max]]" step$="[[step]]" name$="[[name]]" placeholder$="[[placeholder]]" readonly$="[[readonly]]" list$="[[list]]" size$="[[size]]" autocapitalize$="[[autocapitalize]]" autocorrect$="[[autocorrect]]" on-change="_onChange" tabindex$="[[tabindex]]" autosave$="[[autosave]]" results$="[[results]]" accept$="[[accept]]" multiple$="[[multiple]]"> <content select="[suffix]"></content> <template is="dom-if" if="[[errorMessage]]"> <paper-input-error aria-live="assertive">[[errorMessage]]</paper-input-error> </template> <template is="dom-if" if="[[charCounter]]"> <paper-input-char-counter></paper-input-char-counter> </template> </paper-input-container> </template> </dom-module> <script>Polymer({is:"paper-input",behaviors:[Polymer.IronFormElementBehavior,Polymer.PaperInputBehavior]})</script> <dom-module id="query-column-filter-style" assetpath="/res/imp/common/"> <template> <style>:host{display:block;font-family:sans-serif}#filter{margin:0 5px}.container{min-height:120px;width:100%}.item{border-bottom:1px solid #EEE;max-width:250px;min-height:1em;min-width:100px;padding:.1em .2em;line-height:1.5em}.header{height:2em;padding:.25em;line-height:2em}.selector{border:1px solid #000;margin:0 5px;max-height:200px;min-height:130px;min-width:275px;overflow-y:auto}.pointable,.selectable{cursor:pointer}.selectable:hover{background-color:#A6CEE3}.iron-selected{background-color:#1F78B4;color:#fff}.icons{cursor:pointer;height:20px;margin:2px;width:20px;flex-shrink:0}.side-by-side{display:inline-block;vertical-align:top}.bold{font-weight:700}paper-checkbox{max-height:2em;margin:2px;--paper-checkbox-checked-color:black;--paper-checkbox-checked-ink-color:black;--paper-checkbox-unchecked-color:black;--paper-checkbox-unchecked-ink-color:black;--paper-checkbox-label-color:black}</style> </template> </dom-module> <script>!function(){var r=":",i=function(r,i){if(!i)return{idx:0,part:""};if(!r)return{idx:-1};i=i.trim().toLocaleLowerCase(),r=r.toLocaleLowerCase();for(var t=i.split(" "),e=0;e<t.length;e++){var n=r.indexOf(t[e]);if(n!==-1)return{idx:n,part:t[e]}}return{idx:-1}},t=function(i,t,e){if(!t)return!0;if(!i)return!1;if(i=i.toLocaleLowerCase(),t=t.trim().toLocaleLowerCase(),t.indexOf(" ")!==-1||t.indexOf(":")===-1)return!1;var n=t.split(r,1)[0],a=t.substring(n.length+r.length);return e?i===n:i.startsWith(a)};SwarmingBehaviors.QueryColumnFilter=[SwarmingBehaviors.CommonBehavior,{properties:{dimensions:{type:Array},primary_map:{type:Object},primary_arr:{type:Array},special_columns:{type:Array,value:function(){return[]}},filter:{type:Function,computed:"_makeFilter(_filters.*)",notify:!0},FILTER_SEP:{type:String,value:r},_filters:{type:Array},_limit:{type:Number},_primaryItems:{type:Array,computed:"_primary(_query, primary_map, primary_arr, columns.*)"},_primarySelected:{type:String,value:""},_query:{type:String},_secondaryItems:{type:Array,computed:"_secondary(_primarySelected, _query, primary_map)"}},_addFilter:function(r){var i=r.model.item;if(!this._cantAddFilter(this._primarySelected,i)){var t=this._primarySelected+this.FILTER_SEP+i;this.push("_filters",t)}},_removeFilter:function(r){var i=r.model.fil;if(!this._cantRemoveFilter(i)){var t=this._filters.indexOf(i);t!==-1&&this.splice("_filters",t,1)}},_cantAddFilter:function(r,i){if(!r||!i)return!0;var t=r+this.FILTER_SEP+i;return this._filters.indexOf(t)!==-1},_cantRemoveFilter:function(r){return!r||this._filters.indexOf(r)===-1},_makeFilter:function(){var r={};this._filters.forEach(function(i){var t=i.indexOf(this.FILTER_SEP),e=i.slice(0,t),n=i.slice(t+this.FILTER_SEP.length),a=r[e]||[];a.push(n),r[e]=a}.bind(this));var i=this._filterMap||{};return function(t){var e=!0;for(primary in r){var n=r[primary],a=i[primary];a||(a=function(r,i){var t=this._attribute(r,primary);return t.indexOf(i)!==-1}.bind(this)),a&&n.forEach(function(r){e=e&&a.bind(this)(t,r)}.bind(this))}return e}},_manuallyAddFilter:function(){var r=this._query.trim(),i=r.indexOf(this.FILTER_SEP);if(i===-1)return void sk.errorMessage('Invalid filter. Should be like "foo:bar"',5e3);var t=r.slice(0,i),e=r.slice(i+this.FILTER_SEP.length);return swarming.alias.DIMENSIONS_WITH_ALIASES.indexOf(t)!==-1&&(e=swarming.alias.apply(e,t)),r=t+this.FILTER_SEP+e,this._filters.indexOf(r)!==-1?void sk.errorMessage('Filter "'+r+'" is already active',5e3):(this.push("_filters",r),void this.set("_query",""))},_toggleColumn:function(r){var i=r.model.item;if(!this._cantToggleColumn(i)){if(this._columnState(i)){var t=this.columns.indexOf(i);return void(t!==-1&&this.splice("columns",t,1))}this.push("columns",i)}},_cantToggleColumn:function(r){return!1},_columnState:function(r){return!!r&&this.columns.indexOf(r)!==-1},_primary:function(r,e,n){var a=this.primary_arr.filter(function(n){if(t(n,r,!0))return!0;if(i(n,r).idx!==-1)return!0;for(var a=e[n]||[],s=0;s<a.length;s++)if(i(a[s],r).idx!==-1)return!0;return!1});return r&&a.length>0&&a.indexOf(this._primarySelected)===-1&&this.set("_primarySelected",a[0]),a.sort(function(r,i){var t=this._columnState(r),e=this._columnState(i);if(t&&!e)return-1;if(e&&!t)return 1;if(t&&e){if(t=this.special_columns.indexOf(r),e=this.special_columns.indexOf(i),t!==-1&&e===-1)return-1;if(t===-1&&e!==-1)return 1;if(t!==-1&&e!==-1)return t-e}return naturalSort(r,i)}.bind(this)),a},_secondary:function(r,e,n){if(requestAnimationFrame(function(){this.$.secondaryList.render()}.bind(this)),!r)return[];var a=n[r]||[];return t(r,e,!0)?a.sort(function(r,i){var n=t(r,e,!1),a=t(i,e,!1);return n===a?naturalSort(r,i):a-n}):i(r,e).idx!==-1?a.sort(function(r,t){var n=i(r,e).idx!==-1,a=i(t,e).idx!==-1;return n===a?naturalSort(r,t):a-n}):a.filter(function(r){return i(r,e).idx!==-1})},_beforeBold:function(r,t){var e=i(r,t.replace(":"," "));return e.idx===-1?r:r.substring(0,e.idx)},_bold:function(r,t){var e=i(r,t.replace(":"," "));return e.idx===-1?"":r.substring(e.idx,e.idx+e.part.length)},_afterBold:function(r,t){var e=i(r,t.replace(":"," "));return e.idx===-1?"":r.substring(e.idx+e.part.length)},_commonFilters:function(){return{android_devices:function(r,i){var t=this._attribute(r,"android_devices","0");return t.indexOf(i)!==-1},device_os:function(r,i){var t=this._attribute(r,"device_os","none");return t.indexOf(i)!==-1},device_type:function(r,i){var t=this._attribute(r,"device_type","none");return t.indexOf(swarming.alias.unapply(i))!==-1},gpu:function(r,i){var t=this._attribute(r,"gpu","none");return t.indexOf(swarming.alias.unapply(i))!==-1}}}}]}()</script> <script>!function(){var e="unknown";SwarmingBehaviors.BotListBehavior=[SwarmingBehaviors.CommonBehavior,{properties:{BOT_PROPERTIES:{type:Array,value:function(){return["disk_space","uptime","running_time","task","status","version","external_ip","internal_ip","mp_lease_id","mp_lease_expires","last_seen","first_seen","battery_level","battery_voltage","battery_temperature","battery_status","battery_health","bot_temperature","device_temperature"]}}},_attribute:function(t,i,n){return n=n||e,this._dimension(t,i)||this._state(t,i)||[n]},_devices:function(e){return e.state.devices||[]},_deviceType:function(e){return e.device_type.toLowerCase()},_dimension:function(e,t){if(e&&e.dimensions&&t)for(var i=0;i<e.dimensions.length;i++)if(e.dimensions[i].key===t)return e.dimensions[i].value},_state:function(e,t){if(e&&e.state&&e.state[t]){var i=e.state[t];return Array.isArray(i)?i:[i]}},_taskId:function(e){return e&&e.task_id?e.task_id:"idle"}}]}()</script> <dom-module id="bot-filters" assetpath="/res/imp/botlist/"> <template> <style is="custom-style" include="iron-flex iron-flex-alignment iron-positioning query-column-filter-style swarming-app-style"></style> <url-param name="f" value="{{_filters}}" default_values="[]" multi=""> </url-param> <url-param name="c" value="{{columns}}" default_values="["id","os","task","status"]" multi=""> </url-param> <url-param name="q" value="{{_query}}" default_value=""> </url-param> <url-param name="v" value="{{verbose}}"> </url-param> <url-param name="l" default_value="100" value="{{_limit}}"> </url-param> <div class="container horizontal layout"> <div class="narrow-down-selector"> <div> <iron-a11y-keys target="[[_filter_input]]" keys="enter" on-keys-pressed="_manuallyAddFilter"></iron-a11y-keys> <paper-input id="filter" label="Search columns and filters or supply a filter and press enter" placeholder="gpu nvidia pool:Chrome" value="{{_query::input}}"> </paper-input> </div> <div class="selector side-by-side" title="This shows all bot dimension names and other interesting bot properties. Mark the check box to add as a column. Select the row to see filter options."> <iron-selector attr-for-selected="label" selected="{{_primarySelected}}"> <template is="dom-repeat" items="[[_primaryItems]]" as="item"> <div class="selectable item horizontal layout" label="[[item]]"> <span>[[_beforeBold(item,_query)]]<span class="bold">[[_bold(item,_query)]]</span>[[_afterBold(item,_query)]]</span> <span class="flex"></span> <paper-checkbox noink="" disabled$="[[_cantToggleColumn(item)]]" checked="[[_columnState(item,columns.*)]]" on-change="_toggleColumn"> </paper-checkbox> </div> </template> </iron-selector> </div> <div class="selector side-by-side" title="These are all options (if any) that the bot list can be filtered on."> <template is="dom-repeat" id="secondaryList" items="[[_secondaryItems]]" as="item"> <div class="item horizontal layout" label="[[item]]"> <span>[[_beforeBold(item,_query)]]<span class="bold">[[_bold(item,_query)]]</span>[[_afterBold(item,_query)]]</span> <span class="flex"></span> <iron-icon class="icons" icon="icons:arrow-forward" hidden="[[_cantAddFilter(_primarySelected,item,_filters.*)]]" on-tap="_addFilter"> </iron-icon> </div> </template> <template is="dom-if" if="[[_showDimensionMessage(_primarySelected,_secondaryItems.length)]]"> <div class="item"> Only dimensions can be used for filtering. <i>"[[_primarySelected]]"</i> is a part of the bot's state and is informational only. </div> </template> </div> <div class="selector side-by-side" title="These filters are AND'd together and applied to all bots in |
-the fleet."> <template is="dom-repeat" items="[[_filters]]" as="fil"> <div class="item horizontal layout" label="[[fil]]"> <span>[[fil]]</span> <span class="flex"></span> <iron-icon class="icons" icon="icons:remove-circle-outline" hidden="[[_cantRemoveFilter(fil,_filters.*)]]" on-tap="_removeFilter"> </iron-icon> </div> </template> </div> <div class="side-by-side"> <paper-checkbox checked="{{verbose}}">Verbose Entries</paper-checkbox> <paper-input id="_limit" label="Limit Results" auto-validate="" min="0" max="1000" pattern="[0-9]+" value="{{_limit}}"> </paper-input> <a href$="[[_matchingTasksLink(query_params)]]">View Matching Tasks</a> </div> </div> </div> </template> <script>!function(){var i={disk_space:function(i,t){return!0},id:function(i,t){return!0},status:function(i,t){return"quarantined"===t?i.quarantined:"dead"===t?i.is_dead:!i.quarantined&&!i.is_dead},task:function(i,t){return"idle"===t?"idle"===this._taskId(i):"idle"!==this._taskId(i)}};Polymer({is:"bot-filters",behaviors:[SwarmingBehaviors.BotListBehavior,SwarmingBehaviors.QueryColumnFilter],properties:{columns:{type:Array,notify:!0},query_params:{type:Object,computed:"_extractQueryParams(dimensions.*,_filters.*, _limit)",notify:!0},verbose:{type:Boolean,notify:!0},_filter_input:{type:Object,value:function(){return this.$.filter}},_filterMap:{type:Object,value:function(){var t=this._commonFilters();for(var n in i)t[n]=i[n];return t}}},_cantToggleColumn:function(i){return!i||"id"===i},_extractQueryParams:function(){var i={},t=[];this._filters.forEach(function(n){var e=n.split(this.FILTER_SEP,1),s=e[0];if(this.dimensions.indexOf(s)!==-1){var a=n.substring(s.length+this.FILTER_SEP.length);swarming.alias.DIMENSIONS_WITH_ALIASES.indexOf(s)!==-1&&(a=swarming.alias.unapply(a)),t.push(s+this.FILTER_SEP+a)}else if("status"===s){var a=n.substring(s.length+this.FILTER_SEP.length);"alive"===a?(i.is_dead=["FALSE"],i.quarantined=["FALSE"]):"quarantined"===a?i.quarantined=["TRUE"]:"dead"===a&&(i.is_dead=["TRUE"])}}.bind(this)),i.dimensions=t;var n=parseInt(this._limit);return Number.isInteger(n)&&(n=Math.max(n,1),n=Math.min(1e3,n),i.limit=[n],this._limit!=n&&this.set("_limit",n)),i},_matchingTasksLink:function(i){var t=["name","state","created_ts"];return i.dimensions?(i.dimensions.forEach(function(i){var n=i.split(this.FILTER_SEP,1)[0];t.indexOf(n)===-1&&t.push(n)}.bind(this)),this._taskListLink(i.dimensions,t)):this._taskListLink([],t)},_showDimensionMessage:function(i,t){return i&&"id"!==i&&!t}})}()</script> </dom-module><dom-module id="bot-list-data" assetpath="/res/imp/botlist/"> <script>!function(){function e(e){if(!e)return{};var t=[],s=0;for(k in e)t.push(k+": "+e[k]),s+=e[k];return s/=t.length,s=s?s.toFixed(1):"unknown",{average:s,zones:t.join(" | ")||"unknown"}}var t="available",s=["quarantined","error"],n=["first_seen_ts","last_seen_ts","lease_expiration_ts"];Polymer({is:"bot-list-data",behaviors:[SwarmingBehaviors.BotListBehavior],properties:{auth_headers:{type:Object,observer:"signIn"},bots:{type:Array,computed:"parseBots(_list)",notify:!0},busy:{type:Boolean,computed:"_or(_busy2,_busy1)",notify:!0},dimensions:{type:Array,computed:"_makeArray(_dimensions)",notify:!0},fleet:{type:Object,computed:"_fleet(_count)",notify:!0},primary_map:{type:Object,computed:"_primaryMap(_dimensions)",notify:!0},primary_arr:{type:Array,computed:"_primaryArr(dimensions, BOT_PROPERTIES)",notify:!0},_busy1:{type:Boolean,value:!1},_busy2:{type:Boolean,value:!1},_count:{type:Object},_dimensions:{type:Object},_list:{type:Object}},signIn:function(){this._getJsonAsync("_count","/api/swarming/v1/bots/count","_busy2",this.auth_headers),this._getJsonAsync("_dimensions","/api/swarming/v1/bots/dimensions","_busy1",this.auth_headers)},parseBots:function(s){return s&&s.items?(s.items.forEach(function(s){s.state=s.state||"{}",s.state=JSON.parse(s.state)||{};var i=s.state.disks||{},a=Object.keys(i);if(a.length){s.disks=[];for(var o=0;o<a.length;o++)s.disks.push({id:a[o],mb:i[a[o]].free_mb});s.disks.sort(function(e,t){return t.mb-e.mb})}else s.disks=[{id:"unknown",mb:0}];s.state.temp=e(s.state.temp);var r=[],u=s&&s.state&&s.state.devices||{};for(key in u){var d=u[key];d.serial=key,d.okay=d.state===t;var c=this._dimension(s,"device_type")||["unknown"];d.device_type=c[0],d.temp=e(d.temp),r.push(d)}s.state.devices=r,n.forEach(function(e){swarming.sanitizeAndHumanizeTime(s,e)})}.bind(this)),s.items):[]},_fleet:function(){return this._count?{all:this._count.count||-1,alive:this._count.count-this._count.dead||-1,busy:this._count.busy||-1,idle:this._count.count-this._count.busy||-1,dead:this._count.dead||-1,quarantined:this._count.quarantined||-1}:{}},_makeArray:function(e){if(!e||!e.bots_dimensions)return[];var t=[];return e.bots_dimensions.forEach(function(e){s.indexOf(e.key)===-1&&t.push(e.key)}),t.push("id"),t.sort(),t},_primaryArr:function(e,t){return e.concat(t)},_primaryMap:function(e){e=e.bots_dimensions||[];var t={};return e.forEach(function(e){if(swarming.alias.DIMENSIONS_WITH_ALIASES.indexOf(e.key)===-1)t[e.key]=e.value;else{var s=[];e.value.forEach(function(t){s.push(swarming.alias.apply(t,e.key))}),t[e.key]=s}}),t.android_devices&&t.android_devices.push("0"),t.device_os&&t.device_os.push("none"),t.device_type&&t.device_type.push("none"),t.id=[],t.disk_space=[],t.task=["busy","idle"],t.status=["alive","dead","quarantined"],t}})}()</script> </dom-module><dom-module id="bot-list-summary" assetpath="/res/imp/botlist/"> <template> <style include="swarming-app-style">:host{display:block;border-left:1px solid #000;padding:5px 5px;font-family:sans-serif}.header{font-size:1.2em;font-weight:700}.header.buffer{margin-top:5px}.right{text-align:right}.left{text-align:left}</style> <div class="header">Fleet</div> <table> <tbody><tr> <td class="right"> <a href$="[[_makeURL('','',columns.*,sort,verbose)]]">All</a>: </td> <td class="left">[[fleet.all]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('alive','',columns.*,sort,verbose)]]">Alive</a>: </td> <td class="left">[[fleet.alive]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('busy','',columns.*,sort,verbose)]]">Busy</a>: </td> <td class="left">[[fleet.busy]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('idle','',columns.*,sort,verbose)]]">Idle</a>: </td> <td class="left">[[fleet.idle]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('dead','',columns.*,sort,verbose)]]">Dead</a>: </td> <td class="left">[[fleet.dead]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('quarantined','',columns.*,sort,verbose)]]">Quarantined</a>: </td> <td class="left">[[fleet.quarantined]]</td> </tr> </tbody></table> <div class="header buffer">Selected</div> <table> <tbody><tr> <td class="right"> Displayed: </td> <td class="left">[[num_bots]]</td> </tr> <tr> <td class="right"> All: </td> <td class="left">[[_count_query.count]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('alive','true',columns.*,sort,verbose)]]">Alive</a>: </td> <td class="left">[[_computeAlive(_count_query.*)]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('busy','true',columns.*,sort,verbose)]]">Busy</a>: </td> <td class="left">[[_count_query.busy]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('idle','true',columns.*,sort,verbose)]]">Idle</a>: </td> <td class="left">[[_computeIdle(_count_query.*)]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('dead','true',columns.*,sort,verbose)]]">Dead</a>: </td> <td class="left">[[_count_query.dead]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('quarantined','true',columns.*,sort,verbose)]]">Quarantined</a>: </td> <td class="left">[[_count_query.quarantined]]</td> </tr> </tbody></table> </template> <script>Polymer({is:"bot-list-summary",behaviors:[SwarmingBehaviors.BotListBehavior],properties:{auth_headers:{type:Object},columns:{type:Array},count_params:{type:Object},fleet:{type:Object},num_bots:{type:Number},sort:{type:String},verbose:{type:Boolean},busy:{type:Boolean,value:!1,notify:!0},_count_query:{type:Object}},observers:["_recountTotal(auth_headers.*,count_params.*)"],_computeAlive:function(){return this._count_query.count-this._count_query.dead},_computeIdle:function(){return this._count_query.count-this._count_query.busy},_getFilterStr:function(t){return t?"alive"===t||"dead"===t||"quarantined"===t?"status:"+t:"task:"+t:""},_makeURL:function(t,e){if(!e){var r={s:[this.sort],c:this.columns,v:[this.verbose]};return t&&(r.f=[this._getFilterStr(t)]),window.location.href.split("?")[0]+"?"+sk.query.fromParamSet(r)}var o=encodeURIComponent(this._getFilterStr(t));if(window.location.href.indexOf(o)===-1)return window.location.href+"&f="+o},_recountTotal:function(){this.auth_headers&&this.count_params&&this._getJsonAsync("_count_query","/api/swarming/v1/bots/count","busy",this.auth_headers,this.count_params)}})</script> </dom-module><dom-module id="bot-list" assetpath="/res/imp/botlist/"> <template> <style include="iron-flex iron-flex-alignment iron-positioning swarming-app-style dynamic-table-style">bot-filters,bot-list-summary{margin-bottom:8px;margin-right:10px}.old_version{background-color:#ffd}.bad-device,.quarantined{background-color:#fdd}.dead{background-color:#ccc}.alt{background-color:#f8f8f8}.bot-list th>span{padding-right:30px}</style> <url-param name="s" value="{{_sortstr}}" default_value="id:asc"> </url-param> <swarming-app client_id="[[client_id]]" auth_headers="{{_auth_headers}}" signed_in="{{_signed_in}}" server_details="{{_server_details}}" busy="[[_or(_busy1,_busy2,_busy3)]]" name="Swarming Bot List"> <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> <div hidden$="[[_not(_signed_in)]]"> <div class="horizontal layout"> <bot-filters dimensions="[[_dimensions]]" primary_map="[[_primary_map]]" primary_arr="[[_primary_arr]]" special_columns="[[_specialColumns]]" columns="{{_columns}}" query_params="{{_query_params}}" filter="{{_filter}}" verbose="{{_verbose}}"> </bot-filters> <bot-list-summary auth_headers="[[_auth_headers]]" columns="[[_columns]]" count_params="[[_query_params]]" fleet="[[_fleet]]" num_bots="[[_filteredSortedItems.length]]" sort="[[_sortstr]]" verbose="[[_verbose]]" busy="{{_busy3}}"> </bot-list-summary> </div> <bot-list-data id="data" auth_headers="[[_auth_headers]]" query_params="[[_query_params]]" busy="{{_busy1}}" dimensions="{{_dimensions}}" fleet="{{_fleet}}" primary_map="{{_primary_map}}" primary_arr="{{_primary_arr}}"> </bot-list-data> <table class="bot-list"> <thead on-sort_change="_sortChange"> <tr> <th> <span>Bot Id</span> <sort-toggle name="id" current="[[_sort]]"> </sort-toggle> </th> <th hidden$="[[_hide('mp_lease_id', _columns.*)]]"> <span>Machine Provider Lease Id</span> <sort-toggle name="mp_lease_id" current="[[_sort]]"> </sort-toggle> </th> <th hidden$="[[_hide('task', _columns.*)]]"> <span>Current Task</span> <sort-toggle name="task" current="[[_sort]]"> </sort-toggle> </th> <template is="dom-repeat" items="[[_plainColumns]]" as="c"> <th hidden$="[[_hide(c)]]"> <span>[[_header(c)]]</span> <sort-toggle name="[[c]]" current="[[_sort]]"> </sort-toggle> </th> </template> </tr> </thead> <tbody> <template id="bot_table" is="dom-repeat" items="[[_filteredSortedItems]]" as="bot" initial-count="50"> <tr class$="[[_botClass(bot,_server_details.bot_version)]]"> <td> <a class="center" href$="[[_botLink(bot.bot_id)]]" target="_blank" rel="noopener"> [[bot.bot_id]] </a> </td> <td hidden$="[[_hide('mp_lease_id', _columns.*)]]"> <a href$="[[_mpLink(bot, _server_details.machine_provider_template)]]"> [[_column('mp_lease_id', bot,_verbose)]] </a> </td> <td hidden$="[[_hide('task', _columns.*)]]"> <a href$="[[_taskLink(bot.task_id)]]">[[_taskId(bot)]]</a> </td> <template is="dom-repeat" items="[[_plainColumns]]" as="c"> <td hidden$="[[_hide(c)]]"> [[_column(c, bot, _verbose)]] </td> </template> </tr> <template is="dom-repeat" items="[[_devices(bot)]]" as="device"> <tr hidden$="[[_hide('android_devices', _columns.*)]]" class$="[[_deviceClass(device,index)]]"> <td></td> <td hidden$="[[_hide('mp_lease_id', _columns.*)]]"></td> <td hidden$="[[_hide('task', _columns.*)]]"></td> <template is="dom-repeat" items="[[_plainColumns]]" as="c"> <td hidden$="[[_hide(c)]]"> [[_deviceColumn(c, device, _verbose)]] </td> </template> </tr> </template> </template> </tbody> </table> <pageable-data id="page_bots" busy="{{_busy2}}" label="Show more bots" output="{{_items}}" parse="[[_parseBots]]"> </pageable-data> </div> </swarming-app> </template> <script> (function(){ |
+ })(); </script> </dom-module><script>Polymer({is:"iron-a11y-keys",behaviors:[Polymer.IronA11yKeysBehavior],properties:{target:{type:Object,observer:"_targetChanged"},keys:{type:String,reflectToAttribute:!0,observer:"_keysChanged"}},attached:function(){this.target||(this.target=this.parentNode)},_targetChanged:function(e){this.keyEventTarget=e},_keysChanged:function(){this.removeOwnKeyBindings(),this.addOwnKeyBinding(this.keys,"_fireKeysPressed")},_fireKeysPressed:function(e){this.fire("keys-pressed",e.detail,{})}})</script> <script>Polymer({is:"iron-selector",behaviors:[Polymer.IronMultiSelectableBehavior]})</script> <script>Polymer.IronValidatableBehaviorMeta=null,Polymer.IronValidatableBehavior={properties:{validator:{type:String},invalid:{notify:!0,reflectToAttribute:!0,type:Boolean,value:!1},_validatorMeta:{type:Object},validatorType:{type:String,value:"validator"},_validator:{type:Object,computed:"__computeValidator(validator)"}},observers:["_invalidChanged(invalid)"],registered:function(){Polymer.IronValidatableBehaviorMeta=new Polymer.IronMeta({type:"validator"})},_invalidChanged:function(){this.invalid?this.setAttribute("aria-invalid","true"):this.removeAttribute("aria-invalid")},hasValidator:function(){return null!=this._validator},validate:function(a){return this.invalid=!this._getValidity(a),!this.invalid},_getValidity:function(a){return!this.hasValidator()||this._validator.validate(a)},__computeValidator:function(){return Polymer.IronValidatableBehaviorMeta&&Polymer.IronValidatableBehaviorMeta.byKey(this.validator)}}</script> <script>Polymer.IronFormElementBehavior={properties:{name:{type:String},value:{notify:!0,type:String},required:{type:Boolean,value:!1},_parentForm:{type:Object}},attached:function(){this.fire("iron-form-element-register")},detached:function(){this._parentForm&&this._parentForm.fire("iron-form-element-unregister",{target:this})}}</script> <script>Polymer.IronCheckedElementBehaviorImpl={properties:{checked:{type:Boolean,value:!1,reflectToAttribute:!0,notify:!0,observer:"_checkedChanged"},toggles:{type:Boolean,value:!0,reflectToAttribute:!0},value:{type:String,value:"on",observer:"_valueChanged"}},observers:["_requiredChanged(required)"],created:function(){this._hasIronCheckedElementBehavior=!0},_getValidity:function(e){return this.disabled||!this.required||this.checked},_requiredChanged:function(){this.required?this.setAttribute("aria-required","true"):this.removeAttribute("aria-required")},_checkedChanged:function(){this.active=this.checked,this.fire("iron-change")},_valueChanged:function(){void 0!==this.value&&null!==this.value||(this.value="on")}},Polymer.IronCheckedElementBehavior=[Polymer.IronFormElementBehavior,Polymer.IronValidatableBehavior,Polymer.IronCheckedElementBehaviorImpl]</script> <script>Polymer.PaperCheckedElementBehaviorImpl={_checkedChanged:function(){Polymer.IronCheckedElementBehaviorImpl._checkedChanged.call(this),this.hasRipple()&&(this.checked?this._ripple.setAttribute("checked",""):this._ripple.removeAttribute("checked"))},_buttonStateChanged:function(){Polymer.PaperRippleBehavior._buttonStateChanged.call(this),this.disabled||this.isAttached&&(this.checked=this.active)}},Polymer.PaperCheckedElementBehavior=[Polymer.PaperInkyFocusBehavior,Polymer.IronCheckedElementBehavior,Polymer.PaperCheckedElementBehaviorImpl]</script> <dom-module id="paper-checkbox" assetpath="/res/imp/bower_components/paper-checkbox/"> <template strip-whitespace=""> <style>:host{display:inline-block;white-space:nowrap;cursor:pointer;--calculated-paper-checkbox-size:var(--paper-checkbox-size, 18px);--calculated-paper-checkbox-ink-size:var(--paper-checkbox-ink-size, -1px);@apply(--paper-font-common-base);line-height:0;-webkit-tap-highlight-color:transparent}:host([hidden]){display:none!important}:host(:focus){outline:0}.hidden{display:none}#checkboxContainer{display:inline-block;position:relative;width:var(--calculated-paper-checkbox-size);height:var(--calculated-paper-checkbox-size);min-width:var(--calculated-paper-checkbox-size);margin:var(--paper-checkbox-margin,initial);vertical-align:var(--paper-checkbox-vertical-align,middle);background-color:var(--paper-checkbox-unchecked-background-color,transparent)}#ink{position:absolute;top:calc(0px - (var(--calculated-paper-checkbox-ink-size) - var(--calculated-paper-checkbox-size))/ 2);left:calc(0px - (var(--calculated-paper-checkbox-ink-size) - var(--calculated-paper-checkbox-size))/ 2);width:var(--calculated-paper-checkbox-ink-size);height:var(--calculated-paper-checkbox-ink-size);color:var(--paper-checkbox-unchecked-ink-color,var(--primary-text-color));opacity:.6;pointer-events:none}:host-context([dir=rtl]) #ink{right:calc(0px - (var(--calculated-paper-checkbox-ink-size) - var(--calculated-paper-checkbox-size))/ 2);left:auto}#ink[checked]{color:var(--paper-checkbox-checked-ink-color,var(--primary-color))}#checkbox{position:relative;box-sizing:border-box;height:100%;border:solid 2px;border-color:var(--paper-checkbox-unchecked-color,var(--primary-text-color));border-radius:2px;pointer-events:none;-webkit-transition:background-color 140ms,border-color 140ms;transition:background-color 140ms,border-color 140ms}#checkbox.checked #checkmark{-webkit-animation:checkmark-expand 140ms ease-out forwards;animation:checkmark-expand 140ms ease-out forwards}@-webkit-keyframes checkmark-expand{0%{-webkit-transform:scale(0,0) rotate(45deg)}100%{-webkit-transform:scale(1,1) rotate(45deg)}}@keyframes checkmark-expand{0%{transform:scale(0,0) rotate(45deg)}100%{transform:scale(1,1) rotate(45deg)}}#checkbox.checked{background-color:var(--paper-checkbox-checked-color,var(--primary-color));border-color:var(--paper-checkbox-checked-color,var(--primary-color))}#checkmark{position:absolute;width:36%;height:70%;border-style:solid;border-top:none;border-left:none;border-right-width:calc(2/15 * var(--calculated-paper-checkbox-size));border-bottom-width:calc(2/15 * var(--calculated-paper-checkbox-size));border-color:var(--paper-checkbox-checkmark-color,#fff);-webkit-transform-origin:97% 86%;transform-origin:97% 86%;box-sizing:content-box}:host-context([dir=rtl]) #checkmark{-webkit-transform-origin:50% 14%;transform-origin:50% 14%}#checkboxLabel{position:relative;display:inline-block;vertical-align:middle;padding-left:var(--paper-checkbox-label-spacing,8px);white-space:normal;line-height:normal;color:var(--paper-checkbox-label-color,var(--primary-text-color));@apply(--paper-checkbox-label)}:host([checked]) #checkboxLabel{color:var(--paper-checkbox-label-checked-color,var(--paper-checkbox-label-color,var(--primary-text-color)));@apply(--paper-checkbox-label-checked)}:host-context([dir=rtl]) #checkboxLabel{padding-right:var(--paper-checkbox-label-spacing,8px);padding-left:0}#checkboxLabel[hidden]{display:none}:host([disabled]) #checkbox{opacity:.5;border-color:var(--paper-checkbox-unchecked-color,var(--primary-text-color))}:host([disabled][checked]) #checkbox{background-color:var(--paper-checkbox-unchecked-color,var(--primary-text-color));opacity:.5}:host([disabled]) #checkboxLabel{opacity:.65}#checkbox.invalid:not(.checked){border-color:var(--paper-checkbox-error-color,var(--error-color))}</style> <div id="checkboxContainer"> <div id="checkbox" class$="[[_computeCheckboxClass(checked, invalid)]]"> <div id="checkmark" class$="[[_computeCheckmarkClass(checked)]]"></div> </div> </div> <div id="checkboxLabel"><content></content></div> </template> <script>Polymer({is:"paper-checkbox",behaviors:[Polymer.PaperCheckedElementBehavior],hostAttributes:{role:"checkbox","aria-checked":!1,tabindex:0},properties:{ariaActiveAttribute:{type:String,value:"aria-checked"}},attached:function(){var e=this.getComputedStyleValue("--calculated-paper-checkbox-ink-size");if("-1px"===e){var t=parseFloat(this.getComputedStyleValue("--calculated-paper-checkbox-size")),a=Math.floor(8/3*t);a%2!==t%2&&a++,this.customStyle["--paper-checkbox-ink-size"]=a+"px",this.updateStyles()}},_computeCheckboxClass:function(e,t){var a="";return e&&(a+="checked "),t&&(a+="invalid"),a},_computeCheckmarkClass:function(e){return e?"":"hidden"},_createRipple:function(){return this._rippleContainer=this.$.checkboxContainer,Polymer.PaperInkyFocusBehaviorImpl._createRipple.call(this)}})</script> </dom-module> <script>Polymer({is:"iron-input",extends:"input",behaviors:[Polymer.IronValidatableBehavior],properties:{bindValue:{observer:"_bindValueChanged",type:String},preventInvalidInput:{type:Boolean},allowedPattern:{type:String,observer:"_allowedPatternChanged"},_previousValidInput:{type:String,value:""},_patternAlreadyChecked:{type:Boolean,value:!1}},listeners:{input:"_onInput",keypress:"_onKeypress"},registered:function(){this._canDispatchEventOnDisabled()||(this._origDispatchEvent=this.dispatchEvent,this.dispatchEvent=this._dispatchEventFirefoxIE)},created:function(){Polymer.IronA11yAnnouncer.requestAvailability()},_canDispatchEventOnDisabled:function(){var e=document.createElement("input"),t=!1;e.disabled=!0,e.addEventListener("feature-check-dispatch-event",function(){t=!0});try{e.dispatchEvent(new Event("feature-check-dispatch-event"))}catch(e){}return t},_dispatchEventFirefoxIE:function(){var e=this.disabled;this.disabled=!1,this._origDispatchEvent.apply(this,arguments),this.disabled=e},get _patternRegExp(){var e;if(this.allowedPattern)e=new RegExp(this.allowedPattern);else switch(this.type){case"number":e=/[0-9.,e-]/}return e},ready:function(){this.bindValue=this.value},_bindValueChanged:function(){this.value!==this.bindValue&&(this.value=this.bindValue||0===this.bindValue||this.bindValue===!1?this.bindValue:""),this.fire("bind-value-changed",{value:this.bindValue})},_allowedPatternChanged:function(){this.preventInvalidInput=!!this.allowedPattern},_onInput:function(){if(this.preventInvalidInput&&!this._patternAlreadyChecked){var e=this._checkPatternValidity();e||(this._announceInvalidCharacter("Invalid string of characters not entered."),this.value=this._previousValidInput)}this.bindValue=this.value,this._previousValidInput=this.value,this._patternAlreadyChecked=!1},_isPrintable:function(e){var t=8==e.keyCode||9==e.keyCode||13==e.keyCode||27==e.keyCode,i=19==e.keyCode||20==e.keyCode||45==e.keyCode||46==e.keyCode||144==e.keyCode||145==e.keyCode||e.keyCode>32&&e.keyCode<41||e.keyCode>111&&e.keyCode<124;return!(t||0==e.charCode&&i)},_onKeypress:function(e){if(this.preventInvalidInput||"number"===this.type){var t=this._patternRegExp;if(t&&!(e.metaKey||e.ctrlKey||e.altKey)){this._patternAlreadyChecked=!0;var i=String.fromCharCode(e.charCode);this._isPrintable(e)&&!t.test(i)&&(e.preventDefault(),this._announceInvalidCharacter("Invalid character "+i+" not entered."))}}},_checkPatternValidity:function(){var e=this._patternRegExp;if(!e)return!0;for(var t=0;t<this.value.length;t++)if(!e.test(this.value[t]))return!1;return!0},validate:function(){var e=this.checkValidity();return e&&(this.required&&""===this.value?e=!1:this.hasValidator()&&(e=Polymer.IronValidatableBehavior.validate.call(this,this.value))),this.invalid=!e,this.fire("iron-input-validate"),e},_announceInvalidCharacter:function(e){this.fire("iron-announce",{text:e})}})</script> <script>Polymer.PaperInputHelper={},Polymer.PaperInputHelper.NextLabelID=1,Polymer.PaperInputHelper.NextAddonID=1,Polymer.PaperInputBehaviorImpl={properties:{label:{type:String},value:{notify:!0,type:String},disabled:{type:Boolean,value:!1},invalid:{type:Boolean,value:!1,notify:!0},preventInvalidInput:{type:Boolean},allowedPattern:{type:String},type:{type:String},list:{type:String},pattern:{type:String},required:{type:Boolean,value:!1},errorMessage:{type:String},charCounter:{type:Boolean,value:!1},noLabelFloat:{type:Boolean,value:!1},alwaysFloatLabel:{type:Boolean,value:!1},autoValidate:{type:Boolean,value:!1},validator:{type:String},autocomplete:{type:String,value:"off"},autofocus:{type:Boolean,observer:"_autofocusChanged"},inputmode:{type:String},minlength:{type:Number},maxlength:{type:Number},min:{type:String},max:{type:String},step:{type:String},name:{type:String},placeholder:{type:String,value:""},readonly:{type:Boolean,value:!1},size:{type:Number},autocapitalize:{type:String,value:"none"},autocorrect:{type:String,value:"off"},autosave:{type:String},results:{type:Number},accept:{type:String},multiple:{type:Boolean},_ariaDescribedBy:{type:String,value:""},_ariaLabelledBy:{type:String,value:""}},listeners:{"addon-attached":"_onAddonAttached"},keyBindings:{"shift+tab:keydown":"_onShiftTabDown"},hostAttributes:{tabindex:0},get inputElement(){return this.$.input},get _focusableElement(){return this.inputElement},registered:function(){this._typesThatHaveText=["date","datetime","datetime-local","month","time","week","file"]},attached:function(){this._updateAriaLabelledBy(),this.inputElement&&this._typesThatHaveText.indexOf(this.inputElement.type)!==-1&&(this.alwaysFloatLabel=!0)},_appendStringWithSpace:function(e,t){return e=e?e+" "+t:t},_onAddonAttached:function(e){var t=e.path?e.path[0]:e.target;if(t.id)this._ariaDescribedBy=this._appendStringWithSpace(this._ariaDescribedBy,t.id);else{var a="paper-input-add-on-"+Polymer.PaperInputHelper.NextAddonID++;t.id=a,this._ariaDescribedBy=this._appendStringWithSpace(this._ariaDescribedBy,a)}},validate:function(){return this.inputElement.validate()},_focusBlurHandler:function(e){Polymer.IronControlState._focusBlurHandler.call(this,e),this.focused&&!this._shiftTabPressed&&this._focusableElement.focus()},_onShiftTabDown:function(e){var t=this.getAttribute("tabindex");this._shiftTabPressed=!0,this.setAttribute("tabindex","-1"),this.async(function(){this.setAttribute("tabindex",t),this._shiftTabPressed=!1},1)},_handleAutoValidate:function(){this.autoValidate&&this.validate()},updateValueAndPreserveCaret:function(e){try{var t=this.inputElement.selectionStart;this.value=e,this.inputElement.selectionStart=t,this.inputElement.selectionEnd=t}catch(t){this.value=e}},_computeAlwaysFloatLabel:function(e,t){return t||e},_updateAriaLabelledBy:function(){var e=Polymer.dom(this.root).querySelector("label");if(!e)return void(this._ariaLabelledBy="");var t;e.id?t=e.id:(t="paper-input-label-"+Polymer.PaperInputHelper.NextLabelID++,e.id=t),this._ariaLabelledBy=t},_onChange:function(e){this.shadowRoot&&this.fire(e.type,{sourceEvent:e},{node:this,bubbles:e.bubbles,cancelable:e.cancelable})},_autofocusChanged:function(){if(this.autofocus&&this._focusableElement){var e=document.activeElement,t=e instanceof HTMLElement,a=t&&e!==document.body&&e!==document.documentElement;a||this._focusableElement.focus()}}},Polymer.PaperInputBehavior=[Polymer.IronControlState,Polymer.IronA11yKeysBehavior,Polymer.PaperInputBehaviorImpl]</script> <script>Polymer.PaperInputAddonBehavior={hostAttributes:{"add-on":""},attached:function(){this.fire("addon-attached")},update:function(t){}}</script> <dom-module id="paper-input-char-counter" assetpath="/res/imp/bower_components/paper-input/"> <template> <style>:host{display:inline-block;float:right;@apply(--paper-font-caption);@apply(--paper-input-char-counter)}:host([hidden]){display:none!important}:host-context([dir=rtl]){float:left}</style> <span>[[_charCounterStr]]</span> </template> </dom-module> <script>Polymer({is:"paper-input-char-counter",behaviors:[Polymer.PaperInputAddonBehavior],properties:{_charCounterStr:{type:String,value:"0"}},update:function(t){if(t.inputElement){t.value=t.value||"";var e=t.value.toString().length.toString();t.inputElement.hasAttribute("maxlength")&&(e+="/"+t.inputElement.getAttribute("maxlength")),this._charCounterStr=e}}})</script> <dom-module id="paper-input-container" assetpath="/res/imp/bower_components/paper-input/"> <template> <style>:host{display:block;padding:8px 0;@apply(--paper-input-container)}:host([inline]){display:inline-block}:host([disabled]){pointer-events:none;opacity:.33;@apply(--paper-input-container-disabled)}:host([hidden]){display:none!important}.floated-label-placeholder{@apply(--paper-font-caption)}.underline{position:relative}.focused-line{@apply(--layout-fit);background:var(--paper-input-container-focus-color,--primary-color);height:2px;-webkit-transform-origin:center center;transform-origin:center center;-webkit-transform:scale3d(0,1,1);transform:scale3d(0,1,1);@apply(--paper-input-container-underline-focus)}.underline.is-highlighted .focused-line{-webkit-transform:none;transform:none;-webkit-transition:-webkit-transform .25s;transition:transform .25s;@apply(--paper-transition-easing)}.underline.is-invalid .focused-line{background:var(--paper-input-container-invalid-color,--error-color);-webkit-transform:none;transform:none;-webkit-transition:-webkit-transform .25s;transition:transform .25s;@apply(--paper-transition-easing)}.unfocused-line{@apply(--layout-fit);background:var(--paper-input-container-color,--secondary-text-color);height:1px;@apply(--paper-input-container-underline)}:host([disabled]) .unfocused-line{border-bottom:1px dashed;border-color:var(--paper-input-container-color,--secondary-text-color);background:0 0;@apply(--paper-input-container-underline-disabled)}.label-and-input-container{@apply(--layout-flex-auto);@apply(--layout-relative);width:100%;max-width:100%}.input-content{@apply(--layout-horizontal);@apply(--layout-center);position:relative}.input-content ::content .paper-input-label,.input-content ::content label{position:absolute;top:0;right:0;left:0;width:100%;font:inherit;color:var(--paper-input-container-color,--secondary-text-color);-webkit-transition:-webkit-transform .25s,width .25s;transition:transform .25s,width .25s;-webkit-transform-origin:left top;transform-origin:left top;@apply(--paper-font-common-nowrap);@apply(--paper-font-subhead);@apply(--paper-input-container-label);@apply(--paper-transition-easing)}.input-content.label-is-floating ::content .paper-input-label,.input-content.label-is-floating ::content label{-webkit-transform:translateY(-75%) scale(.75);transform:translateY(-75%) scale(.75);width:133%;@apply(--paper-input-container-label-floating)}:host-context([dir=rtl]) .input-content.label-is-floating ::content .paper-input-label,:host-context([dir=rtl]) .input-content.label-is-floating ::content label{width:100%;-webkit-transform-origin:right top;transform-origin:right top}.input-content.label-is-highlighted ::content .paper-input-label,.input-content.label-is-highlighted ::content label{color:var(--paper-input-container-focus-color,--primary-color);@apply(--paper-input-container-label-focus)}.input-content.is-invalid ::content .paper-input-label,.input-content.is-invalid ::content label{color:var(--paper-input-container-invalid-color,--error-color)}.input-content.label-is-hidden ::content .paper-input-label,.input-content.label-is-hidden ::content label{visibility:hidden}.input-content ::content .paper-input-input,.input-content ::content input,.input-content ::content iron-autogrow-textarea,.input-content ::content textarea{position:relative;outline:0;box-shadow:none;padding:0;width:100%;max-width:100%;background:0 0;border:none;color:var(--paper-input-container-input-color,--primary-text-color);-webkit-appearance:none;text-align:inherit;vertical-align:bottom;@apply(--paper-font-subhead);@apply(--paper-input-container-input)}::content [prefix]{@apply(--paper-font-subhead);@apply(--paper-input-prefix);@apply(--layout-flex-none)}::content [suffix]{@apply(--paper-font-subhead);@apply(--paper-input-suffix);@apply(--layout-flex-none)}.input-content ::content input{min-width:0}.input-content ::content textarea{resize:none}.add-on-content{position:relative}.add-on-content.is-invalid ::content *{color:var(--paper-input-container-invalid-color,--error-color)}.add-on-content.is-highlighted ::content *{color:var(--paper-input-container-focus-color,--primary-color)}</style> <template is="dom-if" if="[[!noLabelFloat]]"> <div class="floated-label-placeholder" aria-hidden="true"> </div> </template> <div class$="[[_computeInputContentClass(noLabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent)]]"> <content select="[prefix]" id="prefix"></content> <div class="label-and-input-container" id="labelAndInputContainer"> <content select=":not([add-on]):not([prefix]):not([suffix])"></content> </div> <content select="[suffix]"></content> </div> <div class$="[[_computeUnderlineClass(focused,invalid)]]"> <div class="unfocused-line"></div> <div class="focused-line"></div> </div> <div class$="[[_computeAddOnContentClass(focused,invalid)]]"> <content id="addOnContent" select="[add-on]"></content> </div> </template> </dom-module> <script>Polymer({is:"paper-input-container",properties:{noLabelFloat:{type:Boolean,value:!1},alwaysFloatLabel:{type:Boolean,value:!1},attrForValue:{type:String,value:"bind-value"},autoValidate:{type:Boolean,value:!1},invalid:{observer:"_invalidChanged",type:Boolean,value:!1},focused:{readOnly:!0,type:Boolean,value:!1,notify:!0},_addons:{type:Array},_inputHasContent:{type:Boolean,value:!1},_inputSelector:{type:String,value:"input,textarea,.paper-input-input"},_boundOnFocus:{type:Function,value:function(){return this._onFocus.bind(this)}},_boundOnBlur:{type:Function,value:function(){return this._onBlur.bind(this)}},_boundOnInput:{type:Function,value:function(){return this._onInput.bind(this)}},_boundValueChanged:{type:Function,value:function(){return this._onValueChanged.bind(this)}}},listeners:{"addon-attached":"_onAddonAttached","iron-input-validate":"_onIronInputValidate"},get _valueChangedEvent(){return this.attrForValue+"-changed"},get _propertyForValue(){return Polymer.CaseMap.dashToCamelCase(this.attrForValue)},get _inputElement(){return Polymer.dom(this).querySelector(this._inputSelector)},get _inputElementValue(){return this._inputElement[this._propertyForValue]||this._inputElement.value},ready:function(){this._addons||(this._addons=[]),this.addEventListener("focus",this._boundOnFocus,!0),this.addEventListener("blur",this._boundOnBlur,!0)},attached:function(){this.attrForValue?this._inputElement.addEventListener(this._valueChangedEvent,this._boundValueChanged):this.addEventListener("input",this._onInput),""!=this._inputElementValue?this._handleValueAndAutoValidate(this._inputElement):this._handleValue(this._inputElement)},_onAddonAttached:function(t){this._addons||(this._addons=[]);var n=t.target;this._addons.indexOf(n)===-1&&(this._addons.push(n),this.isAttached&&this._handleValue(this._inputElement))},_onFocus:function(){this._setFocused(!0)},_onBlur:function(){this._setFocused(!1),this._handleValueAndAutoValidate(this._inputElement)},_onInput:function(t){this._handleValueAndAutoValidate(t.target)},_onValueChanged:function(t){this._handleValueAndAutoValidate(t.target)},_handleValue:function(t){var n=this._inputElementValue;n||0===n||"number"===t.type&&!t.checkValidity()?this._inputHasContent=!0:this._inputHasContent=!1,this.updateAddons({inputElement:t,value:n,invalid:this.invalid})},_handleValueAndAutoValidate:function(t){if(this.autoValidate){var n;n=t.validate?t.validate(this._inputElementValue):t.checkValidity(),this.invalid=!n}this._handleValue(t)},_onIronInputValidate:function(t){this.invalid=this._inputElement.invalid},_invalidChanged:function(){this._addons&&this.updateAddons({invalid:this.invalid})},updateAddons:function(t){for(var n,e=0;n=this._addons[e];e++)n.update(t)},_computeInputContentClass:function(t,n,e,i,a){var u="input-content";if(t)a&&(u+=" label-is-hidden");else{var o=this.querySelector("label");n||a?(u+=" label-is-floating",this.$.labelAndInputContainer.style.position="static",i?u+=" is-invalid":e&&(u+=" label-is-highlighted")):o&&(this.$.labelAndInputContainer.style.position="relative")}return u},_computeUnderlineClass:function(t,n){var e="underline";return n?e+=" is-invalid":t&&(e+=" is-highlighted"),e},_computeAddOnContentClass:function(t,n){var e="add-on-content";return n?e+=" is-invalid":t&&(e+=" is-highlighted"),e}})</script> <dom-module id="paper-input-error" assetpath="/res/imp/bower_components/paper-input/"> <template> <style>:host{display:inline-block;visibility:hidden;color:var(--paper-input-container-invalid-color,--error-color);@apply(--paper-font-caption);@apply(--paper-input-error);position:absolute;left:0;right:0}:host([invalid]){visibility:visible};</style> <content></content> </template> </dom-module> <script>Polymer({is:"paper-input-error",behaviors:[Polymer.PaperInputAddonBehavior],properties:{invalid:{readOnly:!0,reflectToAttribute:!0,type:Boolean}},update:function(e){this._setInvalid(e.invalid)}})</script> <dom-module id="paper-input" assetpath="/res/imp/bower_components/paper-input/"> <template> <style>:host{display:block}:host([focused]){outline:0}:host([hidden]){display:none!important}input::-webkit-input-placeholder{color:var(--paper-input-container-color,--secondary-text-color)}input:-moz-placeholder{color:var(--paper-input-container-color,--secondary-text-color)}input::-moz-placeholder{color:var(--paper-input-container-color,--secondary-text-color)}input:-ms-input-placeholder{color:var(--paper-input-container-color,--secondary-text-color)}label{pointer-events:none}</style> <paper-input-container no-label-float="[[noLabelFloat]]" always-float-label="[[_computeAlwaysFloatLabel(alwaysFloatLabel,placeholder)]]" auto-validate$="[[autoValidate]]" disabled$="[[disabled]]" invalid="[[invalid]]"> <content select="[prefix]"></content> <label hidden$="[[!label]]" aria-hidden="true" for="input">[[label]]</label> <input is="iron-input" id="input" aria-labelledby$="[[_ariaLabelledBy]]" aria-describedby$="[[_ariaDescribedBy]]" disabled$="[[disabled]]" title$="[[title]]" bind-value="{{value}}" invalid="{{invalid}}" prevent-invalid-input="[[preventInvalidInput]]" allowed-pattern="[[allowedPattern]]" validator="[[validator]]" type$="[[type]]" pattern$="[[pattern]]" required$="[[required]]" autocomplete$="[[autocomplete]]" autofocus$="[[autofocus]]" inputmode$="[[inputmode]]" minlength$="[[minlength]]" maxlength$="[[maxlength]]" min$="[[min]]" max$="[[max]]" step$="[[step]]" name$="[[name]]" placeholder$="[[placeholder]]" readonly$="[[readonly]]" list$="[[list]]" size$="[[size]]" autocapitalize$="[[autocapitalize]]" autocorrect$="[[autocorrect]]" on-change="_onChange" tabindex$="[[tabindex]]" autosave$="[[autosave]]" results$="[[results]]" accept$="[[accept]]" multiple$="[[multiple]]"> <content select="[suffix]"></content> <template is="dom-if" if="[[errorMessage]]"> <paper-input-error aria-live="assertive">[[errorMessage]]</paper-input-error> </template> <template is="dom-if" if="[[charCounter]]"> <paper-input-char-counter></paper-input-char-counter> </template> </paper-input-container> </template> </dom-module> <script>Polymer({is:"paper-input",behaviors:[Polymer.IronFormElementBehavior,Polymer.PaperInputBehavior]})</script> <dom-module id="query-column-filter-style" assetpath="/res/imp/common/"> <template> <style>:host{display:block;font-family:sans-serif}#filter{margin:0 5px}.container{min-height:120px;width:100%}.item{border-bottom:1px solid #EEE;max-width:250px;min-height:1em;min-width:100px;padding:.1em .2em;line-height:1.5em}.header{height:2em;padding:.25em;line-height:2em}.selector{border:1px solid #000;margin:0 5px;max-height:200px;min-height:130px;min-width:275px;overflow-y:auto}.pointable,.selectable{cursor:pointer}.selectable:hover{background-color:#A6CEE3}.iron-selected{background-color:#1F78B4;color:#fff}.icons{cursor:pointer;height:20px;margin:2px;width:20px;flex-shrink:0}.side-by-side{display:inline-block;vertical-align:top}.bold{font-weight:700}paper-checkbox{max-height:2em;margin:2px;--paper-checkbox-checked-color:black;--paper-checkbox-checked-ink-color:black;--paper-checkbox-unchecked-color:black;--paper-checkbox-unchecked-ink-color:black;--paper-checkbox-label-color:black}</style> </template> </dom-module> <script>!function(){var r=":",i=function(r,i){if(!i)return{idx:0,part:""};if(!r)return{idx:-1};i=i.trim().toLocaleLowerCase(),r=r.toLocaleLowerCase();for(var t=i.split(" "),e=0;e<t.length;e++){var n=r.indexOf(t[e]);if(n!==-1)return{idx:n,part:t[e]}}return{idx:-1}},t=function(i,t,e){if(!t)return!0;if(!i)return!1;if(i=i.toLocaleLowerCase(),t=t.trim().toLocaleLowerCase(),t.indexOf(" ")!==-1||t.indexOf(":")===-1)return!1;var n=t.split(r,1)[0],a=t.substring(n.length+r.length);return e?i===n:i.startsWith(a)};SwarmingBehaviors.QueryColumnFilter=[SwarmingBehaviors.CommonBehavior,{properties:{dimensions:{type:Array},primary_map:{type:Object},primary_arr:{type:Array},special_columns:{type:Array,value:function(){return[]}},filter:{type:Function,computed:"_makeFilter(_filters.*)",notify:!0},FILTER_SEP:{type:String,value:r},_filters:{type:Array},_limit:{type:Number},_primaryItems:{type:Array,computed:"_primary(_query, primary_map, primary_arr, columns.*)"},_primarySelected:{type:String,value:""},_query:{type:String},_secondaryItems:{type:Array,computed:"_secondary(_primarySelected, _query, primary_map)"}},_addFilter:function(r){var i=r.model.item;if(!this._cantAddFilter(this._primarySelected,i)){var t=this._primarySelected+this.FILTER_SEP+i;this.push("_filters",t)}},_removeFilter:function(r){var i=r.model.fil;if(!this._cantRemoveFilter(i)){var t=this._filters.indexOf(i);t!==-1&&this.splice("_filters",t,1)}},_cantAddFilter:function(r,i){if(!r||!i)return!0;var t=r+this.FILTER_SEP+i;return this._filters.indexOf(t)!==-1},_cantRemoveFilter:function(r){return!r||this._filters.indexOf(r)===-1},_makeFilter:function(){var r={};this._filters.forEach(function(i){var t=i.indexOf(this.FILTER_SEP),e=i.slice(0,t),n=i.slice(t+this.FILTER_SEP.length),a=r[e]||[];a.push(n),r[e]=a}.bind(this));var i=this._filterMap||{};return function(t){var e=!0;for(primary in r){var n=r[primary],a=i[primary];a||(a=function(r,i){var t=this._attribute(r,primary);return t.indexOf(i)!==-1}.bind(this)),a&&n.forEach(function(r){e=e&&a.bind(this)(t,r)}.bind(this))}return e}},_manuallyAddFilter:function(){var r=this._query.trim(),i=r.indexOf(this.FILTER_SEP);if(i===-1)return void sk.errorMessage('Invalid filter. Should be like "foo:bar"',5e3);var t=r.slice(0,i),e=r.slice(i+this.FILTER_SEP.length);return swarming.alias.DIMENSIONS_WITH_ALIASES.indexOf(t)!==-1&&(e=swarming.alias.apply(e,t)),r=t+this.FILTER_SEP+e,this._filters.indexOf(r)!==-1?void sk.errorMessage('Filter "'+r+'" is already active',5e3):(this.push("_filters",r),void this.set("_query",""))},_toggleColumn:function(r){var i=r.model.item;if(!this._cantToggleColumn(i)){if(this._columnState(i)){var t=this.columns.indexOf(i);return void(t!==-1&&this.splice("columns",t,1))}this.push("columns",i)}},_cantToggleColumn:function(r){return!1},_columnState:function(r){return!!r&&this.columns.indexOf(r)!==-1},_primary:function(r,e,n){var a=this.primary_arr.filter(function(n){if(t(n,r,!0))return!0;if(i(n,r).idx!==-1)return!0;for(var a=e[n]||[],s=0;s<a.length;s++)if(i(a[s],r).idx!==-1)return!0;return!1});return r&&a.length>0&&a.indexOf(this._primarySelected)===-1&&this.set("_primarySelected",a[0]),a.sort(function(r,i){var t=this._columnState(r),e=this._columnState(i);if(t&&!e)return-1;if(e&&!t)return 1;if(t&&e){if(t=this.special_columns.indexOf(r),e=this.special_columns.indexOf(i),t!==-1&&e===-1)return-1;if(t===-1&&e!==-1)return 1;if(t!==-1&&e!==-1)return t-e}return naturalSort(r,i)}.bind(this)),a},_secondary:function(r,e,n){if(requestAnimationFrame(function(){this.$.secondaryList.render()}.bind(this)),!r)return[];var a=n[r]||[];return t(r,e,!0)?a.sort(function(r,i){var n=t(r,e,!1),a=t(i,e,!1);return n===a?naturalSort(r,i):a-n}):i(r,e).idx!==-1?a.sort(function(r,t){var n=i(r,e).idx!==-1,a=i(t,e).idx!==-1;return n===a?naturalSort(r,t):a-n}):a.filter(function(r){return i(r,e).idx!==-1})},_beforeBold:function(r,t){var e=i(r,t.replace(":"," "));return e.idx===-1?r:r.substring(0,e.idx)},_bold:function(r,t){var e=i(r,t.replace(":"," "));return e.idx===-1?"":r.substring(e.idx,e.idx+e.part.length)},_afterBold:function(r,t){var e=i(r,t.replace(":"," "));return e.idx===-1?"":r.substring(e.idx+e.part.length)},_commonFilters:function(){return{android_devices:function(r,i){var t=this._attribute(r,"android_devices","0");return t.indexOf(i)!==-1},device_os:function(r,i){var t=this._attribute(r,"device_os","none");return t.indexOf(i)!==-1},device_type:function(r,i){var t=this._attribute(r,"device_type","none");return t.indexOf(swarming.alias.unapply(i))!==-1},gpu:function(r,i){var t=this._attribute(r,"gpu","none");return t.indexOf(swarming.alias.unapply(i))!==-1}}}}]}()</script> <script>!function(){var e="unknown";SwarmingBehaviors.BotListBehavior=[SwarmingBehaviors.CommonBehavior,{properties:{BOT_PROPERTIES:{type:Array,value:function(){return["disk_space","uptime","running_time","task","status","version","external_ip","internal_ip","mp_lease_id","mp_lease_expires","last_seen","first_seen","battery_level","battery_voltage","battery_temperature","battery_status","battery_health","bot_temperature","device_temperature","is_mp_bot"]}}},_attribute:function(t,i,n){return n=n||e,this._dimension(t,i)||this._state(t,i)||[n]},_devices:function(e){return e.state.devices||[]},_deviceType:function(e){return e.device_type.toLowerCase()},_dimension:function(e,t){if(e&&e.dimensions&&t)for(var i=0;i<e.dimensions.length;i++)if(e.dimensions[i].key===t)return e.dimensions[i].value},_state:function(e,t){if(e&&e.state&&e.state[t]){var i=e.state[t];return Array.isArray(i)?i:[i]}},_taskId:function(e){return e&&e.task_id?e.task_id:"idle"}}]}()</script> <dom-module id="bot-filters" assetpath="/res/imp/botlist/"> <template> <style is="custom-style" include="iron-flex iron-flex-alignment iron-positioning query-column-filter-style swarming-app-style"></style> <url-param name="f" value="{{_filters}}" default_values="[]" multi=""> </url-param> <url-param name="c" value="{{columns}}" default_values="["id","os","task","status"]" multi=""> </url-param> <url-param name="q" value="{{_query}}" default_value=""> </url-param> <url-param name="v" value="{{verbose}}"> </url-param> <url-param name="l" default_value="100" value="{{_limit}}"> </url-param> <div class="container horizontal layout"> <div class="narrow-down-selector"> <div> <iron-a11y-keys target="[[_filter_input]]" keys="enter" on-keys-pressed="_manuallyAddFilter"></iron-a11y-keys> <paper-input id="filter" label="Search columns and filters or supply a filter and press enter" placeholder="gpu nvidia pool:Chrome" value="{{_query::input}}"> </paper-input> </div> <div class="selector side-by-side" title="This shows all bot dimension names and other interesting bot properties. Mark the check box to add as a column. Select the row to see filter options."> <iron-selector attr-for-selected="label" selected="{{_primarySelected}}"> <template is="dom-repeat" items="[[_primaryItems]]" as="item"> <div class="selectable item horizontal layout" label="[[item]]"> <span>[[_beforeBold(item,_query)]]<span class="bold">[[_bold(item,_query)]]</span>[[_afterBold(item,_query)]]</span> <span class="flex"></span> <paper-checkbox noink="" disabled$="[[_cantToggleColumn(item)]]" checked="[[_columnState(item,columns.*)]]" on-change="_toggleColumn"> </paper-checkbox> </div> </template> </iron-selector> </div> <div class="selector side-by-side" title="These are all options (if any) that the bot list can be filtered on."> <template is="dom-repeat" id="secondaryList" items="[[_secondaryItems]]" as="item"> <div class="item horizontal layout" label="[[item]]"> <span>[[_beforeBold(item,_query)]]<span class="bold">[[_bold(item,_query)]]</span>[[_afterBold(item,_query)]]</span> <span class="flex"></span> <iron-icon class="icons" icon="icons:arrow-forward" hidden="[[_cantAddFilter(_primarySelected,item,_filters.*)]]" on-tap="_addFilter"> </iron-icon> </div> </template> <template is="dom-if" if="[[_showDimensionMessage(_primarySelected,_secondaryItems.length)]]"> <div class="item"> Only dimensions can be used for filtering. <i>"[[_primarySelected]]"</i> is a part of the bot's state and is informational only. </div> </template> </div> <div class="selector side-by-side" title="These filters are AND'd together and applied to all bots in |
+the fleet."> <template is="dom-repeat" items="[[_filters]]" as="fil"> <div class="item horizontal layout" label="[[fil]]"> <span>[[fil]]</span> <span class="flex"></span> <iron-icon class="icons" icon="icons:remove-circle-outline" hidden="[[_cantRemoveFilter(fil,_filters.*)]]" on-tap="_removeFilter"> </iron-icon> </div> </template> </div> <div class="side-by-side"> <paper-checkbox checked="{{verbose}}">Verbose Entries</paper-checkbox> <paper-input id="_limit" label="Limit Results" auto-validate="" min="0" max="1000" pattern="[0-9]+" value="{{_limit}}"> </paper-input> <a href$="[[_matchingTasksLink(query_params)]]">View Matching Tasks</a> </div> </div> </div> </template> <script>!function(){var i={disk_space:function(i,t){return!0},id:function(i,t){return!0},is_mp_bot:function(i,t){return"true"===t?!!i.lease_id:"false"!==t||!i.lease_id},status:function(i,t){return"quarantined"===t?i.quarantined:"dead"===t?i.is_dead:!i.quarantined&&!i.is_dead},task:function(i,t){return"idle"===t?"idle"===this._taskId(i):"idle"!==this._taskId(i)}};Polymer({is:"bot-filters",behaviors:[SwarmingBehaviors.BotListBehavior,SwarmingBehaviors.QueryColumnFilter],properties:{columns:{type:Array,notify:!0},query_params:{type:Object,computed:"_extractQueryParams(dimensions.*,_filters.*, _limit)",notify:!0},verbose:{type:Boolean,notify:!0},_filter_input:{type:Object,value:function(){return this.$.filter}},_filterMap:{type:Object,value:function(){var t=this._commonFilters();for(var n in i)t[n]=i[n];return t}}},_cantToggleColumn:function(i){return!i||"id"===i},_extractQueryParams:function(){var i={},t=[];this._filters.forEach(function(n){var e=n.split(this.FILTER_SEP,1),s=e[0],a=n.substring(s.length+this.FILTER_SEP.length);this.dimensions.indexOf(s)!==-1?(swarming.alias.DIMENSIONS_WITH_ALIASES.indexOf(s)!==-1&&(a=swarming.alias.unapply(a)),t.push(s+this.FILTER_SEP+a)):"status"===s?"alive"===a?(i.is_dead=["FALSE"],i.quarantined=["FALSE"]):"quarantined"===a?i.quarantined=["TRUE"]:"dead"===a&&(i.is_dead=["TRUE"]):"is_mp_bot"===s&&("true"===a?i.is_mp=["TRUE"]:"false"===a&&(i.is_mp=["FALSE"]))}.bind(this)),i.dimensions=t;var n=parseInt(this._limit);return Number.isInteger(n)&&(n=Math.max(n,1),n=Math.min(1e3,n),i.limit=[n],this._limit!=n&&this.set("_limit",n)),i},_matchingTasksLink:function(i){var t=["name","state","created_ts"];return i.dimensions?(i.dimensions.forEach(function(i){var n=i.split(this.FILTER_SEP,1)[0];t.indexOf(n)===-1&&t.push(n)}.bind(this)),this._taskListLink(i.dimensions,t)):this._taskListLink([],t)},_showDimensionMessage:function(i,t){return i&&"id"!==i&&!t}})}()</script> </dom-module><dom-module id="bot-list-data" assetpath="/res/imp/botlist/"> <script>!function(){function e(e){if(!e)return{};var t=[],s=0;for(k in e)t.push(k+": "+e[k]),s+=e[k];return s/=t.length,s=s?s.toFixed(1):"unknown",{average:s,zones:t.join(" | ")||"unknown"}}var t="available",s=["quarantined","error"],n=["first_seen_ts","last_seen_ts","lease_expiration_ts"];Polymer({is:"bot-list-data",behaviors:[SwarmingBehaviors.BotListBehavior],properties:{auth_headers:{type:Object,observer:"signIn"},bots:{type:Array,computed:"parseBots(_list)",notify:!0},busy:{type:Boolean,computed:"_or(_busy2,_busy1)",notify:!0},dimensions:{type:Array,computed:"_makeArray(_dimensions)",notify:!0},fleet:{type:Object,computed:"_fleet(_count)",notify:!0},primary_map:{type:Object,computed:"_primaryMap(_dimensions)",notify:!0},primary_arr:{type:Array,computed:"_primaryArr(dimensions, BOT_PROPERTIES)",notify:!0},_busy1:{type:Boolean,value:!1},_busy2:{type:Boolean,value:!1},_count:{type:Object},_dimensions:{type:Object},_list:{type:Object}},signIn:function(){this._getJsonAsync("_count","/api/swarming/v1/bots/count","_busy2",this.auth_headers),this._getJsonAsync("_dimensions","/api/swarming/v1/bots/dimensions","_busy1",this.auth_headers)},parseBots:function(s){return s&&s.items?(s.items.forEach(function(s){s.state=s.state||"{}",s.state=JSON.parse(s.state)||{};var i=s.state.disks||{},a=Object.keys(i);if(a.length){s.disks=[];for(var o=0;o<a.length;o++)s.disks.push({id:a[o],mb:i[a[o]].free_mb});s.disks.sort(function(e,t){return t.mb-e.mb})}else s.disks=[{id:"unknown",mb:0}];s.state.temp=e(s.state.temp);var r=[],u=s&&s.state&&s.state.devices||{};for(key in u){var _=u[key];_.serial=key,_.okay=_.state===t;var d=this._dimension(s,"device_type")||["unknown"];_.device_type=d[0],_.temp=e(_.temp),r.push(_)}s.state.devices=r,n.forEach(function(e){swarming.sanitizeAndHumanizeTime(s,e)})}.bind(this)),s.items):[]},_fleet:function(){return this._count?{all:this._count.count||-1,alive:this._count.count-this._count.dead||-1,busy:this._count.busy||-1,idle:this._count.count-this._count.busy||-1,dead:this._count.dead||-1,quarantined:this._count.quarantined||-1}:{}},_makeArray:function(e){if(!e||!e.bots_dimensions)return[];var t=[];return e.bots_dimensions.forEach(function(e){s.indexOf(e.key)===-1&&t.push(e.key)}),t.push("id"),t.sort(),t},_primaryArr:function(e,t){return e.concat(t)},_primaryMap:function(e){e=e.bots_dimensions||[];var t={};return e.forEach(function(e){if(swarming.alias.DIMENSIONS_WITH_ALIASES.indexOf(e.key)===-1)t[e.key]=e.value;else{var s=[];e.value.forEach(function(t){s.push(swarming.alias.apply(t,e.key))}),t[e.key]=s}}),t.android_devices&&t.android_devices.push("0"),t.device_os&&t.device_os.push("none"),t.device_type&&t.device_type.push("none"),t.id=[],t.disk_space=[],t.task=["busy","idle"],t.status=["alive","dead","quarantined"],t.is_mp_bot=["true","false"],t}})}()</script> </dom-module><dom-module id="bot-list-summary" assetpath="/res/imp/botlist/"> <template> <style include="swarming-app-style">:host{display:block;border-left:1px solid #000;padding:5px 5px;font-family:sans-serif}.header{font-size:1.2em;font-weight:700}.header.buffer{margin-top:5px}.right{text-align:right}.left{text-align:left}</style> <div class="header">Fleet</div> <table> <tbody><tr> <td class="right"> <a href$="[[_makeURL('','',columns.*,sort,verbose)]]">All</a>: </td> <td class="left">[[fleet.all]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('alive','',columns.*,sort,verbose)]]">Alive</a>: </td> <td class="left">[[fleet.alive]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('busy','',columns.*,sort,verbose)]]">Busy</a>: </td> <td class="left">[[fleet.busy]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('idle','',columns.*,sort,verbose)]]">Idle</a>: </td> <td class="left">[[fleet.idle]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('dead','',columns.*,sort,verbose)]]">Dead</a>: </td> <td class="left">[[fleet.dead]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('quarantined','',columns.*,sort,verbose)]]">Quarantined</a>: </td> <td class="left">[[fleet.quarantined]]</td> </tr> </tbody></table> <div class="header buffer">Selected</div> <table> <tbody><tr> <td class="right"> Displayed: </td> <td class="left">[[num_bots]]</td> </tr> <tr> <td class="right"> All: </td> <td class="left">[[_count_query.count]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('alive','true',columns.*,sort,verbose)]]">Alive</a>: </td> <td class="left">[[_computeAlive(_count_query.*)]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('busy','true',columns.*,sort,verbose)]]">Busy</a>: </td> <td class="left">[[_count_query.busy]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('idle','true',columns.*,sort,verbose)]]">Idle</a>: </td> <td class="left">[[_computeIdle(_count_query.*)]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('dead','true',columns.*,sort,verbose)]]">Dead</a>: </td> <td class="left">[[_count_query.dead]]</td> </tr> <tr> <td class="right"> <a href$="[[_makeURL('quarantined','true',columns.*,sort,verbose)]]">Quarantined</a>: </td> <td class="left">[[_count_query.quarantined]]</td> </tr> </tbody></table> </template> <script>Polymer({is:"bot-list-summary",behaviors:[SwarmingBehaviors.BotListBehavior],properties:{auth_headers:{type:Object},columns:{type:Array},count_params:{type:Object},fleet:{type:Object},num_bots:{type:Number},sort:{type:String},verbose:{type:Boolean},busy:{type:Boolean,value:!1,notify:!0},_count_query:{type:Object}},observers:["_recountTotal(auth_headers.*,count_params.*)"],_computeAlive:function(){return this._count_query.count-this._count_query.dead},_computeIdle:function(){return this._count_query.count-this._count_query.busy},_getFilterStr:function(t){return t?"alive"===t||"dead"===t||"quarantined"===t?"status:"+t:"task:"+t:""},_makeURL:function(t,e){if(!e){var r={s:[this.sort],c:this.columns,v:[this.verbose]};return t&&(r.f=[this._getFilterStr(t)]),window.location.href.split("?")[0]+"?"+sk.query.fromParamSet(r)}var o=encodeURIComponent(this._getFilterStr(t));if(window.location.href.indexOf(o)===-1)return window.location.href+"&f="+o},_recountTotal:function(){this.auth_headers&&this.count_params&&this._getJsonAsync("_count_query","/api/swarming/v1/bots/count","busy",this.auth_headers,this.count_params)}})</script> </dom-module><dom-module id="bot-list" assetpath="/res/imp/botlist/"> <template> <style include="iron-flex iron-flex-alignment iron-positioning swarming-app-style dynamic-table-style">bot-filters,bot-list-summary{margin-bottom:8px;margin-right:10px}.old_version{background-color:#ffd}.bad-device,.quarantined{background-color:#fdd}.dead{background-color:#ccc}.alt{background-color:#f8f8f8}.bot-list th>span{padding-right:30px}</style> <url-param name="s" value="{{_sortstr}}" default_value="id:asc"> </url-param> <swarming-app client_id="[[client_id]]" auth_headers="{{_auth_headers}}" signed_in="{{_signed_in}}" server_details="{{_server_details}}" busy="[[_or(_busy1,_busy2,_busy3)]]" name="Swarming Bot List"> <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> <div hidden$="[[_not(_signed_in)]]"> <div class="horizontal layout"> <bot-filters dimensions="[[_dimensions]]" primary_map="[[_primary_map]]" primary_arr="[[_primary_arr]]" special_columns="[[_specialColumns]]" columns="{{_columns}}" query_params="{{_query_params}}" filter="{{_filter}}" verbose="{{_verbose}}"> </bot-filters> <bot-list-summary auth_headers="[[_auth_headers]]" columns="[[_columns]]" count_params="[[_query_params]]" fleet="[[_fleet]]" num_bots="[[_filteredSortedItems.length]]" sort="[[_sortstr]]" verbose="[[_verbose]]" busy="{{_busy3}}"> </bot-list-summary> </div> <bot-list-data id="data" auth_headers="[[_auth_headers]]" query_params="[[_query_params]]" busy="{{_busy1}}" dimensions="{{_dimensions}}" fleet="{{_fleet}}" primary_map="{{_primary_map}}" primary_arr="{{_primary_arr}}"> </bot-list-data> <table class="bot-list"> <thead on-sort_change="_sortChange"> <tr> <th> <span>Bot Id</span> <sort-toggle name="id" current="[[_sort]]"> </sort-toggle> </th> <th hidden$="[[_hide('mp_lease_id', _columns.*)]]"> <span>Machine Provider Lease Id</span> <sort-toggle name="mp_lease_id" current="[[_sort]]"> </sort-toggle> </th> <th hidden$="[[_hide('task', _columns.*)]]"> <span>Current Task</span> <sort-toggle name="task" current="[[_sort]]"> </sort-toggle> </th> <template is="dom-repeat" items="[[_plainColumns]]" as="c"> <th hidden$="[[_hide(c)]]"> <span>[[_header(c)]]</span> <sort-toggle name="[[c]]" current="[[_sort]]"> </sort-toggle> </th> </template> </tr> </thead> <tbody> <template id="bot_table" is="dom-repeat" items="[[_filteredSortedItems]]" as="bot" initial-count="50"> <tr class$="[[_botClass(bot,_server_details.bot_version)]]"> <td> <a class="center" href$="[[_botLink(bot.bot_id)]]" target="_blank" rel="noopener"> [[bot.bot_id]] </a> </td> <td hidden$="[[_hide('mp_lease_id', _columns.*)]]"> <a href$="[[_mpLink(bot, _server_details.machine_provider_template)]]"> [[_column('mp_lease_id', bot,_verbose)]] </a> </td> <td hidden$="[[_hide('task', _columns.*)]]"> <a href$="[[_taskLink(bot.task_id)]]">[[_taskId(bot)]]</a> </td> <template is="dom-repeat" items="[[_plainColumns]]" as="c"> <td hidden$="[[_hide(c)]]"> [[_column(c, bot, _verbose)]] </td> </template> </tr> <template is="dom-repeat" items="[[_devices(bot)]]" as="device"> <tr hidden$="[[_hide('android_devices', _columns.*)]]" class$="[[_deviceClass(device,index)]]"> <td></td> <td hidden$="[[_hide('mp_lease_id', _columns.*)]]"></td> <td hidden$="[[_hide('task', _columns.*)]]"></td> <template is="dom-repeat" items="[[_plainColumns]]" as="c"> <td hidden$="[[_hide(c)]]"> [[_deviceColumn(c, device, _verbose)]] </td> </template> </tr> </template> </template> </tbody> </table> <pageable-data id="page_bots" busy="{{_busy2}}" label="Show more bots" output="{{_items}}" parse="[[_parseBots]]"> </pageable-data> </div> </swarming-app> </template> <script> (function(){ |
var UNKNOWN = "unknown"; |
// see dynamic-table for more information on specialColumns, headerMap, |
// columnMap, and specialSort |