/*

 Copyright 2019-2020 The Go Authors. All rights reserved.
 Use of this source code is governed by a BSD-style
 license that can be found in the LICENSE file.
*/
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(b){var c=0;return function(){return c<b.length?{done:!1,value:b[c++]}:{done:!0}}};$jscomp.arrayIterator=function(b){return{next:$jscomp.arrayIteratorImpl(b)}};$jscomp.makeIterator=function(b){var c="undefined"!=typeof Symbol&&Symbol.iterator&&b[Symbol.iterator];return c?c.call(b):$jscomp.arrayIterator(b)};
(function(b,c){"object"===typeof exports&&"undefined"!==typeof module?module.exports=c():"function"===typeof define&&define.amd?define(c):(b=b||self,b.dialogPolyfill=c())})(this,function(){function b(a){for(;a&&a!==document.body;){var h=window.getComputedStyle(a),b=function(a,b){return!(void 0===h[a]||h[a]===b)};if(1>h.opacity||b("zIndex","auto")||b("transform","none")||b("mixBlendMode","normal")||b("filter","none")||b("perspective","none")||"isolate"===h.isolation||"fixed"===h.position||"touch"===
h.webkitOverflowScrolling)return!0;a=a.parentElement}return!1}function c(a){for(;a;){if("dialog"===a.localName)return a;a=a.parentElement}return null}function e(a){a&&a.blur&&a!==document.body&&a.blur()}function d(a){return a&&a.hasAttribute("method")?"dialog"===a.getAttribute("method").toLowerCase():!1}function g(a){this.dialog_=a;this.openAsModal_=this.replacedStyleTop_=!1;a.hasAttribute("role")||a.setAttribute("role","dialog");a.show=this.show.bind(this);a.showModal=this.showModal.bind(this);a.close=
this.close.bind(this);"returnValue"in a||(a.returnValue="");if("MutationObserver"in window)(new MutationObserver(this.maybeHideModal.bind(this))).observe(a,{attributes:!0,attributeFilter:["open"]});else{var b=!1,c=function(){b?this.downgradeModal():this.maybeHideModal();b=!1}.bind(this),d,f=function(h){h.target===a&&(b|="DOMNodeRemoved"===h.type.substr(0,14),window.clearTimeout(d),d=window.setTimeout(c,0))};["DOMAttrModified","DOMNodeRemoved","DOMNodeRemovedFromDocument"].forEach(function(b){a.addEventListener(b,
f)})}Object.defineProperty(a,"open",{set:this.setOpen.bind(this),get:a.hasAttribute.bind(a,"open")});this.backdrop_=document.createElement("div");this.backdrop_.className="backdrop";this.backdrop_.addEventListener("click",this.backdropClick_.bind(this))}var l=window.CustomEvent;l&&"object"!==typeof l||(l=function(a,b){b=b||{};var h=document.createEvent("CustomEvent");h.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail||null);return h},l.prototype=window.Event.prototype);g.prototype={get dialog(){return this.dialog_},
maybeHideModal:function(){this.dialog_.hasAttribute("open")&&document.body.contains(this.dialog_)||this.downgradeModal()},downgradeModal:function(){this.openAsModal_&&(this.openAsModal_=!1,this.dialog_.style.zIndex="",this.replacedStyleTop_&&(this.dialog_.style.top="",this.replacedStyleTop_=!1),this.backdrop_.parentNode&&this.backdrop_.parentNode.removeChild(this.backdrop_),f.dm.removeDialog(this))},setOpen:function(a){a?this.dialog_.hasAttribute("open")||this.dialog_.setAttribute("open",""):(this.dialog_.removeAttribute("open"),
this.maybeHideModal())},backdropClick_:function(a){if(this.dialog_.hasAttribute("tabindex"))this.dialog_.focus();else{var b=document.createElement("div");this.dialog_.insertBefore(b,this.dialog_.firstChild);b.tabIndex=-1;b.focus();this.dialog_.removeChild(b)}b=document.createEvent("MouseEvents");b.initMouseEvent(a.type,a.bubbles,a.cancelable,window,a.detail,a.screenX,a.screenY,a.clientX,a.clientY,a.ctrlKey,a.altKey,a.shiftKey,a.metaKey,a.button,a.relatedTarget);this.dialog_.dispatchEvent(b);a.stopPropagation()},
focus_:function(){var a=this.dialog_.querySelector("[autofocus]:not([disabled])");!a&&0<=this.dialog_.tabIndex&&(a=this.dialog_);a||(a=["button","input","keygen","select","textarea"].map(function(a){return a+":not([disabled])"}),a.push('[tabindex]:not([disabled]):not([tabindex=""])'),a=this.dialog_.querySelector(a.join(", ")));e(document.activeElement);a&&a.focus()},updateZIndex:function(a,b){if(a<b)throw Error("dialogZ should never be < backdropZ");this.dialog_.style.zIndex=a;this.backdrop_.style.zIndex=
b},show:function(){this.dialog_.open||(this.setOpen(!0),this.focus_())},showModal:function(){if(this.dialog_.hasAttribute("open"))throw Error("Failed to execute 'showModal' on dialog: The element is already open, and therefore cannot be opened modally.");if(!document.body.contains(this.dialog_))throw Error("Failed to execute 'showModal' on dialog: The element is not in a Document.");if(!f.dm.pushDialog(this))throw Error("Failed to execute 'showModal' on dialog: There are too many open modal dialogs.");
b(this.dialog_.parentElement)&&console.warn("A dialog is being shown inside a stacking context. This may cause it to be unusable. For more information, see this link: https://github.com/GoogleChrome/dialog-polyfill/#stacking-context");this.setOpen(!0);this.openAsModal_=!0;f.needsCentering(this.dialog_)?(f.reposition(this.dialog_),this.replacedStyleTop_=!0):this.replacedStyleTop_=!1;this.dialog_.parentNode.insertBefore(this.backdrop_,this.dialog_.nextSibling);this.focus_()},close:function(a){if(!this.dialog_.hasAttribute("open"))throw Error("Failed to execute 'close' on dialog: The element does not have an 'open' attribute, and therefore cannot be closed.");
this.setOpen(!1);void 0!==a&&(this.dialog_.returnValue=a);a=new l("close",{bubbles:!1,cancelable:!1});if(this.dialog_.onclose instanceof Function)this.dialog_.onclose(a);this.dialog_.dispatchEvent(a)}};var f={reposition:function(a){var b=document.body.scrollTop||document.documentElement.scrollTop;a.style.top=Math.max(b,b+(window.innerHeight-a.offsetHeight)/2)+"px"},isInlinePositionSetByStylesheet:function(a){for(var b=0;b<document.styleSheets.length;++b){var c=document.styleSheets[b],d=null;try{d=
c.cssRules}catch(m){}if(d)for(c=0;c<d.length;++c){var f=d[c],e=null;try{e=document.querySelectorAll(f.selectorText)}catch(m){}var g;if(!(g=!e)){a:{for(g=0;g<e.length;++g)if(e[g]===a){e=!0;break a}e=!1}g=!e}if(!g&&(e=f.style.getPropertyValue("top"),f=f.style.getPropertyValue("bottom"),e&&"auto"!==e||f&&"auto"!==f))return!0}}return!1},needsCentering:function(a){return"absolute"!==window.getComputedStyle(a).position||"auto"!==a.style.top&&""!==a.style.top||"auto"!==a.style.bottom&&""!==a.style.bottom?
!1:!f.isInlinePositionSetByStylesheet(a)},forceRegisterDialog:function(a){(window.HTMLDialogElement||a.showModal)&&console.warn("This browser already supports <dialog>, the polyfill may not work correctly",a);if("dialog"!==a.localName)throw Error("Failed to register dialog: The element is not a dialog.");new g(a)},registerDialog:function(a){a.showModal||f.forceRegisterDialog(a)},DialogManager:function(){this.pendingDialogStack=[];var a=this.checkDOM_.bind(this);this.overlay=document.createElement("div");
this.overlay.className="_dialog_overlay";this.overlay.addEventListener("click",function(b){this.forwardTab_=void 0;b.stopPropagation();a([])}.bind(this));this.handleKey_=this.handleKey_.bind(this);this.handleFocus_=this.handleFocus_.bind(this);this.zIndexLow_=1E5;this.zIndexHigh_=100150;this.forwardTab_=void 0;"MutationObserver"in window&&(this.mo_=new MutationObserver(function(b){var c=[];b.forEach(function(a){for(var b=0,h;h=a.removedNodes[b];++b)h instanceof Element&&("dialog"===h.localName&&c.push(h),
c=c.concat(h.querySelectorAll("dialog")))});c.length&&a(c)}))}};f.DialogManager.prototype.blockDocument=function(){document.documentElement.addEventListener("focus",this.handleFocus_,!0);document.addEventListener("keydown",this.handleKey_);this.mo_&&this.mo_.observe(document,{childList:!0,subtree:!0})};f.DialogManager.prototype.unblockDocument=function(){document.documentElement.removeEventListener("focus",this.handleFocus_,!0);document.removeEventListener("keydown",this.handleKey_);this.mo_&&this.mo_.disconnect()};
f.DialogManager.prototype.updateStacking=function(){for(var a=this.zIndexHigh_,b=0,c;c=this.pendingDialogStack[b];++b)c.updateZIndex(--a,--a),0===b&&(this.overlay.style.zIndex=--a);(a=this.pendingDialogStack[0])?(a.dialog.parentNode||document.body).appendChild(this.overlay):this.overlay.parentNode&&this.overlay.parentNode.removeChild(this.overlay)};f.DialogManager.prototype.containedByTopDialog_=function(a){for(;a=c(a);){for(var b=0,d;d=this.pendingDialogStack[b];++b)if(d.dialog===a)return 0===b;
a=a.parentElement}return!1};f.DialogManager.prototype.handleFocus_=function(a){if(!this.containedByTopDialog_(a.target)&&document.activeElement!==document.documentElement&&(a.preventDefault(),a.stopPropagation(),e(a.target),void 0!==this.forwardTab_)){var b=this.pendingDialogStack[0];b.dialog.compareDocumentPosition(a.target)&Node.DOCUMENT_POSITION_PRECEDING&&(this.forwardTab_?b.focus_():a.target!==document.documentElement&&document.documentElement.focus());return!1}};f.DialogManager.prototype.handleKey_=
function(a){this.forwardTab_=void 0;if(27===a.keyCode){a.preventDefault();a.stopPropagation();a=new l("cancel",{bubbles:!1,cancelable:!0});var b=this.pendingDialogStack[0];b&&b.dialog.dispatchEvent(a)&&b.dialog.close()}else 9===a.keyCode&&(this.forwardTab_=!a.shiftKey)};f.DialogManager.prototype.checkDOM_=function(a){this.pendingDialogStack.slice().forEach(function(b){-1!==a.indexOf(b.dialog)?b.downgradeModal():b.maybeHideModal()})};f.DialogManager.prototype.pushDialog=function(a){if(this.pendingDialogStack.length>=
(this.zIndexHigh_-this.zIndexLow_)/2-1)return!1;1===this.pendingDialogStack.unshift(a)&&this.blockDocument();this.updateStacking();return!0};f.DialogManager.prototype.removeDialog=function(a){a=this.pendingDialogStack.indexOf(a);-1!==a&&(this.pendingDialogStack.splice(a,1),0===this.pendingDialogStack.length&&this.unblockDocument(),this.updateStacking())};f.dm=new f.DialogManager;f.formSubmitter=null;f.useValue=null;if(void 0===window.HTMLDialogElement){var k=document.createElement("form");k.setAttribute("method",
"dialog");if("dialog"!==k.method&&(k=Object.getOwnPropertyDescriptor(HTMLFormElement.prototype,"method"))){var n=k.get;k.get=function(){return d(this)?"dialog":n.call(this)};var p=k.set;k.set=function(a){return"string"===typeof a&&"dialog"===a.toLowerCase()?this.setAttribute("method",a):p.call(this,a)};Object.defineProperty(HTMLFormElement.prototype,"method",k)}document.addEventListener("click",function(a){f.formSubmitter=null;f.useValue=null;if(!a.defaultPrevented){var b=a.target;if(b&&d(b.form)){if(!("submit"===
b.type&&-1<["button","input"].indexOf(b.localName))){if("input"!==b.localName||"image"!==b.type)return;f.useValue=a.offsetX+","+a.offsetY}c(b)&&(f.formSubmitter=b)}}},!1);var q=HTMLFormElement.prototype.submit;HTMLFormElement.prototype.submit=function(){if(!d(this))return q.call(this);var a=c(this);a&&a.close()};document.addEventListener("submit",function(a){if(!a.defaultPrevented){var b=a.target;if(d(b)&&(a.preventDefault(),a=c(b))){var e=f.formSubmitter;e&&e.form===b?a.close(f.useValue||e.value):
a.close();f.formSubmitter=null}}},!1)}return f});var jumpDialog=document.querySelector(".JumpDialog"),jumpBody=jumpDialog.querySelector(".JumpDialog-body"),jumpList=jumpDialog.querySelector(".JumpDialog-list"),jumpFilter=jumpDialog.querySelector(".JumpDialog-input");jumpDialog.showModal||dialogPolyfill.registerDialog(jumpDialog);var jumpListItems;
function collectJumpListItems(){for(var b=[],c=document.querySelector(".Documentation"),e=$jscomp.makeIterator(c.querySelectorAll("[data-kind]")),d=e.next();!d.done;d=e.next())b.push(newJumpListItem(d.value));0==b.length&&(b=collectJumpListItemsFallback(c));c=$jscomp.makeIterator(b);for(e=c.next();!e.done;e=c.next())e.value.link.addEventListener("click",function(){jumpDialog.close()});b.sort(function(b,c){return b.lower.localeCompare(c.lower)});return b}
function collectJumpListItemsFallback(b){var c=[],e={};b=$jscomp.makeIterator(b.querySelectorAll("*[id]"));for(var d=b.next();!d.done;d=b.next()){d=d.value;var g=d.getAttribute("id");!e[g]&&/^[^_][^-]*$/.test(g)&&(e[g]=!0,c.push(newJumpListItem(d)))}return c}
function newJumpListItem(b){var c=document.createElement("a"),e=b.getAttribute("id");c.setAttribute("href","#"+e);c.setAttribute("tabindex","-1");var d=b.getAttribute("data-kind");d||(d=guessKind(b));return{link:c,name:e,kind:d,lower:e.toLowerCase()}}
function guessKind(b){switch(b.getAttribute("class")){case "Documentation-functionHeader":case "Documentation-typeFuncHeader":return"function";case "Documentation-typeHeader":return"type";case "Documentation-typeMethodHeader":return"method";default:switch(b.closest("section").getAttribute("class")){case "Documentation-variables":return"variable";case "Documentation-constants":return"constant";case "Documentation-types":return"field";default:return""}}}var lastFilterValue,activeJumpItem=-1;
function updateJumpList(b){lastFilterValue=b;jumpListItems||(jumpListItems=collectJumpListItems());for(setActiveJumpItem(-1);jumpList.firstChild;)jumpList.firstChild.remove();for(var c=new RegExp(b.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1"),"gi"),e=$jscomp.makeIterator(jumpListItems),d=e.next();!d.done;d=e.next()){d=d.value;var g=d.name;if(b&&(g=g.replace(c,function(b){return"<b>"+b+"</b>"}),g==d.name))continue;d.link.innerHTML=g+" <i>"+d.kind+"</i>";jumpList.appendChild(d.link)}jumpBody.scrollTop=
0;0<jumpList.children.length&&setActiveJumpItem(0)}function setActiveJumpItem(b){var c=jumpList.children;0<=activeJumpItem&&c[activeJumpItem].classList.remove("JumpDialog-active");b>=c.length&&(b=c.length-1);if(0<=b){c[b].classList.add("JumpDialog-active");var e=c[b].offsetTop-c[0].offsetTop;c=e+c[b].clientHeight;e<jumpBody.scrollTop?jumpBody.scrollTop=e:c>jumpBody.scrollTop+jumpBody.clientHeight&&(jumpBody.scrollTop=c-jumpBody.clientHeight)}activeJumpItem=b}
function incActiveJumpItem(b){0>activeJumpItem||(b=activeJumpItem+b,0>b&&(b=0),setActiveJumpItem(b))}jumpFilter.addEventListener("keyup",function(b){jumpFilter.value.toUpperCase()!=lastFilterValue.toUpperCase()&&updateJumpList(jumpFilter.value)});jumpFilter.addEventListener("keydown",function(b){switch(b.which){case 38:incActiveJumpItem(-1);b.preventDefault();break;case 40:incActiveJumpItem(1);b.preventDefault();break;case 13:0<=activeJumpItem&&jumpList.children[activeJumpItem].click()}});
var shortcutsDialog=document.querySelector(".ShortcutsDialog");shortcutsDialog.showModal||dialogPolyfill.registerDialog(shortcutsDialog);
document.addEventListener("keypress",function(b){if(!jumpDialog.open&&!shortcutsDialog.open){var c=b.target.tagName;if("INPUT"!=c&&"SELECT"!=c&&"TEXTAREA"!=c&&!(b.target.contentEditable&&"true"==b.target.contentEditable||b.metaKey||b.ctrlKey))switch(String.fromCharCode(b.which)){case "f":case "F":b.preventDefault();jumpFilter.value="";jumpDialog.showModal();updateJumpList("");break;case "?":shortcutsDialog.showModal()}}});
