/*
    A simple jQuery modal (http://github.com/kylefox/jquery-modal)
    Version 0.9.1 (This version as been patched to be TT compatible: https://appsheet-third-party.googlesource.com/jquery-modal/)
*/
!function(e){"object"==typeof module&&"object"==typeof module.exports?e(require("jquery"),window,document):e(jQuery,window,document)}(function(e,t,i,l){var n=[],a=function(){return n.length?n[n.length-1]:null},r=function(){var e,t=!1;for(e=n.length-1;e>=0;e--)n[e].$blocker&&(n[e].$blocker.toggleClass("current",!t).toggleClass("behind",t),t=!0)};e.modal=function(o,i){var l,r;if(this.$body=e("body"),this.options=e.extend({},e.modal.defaults,i),this.options.doFade=!isNaN(parseInt(this.options.fadeDuration,10)),this.$blocker=null,this.options.closeExisting)for(;e.modal.isActive();)e.modal.close();if(n.push(this),o.is("a"))if(r=o.attr("href"),this.anchor=o,/^#/.test(r)){if(this.$elm=e(r),1!==this.$elm.length)return null;this.$body.append(this.$elm),this.open()}else this.$elm=e("<div>"),this.$body.append(this.$elm),l=function(e,t){t.elm.remove()},this.showSpinner(),o.trigger(e.modal.AJAX_SEND),e.get(r).done(function(i){if(e.modal.isActive()){o.trigger(e.modal.AJAX_SUCCESS);var n=a();if(t.trustedTypes&&t.trustedTypes.createPolicy){const r=self.trustedTypes.createPolicy("jquery-modal-fix",{createHTML:function(e){return i}});safeHtml=r.createHTML("_ignored")}else safeHtml=i;s.$elm[0].innerHTML=trustedTypes.emptyHTML,s.$elm[0].innerHTML=safeHtml,s.$elm.on(e.modal.CLOSE,l),n.hideSpinner(),n.open(),o.trigger(e.modal.AJAX_COMPLETE)}}).fail(function(){o.trigger(e.modal.AJAX_FAIL);var t=a();t.hideSpinner(),n.pop(),o.trigger(e.modal.AJAX_COMPLETE)});else this.$elm=o,this.anchor=o,this.$body.append(this.$elm),this.open()},e.modal.prototype={constructor:e.modal,open:function(){var t=this;this.block(),this.anchor.blur(),this.options.doFade?setTimeout(function(){t.show()},this.options.fadeDuration*this.options.fadeDelay):this.show(),e(i).off("keydown.modal").on("keydown.modal",function(e){var t=a();27===e.which&&t.options.escapeClose&&t.close()}),this.options.clickClose&&this.$blocker.click(function(t){t.target===this&&e.modal.close()})},close:function(){n.pop(),this.unblock(),this.hide(),e.modal.isActive()||e(i).off("keydown.modal")},block:function(){var t=i.createElement("div");t.setAttribute("class",this.options.blockerClass+" blocker current"),this.$elm.trigger(e.modal.BEFORE_BLOCK,[this._ctx()]),this.$body.css("overflow","hidden"),this.$blocker=e(this.$body[0].appendChild(t)),r(),this.options.doFade&&this.$blocker.css("opacity",0).animate({opacity:1},this.options.fadeDuration),this.$elm.trigger(e.modal.BLOCK,[this._ctx()])},unblock:function(t){!t&&this.options.doFade?this.$blocker.fadeOut(this.options.fadeDuration,this.unblock.bind(this,!0)):(this.$blocker.children().appendTo(this.$body),this.$blocker.remove(),this.$blocker=null,r(),e.modal.isActive()||this.$body.css("overflow",""))},show:function(){if(this.$elm.trigger(e.modal.BEFORE_OPEN,[this._ctx()]),this.options.showClose){var t;this.$elm.trigger(o.modal.BEFORE_OPEN,[this._ctx()]),t=i.createElement("a"),t.setAttribute("href","#close-modal"),t.setAttribute("rel","modal:close"),t.setAttribute("class","close-modal "+this.options.closeClass),txt=i.createTextNode(this.options.closeText),t.appendChild(txt),this.$elm.append(this.closeButton)}this.$elm.addClass(this.options.modalClass).appendTo(this.$blocker),this.options.doFade?this.$elm.css({opacity:0,display:"inline-block"}).animate({opacity:1},this.options.fadeDuration):this.$elm.css("display","inline-block"),this.$elm.trigger(e.modal.OPEN,[this._ctx()])},hide:function(){this.$elm.trigger(e.modal.BEFORE_CLOSE,[this._ctx()]),this.closeButton&&this.closeButton.remove();var t=this;this.options.doFade?this.$elm.fadeOut(this.options.fadeDuration,function(){t.$elm.trigger(e.modal.AFTER_CLOSE,[t._ctx()])}):this.$elm.hide(0,function(){t.$elm.trigger(e.modal.AFTER_CLOSE,[t._ctx()])}),this.$elm.trigger(e.modal.CLOSE,[this._ctx()])},showSpinner:function(){if(this.options.showSpinner){var t=i.createElement("div");t.setAttribute("class",this.options.modalClass+"-spinner");var o=i.createElement("div");o.setAttribute("class","rect1"),t.appendChild(o);var s=i.createElement("div");s.setAttribute("class","rect2"),t.appendChild(s);var l=i.createElement("div");l.setAttribute("class","rect3"),t.appendChild(l);var n=i.createElement("div");n.setAttribute("class","rect4"),t.appendChild(n),this.spinner=this.spinner||e(t),this.$body.append(this.spinner),this.spinner.show()}},hideSpinner:function(){this.spinner&&this.spinner.remove()},_ctx:function(){return{elm:this.$elm,$elm:this.$elm,$blocker:this.$blocker,options:this.options}}},e.modal.close=function(t){if(e.modal.isActive()){t&&t.preventDefault();var o=a();return o.close(),o.$elm}},e.modal.isActive=function(){return n.length>0},e.modal.getCurrent=a,e.modal.defaults={closeExisting:!0,escapeClose:!0,clickClose:!0,closeText:"Close",closeClass:"",modalClass:"modal",blockerClass:"jquery-modal",spinnerHtml:'<div class="rect1"></div><div class="rect2"></div><div class="rect3"></div><div class="rect4"></div>',showSpinner:!0,showClose:!0,fadeDuration:null,fadeDelay:1},e.modal.BEFORE_BLOCK="modal:before-block",e.modal.BLOCK="modal:block",e.modal.BEFORE_OPEN="modal:before-open",e.modal.OPEN="modal:open",e.modal.BEFORE_CLOSE="modal:before-close",e.modal.CLOSE="modal:close",e.modal.AFTER_CLOSE="modal:after-close",e.modal.AJAX_SEND="modal:ajax:send",e.modal.AJAX_SUCCESS="modal:ajax:success",e.modal.AJAX_FAIL="modal:ajax:fail",e.modal.AJAX_COMPLETE="modal:ajax:complete",e.fn.modal=function(t){return 1===this.length&&new e.modal(this,t),this},e(i).on("click.modal",'a[rel~="modal:close"]',e.modal.close),e(i).on("click.modal",'a[rel~="modal:open"]',function(t){t.preventDefault(),e(this).modal()})});
