/*

    Copyright 2019 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()}}});
