bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/bosun/web/static/js/angular-strap.min.js.map (about)
1 {"version":3,"sources":["angular-strap.js","typeahead/typeahead.js","helpers/compiler.js","datepicker/datepicker.js","tab/tab.js","tooltip/tooltip.js","timepicker/timepicker.js","scrollspy/scrollspy.js","select/select.js","popover/popover.js","navbar/navbar.js","modal/modal.js","dropdown/dropdown.js","helpers/raf.js","helpers/parse-options.js","helpers/dimensions.js","helpers/debounce.js","helpers/date-parser.js","helpers/date-formatter.js","button/button.js","collapse/collapse.js","aside/aside.js","alert/alert.js","affix/affix.js","module.js"],"names":["prefixEvent","undefined","templateUrl","options","cache","$templateCache","then","element","res","fetchTemplate","template","fetchPromises","module","$http","get","defaults","animation","prefixClass","data","this","compile","controller","console","controllerAs","resolve","copy","locals","bindToController","angular","forEach","value","isString","$injector","key","invoke","transformTemplate","identity","extend","$template","when","$q","all","templateEl","Error","findElement","contentTemplate","templates","contentEl","removeAttr","html","replace","next","remove","outerHTML","link","scope","trim","contents","linkFn","invokeCtrl","children","instance","ctrl","isObject","arguments","apply","bsCompilerService","$inject","trigger","provider","container","keyboard","delay","minLength","filter","limit","autoSelect","comparator","trimValue","$get","$typeahead","parentScope","$resetMatches","$window","$rootScope","$tooltip","$$rAF","$timeout","$matches","config","$$postDigest","$scope","activate","$activeIndex","select","index","$select","evt","matches","$isVisible","safeDigest","update","$render","$emit","isDefined","onSelect","$setViewValue","length","isFunction","equals","$onMouseDown","preventDefault","stopPropagation","keyCode","$digest","show","$element","hide","$onKeyDown","$$phase","$root","TypeaheadFactory","array","$filter","expression","directive","results","postLink","attr","restrict","require","falseValueRegExp","bsKey","charAt","toUpperCase","slice","test","bsOptions","parsedOptions","$parseOptions","typeahead","watchedOptions","$watchCollection","values","watchOptions","$match","$watch","ngModel","newValue","oldValue","$modelValue","valuesFn","selectMode","$viewValue","substring","displayValue","$formatters","push","modelValue","selected","ss","selectionStart","val","selectionEnd","setSelectionRange","sd","label","destroy","$on","self","$options","navClass","activeClass","$activeClass","$panes","$activePaneChangeListeners","$push","pane","isUndefined","$active","$attrs","$navClass","$remove","active","activeIndex","indexOf","splice","map","$setActive","name","fn","$pane","$tab","transclude","ngModelCtrl","bsTabsCtrl","attrs","bsActivePane","parsedBsActivePane","assign","$parse","$observe","controllers","render","$animate","$isActive","addClass","disabled","customClass","target","placement","titleTemplate","title","type","autoClose","bsEnabled","mouseDownPreventDefault","mouseDownStopPropagation","viewport","selector","padding","TooltipFactory","promise","$bsCompiler","split","clearTimeout","hoverState","onShow","leaveAnimateCallback","destroyTipElement","onHide","_tipToHide","triggers","nodeName","on","isTouch","toggle","enter","unbindTriggerEvents","$onFocusElementMouseDown","off","i","bindKeyboardEvents","tipElement","$onKeyUp","unbindKeyboardEvents","_autoCloseEventsBinded","bindAutoCloseEvents","$body","unbindAutoCloseEvents","stopEventPropagation","event","getPosition","elRect","getBoundingClientRect","rect","p","width","height","top","left","dimensions","offset","el","scroll","outerDims","isBody","document","documentElement","scrollTop","body","prop","clientWidth","innerHeight","position","actualWidth","actualHeight","marginLeft","isNaN","setOffset","using","parseInt","props","css","right","marginTop","tip","offsetHeight","getViewportAdjustedDelta","delta","offsetWidth","isVertical","arrowDelta","replaceArrow","arrowOffsetPosition","viewportDimensions","$viewport","topEdgeOffset","bottomEdgeOffset","viewportPadding","leftEdgeOffset","rightEdgeOffset","dimension","isHorizontal","$arrow","timeout","$isShown","tipScope","$destroy","$promise","$new","toLowerCase","$id","parseFloat","$sce","trustAsHtml","$setEnabled","id","$hide","setEnabled","isEnabled","compileData","tipContainer","init","bindTriggerEvents","isElement","focus","onBeforeShow","after","parent","lastChild","display","visibility","clonedElement","version","prepend","$applyPlacement","enterAnimateCallback","_blur","leave","onBeforeHide","autoPlace","autoToken","elementPosition","tipWidth","tipHeight","viewportPosition","originalPlacement","removeClass","tipPosition","getCalculatedOffset","applyPlacement","blur","query","querySelectorAll","isNative","tooltip","transclusion","$eval","dataTarget","hasOwnProperty","bsTooltip","bsShow","match","setViewport","useNative","timeType","timeFormat","timezone","modelTimeFormat","autoclose","minTime","maxTime","Infinity","hourStep","minuteStep","secondStep","roundDisplay","iconUp","iconDown","arrowBehavior","$timepicker","timepickerFactory","formatDate","format","viewDate","hour","startDate","getHours","meridian","coeff","selRange","end","start","collapse","moveStart","moveEnd","focusElement","_init","floorMinutes","time","floor","lang","selectedIndex","date","defaultDate","second","getSeconds","millisecond","getMilliseconds","$dateValue","hoursFormat","$dateFormatter","timeSeparator","minute","minutesFormat","secondsFormat","showSeconds","$iconUp","$moveIndex","$switchMeridian","switchMeridian","isDate","getMinutes","getTime","$build","$isBuilt","keep","Date","setHours","setMinutes","setSeconds","midIndex","hours","minutes","$date","seconds","rows","$isDisabled","showAM","$isSelected","isAM","selectedTime","$arrowAction","$setTimeByStep","newDate","targetDate","targetEl","triggerHandler","hoursLength","minutesLength","sepLength","lateralMove","count","selectRange","incr","isSeconds","isMeridian","secondsLength","createSelection","createTextRange","_destroy","_show","_hide","navigator","userAgent","isMaxValid","isValid","parsedTime","isMinValid","setFullYear","$setValidity","$parsers","unshift","viewValue","getTimeFormattedString","timepicker","dateParser","$dateParser","validateAgainstMinMaxTime","timezoneOffsetAdjust","NaN","parse","spies","$document","windowEl","debounce","bodyEl","throttle","ScrollSpyFactory","scrollEl","isWindowSpy","scrollId","$$count","$scrollspy","unbindViewContentLoaded","unbindIncludeContentLoaded","trackedElements","sortedElements","activeTarget","debouncedCheckOffsets","viewportHeight","debouncedCheckPosition","throttledCheckPosition","checkPositionWithEventLoop","checkOffsets","checkPosition","docEl","$activateElement","offsetTop","setTimeout","activeElement","source","$getTrackedElement","targetElement","querySelector","trackedElement","b","trackElement","toDelete","untrackElement","scrollspy","childEl","child","multiple","allNoneButtons","sort","caretHtml","placeholder","allText","noneText","maxLength","maxLengthHtml","iconCheckmark","SelectFactory","$isMultiple","$showAllNoneButtons","$iconCheckmark","$allText","$activate","$selectNone","$updateActiveIndex","a","$apply","isArray","$getIndex","$selectScrollFix","$isIE","stopImmediatePropagation","ua","tagName","e","dataMultiple","inputEl","addEventListener","join","$isEmpty","content","$popover","PopoverFactory","requestAnimationFrame","bsPopover","popover","routeAttr","$navbar","liElements","li","liElement","pattern","path","RegExp","regexp","backdrop","size","bodyElement","backdropCount","dialogBaseZindex","validSizes","ModalFactory","$modal","unbindBackdropEvents","modalElement","hideOnBackdropClick","backdropElement","preventEventDefault","modalScope","$show","bottom","destroyModalElement","z-index","backdropBaseZindex","defaultPrevented","minor","backdropAnimation","bindBackdropEvents","which","lg","sm","modalClass","bsModal","modal","matchesSelector","DropdownFactory","$dropdown","onBodyClick","items","parentEl","hasClass","prototype","tAttrs","nextSibling","nodeType","parentNode","removeChild","dropdown","dot","cancelAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","rafSupported","raf","timer","cancel","supported","$values","valueName","keyName","displayFn","valueFn","ParseOptionsFactory","groupByFn","factory","offsetParent","docElement","ownerDocument","outer","window","getComputedStyle","extra","currentStyle","boxRect","style","curPosition","curLeft","curCSSTop","curTop","calculatePosition","curElem","curCSSLeft","curOffset","call","offsetParentRect","offsetParentEl","offsetParentElement","func","immediate","args","context","callNow","leading","wait","trailing","year","$localeProvider","milliseconds","ParseDate","noop","indexOfCaseInsensitive","len","str","toString","strict","DateParserFactory","day","month","getFullYear","getMonth","proto","isNumeric","toDate","regExpMap","sss","$locale","dateFilter","mm","literalRegex","formatParts","escapedLiteralFormat","dateElements","keys","escapedFormat","isFormatStringLiteral","part","trimLiteralEscapeChars","dateRegexParts","escapeReservedSymbols","text","re","abstractRegex","buildDateParseRegex","setMapForFormat","buildDateAbstractRegex","buildDateParseValuesMap","Object","valuesMatch","keyIndex","valueKey","valuesFunctionMap","valueFunction","valuesRegex","exec","setFnMap","setMap","m","HH","H","hh","h","EEEE","EEE","DATETIME_FORMATS","SHORTDAY","dd","d","MMMM","MMM","SHORTMONTH","MM","M","DAY","yyyy","yy","y","MONTH","s","setDate","setMonth","regex","$format","regExpForFormat","baseDate","formatRegex","formatSetMap","fromDate","getDate","today","getDateForAttribute","substr","getTimeForAttribute","daylightSavingAdjust","undo","getTimezoneOffset","getDefaultLocale","getDatetimeFormat","weekdaysShort","splitTimeFormat","service","dateType","dateFormat","modelDateFormat","dayFormat","monthFormat","yearFormat","monthTitleFormat","yearTitleFormat","strictFormat","minDate","maxDate","startView","minView","startWeek","daysOfWeekDisabled","hasToday","hasClear","iconLeft","iconRight","DatepickerFactory","$datepicker","pickerViews","views","$iconLeft","$iconRight","$hasToday","$picker","$selectPane","$hasClear","$toggleMode","$views","$mode","setMode","$setToday","$clear","updateDisabledDates","disabledDateRanges","dateRanges","$setDisabledEl","mode","pristine","$updateSelected","built","isDisabled","steps","getUTCFullYear","getUTCMonth","UTC","getUTCDate","shiftKey","altKey","onKeyDown","datepickerViews","previousValue","normalizeDateRanges","ranges","disabledRanges","datepicker","parsedDate","getDateFormattedString","validateAgainstMinMaxDate","disabledDates","arrays","mod","n","arr","weekDaysMin","weekDaysLabelsHtml","picker","weekDaysLabels","concat","firstDayOfMonth","firstDayOfMonthOffset","firstDate","firstDateOffset","build","days","isToday","toDateString","muted","showLabels","labels","isTodayDisabled","isSelected","getDay","months","lastDate","actualMonth","firstYear","years","actualYear","Array","setYear","$button","constantValueRegExp","isInput","trueValue","falseValue","hasExoticValues","isActive","checked","bind","toggleEvent","toggleClass","v","startCollapsed","allowMultiple","activeIndexes","$targets","activeItems","activateItem","$collapse","$viewChangeListeners","$registerToggle","$toggles","$unregisterToggle","$unregisterTarget","deactivateItem","fixActiveItemIndexes","disallowToggle","$activeIndexes","bsCollapseCtrl","bsCollapseToggle","$registerTarget","action","AsideFactory","$aside","bsAside","aside","duration","dismissable","AlertFactory","$alert","bsAlert","alert","AffixFactory","$affix","inlineStyles","reset","initialOffsetTop","getRequiredAffixClass","_unpin","getScrollTop","scrollHeight","getScrollHeight","offsetBottom","elementHeight","initialAffixTop","pageYOffset","affixed","unpin","$parseOffsets","affix","setWidth","offsetUnpin","$onResize","$debouncedOnResize","initialPosition","affixTarget","option"],"mappings":"CAOA,SCIAA,EAAAA,EAAAC,GDHE,YA+jGA,SEx/FFC,GAAAC,EAAAD,EAAAA,EAAAA,EAAAA,EAAAA,GFkkGI,QEz9FJE,GAAAC,EAAAA,GF09FM,MEz9FNC,SAAAC,SAAAC,GAAAA,GAAAA,iBAAAA,IF49FI,QAASC,GAAcC,GACrB,MAAIC,GAAcD,GAAkBC,EAAcD,GGlpGxDE,EAAAF,GAAAG,EAAAC,IACAJ,GAMAK,MAAAA,IACAC,KAAAA,SAAAR,GAGAS,MAAAA,GAAAC,OHyjGIC,KEx/FJC,QAAAV,SAAAP,GACAkB,EAAAA,UAAAlB,UAAAkB,KAAAA,EAAAA,YACAC,QAAAC,KAAAA,oGACApB,EAAAqB,YAAAC,EAAAtB,SACAA,EAAAuB,SAAAD,GAEA,IAAAE,GAAAA,EAAAxB,YAKAyB,EAAAC,EAAAL,UAAAM,GACAT,EAAAU,EAAAD,WACAN,EAAAQ,EAAAA,aFq/FUR,EEp/FVI,QAAAH,KAAAtB,EAAAqB,aACAA,EAAAS,QAAAD,KAAAA,EAAAE,YFq/FUC,EAAoBhC,EAAQgC,mBAAqBP,QAAQQ,SACzDT,EAAmBxB,EAAQwB,gBEv+FrC,IAVAC,QAAAS,QAAAb,EAAAE,SAAAA,EAAAA,GAEAhB,QAAAqB,SAAAD,GACAN,EAAAc,GAAAA,EAAAC,IAAA7B,GAEAc,EAAAc,GAAAA,EAAA7B,OAAAP,KFo/FM0B,QAAQS,OAAOb,EAASE,GE/+F9BvB,EACAqB,EAAAc,UAAAE,EAAAC,KAAAA,OAEA,CAAA,IAAAC,EFk/FQ,KAAM,IAAIC,OAAM,6CAFhBnB,GE/+FRoB,UAAAnC,EAAAP,GFkgGM,ME3/FNC,GAAA0C,gBAEArB,EAAAc,UAAAE,EAAAC,KAAAjB,EAAAc,UAAA7B,EAAAN,EAAA0C,iBAAAA,KACAvC,SAAAwC,GACA,GAAAJ,GAAAd,QAAArB,QAAAuC,EAAA,GAKA,OAJAF,GAAAG,oBAAAL,EAAA,IAAAM,WAAAN,WACAM,KAAAA,EAAA,IAGA7C,EAAAD,GAAAA,aF0+FUC,EAAQ0C,kBEp+FlBrB,EAAAiB,UAAAjB,EAAAlB,KAAAkB,EAAAE,UAAAA,EAAAA,EAAAA,mBAAAA,KAAAA,SAAAA,GAEA,GAAAhB,GAAAyB,QAAAA,QAAAT,EAAAY,IACAnC,EAAAyC,EAAA,sBAAAF,EAAA,IAAAM,WAAA,WAAAC,KAAAH,EAAA,GFs+FU,OEr+FVpC,GAAAA,aAAAwC,EAAAC,OAAAC,SFq+FiBV,EAAW,GAAGW,aE99F/Bb,EAAAC,IAAAjB,GAAAlB,KAAA,SAAAoB,GFk+FQ,GEj+FRA,GAAAA,EAAAA,EAAAA,UACAnB,GAAAA,OACA+C,EAAA5C,EAAA6C,QAAAA,cAAAA,kBFm+FQ,IE/9FRhD,GAAAc,QAAAd,QAAA,SAAA0C,KAAAvC,EAAA8C,QAAAC,WFg+FYC,EE/9FZC,EAAAA,EFg+FQ,QACEjC,OE/9FVE,EFg+FUrB,QAASA,EACT+C,KE99FV,SAAA1B,GFg+FY,GADAF,EE79FZnB,OAAAgD,EACAhD,EAAAqD,CAEA,GAAArC,GAAAA,EAAAF,EAAAK,GAAA,EACA6B,IF69FgB3B,QAAQS,OAAOsB,EAAWE,SAAUnC,EEz9FpD,IAAAoC,GAAAJ,QAAAK,SAAAC,GAAAA,EAAAA,GF49FczD,GAAQW,KAAK,0BAA2B4C,GACxCvD,EAAQqD,WAAW1C,KAAK,0BAA2B4C,GAC/CvC,IACFgC,EAAMhC,GAAgBuC,GAG1B,MAAOJ,GAAOO,MAAM,KAAMD,eAQlC,IAAIrD,MA3oGNuD,ECIFC,SAAA,KAAA,QAAA,YAAA,WAAA,cAAA,kBDHEvC,QCIFwC,OAAA,4BAAA,yBAAA,wCAAAC,SAAA,aAAA,WDHI,GCIJC,GAAAnD,KAAAJ,UACAwD,UAAA,UACAtB,YAAA,YACAuB,YAAA,aACAC,UAAA,cACAC,YAAA,+BACAC,QAAA,QACAC,WAAAA,EACAC,UAAAA,EACAC,MAAAA,EDHMN,MAAO,ECMbrD,UAAA4D,EAEAL,OAAA,gBDLMC,MCONK,EDNMJ,YCSNzE,EDRM0E,WCUNG,GDTMF,WCUNG,EDRI9D,MCWJoC,MAAA2B,UAAAA,aAAA,WAAA,QAAA,WAAA,SAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GDVM,QCWNhC,GAAAiC,EAAAA,EAAAA,GDVQ,GCWRjC,MDVYpD,EAAUyB,QAAQS,UAAWtB,EAAU0E,ECYnDlC,GAAA2B,EAAAA,EAAAA,EAEA3B,IAAAA,GAAAkC,EAAAlC,MACAA,EAAAmC,EAAAC,MDXQpC,GCYRyB,cAAAY,WDXUrC,EAAMiC,YACNjC,EAAMsC,aAAe1F,EAAQyE,WAAa,EAAI,IAEhDrB,ECaRA,gBDZQA,ECaRyB,UAAAc,SAAAC,GDZUxC,EAAMmC,aAAa,WACjBV,EAAWY,SAASG,MAGxBxC,EAAMyC,QAAU,SAASD,EAAOE,GCkBxCjB,EAAAA,aAAA,WACAzB,EAAAiC,OAAAU,MDdQ3C,EAAM4C,WAAa,WCqB3BC,MAAAA,GAAA7C,cDlBQyB,EAAWqB,OAAS,SAASH,GCsBrClB,EAAAA,SAAAY,EACArC,EAAAsC,cAAAE,EAAAA,SDpBYxC,EAAMsC,aAAe1F,EAAQyE,WAAa,EAAI,ICwB1DwB,EAAAL,GACAT,EAAAxD,EAAAyB,kBDpBQyB,ECuBR3D,SAAAiF,SAAAA,GACA/C,EAAA2B,aAAAA,GDrBQF,ECwBRuB,OAAApG,SAAAH,GACA,GAAAwG,KAAA5E,EAAA,CDvBU,GCwBVzB,GAAAsG,EAAAA,SAAAV,GAAAf,KDvBU3D,GAAWqF,cAAc5E,GACzBT,EAAWiF,UC4BrBtB,EAAAA,gBACAC,GAAAR,EAAApD,UD1BUkC,EC2BVgD,MAAAhD,EAAAiC,YAAAmB,UAAAA,EAAAA,EAAAA,GD1Bc/E,QAAQ4E,UAAUrG,EAAQsG,WAAa7E,QAAQgF,WAAWzG,EAAQsG,WC6BhFtG,EAAAoD,SAAAiC,EAAAmB,EAAA/E,KDzBQoD,EC6BRe,WAAAA,WACA,MAAAA,GAAAxC,WAAAiC,EAGAO,EAAAA,SAAAA,QAAAA,QAAAA,SAAAA,EAAAA,aAAAA,EAAAA,WAAAA,QAAAA,EAAAA,YAFAnE,EAAAiF,SAAAtD,QAKAyB,EAAA8B,UAAAA,SAAAhF,GAEAmE,GAAAc,EACAd,KAAAe,EAAAA,EAAAA,SAAAA,OAAAA,MD9BgBpF,QAAQiF,OAAOtD,EAAMiC,SAASO,GAAOjE,MAAOA,KCkC5D,MAAAiE,ID9BQf,ECkCR+B,aAAAA,SAAAA,GDjCUd,ECkCVA,iBDjCUA,EAAIe,mBAENhC,ECoCRA,WAAAzB,SAAAsC,GDnCe,aCqCfoB,KAAAA,EAAAA,YACA1D,EAAAsC,cAAAA,KAAAA,EAAAA,SAAAA,KAAAA,EAAAA,eDpCYI,EAAIc,iBCsChBxD,EAAAA,mBAEAsC,KAAAtC,EAAAsC,SAAAtC,EAAAiC,SAAAmB,ODpCY3B,EAAWc,OAAOvC,EAAMsC,cCsCpCqB,KAAAA,EAAAA,SAAAA,EAAAA,aAAAA,EDpCY3D,EAAMsC,eCyClBsB,KAAAnC,EAAAA,SAAAmC,EAAAA,aAAAA,EAAAA,SAAAA,OAAAA,EACAnC,EAAAA,eACAmC,QAAAA,YAAAA,EAAAA,gBAGA5B,EAAAA,aAAA,GDxCUhC,EC0CVyB,WDxCQ,IAAImC,GC0CZnC,EAAAzE,IDzCQyE,GAAWmC,KAAO,WAChBA,IACA5B,EC0CV,WDzCgBP,EAAWoC,WC4C3BC,EAAArC,SAAAqC,GAAAA,YAAAA,EAAAA,cACArC,EAAAT,UACAS,GAAAoC,EAAApC,GAAAA,UAAAoC,EAAAE,cDxCa,GAAG,GAER,IC2CRtC,GAAAA,EAAAY,IDhCQ,OAVAZ,GAAWqC,KAAO,WC4C1BA,EAAAA,UAAAA,EAAAA,SAAAA,IAAAA,YAAAA,EAAAA,cD1CclH,EAAQoE,UC6CtBS,GAAAA,EAAAA,IAAAA,UAAAA,EAAAA,YAMAoB,EAAAA,YAEA7C,EAAAgE,SAAAC,IAIAC,KDjDezC,ECyDf,QAAAoB,GAAAsB,GACAnE,EAAAmE,SAAA9F,EAAAgF,OAAAc,EAAApH,MAAAiH,SAAAhE,EAAA2D,UDpDM,MADAO,GCuDNE,SAAA5G,EDtDa0G,MAER/C,OCuDL,iBAAAgD,UAAAE,SAAA/C,GDtDI,MAAO,UAAS6C,EAAOE,EAAY/C,GACjC,MCyDNgD,IAAAjG,QAAAgF,WAAAc,EAAApH,MAEAS,EAAAiE,KAAAA,SAAAjE,GAEA,MAAA4G,GAAA,UAAAG,EAAAF,EAAA/C,KAGA8C,EAAAI,UAAAxE,EAAAhD,EAAAyH,ODzDOH,UCiEP1H,eAAAA,UAAAA,SAAAA,KAAAA,aAAAA,gBAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GDhEI,GAAIY,GCiERwC,EAAAA,QDhEI,QACE0E,SCiENpG,MDhEMqG,QCiENtG,UDhEM0B,KAAM,SAAkBC,EAAOhD,EAASyH,EAAM3G,GCoEpDd,EAAA4H,IAAAA,SACAvG,IAAAA,IACA2B,MAAA3B,EAIAA,SAAAC,SAAA,WAAA,cAAA,aAAA,eAAA,YAAA,YAAAI,QAAAA,UAAAA,WAAAA,OAAAA,YAAAA,SAAAA,QAAAA,YAAAA,eAAAA,aAAAA,aAAAA,aAAAA,KAAAA,cAAAA,eAAAA,SAAAA,GACAmG,QAAA5B,UAAAvE,EAAAoG,MAAAC,EAAAA,GAAArG,EAAAsG,KDnEQ,ICqERpI,GAAAoD,eDpEQ3B,SAAQC,SAAU,OAAQ,YAAa,YAAa,UAAY,SAASI,GACnEL,QAAQ4E,UAAUwB,EAAK/F,KAASkG,EAAiBK,KAAKR,EAAK/F,MAAO9B,EAAQ8B,IAAO,KC2E/FL,QAAA8C,SAAA9C,eAAAzB,SAAAuE,eAAAA,SAAA3D,YAAA2D,SAAAA,GACA,GAAAC,GAAAxE,KAAAwE,EAAAA,OAAA5D,GAAAA,cAAA4D,EAAAA,MAAAA,EACAE,SAAAA,UAAA1E,EAAA0E,MAEA4D,EAAAA,GAAAT,EAAAS,MAAAA,EAAAA,OAGAlI,EAAAsE,KAAA4D,iBAAAlI,EAAAsE,KAAAA,eAAAA,MDzEQ,IAAIH,GAAS9C,QAAQ4E,UAAUrG,EAAQuE,QAAUvE,EAAQuE,OAAS3D,EAAS2D,OC2EnFC,EAAA8D,EAAAA,OAAA1H,EAAA4D,MACA+D,EAAAA,EAAAC,YAAAF,EAAAA,WAGAG,EAAA5D,EAAAA,SAGA7E,KAEAsI,GAAAI,MAAAH,EAAAA,cACAnF,IAAAuF,GAAAD,IAAAA,ID7EYlE,ICgFZiE,GAAAG,cAAAA,ED/EQ,IAAIL,GCgFZpC,EAAAA,GD/EYsC,EAAY5D,EAAWzE,EAASc,EAAYlB,EAChD,IAAIA,EAAQ6I,aAAc,CACxB,GAAIH,GAAiBH,EAAcO,OAAO,GAAG/F,QAAQ,OAAQ,IAAIA,QAAQ,UAAW,IAAIM,MCmFlGD,GAAA2F,iBAAAC,EAAAC,SAAAC,EAAAA,GAEA9F,EAAA+F,SAAAF,EAAAA,GAAAA,KAAAA,SAAAA,GACAV,EAAAa,OAAAA,GAIAlI,EAAAmI,cDlFQjG,ECsFR2F,OAAAH,EAAApC,QAAAhC,SAAAoE,EAAAA,GDrFUxF,ECsFVqF,YAAAG,EDrFUL,ECuFVpC,SAAAA,EAAAA,GAAAA,KAAAA,SAAAA,GDtFY,MAAInG,GAAQqJ,aAAeT,EAAOpC,QAAUyC,EAASzC,OAAS,MAC5DtF,GAAWqF,cAAcrF,EAAWoI,WAAWC,UAAU,EAAGrI,EAAWoI,WAAW9C,OAAS,KC+FzGgD,EAAAA,OAAAhF,IAAAoE,EAAAA,EAAAR,MAAA,EAAA5D,IACAiE,EAAAe,OAAAA,OD3FYtI,GAAWiF,eAGfjF,EAAWuI,YAAYC,KAAK,SAASC,GCgG7C,GAAAH,GAAAjB,EAAAiB,aAAAG,ED9FU,OAAIH,GCkGdrD,EAGA1E,QAAArB,UAAAuJ,IAAA,gBAAAA,GDjGmBA,ECoGnBC,KDhGQ1I,ECkGRS,QAAAiI,WACA,GAAAC,EAAAzJ,SAAA0J,EAAAA,YACA,MAAA1J,GAAA2J,IAAAC,GAEA5J,IAAAA,GAAA6J,EAAAA,UAAAJ,EAAAK,aDjGcN,EAAqB,KAAVhE,EAAe6C,EAAUjD,OAAOH,SAASO,GAAOuE,MAAQjJ,EAAWoI,UCqG5FlG,GAAA3B,QAAAmC,SAAAgG,GAAArB,EAAAiB,aAAAI,GAAAA,CACA,IAAAnB,GAAAA,EAAAA,EAAA2B,WAAAA,QAAAA,iBAAAA,IAAAA,GACApK,EAAAA,EAAA,GAAA8J,eACArB,EAAAA,EAAA,GAAAuB,YDnGU5J,GAAQ2J,IAAI/J,EAAQ2E,aAAc,EAAQhD,EAAQA,EAAM0B,QACxDjD,EAAQ,GAAG6J,kBAAkBJ,EAAIK,IAEnC9G,EAAMiH,IAAI,WAAY,WIlO9B5J,GAAAgI,EAAA2B,UAIAxJ,EAAAI,KACAH,EAAA,YJqOEY,QI/NFP,OAAAA,yBAAAgD,SAAAsB,OAAAyB,WJgOI,GI/NJrG,GAAAI,KAAAA,UAGAsJ,UAAAC,UACA9I,SAAAC,mBJ8NM8I,SI7NN/I,WJ8NMgJ,YAAa,UIzNnBjF,EAAAkF,KAAAA,WAAAH,SAAAE,EAAAA,EAAAA,GAEAH,GAAAA,GAAAK,IAKAL,GAAAM,SAAAA,QAAAA,KAAAA,GAEAN,QAAAO,SAAA,YAAAC,WAAAA,eAAAA,SAAAA,GACArJ,QAAAsJ,UAAAA,EAAAJ,MAAAK,EAAAA,SAAAlJ,GAAAmJ,EAAAnJ,MJuNM0D,EAAO0F,UAAYZ,EAAKC,SAASC,SACjChF,EIrNNmF,aAAAG,EAAAA,SAAAA,YJsNMR,EAAKK,OAASnF,EAAOmF,UInN3BL,EAAAa,2BAAAL,EAAAA,wBJqNMR,EIpNNO,MAAAjF,SAAA+E,GACAS,QAAAA,YAAAT,EAAAK,OAAAA,UACAxF,EAAA6F,WAAAA,EAAAA,MAAAA,GJsNQf,EIpNRe,OAAAA,KAAAf,IJsNMA,EAAKa,QIpNXC,SAAAA,GJqNQ,GAEIC,GAFAzF,EIpNZ0E,EAAAK,OAAAW,QAAAR,GACAO,EAAAA,EAAAf,OAAAK,OAMAU,GAFAf,QAAAiB,SAAA3F,GAEAyF,EAAAA,OAAAG,IAAA,SAAAV,GAGAO,MAAAA,GAAAA,OJgNaC,QI/Mb1F,GJiNwB0E,EAAKK,OAAOK,QAE5BV,EI7MRA,OAAAmB,OAAAnB,EAAAK,GACAU,EJ6MYzF,EI5MZ0E,IJ8MmB1E,IAAUyF,GAAeA,IAAgBf,EAAKK,OAAOnE,QAC9D6E,II1MVf,GAAAU,GAAArJ,EAAAA,EAAAA,OAAAA,OACA2I,EAAAM,WAAAA,EAAAA,OAAAA,GAAAc,MAAAC,GJ8MUrB,EAAKmB,cAGTnB,EI3MNmB,WAAAd,EAAAK,WAAAY,SAAAtB,GJ4MQA,EAAKK,OAAOK,QAAUrJ,EACtB2I,EAAKM,2BAA2BlJ,QAAQ,SAASiK,GIxMzD/G,OAGAiH,EAAA3K,UAAAA,EAAAA,UAAAA,SAAAA,EAAAA,GACA,MAAA2K,GAAAA,OAAAA,UAAAA,EAAAA,MAAAA,EAAAA,OAAAA,UAAAA,GAOA7K,MAAAJ,KAAAA,WAEA,GAAAiL,KAGAzI,OAFA2E,GAAAA,SAAAnH,EACAkL,EAAAA,WAAA5K,EACA2K,KJsMKnE,UIpML3H,UAAA,UAAA8H,WAAAA,OAAAA,SAAAA,SAAAA,EAAAA,EAAAA,EAAAA,GJqMI,GIpMJjH,GAAAiH,EAAAtH,QJqMI,QInMJ4C,SAAA,WAAAyE,UJqMMkE,YInMNC,EJoMM3I,OInMN4I,EJoMM9K,YIhMN6K,SAAA,WAAA,SAAAF,EAAA3K,YJiMMnB,YI9LNiM,SAAApB,EAAAA,GJ+LQ,MI9LRmB,GAAAA,UAAAxF,EAAAyF,UJgMM7I,KI5LN4I,SAAAtC,EAAAC,EAAAuC,EAAAtC,GJ6LQ,GI3LRqC,GAAAP,EAAA9B,GACAqC,EAAArC,EAAAA,EJqMQ,IATIoC,IACFC,EAAWpB,2BAA2BlB,KAAK,WIxLrDuC,EAAAC,cAAAF,EAAArB,OAAAK,WAMAgB,EAAApB,YAAAA,KAAAA,SAAAlB,GJuLY,MItLZyC,GAAAA,WAAAC,GJsLmBzC,KAGPsC,EInLZC,aAAA,CJoLU,GAAIC,GAAqBE,EAAOJ,EAAMC,aACtCF,GAAWpB,2BAA2BlB,KAAK,WACzCyC,EAAmBC,OAAOhJ,EAAO4I,EAAWrB,OAAOK,WI7K/D5H,EAAA2F,OAAAkD,EAAAC,aAAA,SAAAjD,EAAAC,GACAnB,EAAA0D,WAAAxC,KACA,SJmLOvB,UIzKP4E,UAAA,UAAA,WAAApD,OAAAA,SAAAA,EAAAA,EAAAA,GJ0KI,OACEnB,SAAW,YAAa,WACxB3E,OIvKNA,EJwKMD,KIrKN6I,SAAAzB,EAAA1J,EAAAoL,EAAAM,GAwBAC,QAAAA,KJ+JU,GAAI5G,GAAQoG,EAAWrB,OAAOW,QAAQlI,EACtCqJ,GAAST,EAAWU,UAAUtJ,EAAOwC,GAAS,WAAa,eAAexF,EAAS4L,EAAWzB,SAASE,aAlBzG,GIrKRrK,GAAAuM,EAAAX,EJsKQ5L,GAAQuM,SAAS,YInKzBV,EAAAK,SAAA,QAAA,SAAArD,EAAAA,GACA7F,EAAAwJ,MAAAA,EAAAxJ,YAAA6F,KAIA+C,EAAAA,KAAAnB,EAAAzH,KAGAA,EAAAmH,SAAA1J,WACAmL,EAAAA,SAAAb,EAAA/H,SAAAA,WAGA6I,EAAAK,SAAAE,WAAAA,SAAAA,EAAAA,GACApJ,EAAAwC,SAAAoG,EAAArB,MAAAA,KJiKQqB,EAAWnB,MAAMzH,GI7JzB4I,EAAAA,IAAAA,WAAApB,WACA4B,EAAAA,QAAAA,KC9LA/K,EAAAmJ,2BAAAlB,KAAA,WAIA9I,MAEAiM,SLmWEpL,QK/VFqL,OAAA,0BAAA,sBAAA,sCAAA5I,SAAA,WAAA,WLgWI,GK/VJ6I,GAAA/L,KAAAJ,UACAb,UAAAA,UACAQ,YAAA,GACAyM,YAAAA,UACA/I,YAAA,UACAG,WAAA,EACAtB,QAAA,EACAkE,UAAA,MACAiG,YAAA,2BACAC,SAAA,GACA7I,eAAA,EACA8I,QAAAA,cACAC,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACAC,MAAAA,GLgWML,KK/VNM,GLgWMnJ,MK/VNoJ,ELgWMN,WAAW,EACXC,WAAW,EK7VjBpM,yBAAA,EAEAsM,0BAAA,EACAC,UACAC,SAAA/L,OAEAgM,QAAAC,GL+VI1M,MKzVJ4D,MAAA+I,UAAAzI,aAAA0I,cAAA3M,KAAAjB,iBAAAA,QAAAA,WAAAA,OAAAA,aAAAA,QAAAA,WAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GL6VM,QKxVN6N,GAAAxJ,EAAAwJ,GLgfQ,QKxRRC,KACAC,EAAAA,MAAAA,EAAAlO,YAAA,QAAAqF,GACAzD,QAAAzB,UAAAqE,EAAArE,SAAAkH,QAAAT,WAAAzG,EAAAgO,SACAhO,EAAAkF,OAAAA,GL+TQ,QKpQR+I,KAQA/I,GL6PU9B,EAAMgD,MAAMpG,EAAQH,YAAc,QAASqF,GKjQrDgJ,QAAAA,UAAAA,EAAAA,SAAAA,QAAAA,WAAAA,EAAAA,SLmQYlO,EAAQmO,OAAOjJ,GK/P3BA,IAAAkJ,EAAAtI,CACA,GAAAA,GAAA,UAAA9F,EAAAiE,QAAA6B,MAAAc,GAAAA,GAAAA,MACAsH,MLiVQ,QKzOR9N,KL0OU,GKzOViO,GAAAC,EAAArK,QAAA4J,MAAA5J,IL0OUxC,SKzOVrB,QAAAmO,EAAAC,SAAAvK,GL0O4B,UAAZA,GAAmC,gBAAZA,EACzB7D,EAAQmO,GAAGtK,EAASiB,EAASuJ,QACR,WAAZxK,IACT7D,EAAQmO,GAAe,UAAZtK,EAAsB,aAAe,QAASiB,EAASwJ,OKvOhFtO,EAAAuO,GAAAA,UAAAA,EAAAA,aAAAA,OAAAA,EAAAA,OACA3O,WAAAqO,GAAA,UAAAR,GACAzN,EAAAiO,GAAAA,EAAA7H,aAAA,YAAAtB,EAAA0J,6BL6OQ,QKxORxO,KL0OU,IKxOV,GADAA,GAAAyO,EAAA5K,QAAA4J,MAAA,KACAS,EAAAA,EAAA9H,OAAAsI,KAAA7K,CLyOY,GKxOZ7D,GAAAyO,EAAAL,ELyO4B,WAAZvK,GAAmC,gBAAZA,EACzB7D,EAAQyO,IAAI5K,EAASiB,EAASuJ,QACT,WAAZxK,IACT7D,EAAQyO,IAAgB,UAAZ5K,EAAsB,aAAe,QAASiB,EAASwJ,OKtOjFtO,EAAA2O,IAAAA,UAAAA,EAAAA,aAAAA,OAAAA,EAAAA,OACA9K,WAAAjE,GAAA,UAAAiE,GACA+K,EAAAT,IAAAC,EAAAtJ,aAAA+J,YAAAA,EAAAA,4BAMA,QAAAC,KACA,UAAAlP,EAAAiE,QACA+K,EAAAH,GAAAA,QAAA3J,EAAAA,UAEA9E,EAAAyO,GAAAA,QAAA3J,EAAAA,eAIA,QAAAiK,KACAC,UAAApP,EAAAoP,QAGAhK,EAAAyJ,IAAA,QAAA3J,EAAA+J,UAKAI,EAAAd,IAAA,QAAArJ,EAAAgC,eAMA,QAAAoI,KACAlK,EAAA+J,WACAH,EAAAH,GAAAA,QAAAU,GACAF,EAAAR,GAAAA,QAAA3J,EAAAA,MACAiK,GAAA,GL+Na,GAAG,GK3NhB,QAAAI,KACAC,IL8NYR,EAAWH,IAAI,QAASU,GKzNpCF,EAAAI,IAAAA,QAAAxI,EAAAA,MACAA,GAAAjH,GL6NQ,QKxNR0P,GAAAC,GACAH,EAAAI,kBL0NQ,QKnNRC,GAAAA,GLoNU5I,EAAWA,GAAajH,EAAQ8M,QAAU1M,CKhNpD,IAAAwP,GAAAE,EAAAA,GAEAF,EAAAA,SAAAnO,EAAAA,QAAAqO,EAAAJ,EAAAA,wBAAAK,ILmNU,KAAK,GAAIF,KAAKH,GACZE,EAAKC,GAAKH,EAAOG,EKlN7B,QAAAG,EAAAF,QAAAG,EAAAxO,QAAAS,UAAA0N,GAAAM,MAAAA,EAAAC,MAAAC,EAAAA,KACAC,OAAAA,EAAAA,OAAAA,EAAAA,MACA,IAAAC,GAAAA,GAAAR,IAAAA,EAAAC,KAAAA,GAAAG,EAAAC,OAAAC,GAEAC,GL2NYA,OAAQE,EAASC,EAASC,gBAAgBC,WAAaF,EAASG,KAAKD,UAAYzJ,EAAS2J,KAAK,cAAgB,GKvN3HT,EAAAA,GACAL,MAAAjC,EAAAd,gBAAA8D,YAEAd,OAAAlC,EAAAiD,aACA,ILyNU,OKxNVX,SAAAA,UAAAA,EAAAA,EAAAA,EAAAA,GL0NQ,QKxNRF,GAAAc,EAAAjB,EAAAA,EAAAA,GLyNU,GAAIK,GKvNdtC,EAAAd,EAAAc,MAAA,ILyNU,QAAQA,EAAM,IKxNxB,IAAA,QACAsC,GACAH,IAAAe,EAAAf,IAAAe,EAAAhB,OAAAA,EAAAA,EAAAA,EACAE,KAAAc,EAAAd,KAAAc,EAAAjB,MAEA,MACA,KAAA,SACAK,GACAH,IAAAe,EAAAf,IAAAe,EAAAhB,OACAE,KAAAc,EAAAd,KAAAe,EAAAA,MAAAA,EAAAA,EAAAA,EAEA,MACA,KAAA,OACAb,GACAH,IAAAe,EAAAf,IAAAiB,EAAAA,OAAAA,EAAAA,EAAAA,EACAhB,KAAAc,EAAAd,KAAAc,EAEA,MAGA,SACAZ,GL2NcH,IAAKe,EAASf,IAAMiB,EKvNlCpD,KAAAkD,EAAAd,KAAApC,EAAAiC,MAAA,EAAAkB,EAAA,GL4NU,IKxNVnD,EAAA,GLyNY,MAAOsC,EAET,IKzNVF,QAAAE,EAAAA,IAAAY,WAAAA,EAAAd,GL0NY,OKzNZpC,EAAA,IL0Na,IAAK,OKzNlBsC,EAAAF,KAAAc,EAAAd,IACA,ML4Na,KK1Nb,QACAE,EAAAtC,KAAAkD,EAAAd,KAAAc,EAAAjB,MAAAkB,MAKAb,IAAAY,SAAAf,EAAAe,IAAAf,UAAAA,EAAAA,GL4NY,OK3NZnC,EAAA,IL4Na,IAAK,MK3NlBsC,EAAAH,IAAAe,EAAAf,IAAAiB,EAAAF,EAAAhB,MACA,ML8Na,KAAK,SK1NlBI,EAAAA,IAAAA,EAAAA,IAUA,MAAAe,GL0NQ,QKtNRC,GAAAD,EAAAA,GAEAf,GAAAA,GAAAH,EAAAA,GACAG,EAAAF,EAAAE,YAIAD,EAAAkB,EAAAA,aACAC,EAAAC,SAAAC,EAAAA,IAAAA,EAAAA,cAAAA,IACAvC,EAAAwC,SAAAA,EAAAA,IAAAA,EAAAA,eAAAA,GLmNcL,OKlNdnB,KAAAuB,EAAAvB,GLmNcmB,MKlNdlB,KAAAsB,EAAAtB,GLmNUE,EKlNVsB,IAAAtB,EAAAH,IAAA0B,ELmNUvB,EAAOF,KAAOE,EAAOF,KAAOiB,EAC5BhB,EAAWkB,UAAUO,EAAKlQ,QAAQS,QAChCmP,MKlNZlB,SAAAoB,GAGAP,EAAAA,KACAC,IAAAA,KAAAA,MAAAU,EAAAC,KAAAA,KAEA7E,KAAAA,KAAAA,MAAAwE,EAAAN,MAAAA,KACAd,MAAAH,OAOAG,GAAA0B,EAEA,IAAAC,GAAAH,EAAAI,YACA5B,EAAA2B,EAAA7B,YAKAC,IAJA,QL0McnD,GK1MdkE,IAAAlB,IACAI,EAAAH,IAAAA,EAAAA,IAAAA,EAAAA,IAGAE,8CAAAC,KAAAA,GAAAD,CAEA,GAAA4B,GAAAD,EAAA9E,EAAAoD,EAAAa,EAAAC,EAUA,IATAa,EAAAE,KACA7B,EAAA8B,MAAAA,EAAAD,KAGAE,EAAAA,KAAAD,EAAAA,ILyMU/B,EAAWkB,UAAUO,EAAKxB,GKpMpC,wBAAA0B,KAAA9E,GAAAgE,CACA,GAAAe,GAAAA,aAAAA,KAAAA,GAAA9B,EAAAgC,EAAA,EAAAF,EAAA7B,KAAAH,EAAAkB,EAAA,EAAAc,EAAA9B,IAAAD,EAAAkB,EAAAhB,EAAA+B,EAAA,cAAA,cLwMYE,GAAaD,EAAYN,EAAIQ,GAAsBH,KAGvD,QKvMRI,GAAA3C,EAAAvK,EAAAmN,EAAAA,GAEA,GAAAP,IACA9B,IAAAsC,EACArC,KAAAsC,ELwMU,KKtMVT,EAAA9B,UAAAoC,MAAAA,ELuMU,IAAII,GKtMdD,EAAAA,UAAAH,EAAAA,SAAAA,SAAAA,EACAN,EAAAM,EAAApC,EAAAoC,ULuMU,IAAI,aAAa/J,KAAK0E,GAAY,CAChC,GAAIuF,GKtMhBvB,EAAAf,IAAAwC,EAAAJ,EAAA/B,OACAoC,EAAA1B,EAAAd,IAAAuC,EAAAA,EAAAA,OAAAA,CACAE,GAAAA,EAAAF,IACAV,EAAAW,IAAAA,EAAAL,IAAAA,EACAnC,EAAAmC,EAAAK,IAAAA,EAAAA,SLuMcX,EKtMd9B,IAAA0C,EAAAN,IAAAA,EAAArC,OAAAwC,OLwMiB,CACL,GAAIE,GAAiB1B,EAASd,KAAOuC,EKpMjDE,EAAAZ,EAAAA,KAAAA,EAAAA,CLsMgBW,GAAiBL,EAAmBnC,KKnMpD6B,EAAAI,KAAAA,EAAAS,KAAAC,EACAnQ,EAAA2P,EAAAX,QAEAoB,EAAArB,KAAAoB,EAAA3C,KAAAmC,EAAAO,MAAAA,GAMA7E,MAAAA,GLkMQ,QK/LR9N,GAAAmN,EAAAwF,EAAAC,GLgMU,GK/LVtD,GAAAA,EAAAA,yBAAAA,EAAAA,GLgMUuD,GAAOrB,IAAIoB,EAAe,OAAS,MAAO,IAAM,EAAId,EAAQa,GAAa,KAAKnB,IAAIoB,EAAe,MAAQ,OAAQ,IAEnH,QK9LR1D,KL+LUpB,aAAagF,GACT5N,EAAS6N,UAA2B,OAAf/D,IK5LnCgE,EAAA7F,WACA6F,IL+LgBhT,EAAQoE,UK3LxB4K,KL+LcgE,IACFA,EAASC,WK1LrBD,EAAA9N,MAMA8J,IAEA5L,EAAAgE,SLuLY4H,EAAa9J,EAAS+B,SAAW,MAvgBrC,GKxVRjH,MAAAgH,EAAA6G,EAAAtD,SAAA9I,QAAAS,UAAAtB,EAAA0E,GAAA4B,EAAA2G,EAAAqF,SAAAtF,EAAA3M,QAAAjB,GL2VYoD,EK3VZ8B,EAAAM,OAAAxF,EAAAoD,OAAApD,EAAAoD,MAAA+P,QAAAlO,EAAAkO,OL4VY7E,EAAWlO,EAAQ,GAAGkO,SAAS8E,aKtV3ClO,IAAAA,EAAAmO,OAAArT,QAAAI,SAAAyH,EAAAxD,OAAA,CAGA,GAAArE,GAAAiN,EAAA5I,MAAAwJ,MAAA,KAAArC,IAAA8H,WACAlQ,GAAA6J,MAAAsG,EAAAC,OAAAxT,GLsVYgH,KAAM6G,EAAM,GKlVxBzK,KAAAqQ,EAAAA,IACArQ,EAAAmC,GLqVQL,EAASmO,IAAMrT,EAAQ0T,IAAMtT,EAAQyH,KAAK,OAAS,GAC/C7H,EAAQiN,QKlVpB7J,EAAAuQ,MAAAJ,EAAAC,YAAAxT,EAAAiN,QLqVQ7J,EKnVR8B,YAAAgC,SAAAA,GLoVU9D,EAAMmC,aAAa,WACjBL,EAAS0O,WAAWC,MAGxBzQ,EKnVR8B,MAAA8B,WLoVU5D,EAAMmC,aAAa,WACjBL,EAASgC,UAGb9D,EKnVR8B,MAAAuJ,WLoVUrL,EAAMmC,aAAa,WACjBL,EAAS8B,UK7UrB5D,EAAA2K,QAAAA,WAGA3K,EAAA0Q,aAAAA,WACA9E,EAAAA,YAGArB,EAAAxN,SAAAiD,EAAArC,UAAAA,CL+UQ,IK9UR+S,GACA5O,EL+UY4O,EK5UZ5O,EAGA6O,EACA/T,CL4UQ2N,GK3UR3G,KAAAhH,SAAAqE,GL4UUyP,EK3UV9T,EL4UUkF,EAAS8O,SAEX9O,EKpURlF,KAAAmE,WACA4P,EAAAA,OAAA3T,QAAAA,SAAAA,EAAAA,SLqUYJ,EKpUZqE,OACA0P,KAAAA,EAAA/T,MLqUckH,KKpUdlH,EAAAA,QAKAiU,SAAAA,EAAAA,UAGAF,EAAAjH,EACAA,QAAArL,UAAAyS,EAAAlU,WLiUY+T,EAAe/T,EAAQmE,UK7TnCnE,EAAAmE,YACAf,EAAAmC,EAAAvF,EAAAmE,YLgUU8P,IACIjU,EK9Td8M,SL+TY9M,EK9TZkF,OAAA8B,QAAAA,UAAAA,EAAAA,QAAAA,EAAAA,OAAAA,EAAAA,EAAAA,SLgUchH,EAAQgH,MACV5D,EAAMmC,aAAa,WACO,UAApBvF,EAAQiE,QK3T1BiB,EAAAkF,GAAA+J,QAMAjG,EAAAA,UL6TQhJ,EKnTR6I,QAAA,WACAY,ILoTUT,IACA9K,EAAM6P,YAER/N,EKlTR6I,MAAAA,WAKA7I,ML8SU4I,cKlTVzJ,GLmTU0J,EAAa,KK/SvB7I,EAAA8B,OAAAhH,EAAAqE,MAAA2C,UAIA8L,EAAArR,WAAA4E,WACA+N,OAAApU,GAAAkF,EAAAA,QLgTalF,EAAQqE,MAAM2C,OKpT3BhH,EAAAoN,QLsTQlI,EK/SRmP,KAAAA,WACA,GAAArU,EAAAmE,YAAAe,EAAA6N,SAAA,CLgTU3P,EK/SVkR,MAAAP,EAAAA,YAAAA,eAAAA,GACAtS,QAAAsS,UAAAQ,EAAAA,eAAA9S,QAAAgF,WAAAzG,EAAAoU,eLgTYpU,EK/SZqU,aAAAjU,ELiTU,IK/SViU,GLgTcA,CACArU,GK/SdmE,WACAmQ,EAAAP,ELiTcM,EKhTdA,EAAAjU,GAAAA,ULgTsBqB,QAAQrB,QAAQ2T,EAAa,GAAGQ,WKzStDrP,OAKA8K,EAAA,KAAAC,EAAA7P,GAAAoU,GAAAtG,IL6SU8E,EK7SVyB,EAAAjP,OAAA2N,OL8SUnE,EAAa9J,EAAS+B,SAAW6M,EAAY3Q,KAAK6P,EAAU,SAAS0B,EAAetR,MK3S9F4L,EAAAhP,KAEAgQ,IAAAhQ,UAEAiQ,KAAAjQ,UAKAyR,MAAA4C,OACAA,QAAAA,QLuSYI,WKtSZ,WLwSczU,EAAQa,WAAWmO,EAAWrC,SAAS3M,EAAQa,WKpS7DqE,EAAA6N,MAAAA,EAAAA,SAAA/S,EAAAc,YAAA,IAAAd,EAAAkN,MACAjH,EAAA7C,aAAAA,EAAAA,SAAAA,EAAAA,aAGA8B,EAKAmP,EAAA5S,MAAAkT,GLiSYL,EK/RZM,QAAA5F,GLiSU9J,EAAS6N,SAAW3P,EAAM2P,UAAW,EK9R/C9M,EAAA7C,GAEA+B,EAAA0P,kBAEApT,QAAAuN,QAAAA,OAAAwC,EL8RY/E,EK9RZgI,MAAAzF,EAAAsF,EAAAD,EAAAS,GAGArI,EAAAzM,MAAAoE,EAAAkQ,EAAAD,GAAAlU,KAAA2U,GL+RU7O,EK7RVf,GL8RUC,EAAM,WK5RhB4J,GAAAA,EAAAA,KL8Rc0F,WAAY,YK1R1BzU,EAAAmN,WACAiC,UAAAA,EAAAA,SL6RgBlK,EAASiP,QKxRzBpF,OAGA/O,EAAAgO,WL2RYoB,MASJlK,EKxRR6I,MAAAA,WL2RU,MAFAD,cKxRV5G,GLyRU6G,EAAa,MKvRvB/N,EAAAqE,OAAA6C,EAAAA,MAAAA,UAKA4L,EAAA1E,WAAAA,WACA,QAAAlJ,GAEAA,EAAAA,QAEAlF,EAAAyB,MAAA4E,OL+QmBnB,EAASgC,OAQpB,IAAI6N,GKlRZA,CLoRQ7P,GKhRRkJ,KAAAY,SAAAA,GAIAvN,EAAAkT,WL8QUvR,EK7QVqJ,MAAAuI,EAAAhG,YAAAf,eAAAA,GL8QcxM,QK7Qd4E,UAAArG,EAAAiV,eAAAxT,QAAAgF,WAAAzG,EAAAiV,eACAxI,EAAAA,aAAAuC,GAGA9J,EAAAA,EACAe,EAAA7C,EAGApD,QAAAoE,QAAAA,OAAA4K,EACAE,EAAAA,MAAAA,EAAAA,GAGAzC,EAAAzM,MAAAmN,GAAA6B,KAAAA,GL2QU9J,EAAS6N,SAAW3P,EAAM2P,UAAW,EACrC9M,EAAW7C,GKvQrBpD,EAAAiO,UAAAA,OAAAA,GACA7K,IAEApD,EAAAmO,WAAAjJ,OAAAA,GLyQYoK,MAeJpK,EKnQRA,OAAAwJ,SAAAA,GLoQc5I,GACFA,EAAIc,iBKhQhBoI,EAAA+D,SLmQY7N,EAAS8P,QK/PrBhV,EAAAoN,SLoQQlI,EKhQRlF,MAAAuN,WLiQUyB,EAAW,GAAGmF,SAEhBjP,EK7PR8J,WAAA,SAAA6E,GAGA7T,EAAA+M,UAAA/M,GL6PQkF,EK3PRgQ,YAAAC,SAAA9M,GAEArI,EAAAkV,SAAA3H,GL4PQrI,EAAS2P,gBAAkB,WKtPnC7F,GAAAA,EAAAA,CAIA,GAAAoG,GAAAA,EAAA3F,UACA4F,EAAArG,eACAsG,EAAAtG,EAAAA,KAAA4B,EAGA1L,KAGA6H,EAAAmI,EAAAnS,QAAAoS,EAAA,KAAAvU,EAAAmM,WLkPUiC,EKhPVuG,SAAAA,EAAA9F,ULiPU,IK/OV2F,GAAAI,IACAzI,EAAAA,EAAAyI,KAAAA,eLgPcF,EK/OdtG,EAAAwG,KAAAA,eLiPU,IADAtQ,EK/OV6H,UAAAyI,EAAAA,UAAAzS,EAAA/C,EAAAuN,SAAAC,UAAAxN,EAAAuN,ULgPc2H,EAAW,CK7OzB,GAAAM,GAAAA,EACAzI,EAAAA,EAAA7H,EAAAmN,UL+OgB,UK9OhBhK,KAAAmN,IAAAA,EAAAJ,OAAA3D,EAAA4D,EAAAE,OACAxI,EAAAA,EAAAhK,QAAA,SAAA,OL+OuB,MAAMsF,KAAKmN,IAAsBJ,EAAgBpF,IAAMsF,EAAYC,EAAiBvF,MK5O3GhB,EAAAyG,EAAAD,QAAAA,MAAA7I,WAIA+I,OAAAA,KAAAC,IAAA5I,EAAAqI,KAAAA,EAAAC,EAAAC,KACAM,EAAAF,EAAAA,QAAA3I,OAAAA,SL4OuB,QAAQ1E,KAAKmN,IAAsBJ,EAAgB3D,MAAQ4D,EAAWE,EAAiBzF,QKzO9G5K,EAAA+J,EAAAlM,QAAA+C,QAAAA,SAEAZ,EAAAgC,YAAAA,GAAAA,SAAAA,GL4OU,GAAIwO,GAAcC,EAAoB5I,EAAWqI,EAAiBC,EAAUC,EAC5EM,GAAeF,EAAa3I,KAE9B7H,EKzORY,SAAA,SAAAA,GACA+P,KAAAzV,EAAAA,OAAAyV,EAAAA,WACA/P,EAAAe,OL0OYf,EAAIe,oBAGR3B,EKxORlF,cAAAqN,SAAAA,GAAAzG,KAAAd,EAAAc,QL0OYxG,EAAQ,GAAGyV,OKzOvB/P,EAAA9F,oBL6OQkF,EK3ORA,yBAAA,SAAAY,GACA1F,EAAAiN,yBL4OYvH,EAAIc,iBAEF5G,EAAQsN,0BACVxH,EAAIe,kBKvOhBwH,EAAAA,SACA5M,EAAAC,GAAAA,OL2OYtB,EKzOZA,GAAAmO,QLuRQ,IAAIY,IAAyB,CAuM7B,OAAOjK,GAET,QAASe,GAAW7C,GK9K1BsE,EAAAA,SAAAtE,EAAAiE,OAAAjE,EAAAiE,MAAAD,SAAAhE,EAAA2D,UAGAe,QAAAA,GAAAgO,EAAA1V,GACAgD,MAAA3B,SAAArB,SAAAA,GAAAoQ,GAAAuF,iBAAAD,ILtWM,GKzVNE,GAAA9Q,6BAAA9B,KAAApD,EAAAoD,UAAA+P,WAEA3E,EAAAF,eAAAA,GAAA8E,UAAAA,EACA/D,EAAArP,QAAAqE,QAAA5C,EAAAG,SL42BM,OK7KNqU,OL+KKvO,UK7KLtE,aAAAA,UAAAA,YAAAA,OAAAA,SAAAA,WAAAA,QAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GL8KI,OACE0E,SK9KNpG,ML+KM0B,OK9KN,EL+KMD,KAAM,SAAkBC,EAAOhD,EAASyH,EAAMqO,GK3KpD,GAAAlO,GACAvG,GACA2B,MAAA3B,EL8KQA,SAAQC,SAAU,WAAY,cAAe,aAAc,eAAgB,gBAAiB,YAAa,YAAa,QAAS,UAAW,OAAQ,YAAa,oBAAqB,OAAQ,cAAe,MAAQ,SAASI,GACtNL,QAAQ4E,UAAUwB,EAAK/F,MAAO9B,EAAQ8B,GAAO+F,EAAK/F,KAExD,IK1KRkG,GAAAlG,eL2KQL,SK1KRA,SAAA4E,OAAAwB,aAAA,SAAA/F,GACA9B,QAAA8B,UAAAsB,EAAA+S,KAAAlO,EAAAA,KAAAA,EAAAA,ML2KYjI,EAAQ8B,IAAO,KKrK3BL,QAAAA,SAAA4E,eAAA+P,SAAA,eAAA,UAAA,SAAAtU,GACA,GAAAkG,GAAAA,KAAAA,EAAAK,OAAA+N,GAAAA,cAAAtU,EAAAsG,MAAA,EACApI,SAAA8M,UAAAjF,EAAAI,MLyKYjI,EKxKZ8B,GAAAsB,EAAA+S,MAAAtO,EAAAI,ML2KQ,IAAImO,GAAahW,EAAQyH,KAAK,cKpKtCpG,SAAA4U,UAAAA,KACAjT,EAAAiF,KAAA+N,GLsKYpW,EAAQ8M,QAAS,EKjK7B9M,EAAAyB,OAAA4E,GAGAjD,EAAA3B,eAAAyH,WLoKU9F,EKnKV+B,MAAA,ILqKQ0C,EAAKyE,SAAS,QAAS,SAASrD,GAC9B,GAAIxH,QAAQ4E,UAAU4C,KAAc7F,EAAMiT,eAAe,SAAU,CACjE,GAAInN,GAAW9F,EAAM6J,KACrB7J,GAAM6J,MAAQsG,EAAKC,YAAYvK,GKjK3CqD,QAAAjG,UAAA6C,IACAD,EAAAA,WACA/B,GAAAA,EAAAA,uBLuKQW,EKhKRyE,SAAA7K,WAAAwH,SAAAA,GACAxH,GAAAS,EAAAkB,ULiKY6S,EKhKZ/O,SAGAW,EAAApG,WLiKU2B,EKhKV+B,OAAA0C,EAAAyO,UAAA,SAAArN,EAAAC,GACAzH,QAAAwU,SAAAA,GLiKcxU,QAAQS,OAAOkB,EAAO6F,GK9JpC7F,EAAA6J,MAAAhE,EAIApB,QAAA0O,UAAArN,IACA9F,EAAA2F,WACAkN,GAAAxU,EAAA4E,sBLiKa,GAEDwB,EK9JZoO,QL+JU7S,EAAM2F,OAAOlB,EAAK0O,OAAQ,SAAStN,EAAUC,GACtC+M,GAAYxU,QAAQ4E,UAAU4C,KAC/BxH,QAAQG,SAASqH,KAAWA,IAAaA,EAASuN,MAAM,wBK3JxE3O,KAAA,EACAzE,EAAA2F,OAGAkN,EAAAxU,UL+JYoG,EK3JZoO,WL4JU7S,EAAM2F,OAAOlB,EAAKuF,UAAW,SAASnE,EAAUC,GACzC+M,GAAYxU,QAAQ4E,UAAU4C,KAC/BxH,QAAQG,SAASqH,KAAWA,IAAaA,EAASuN,MAAM,0BKxJxE3O,KAAA,EACAzE,EAAA2F,YAAAwE,GAEA0I,EAAAQ,YAAAxN,MAQA7F,EAAAiH,UACAjH,EAAA6S,OAAAA,EAAAA,SAAA7L,SAAAA,GACApK,GAAAyB,QAAA4E,UAAA4C,IACAgN,EAAAQ,YAAAxN,KLwJQgN,EAAU/Q,EAAS9E,EAASJ,GAC5BoD,EAAMiH,IAAI,WAAY,WM5/B9B5J,GAAAwV,EAAA7L,UAIAxJ,EAAAI,KACAH,EAAA,YN+/BEY,QMx/BFwC,OAAA,6BAAA,oCAAA,uCAAA,2BAAAC,SAAA,cAAA,WNy/BI,GMx/BJC,GAAAnD,KAAAJ,UACAwD,UAAA,UACAtB,YAAA,OACAuB,YAAA,aAEAqS,UAAA,cACAC,YAAA,iCACAC,QAAAA,QACAC,WAAA,EACAC,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACAC,WAAAC,EACA1Q,SAAA,OACA2Q,WAAA,YACAC,SAAAA,KACAC,gBAAA,KACAC,WAAAA,EACAC,UAAAL,EAAAA,GACAM,UAAAN,EAAAA,GACAO,OAAAA,ENw/BMN,SAAU,EMr/BhBnW,WAAA,EAEAqW,WAAArB,EACAsB,cAAA,EACAC,OAAA3W,iCNs/BM4W,SMr/BN5W,mCNs/BM6W,cAAe,QAEjBzW,MMn/BJ4D,MAAA8S,UAAAxS,YAAA9E,aAAA8B,OAAAtB,iBAAA0E,WAAAA,WAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GNy/BM,QMl/BNqS,GAAAC,EAAAA,EAAAC,GAcA,QAAAC,GAAAA,GACAC,GAAAA,GAAAC,IAAAC,EAAAA,UACAC,OAAAA,IAAAF,MAAAA,KAAAC,MAAAA,EAAAA,UAAAE,GAAAA,GN0tCQ,QM/7BRC,GAAAzS,EAAAA,GNg8BU,GAAI0S,GM/7BdC,EAAAlY,CNg8BU,IM/7BVA,EAAA,GAAA6J,gBAAAqO,CNg8BY,GAAIF,GM/7BhB3W,EAAAsJ,GAAAA,iBACA3K,GAAAmY,UAAAzO,GACA1J,EAAAoY,UAAAxO,YAAAqO,GNg8BYD,EAASK,QAAQ,YAAaJ,GAC9BD,EAASzS,aM77BrB+S,GAAAA,GAAAA,kBACAtY,EAAA,GAAA+T,kBAAAA,EAAAA,GN+7BqB1S,QAAQsJ,YAAY3K,EAAQ,GAAG0J,kBM17BpD6O,EAAAjB,GAAAA,eAAA1D,EACA0D,EAAA1D,GAAAA,aAAAqE,GN87BQ,QM37BRjY,KN47BUA,EM37BV,GAAA+T,QNorBQ,GAAIuD,GAAcxS,EAAS9E,EAASqB,QAAQS,UAAWtB,EAAU0E,IMh/BzER,EAAA8T,EAAAC,MAEA7Y,EAAA0X,EAAA1X,SACAoD,EAAAsU,EAAAoB,ONi/BYC,EAAO/Y,EAAQ+Y,KM5+B3BC,EAAAA,SAAAC,EAAApB,EAAAhB,GACA,MAAAqC,GAAAlZ,WAAAsX,EAAAsB,EAAAA,EAAA/B,IAMAsC,EAAAC,EACAC,EAAArB,EAAAsB,aAAAA,EAAAA,GAAAA,OAAAA,GAAAA,MN8+BYtB,EAAY9W,EAAWqY,YAAcL,EM3+BjDrB,GAEAE,KAAAyB,EAAAC,WACAvB,SAAAwB,EAAAD,WAAAC,GACAC,OAAAC,EAAAH,aACAN,OAAAU,EAAAJ,aACAJ,YAAAS,EAAAL,mBAGArW,EAAA2W,EAAAxC,kBAAAA,EAAAA,WAAAA,GACAnU,EAAApD,EAAAwX,YAAAA,GAIApU,EAAAqW,EAAA7T,cAAAA,GACA8R,EAAA/R,EAAAC,cAAAA,GNw+BYiU,EAAgBJ,EAAeI,cAAchC,GMt+BzDzU,EAAA4W,EAAArY,YAAAiE,GACA8R,EAAAA,EAAA/V,OAAAiE,ENw+BQxC,GAAM2W,QAAU/Z,EAAQuX,OMt+BhCnU,EAAA6W,UAAAA,EAAAzC,SNw+BQpU,EMv+BRsU,QAAAwC,SAAAA,EAAAjB,GNw+BUvB,EAAY/R,OAAOsT,EAAMrT,IAE3BxC,EMn+BR3B,WAAA0Y,SAAAlB,EAAA9H,GNo+BUuG,EMn+BVA,WAAAuB,EAAAA,INq+BQ7V,EMn+BR2U,gBAAAE,SAAAA,GNo+BUP,EMn+BVuB,eAAAmB,INq+BQ1C,EMn+BR2B,OAAAJ,SAAAK,GNo+Bc7X,QAAQ0Y,OAAOlB,KAAU9H,MAAM8H,EAAKoB,YMl+BlD3C,EAAA4C,MAAAA,ENo+BY7Y,QMn+BZS,OAAAwV,GACAA,KAAAA,EAAA4C,WNo+BcX,OAAQV,EAAKmB,aACbjB,OAAQF,EAAKG,aMj+B3B1B,YAAA/R,EAAA2T,oBAGApY,EAAAqY,UNk+BsB7B,EAAY6C,UM/9BlC7C,EAAAyC,UNm+BQzC,EM99BRxW,OAAAiF,SAAAA,EAAAA,EAAAA,KACAnG,EAAA+W,YAAAyD,MAAAtZ,EAAAqY,WAAAc,cACAjV,EAAAmU,WAAA,UAAAvZ,EAAAkZ,YAAA,GAAAuB,MAAA,GAAAA,MAAA,KAAA,EAAA,INg+BehZ,QAAQ0Y,OAAOlB,KAAOA,EAAO,GAAIwB,MAAKxB,IAC7B,IAAVrT,EAAa1E,EAAWqY,WAAWmB,SAASzB,EAAKhB,YAAgC,IAAVrS,EAAa1E,EAAWqY,WAAWoB,WAAW1B,EAAKmB,cAAkC,IAAVxU,GAAa1E,EAAWqY,WAAWqB,WAAW3B,EAAKG,cACzMlY,EAAWqF,cAAc9E,QAAQH,KAAKJ,EAAWqY,aM59B3D7B,EAAAwC,UACAla,EAAAkB,YAAAqY,GACAnU,EAAA,WN89BcsS,EAAYxQ,MAAK,MAIvBwQ,EM79BRxW,eAAAiF,SAAAA,GN89BU,GAAKjF,EAAWqY,aAAcpI,MAAMjQ,EAAWqY,WAAWc,WAA1D,CMt9BV,GAAAQ,IAAAA,GAAAA,EAAAvJ,YAAAtR,UACAkB,GAAA4Z,WAAAA,SAAAA,GAAAA,EAAAA,EAAAA,GAAAA,EAAAA,IACA5Z,EAAA6W,cAAAA,QAAAA,KAAAA,EAAAA,aACA7W,EAAAiF,YN29BQuR,EMz9BRhO,OAAAA,WN09BU,GMz9BVuP,GAGArM,EAFAzC,EAAAyN,EAAAA,SAAA4B,SAAAA,EAAAA,OAAAA,EAAAA,IACA5P,IN29BU,KAAKkF,EAAI,EAAGA,EAAI9O,EAAQwG,OAAQsI,IAC9BiJ,EAAO,GAAI0C,MAAK,KAAM,EAAG,EAAG3C,EAASC,MAAQ8C,EAAW/L,GAAK9O,EAAQmX,UMx9BjF2D,EAAAC,MACApB,KAAAA,EACAxP,MAAAyN,EAAA5X,EAAAwG,GACAmT,SAAAjC,EAAAsD,OAAAlD,EAAA6B,YAAAkB,EAAA/L,GACAiM,SAAArR,EAAAA,YAAAA,EAAAA,IN49BU,IMx9BVkD,GADAhD,IN29BU,KAAKkF,EAAI,EAAGA,EAAI9O,EAAQwG,OAAQsI,IAC9B6K,EAAS,GAAIc,MAAK,KAAM,EAAG,EAAG,EAAG3C,EAAS6B,QAAUkB,EAAW/L,GAAK9O,EAAQoX,YMx9BxF2D,EAAAE,MACA9B,KAAAA,EACAhP,MAAAyN,EAAA5X,EAAAwG,GACA2S,SAAAzB,EAAAsD,OAAAtD,EAAAyB,YAAA0B,EAAAA,GACAI,SAAAvR,EAAAA,YAAAA,EAAAA,IN49BU,IMx9BVkD,GADAhD,IN29BU,KAAKkF,EAAI,EAAGA,EAAI9O,EAAQwG,OAAQsI,IAC9BqK,EAAS,GAAIsB,MAAK,KAAM,EAAG,EAAG,EAAG,EAAG3C,EAASqB,QAAU0B,EAAW/L,GAAK9O,EAAQqX,YMv9B3F4D,EAAAC,MACAjC,KAAAE,EACAhP,MAAA2P,EAAAX,EAAAU,GACAqB,SAAAxR,EAAAqR,OAAAjM,EAAAA,YAAAA,EAAAA,GNy9BclC,SMx9Bd8K,EAAAyD,YAAAhC,EAAA,IN29BU,IAAI+B,KMv9Bd9X,KAAAA,EAAA8X,EAAAA,EAAAA,EAAAA,OAAAA,IACApB,EACA1W,EAAAgY,MAAAA,EAAAA,GAAAA,EAAAA,GAAAA,EAAAA,KAEAhY,EAAAsW,MAAAA,EAAAA,GAAAA,EAAAA,IAIAhC,GAAAA,KAAA2D,EACAjY,EAAAsU,YAAAsD,ENw9BU5X,EMt9BVgY,OAAAnD,ENu9BU7U,EAAMkY,MMt9BhB1V,EAAAoV,OAAAF,EAAAD,GAAA5B,MAAAhB,WAAA,GNu9BU7U,EMt9BVsW,cAAAU,ENu9BU1C,EMt9BV9R,UAAA,GNw9BQ8R,EAAY2D,YAAc,SAASpC,EAAMrT,GACvC,MAAK8R,GAAYsD,MAAwC,IAAVpV,EMp9BzD8R,EAAAyD,aAAAzD,EAAA9R,MAAAA,WACA2V,IAAAA,EACA3V,EAAAwU,eAAA1C,EAAAsD,MAAAZ,aACAnB,IAAAsC,EACAtC,EAAArT,eAAA8R,EAAAsD,MAAA5B,aADAmC,QNi9ByC,GAQjC7D,EMr9BR6D,YAAAlB,SAAAA,EAAAvC,GNs9BU,GAAIyD,EAQJ,OM59BVA,KAAA3V,ENs9BY2V,EAAetC,EAAKoB,UAA8B,IAAlBvC,EAAS6B,OAAiC,IAAlB7B,EAASqB,OMn9B7E,IAAAqC,EACAD,EAAA9D,EAAAA,UAAA,KAAAK,EAAAC,KAAA,IAAAD,EAAAqB,OACAsC,IAAA/D,INq9BY6D,EMp9BZtC,EAAAoB,UAAA,KAAAvC,EAAAC,KAAA,IAAAD,EAAA6B,QNs9BiB4B,EAAiC,EAAlBvb,EAAQgX,SAAeuE,EAAiC,EAAlBvb,EAAQiX,SMj9B9ES,EAAAA,aAAA+D,SAAA9Z,EAAAiE,GACA8R,WAAAgE,EAAAA,cACAhE,EAAAgE,eAAAzD,EAAAA,GAEAP,EAAAgE,WAAAtC,EAAAA,INs9BQ1B,EMn9BR+D,eAAA,SAAA9Z,EAAAiE,GNo9BU,GMn9BV8V,GAAAf,GAAAA,MAAAI,EAAAzJ,OAAAtR,GNo9Bc8a,EMn9BdlV,EAAAA,WACA8V,EAAAd,EAAAK,aNo9BcA,EAAUS,EAAQtC,YMl9BhCzT,KAAA+R,ENo9BYgE,EAAQhB,SAASI,EAAQxJ,SAAStR,EAAQmX,SAAU,IAAMxV,GMj9BtEqY,IAAAA,EACA0B,EAAAC,WAAAA,EAAAA,SAAAA,EAAAA,WAAAA,IAAAA,GACA,IAAA/V,GACA+V,EAAAA,WAAAlB,EAAAnJ,SAAAwG,EAAAC,WAAA/X,IAAAA,GNo9BU0X,EMl9BViE,OAAAA,EAAA1D,GAAAA,INo9BQP,EMl9BRsC,WAAA,SAAArY,EAAAiE,GNm9BU,GMl9BV+V,EACAzZ,KAAAT,GNm9BYka,EMl9BZA,GAAAA,MAAAvB,KAAAA,EAAAA,EAAAA,EAAAA,KAAAA,EAAAA,EAAAA,OAAAA,EAAAA,OAAAA,EAAAA,QNm9BY3Y,QAAQS,OAAO4V,GACbC,KMl9Bd4D,EAAA1D,cAEAH,IAAA5V,GNm9BYyZ,EMl9BZA,GAAAA,MAAAvC,KAAAA,EAAAA,EAAAA,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,EAAAA,OAAAA,EAAAA,WAAAA,EAAAA,QNm9BY3X,QAAQS,OAAO4V,GACb6B,OAAQgC,EAAWvB,gBAEF,IAAVxU,IMh9BrB8R,EAAA/Q,GAAAA,MAAAA,KAAA,EAAA,EAAAb,EAAAA,KAAAA,EAAAA,OAAAA,EAAAA,OAAAA,EAAAA,EAAAA,OAAAA,EAAAA,YAEArE,QAAAqL,OAAAwB,GACAzH,OAAAA,EAAAA,gBNm9BU6Q,EM/8BVkE,UNi9BQlE,EAAY/Q,aAAe,SAASb,GAGlC,GMj9BV,UAAA8V,EAAAA,OAAAC,SAAAA,eAAA/V,EAAAc,iBNg9BUd,EAAIe,kBACA2H,EAAS,CM78BvBkJ,GAAAA,GAAAvQ,QAAA/G,QAAA0F,EAAAA,OACAA,YAAA8V,EAAA,GAAAtN,SAAAjG,gBACAzB,EAAAA,EAAAA,UAIAgV,EAAA9U,eAAA,WN+8BQ4Q,EAAYvQ,WAAa,SAASrB,GMz8B1C,GAAA4V,mBAAAhE,KAAAA,EAAAA,WAAAsD,EAAAA,WAAAA,EAAAA,OAAA,CAGA,GAFAlV,EAAAgV,iBACAhV,EAAAgW,kBACAJ,KAAAX,EAAAA,QAEA,WADArD,GAAAqE,MAAAA,EAGA,IAAAC,GAAAA,GAAAvB,MAAA/C,EAAAsD,OACAiB,EAAAA,EAAAhE,WACAiE,EAAApC,EAAAA,EAAAsB,GAAA5U,OAGAyV,EAAAA,EAAA7B,aACA2B,EAAAjV,EAAAkS,EAAAA,GAAAA,ONy8BciC,EAAUS,EAAQtC,aMp8BhC+C,EAAAvE,EAAAkE,EAAAA,GAAAA,OACAM,EAAA,EACAtW,EAAAgB,UAAAsV,KAAAtW,EAAAgB,SACAhB,EAAAgB,EAAAsV,EAAAtV,EAAA,EAAAsU,CACAiB,KACArD,KAAAsD,EAAAA,QAAAtD,EAAAA,EAAAc,EAAAd,EAAAA,EAAAA,EAAAc,EAAAA,KAAAA,EAAAA,UAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GNu8BU,IMr8BV4B,IAAAZ,EAAAA,GAEAgB,EAAAA,CACA,MAAAK,EAAAA,UAAAL,EAAAA,IACA9C,KNo8BclT,EMp8BdgB,UAAAkS,EAAA,ENq8BU,IMp8BV0C,GAAAU,IAAAzB,GAAArJ,EAEAyK,EAAAL,IAAAK,IAAAnC,GAAApT,IAAAA,GAAAA,CACAsV,KAAAK,GNo8BYT,EMn8BZhB,SAAA2B,EAAAD,EAAA9K,SAAAtR,EAAAmX,SAAA,KACAuE,EAAAd,EAAAK,EAAAmB,GAAApc,OAEAuc,GAAA3E,EAAAA,IACAkE,IAAAK,GNm8BYT,EMl8BZf,WAAA2B,EAAAF,EAAA9K,SAAAtR,EAAAoX,WAAA,KACA2E,EAAAE,EAAAvE,EAAAwC,GAAAA,OACAiC,GAAAL,EAAAE,EAAAA,INm8BqBK,GMj8BrB3E,EAAAA,WAAAgE,EAAA1C,EAAAA,SAAAhZ,EAAAqX,WAAA,KACAmF,EAAAL,EAAAT,EAAAS,GAAA3V,OACA1B,GAAAiC,EAAAA,EAAAA,EAAAA,EAAAA,INm8BqBuV,IM97BrBE,GAAAA,EAAAhW,iBACA2V,GAAA3V,EAAAA,EAAAA,EAAAA,GAAAA,EAAAA,GAAAA,EAAAA,INi8BUkR,EM/7BVU,OAAAhY,EAAAqc,GAAAA,GNg8BUD,EM/7BVjE,EAAA,GAAA4D,EAAA,INg8BUrX,EM/7BV0T,WNm9BQ,IM37BRpY,GAAAwQ,EAAAoD,IN47BQ0D,GM37BR7P,KAAA,WN47BU,MM37BVzH,IAAAJ,EAAA0Y,WN47BYtY,EAAQwQ,KAAK,OAAQ,YM17BjC+H,GAAAA,IAAAA,qBAAAA,eAGA+D,IACAhF,EAAAtN,KAAAA,OAAA,QACAhK,EAAA4V,KAAAA,WAAAU,QACAtW,EAAAyO,GAAAA,QAAA6J,QAEAgE,MAGA,IAAAC,GAAAjF,EAAA1Q,OACA0Q,GAAA1Q,QAAA,WACAgP,GAAA5V,EAAAyH,WACA8U,EAAAA,IAAAA,QAAAA,GN27BUD,IAEF,IAAIC,GMv7BZvc,EAAAA,INw7BQsX,GAAY1Q,KAAO,YMt7B3BwH,GAAApO,EAAAyH,KAAA,aAAAzH,EAAAyH,KAAA,cNw7BU8U,IMr7BVvX,EAAAwX,WACAlF,EAAAzQ,UAAA4O,EAAAA,SAAAA,GAAAA,EAAAA,aAAAA,YAAAA,EAAAA,cACA6B,EAAAA,UACAA,GAAAzQ,EAAAA,GAAAyQ,UAAAzQ,EAAAuH,aAEA,GAAApO,INw7BQ,IMt7BRwc,GAAA/G,EAAAA,IAkBAG,ONq6BQ0B,GAAYxQ,KAAO,SAAS2O,GMp7BpC6B,EAAAA,WNs7BcA,EAAYzQ,UAAUyQ,EAAYzQ,SAAS4H,IAAIL,EAAU,aAAe,YAAakJ,EAAY/Q,cMl7B/GgR,EAAAA,UACAA,GAAAA,EAAAA,IAAAA,UAAAA,EAAAA,YAOAjQ,EAAAmO,KAGAG,ENsnBM,GMn/BNA,GAAAlR,6BAAA1B,KAAAA,EAAAA,UAAAA,WACAoL,EAAAxO,eAAAuK,GAAAA,UAAAA,CAgYAxC,OA/XAnH,GAAA8W,OAEA9W,EAAAmY,KAAA/Y,EAAA+Y,oBA4XAjR,EAAAlH,SAAAA,EACAmH,MN86BKL,UM16BL1H,gBAAAA,UAAAA,SAAAA,KAAAA,iBAAAA,cAAAA,cAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GN26BI,GAAIY,GM16BRwC,EAAAA,SN26BQ4S,EAAW,6BAA6B3N,KAAKrD,EAAQ6X,UAAUC,UACnE,QACEhV,SM16BNrG,MN26BMsG,QAAS,UACT5E,KMx6BN6E,SAAAA,EAAA5H,EAAAyH,EAAA3G,GN69BQ,QMx5BRA,GAAA6b,GAEA,GAAAC,QAAAA,OAAAC,GAAA,CNw5BU,GMv5BVC,GAAA/L,MAAAnR,EAAAgX,UAAA,GAAAyD,MAAAwC,EAAA5C,WAAA8C,YAAA,KAAA,EAAA,IAAAnd,EAAAgX,QNw5Bc+F,EAAa5L,MAAMnR,EAAQiX,UAAY,GAAIwD,MAAKwC,EAAW5C,WAAW8C,YAAY,KAAM,EAAG,IAAMnd,EAAQiX,QMt5BvH/V,EAAAqY,GAAA0D,CNw5BU/b,GAAWkc,aAAa,OAAQJ,GMp5B1C9b,EAAAmc,aAAAC,MAAAJ,GAEAhc,EAAA+X,aAAAA,MAAAA,GAEAsE,INs5BUrc,EAAWqY,WAAa0D,IA+C1B,QAASO,KACP,OAAQtc,EAAWqY,YAAcpI,MAAMjQ,EAAWqY,WAAWc,WAAa,GAAKzC,EAAW1W,EAAWqY,WAAYvZ,EAAQ4W,YMvhCnInV,GAAAA,IACA2B,MAAA3B,EN06BQA,SAAQC,SAAU,WAAY,cAAe,aAAc,eAAgB,YAAa,YAAa,QAAS,UAAW,WAAY,OAAQ,YAAa,YAAa,WAAY,aAAc,WAAY,kBAAmB,YAAa,WAAY,aAAc,aAAc,SAAU,gBAAiB,SAAU,WAAY,eAAgB,KAAM,cAAe,cAAe,eAAiB,SAASI,GAC9YL,QAAQ4E,UAAUwB,EAAK/F,MAAO9B,EAAQ8B,GAAO+F,EAAK/F,KAExD,IMt6BRkG,GAAAlG,eNu6BQL,SMt6BRA,SAAA4E,OAAAwB,YAAA,YAAA,YAAA,gBAAA,SAAA/F,GACA9B,QAAA8B,UAAAsB,EAAA+S,KAAAlO,EAAAA,KAAAA,EAAAA,MNu6BYjI,EAAQ8B,IAAO,KMj6B3BL,QAAAgc,SAAA/F,eAAAtX,SAAAc,eAAAlB,UAAAA,SAAAA,GACAA,GAAAA,GAAAyd,KAAAlT,EAAAA,OAAAA,GAAAA,cAAAA,EAAAA,MAAAA,EAEAwO,SAAA/Y,UAAA+Y,EAAAA,MACAnB,EAAAA,GAAAxU,EAAA+S,MAAA8C,EAAApB,OAKAhQ,IAAA7H,EAAA0W,WAAA9V,EAAA8V,aAAA1W,EAAA4W,WAAA,QNk6BQ,IMj6BRxT,GAAAyE,EAAAzH,EAAA6I,EAAAC,ENk6BQlJ,GMj6BRyd,EAAAA,QNk6BQ,IMj6BR1E,GAAAtX,EAAAG,KACAgW,EAAA3O,SAAAgQ,EAAApB,EAAAhB,GNk6BU,MMj6BV4G,GAAAzW,WAAAA,EAAAA,EAAAA,EAAAA,GNm6BYa,GMj6BZ4V,QNk6BUra,EAAM2F,OAAOlB,EAAK0O,OAAQ,SAAStN,EAAUC,GACtCuU,GAAehc,QAAQ4E,UAAU4C,KAClCxH,QAAQG,SAASqH,KAAWA,IAAaA,EAASuN,MAAM,2BM95BxEkH,KAAAC,EACA9F,EAAA7X,ONi6Bcyd,EAAWvW,SAIjB,IAAIwW,GM55BZnT,GN65BUsN,OM55BV7X,EAAAyd,WN65BU1E,KM55BV6E,GN85BQnc,SAAQC,SAAU,UAAW,WAAa,SAASI,GAC7CL,QAAQ4E,UAAUwB,EAAK/F,KMz5BrCsB,EAAA2F,SAAAC,EAAAA,SAAAC,GAEAwU,EAAAvX,SAAAhF,GAAAqY,EAAAA,oBAAAA,EAAAA,GACApI,MAAAsM,EAAAlT,SAAAzI,KAAA2b,EAAAnD,SAEAsD,EAAAA,EAAAX,gBN45BQ7Z,EMx5BR4Z,OAAAA,EAAAE,QAAAA,SAAAH,EAAAA,GACA7b,EAAAkc,OAAAA,EAAA7D,cACArY,GNs6BQA,EMh5BR+b,SAAAA,QAAAA,SAAAA,GNi5BU,GMh5BV/b,ENi5BU,KM94BVqc,EAEAK,MN64BY1c,GAAWkc,aAAa,QAAQ,GM74B5CQ,INg5BU,IM74BV3E,GAAAyE,QAAAG,OAAAA,GAAAZ,EAAAjd,EAAA6W,MAAA0G,EAAArc,EAAAqY,WN84BU,QM74BV0D,GAAArF,MAAAqB,EAAAnC,YN84BY5V,EAAWkc,aAAa,QAAQ,GM54B5CM,IN+4BUE,EM74BVvD,GACA1D,WN64Bc3W,EM74BdA,UACAiZ,EAAAA,EAAAoB,qBAAA4C,EAAAjd,EAAA6W,UAAA,GACAe,EAAAjB,EAAAA,EAAAG,iBAAA9W,EAAA4W,cN+4BUqC,EAAOyE,EAAWG,qBAAqB3c,EAAWqY,WAAYvZ,EAAQ6W,UAAU,GM54B1FoC,WAAAjZ,EAAAya,SN84BmBxB,EAAKoB,UM14BxB,SAAA5Q,EAAAA,SAEAwP,EAAAA,UAAAA,IACAtP,QAAAlI,EAAAsJ,SACA+S,EAAAA,cAEA7E,GAAAtP,MAAAA,ON44BQzI,EM14BRwc,YAAAK,KAAApU,SAAAA,GN24BU,GAAIsP,EAaJ,OAXEA,GM34BZA,QAAAlO,YAAApB,IAAA,OAAAA,EACAmU,IACArc,QAAAkI,OAAAA,GN24BmBA,EMv4BnB+T,WAAAnE,EAAAA,SACAiE,EAAAA,MAAAA,EAAAA,KAAAA,EAAAA,iBNy4B0C,SAArBxd,EAAQ2W,SMr4B7BxQ,GAAAA,MAAA,IAAAA,GNw4BmB,GAAIsU,MAAK9Q,GMl4B5BzI,EAAAA,WAAAqY,EAAApI,qBAAAoI,EAAAc,EAAAA,UNq4BiBmD,MAETtc,EMl4BRuc,QAAAA,WACAzd,EAAAA,IAAAwd,MNu4BQpa,EAAMiH,IAAI,WAAY,WOt9C9B5J,GAAAgd,EAAArT,UAKA4T,EAAAhd,KAEAJ,EAAAI,YPu9CES,QOj9CFmD,OAAAA,4BAAA,kCAAA,sCAAAqZ,SAAAhZ,aAAAiL,WPk9CI,GOh9CJ8N,GAAAE,KAAAzc,WACAb,EAAAa,KAAAA,UACA0c,SAAAC,IAIAC,SAAA/P,IP88CM6B,OO78CN,IP+8CInP,MO58CJ4D,MAAA0Z,UAAAA,YAAAhZ,aAAAA,aAAAA,WAAAA,WAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GPg9CM,QO18CNiZ,GAAAC,EAAAA,GACA,MAAAC,GAAAD,GAAAA,UAAApe,EAAA,GAAAJ,SAAA0T,gBAAAA,EAAAA,cP48CM,QOx8CNsK,GAAAU,GPy8CQ,GOx8CR1e,GAAAge,QAAAS,UAAAA,EAAAA,EPy8Caze,GAAQI,UAASJ,EAAQI,QAAUge,EOt8ChD,IAAAO,GAAAA,EAAAA,EAAAA,QAAAA,QAGAC,EAAAA,EAAAA,EAAAA,EAAAA,QACAC,EAAAA,EAAAA,SAAAA,EAAAA,EACA,IAAAC,EAAAA,GAEA,MADAd,GAAAe,GAAAA,UACAC,EAAAA,EAEA,IACAC,GAEAC,EAOAle,EAGAme,EACAC,EACAb,EACAL,EACAK,EAjBAa,KAKA1O,EAAAA,EAAAA,oBAEAiO,IA+JAxb,OP0yCQwb,GO77CRM,KAAAA,WACAL,KAAAA,QAAAA,EACAC,EAAAA,EAAA5Z,KAAAA,cAAAjF,EAAAme,UACAc,EAAAA,EAAAA,KAAAA,cAAAA,EAAAA,UAGAV,EAAAE,GAAAA,QAAAzd,KAAAqe,4BP47CUnB,EO37CVO,GAAAA,SAAAE,GP47CUJ,EAAShQ,GAAG,SAAU6Q,GACtBH,EAAwBd,EAASnd,KAAKse,aAActf,EAAQme,UOx7CtEQ,EAAA1Z,EAAAoF,IAAA,qBAAA4U,GAGAje,EAAA0d,EAAAA,IAAAA,wBAAAA,GACAO,IACAR,IPw7CYT,EAAMS,GAAYE,IAGtBA,EOr7CR9P,QAAA,WACA+P,KAAAA,UACAC,KAAAA,QAAAA,IPw7CUN,EAAS1P,IAAI,QAAS7N,KAAKqe,4BAC3BnB,EAASrP,IAAI,SAAUsQ,GOn7CjCR,EAAAY,IAAAA,SAAAA,GAGAX,IAGAlO,IAGAwO,SAGAxO,GAAAA,KP+6CQiO,EO16CR7P,cAAAiQ,WP26CU,GO16CVA,EAAAhU,OP06CU,CAGA,GAFA2F,GO16CVsO,EAAAD,EAAAA,YAAAR,EAAA3N,KAAA,eAAA,EP26CUsO,EO16CVxO,KAAAqO,IAAAA,EAAAjQ,YAAA0Q,EAAA5O,KAAA,iBACAF,EAAAqO,EAAArO,GAAAA,WAAAqO,IAAAA,EAAA,GAAAjS,OACA,MAAA6R,GAAAc,iBAAAV,EAAAjQ,GP46CU,KAAK,GAAIA,GAAIiQ,EAAevY,OAAQsI,KOv6C9C6P,IAAAA,QAAAU,YAAAA,EAAAvQ,GAAA4Q,YAAA,OAAAX,EAAAjQ,GAAA4Q,WAGAC,IAAAJ,EAAAzQ,GAAAhC,UPu6CgB4D,EAAYqO,EAAejQ,GAAG4Q,WOl6C9Cf,EAAAc,EAAAA,IAAA/O,EAAAtQ,EAAAA,EAAAA,GAAAA,WACA,MAAA4e,GAAAS,iBAAAV,EAAAjQ,MPs6CQ6P,EOn6CRiB,2BAAA,WPo6CUD,WOn6CVrR,EAAAsR,cAAAC,IPq6CQlB,EAAWc,iBAAmB,SAASrf,GACrC,GAAI4e,EAAc,CAChB,GAAIY,GAAgBjB,EAAWmB,mBAAmBd,EOl6C9DA,KACA5e,EAAAuM,OAAA8I,YAAA,UACAnH,EAAAlO,EAAAyf,OAAAvR,OAAAlO,EAAAyf,EAAAvL,OAAAA,SAAAA,SAAA,OACAlU,EAAAkU,OAAAA,SAAA3H,SAAA8I,YAAA,WAKAuJ,EAAAF,EAAAva,OPm6CUnE,EOl6CVyf,OAAA/S,SAAAA,UACAwB,EAAAlO,EAAAyf,OAAA,OAAAvR,EAAAlO,EAAAyf,OAAAvL,SAAAA,SAAA,OPm6CYlU,EAAQyf,OAAOvL,SAASA,SAAS3H,SAAS,WAG9CgS,EO95CRoB,mBAAAvP,SAAAwP,GP+5CU,MO95CVC,GAAAP,OAAAK,SAAAA,GACA,MAAA/f,GAAAA,SAAAigB,IP+5Ca,IAELtB,EO55CRvO,aAAAsP,WP65CUje,QO35CVC,QAAAod,EAAAoB,SAAAA,GACA,GAAAH,GAAAL,EAAAA,cAAAA,EAAAA,OP45CYO,GAAeP,UAAYK,EAAgB7P,EAAWC,OAAO4P,GAAe/P,IAAM,KOz5C9FmP,EAAAA,QAAAA,OAAAA,EAAAA,YAAAA,EAAAA,WAAAA,EAAAA,EAAAA,UAIAR,EAAAwB,EAAArT,OAAAA,SAAA+S,GACAf,MAAApV,QAAAoV,EAAAA,YAAAhS,KAAAA,SAAAA,EAAAA,GAAA+S,MAAAA,GAAAA,UAAAA,EAAAA,YP45CUV,KAEFR,EO15CRyB,aAAAA,SAAAA,EAAAA,GACAtB,EAAAA,MACAhS,OAAAgS,EP25CYe,OO15CZO,KP65CQzB,EAAW0B,eAAiB,SAASvT,EAAQ+S,GAE3C,IAAK,GO35Cff,GP25CmBhQ,EAAIgQ,EAAgBtY,OAAQsI,KOx5C/C6P,GAAAA,EAAA7P,GAAAhC,SAAAgC,GAAAA,EAAAA,GAAAA,SAAAA,EAAAA,CACAgQ,EAAAA,CP05Cc,OAGJA,EAAgBvT,OAAO6U,EAAU,IAEnCzB,EAAWlZ,SAAW,SAASqJ,GO/4CvCpH,EAAAoH,GAAAnC,SAAA,WAGA7E,EAAAkM,OACA2K,EP+wCM,GO18CNT,GAAAle,QAAAyB,QAAAS,GACAsd,EAAAxf,QAAAI,QAAAJ,EAAAI,KAAAge,oBACAA,EAAAI,QAAAlQ,QAAAtO,EAAAI,SAAAuQ,KP0kDM,OO/4CNvN,OPi5CKsE,UOh5CLjG,eAAA,aAAA,WAAAK,aAAAA,aAAAA,SAAAA,EAAAA,EAAAA,EAAAA,GPi5CI,OACEgG,SAAU,MACV3E,KO/4CNmd,SAAA3B,EAAA3e,EAAAA,GACAsgB,GAAAA,IAEAld,MAAAiH,EPg5CQ5I,SO94CR6e,SAAAD,SAAAA,UAAAvT,SAAA1M,GACAkgB,QAAAlW,UAAAA,EAAAA,MAAAA,EAAAA,GAAAA,EAAAA,KPg5CQ,IO94CRpK,GAAA2e,EAAA3e,EP+4CQsgB,GO94CRA,aAAAtgB,EAAA8M,OAAA1M,GP+4CQgD,EAAMiH,IAAI,WAAY,WAChBiW,IACFA,EAAUD,eAAergB,EAAQ8M,OAAQ1M,GOx4CrDsH,EAAA0C,WAGAtC,EAAA,KACA7G,EAAA,YP44COyG,UOx4CP6Y,mBAAA,aAAA1Y,WAAA,aAAA0Y,aAAA,SAAAtb,EAAAkZ,EAAAjO,EAAAyO,GPy4CI,OACE7W,SAAU,IACV7G,QAAS,SAAkBb,EAASyH,GAClC,GAAIpE,GAAWrD,EAAQ,GAAG2V,iBAAiB,eQpoDnDtU,SAAAhB,QAAAgD,EAAA,SAAA+c,GAIA5f,GAAAA,GAAAA,QAAAA,QAAAA,EACAC,GAAAyT,SAAAzM,KAAA,eAAA,IAAAA,KAAA,cAAA0Y,EAAA1Y,KAAA,gBRuoDEpG,QQloDFwC,OAAA,yBAAA,yBAAA,wCAAAC,SAAA,UAAA,WRmoDI,GQloDJC,GAAAnD,KAAAJ,UACAwD,UAAA,UACAtB,YAAA,SACAuB,YAAA,UACAoc,UAAA,cACAC,YAAAA,yBACAC,QAAA,QACAC,WAAA,EACAC,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACAC,UAAAA,EACAC,gBAAA,EACAC,MAAAA,EACAzS,UAAA,oCRmoDMoS,YAAa,gCQhoDnB7f,QAAA4D,MAGAmc,SAAA/K,OACAgL,UAAAxS,EAEAyS,cAAAE,WR+nDMD,cQ7nDNrb;AR8nDM4I,QQ3nDNzO,ER6nDIgB,MQ1nDJ4D,MAAAxB,UAAAoC,YAAAA,aAAAA,WAAAA,WAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GR6nDM,QQznDNpC,GAAAsC,EAAAA,EAAAA,GR0nDQ,GAAIG,MQxnDZzC,EAAAsC,QAAAA,UAAA9E,EAAA0E,ER0nDQO,GAAUX,EAAS9E,EAASJ,EQxnDpCoD,IAAAA,GAAAge,EAAAphB,MACAoD,GAAAie,YACAje,EAAAke,SACAle,EAAAme,gBAGAne,EAAAoe,aAAA,GR0nDQpe,EQxnDRyC,YAAAJ,EAAAG,SRynDQxC,EAAMie,oBAAsBrhB,EAAQ0gB,gBAAkB1gB,EAAQygB,SAC9Drd,EAAMke,eAAiBthB,EAAQkhB,cQtnDvC9d,EAAAyC,SAAA7F,EAAA4F,QRwnDQxC,EQvnDRA,UAAAmC,EAAAwb,SRwnDQ3d,EQvnDRyC,UAAAF,SAAAC,GRwnDUxC,EAAMmC,aAAa,WACjBM,EAAQJ,SAASG,MAGrBxC,EAAMyC,QAAU,SAASD,EAAOE,GQpnDxC1C,EAAAsJ,aAAA,WACA7G,EAAAA,OAAA6G,MRwnDQtJ,EQpnDR4C,WAAA8I,WRqnDU,MQpnDV1L,GAAAsJ,cRsnDQtJ,EAAMsJ,UAAY,SAAS9G,GACzB,MAAOC,GAAQ6G,UAAU9G,IQjnDnCxC,EAAAqe,WAAAA,WACA,IAAA,GAAA3S,GAAA,EAAAA,EAAA1L,EAAAiC,SAAAmB,OAAAsI,IACA1L,EAAAsJ,UAAAoC,IACA1L,EAAAyC,QAAAiJ,IAOAjJ,EAAAA,YAAA,WACAzC,IAAAA,GAAAiC,GAAAA,EAAAA,EAAAU,EAAAA,SAAAA,OAAAA,IACAF,EAAA6b,UAAAA,IRinDcte,EAAMyC,QAAQiJ,IAIpBjJ,EQ/mDRzC,OAAAsC,SAAA6F,GRgnDUnI,EAAMiC,SQ/mDhBU,ERgnDUF,EQ/mDVzC,sBRinDQyC,EQ/mDR7F,SAAA2gB,SAAAjb,GAUAtC,MAVApD,GAAA2hB,URinDgB9b,EAAQ6G,UAAU9G,GACpBxC,EQjnDdsC,aAAA6F,OAAAnI,EAAAsC,aAAA4F,QAAA1F,GAAA,GRmnDcxC,EAAMsC,aAAagE,KAAK9D,GAEtB5F,EAAQ2gB,MAAMvd,EAAMsC,aAAaib,KAAK,SAASgB,EAAGzB,GQ/mDlEra,MAAAF,GAAAua,KRmnDY9c,EAAMsC,aAAeE,EQhnDjCgc,EAAAlc,cRonDQG,EQlnDR7F,OAAAygB,SAAA7a,GRmnDU,KQlnDV1E,QAAAA,YAAAqF,IAAAb,EAAAtC,GAAAsC,GAAAtC,EAAAwC,SAAAA,QRknDU,CAGA,GAAIjE,GAAQyB,EAAMiC,SAASO,GAAOjE,KAClCyB,GQlnDVwe,OAAAxe,WRmnDYyC,EAAQJ,SAASG,GACb5F,EQlnDhBygB,SACAvf,EAAAlB,cAAAoD,EAAAsC,aAAA8F,IAAA,SAAA5F,GACA1E,MAAAA,SAAAqF,YAAAA,EAAA5E,SAAAT,IACA,KRonDuBkC,EAAMiC,SAASO,GAAOjE,UAG3B3B,EAAQyO,OQ/mD1BrI,EAAApG,cAAAH,IAAAqB,EAAA0E,YAAAC,EAAAA,GAEA7F,EAAAsG,cAAAV,GRknDcC,EAAQqB,UAGZ9D,EQ7mDV3B,MAAAA,EAAAogB,YAAA1Y,UAAAA,EAAAvD,EAAAC,GACAzC,QAAAsC,UAAAA,EAAAxE,WAAAiI,QAAAqC,WAAA7J,EAAAA,WR8mDY3B,EQ7mDZsG,SAAAT,EAAAic,EAAAngB,KRgnDQkE,EQ7mDRzC,mBAAAsC,WR8mDc1F,EAAQygB,SACNhf,QQ7mDhBogB,QAAA3gB,EAAAiI,aACA/F,EAAA3B,aAAAP,EAAAiI,YAAAA,IAAA/F,SAAAiC,GACAjC,MAAAsC,GAAAA,UAAAG,KRgnDczC,EAAMsC,gBQzmDpBM,QAAAA,UAAA9E,EAAAiI,cAAA/F,EAAAiC,SAAAmB,OACApD,EAAApD,aAAAsE,EAAApD,UAAAA,EAAAiI,aR8mDc/F,EAAMsC,aAAe,IAI3BG,EQ1mDR7F,WAAAygB,WR2mDU,MQ1mDVzgB,GAAAoD,WAAAsC,ER6mDiBtC,EAAMiC,SAASmB,QAAUtF,EAAWoI,WAAW9C,QAAUxG,EAAQsE,UAF/DlB,EAAMiC,SAASmB,QAI1BX,EQzmDRD,UAAAA,SAAAA,GACA,MAAA5F,GAAA4F,SACAjE,KAAAF,EAAAiF,aAAArB,QAAAO,GAEAA,EAAAA,eAAAA,GAGAC,EAAAc,UAAAA,SAAAhF,GAEAmE,GAAAc,EACAd,KAAAe,EAAAA,EAAAA,SAAAA,OAAAA,MAEA2H,QAAA9H,OAAAtD,EAAAiC,SAAAO,GAAAjE,MAAAA,KRwmDU,MQtmDVia,IRwmDQ/V,EAAQc,aAAe,SAASb,GQjmDxC,GAHAD,EAAAA,iBACAC,EAAAe,kBAEAf,EAAAgB,CACAhB,GAAAc,GAAAA,QAAAA,QAAAA,EAAAA,OACAd,GAAAe,eAAAA,WRumDQhB,EQlmDRsB,WAAAD,SAAAA,GRmmDU,MAAK,eAAemB,KAAKvC,EAAIgB,UQ/lDvC2Z,IAAA3a,EAAA9F,UACA8F,EAAAc,iBRimDYd,EAAIe,mBQ5lDhB7G,EAAA8G,UAAApB,IAAAI,EAAA1C,QAIA2D,EAAAA,OR6lDe/G,EAAQygB,UAA6B,KAAhB3a,EAAIgB,SAAkC,IAAhBhB,EAAIgB,aQvlD9D9G,EAAAsL,WR2lDgC,KAAhBxF,EAAIgB,SAAkB1D,EAAMsC,aAAe,EAAGtC,EAAMsC,eAAyC,KAAhBI,EAAIgB,SAAkB1D,EAAMsC,aAAe,EAAGtC,EAAMsC,aAAetC,EAAMiC,SAASmB,OAAS,EAA4B,KAAhBV,EAAIgB,SAAkB1D,EAAMsC,aAAetC,EAAMiC,SAASmB,OAAS,EAAGpD,EAAMsC,eAAyBjE,QAAQsJ,YAAY3H,EAAMsC,gBAAetC,EAAMsC,aAAe,GQxlDvWG,EAAAkc,YALAC,EAAArc,OAAAvC,EAAAsC,eRilDU,QAgBFG,EQzlDRoc,MAAAA,WR0lDU,GQzlDVnV,GAAAA,EAAAqH,UAAAA,SR0lDU,OAAO+N,GAAG5W,QAAQ,SAAW,GAAK4W,EAAG5W,QAAQ,YAAc,GAAK4W,EAAG5W,QAAQ,SAAW,GQplDhGzF,EAAA8W,iBAAA3V,SAAAA,GACA,OAAAnB,EAAA,GAAA+Z,cAAAuC,UACAxF,EAAAA,iBACAyF,EAAApiB,2BACA6F,EAAAA,OAAAoB,SRylDQ,IQplDRpB,GAAAoB,EAAAA,IRqlDQpB,GQplDR7F,KAAAA,WRqlDU2c,IACI3c,EAAQygB,UACV5a,EQplDZoB,SAAA0F,SAAA,mBAGAvH,EAAAwX,WACA/W,EAAAqB,SAAAqH,GAAAC,EAAA,aAAA,YAAA3I,EAAAc,cACA3G,EAAAygB,UACArd,EAAAsC,GAAAA,UAAAG,EAAAsB,aAEAtB,GAAAA,GRqlDQ,IQnlDRzF,GAAAyO,EAAA3H,IAoBA,ORgkDQrB,GAAQqB,KAAO,YQllDvB0V,EAAA6D,UAAAhf,QAAAsJ,YAAA7J,EAAAiI,eRolDY/F,EAAMsC,aAAe,IAEvBG,EAAQoB,SAAS4H,IAAIL,EAAU,aAAe,YAAa3I,EAAQc,cQ/kD7Ewa,EAAAvgB,UACAR,EAAA+gB,IAAAA,UAAAA,EAAAA,YAMAzZ,GAAA,IAIA7B,ER24CM,GQznDNzC,GAAAiC,6BAAAA,KAAAA,EAAAA,UAAAA,WACAmJ,EAAAiS,eAAAzb,GAAAwL,UAAAwF,CAgPA7S,OADA4E,GAAAnH,SAAAA,EACAugB,MR4kDKzZ,UQzkDLtE,YAAAA,UAAAA,SAAAA,KAAAA,UAAAA,gBAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GR0kDI,GAAIxC,GQ1kDRigB,EAAAjgB,QR2kDI,QACEkH,SQ3kDNpG,MR4kDMqG,QQ3kDNtG,UR4kDM0B,KAAM,SAAkBC,EAAOhD,EAASyH,EAAM3G,GQxkDpD,GAAA8G,IACAvG,MAAAC,EACAmf,YAAAxa,EAAAwB,YR2kDQpG,SAAQC,SAAU,WAAY,cAAe,aAAc,eAAgB,YAAa,YAAa,QAAS,UAAW,WAAY,OAAQ,YAAa,cAAe,iBAAkB,YAAa,gBAAiB,UAAW,WAAY,gBAAiB,YAAa,KAAM,OAAQ,YAAa,cAAe,cAAe,UAAY,SAASI,GACtVL,QAAQ4E,UAAUwB,EAAK/F,MAAO9B,EAAQ8B,GAAO+F,EAAK/F,KAExD,IQvkDRkG,GAAAlG,eRwkDQL,SQvkDRA,SAAA4E,OAAAwB,YAAA,iBAAA,QAAA,SAAA/F,GACA9B,QAAA8B,UAAAsB,EAAA+S,KAAAlO,EAAAA,KAAAA,EAAAA,MRwkDYjI,EAAQ8B,IAAO,KQjkD3BL,QAAAA,SAAA4E,eAAAgc,SAAA,eAAA,SAAA,YAAA,SAAAvgB,GACA,GAAAkG,GAAAA,KAAAA,EAAAK,OAAAga,GAAAA,cAAAvgB,EAAAsG,MAAA,EACApI,SAAAygB,UAAA5Y,EAAAI,MRqkDYjI,EQpkDZ8B,GAAAsB,EAAA+S,MAAAtO,EAAAI,MRukDQ,IAAIoa,GAAejiB,EAAQyH,KAAK,gBQtjDxC,IAXAzH,QAAAiG,UAAAiI,KACAgU,EAAAliB,KAAAA,GACAkiB,EAAA9Q,UAAA,EAEA8Q,EAAAjO,SAAAjU,GAOAJ,WAAA2F,EAAAA,GAAAE,SAAAzF,cAAAJ,CAEA,GAAA2F,GAAAqc,CACA5hB,GAAAoR,IAAA+Q,UAAAA,QR8jDUniB,EAAUqB,QAAQrB,QAAQ,2DQ1jDpCkiB,EAAA5Z,MAAAA,GR6jDQ,GQ1jDRH,GAAAa,EAAAlI,EAAAA,WAEAyE,EAAAO,EAAA0C,EAAAA,EAAAA,EACA1H,GAAAA,SR0jDUd,EAAQ,GAAGmiB,iBAAiB,OAAQ5c,EAAOoc,iBQrjDrD3e,IAAAA,GAAA4F,EAAAF,OAAAG,GAAAA,QAAAC,OAAAA,IAAAA,MRwjDQ9F,GQtjDRuC,OAAA+b,EAAAA,SAAAA,EAAAA,GACAxgB,EAAAiF,SAAAA,EAAAA,GAAAA,KAAAA,SAAAA,GACAR,EAAAO,OAAA0C,GAGA1H,EAAAiF,cAGA,GRojDQ/C,EQnjDRpD,OAAAA,EAAAygB,QAAAhf,SAAAogB,EAAA3gB,GRojDUyE,EQnjDViE,qBRojDU1I,EQnjDV0E,YRojDW,GACH1E,EQnjDRqD,QAAA9C,WRojDU,GQnjDVmI,GACAA,CRojDc5J,GQnjDdygB,UAAAhf,QAAAogB,QAAA3gB,EAAAiI,cRojDYS,EQnjDZA,EAAA4Y,YAAAhX,IAAA,SAAA7J,GRqjDc,MADAiE,GAAQD,EAAOmc,UAAUngB,GQljDvC,KAAAiE,EAAAD,EAAAH,OAAAH,SAAAO,GAAAuE,OAAA,IACAvE,OAAAD,QAAAmc,WRqjDclY,EQpjDdA,EAAAhE,QAAA5F,EAAA2F,WAAAN,EAAAO,WRojDyBgE,EAASpD,OAAS,KAAOxG,EAAQihB,eAAiBrgB,EAASqgB,eAE3DrX,EAAS4Y,KAAK,QQ/iDvC5c,EAAAjE,EAAAA,UAAA6E,EAAA2C,aRmjDYS,EAAqB,KAAVhE,EAAeD,EAAOH,OAAOH,SAASO,GAAOuE,OAAQ,GQ9iD5E/G,EAAAN,MAAA8G,GAAA5J,EAAA6gB,cAAA7gB,EAAA4gB,WAAAhgB,EAAAggB,aAEA5gB,EAAAygB,WACA9a,EAAA8c,SAAA,SAAA9gB,GRijDY,OAAQA,GAA0B,IAAjBA,EAAM6E,SAG3BpD,EAAMiH,IAAI,WAAY,WSx7D9B5J,GAAAkF,EAAAyE,UAIAxJ,EAAAI,KACAH,EAAA,YT27DEY,QSn7DF1B,OAAAA,0BAAA,2BAAAmE,SAAA,WAAA,WTo7DI,GSn7DJxB,GAAAA,KAAA9B,UACAqD,UAAA,UACAG,YAAA,GACAtB,WAAA,EACAmK,QAAA,EACAyV,UAAA,QACAre,YAAA,2BACA8I,iBAAA,ETo7DMlJ,QAAS,QSj7DfjD,UAAA4D,EAEA9B,MAAA,ETk7DMmK,MS/6DNjN,GTg7DM0iB,QS96DNC,GT+6DMte,MS56DNrE,ET66DMmN,WS56DNwV,ET86DI3hB,MS36DJ4D,MAAA+d,WAAAA,SAAAA,GT46DM,QAASC,GAAexiB,EAASkF,GSx6DvC,GAAAtF,GAAA4iB,QAAAA,UAAAA,EAAAA,GT06DYD,EAAWzd,EAAS9E,EAASJ,ES/5DzC8H,OALAJ,GAAAgb,UAEAG,EAAAA,OAAAA,QAAA7d,EAAA6d,SAGA/a,EAEA3E,MAAAyf,OTq6DKlb,USj6DL1H,aAAAA,UAAAA,OAAAA,WAAAA,SAAAA,EAAAA,EAAAA,GTk6DI,GAAI6iB,GSl6DRzf,EAAAA,uBAAAA,EAAAA,UTm6DI,QACE0E,SSn6DNpG,MTo6DM0B,OSn6DN,ETo6DMD,KAAM,SAAkBC,EAAOhD,EAASyH,GSh6D9C,GAAAG,GACAvG,GACA2B,MAAA3B,EAIAA,SAAAC,SAAA,WAAA,cAAA,aAAA,eAAA,kBAAAI,YAAAA,YAAAA,QAAAA,UAAAA,OAAAA,YAAAA,cAAAA,YAAAA,KAAAA,cAAAA,eAAAA,SAAAA,GACAmG,QAAA5B,UAAAvE,EAAAoG,MAAAC,EAAAA,GAAArG,EAAAsG,KTi6DQ,IS/5DRpI,GAAAoD,eTg6DQ3B,SAAQC,SAAU,OAAQ,YAAa,aAAe,SAASI,GACzDL,QAAQ4E,UAAUwB,EAAK/F,KAASkG,EAAiBK,KAAKR,EAAK/F,MAAO9B,EAAQ8B,IAAO,KS35D/FL,QAAAA,SAAA4E,eAAA+P,SAAA,eAAA,UAAA,SAAAtU,GACA,GAAAkG,GAAAA,KAAAA,EAAAK,OAAA+N,GAAAA,cAAAtU,EAAAsG,MAAA,EACApI,SAAA8M,UAAAjF,EAAAI,MT85DYjI,ES75DZ8B,GAAAsB,EAAA+S,MAAAtO,EAAAI,MTg6DQ,IAAImO,GAAahW,EAAQyH,KAAK,cS15DtCpG,SAAAC,UAAA0U,KACAvO,EAAAQ,KAAA+N,GACAvO,EAAAyE,QAAAxK,ET65DY9B,ES35DZyB,OAAA4E,GT85DQ5E,QAAQC,SAAU,QAAS,WAAa,SAASI,GAC3C+F,EAAK/F,IACP+F,EAAKyE,SAASxK,EAAK,SAASmH,EAAUC,GACpC9F,EAAMtB,GAAOyR,EAAKC,YAAYvK,GAC1BxH,QAAQ4E,UAAU6C,ISx5DpCrB,EAAA,WACAkB,GAAA+Z,EAAAjO,wBAMAhN,EAAApG,WT05DU2B,ESz5DVyf,OAAAA,EAAAA,UAAA,SAAA5Z,EAAAC,GACAzH,QAAAshB,SAAAA,GT05DcthB,QAAQS,OAAOkB,EAAO6F,GSv5DpC7F,EAAAsf,QAAAzZ,EAIApB,QAAA0O,UAAArN,IACA9F,EAAA,WACA2f,GAAAthB,EAAA4E,sBT05Da,GAEDwB,ESv5DZkb,QTw5DU3f,EAAM2F,OAAOlB,EAAK0O,OAAQ,SAAStN,EAAUC,GACtC6Z,GAAYthB,QAAQ4E,UAAU4C,KAC/BxH,QAAQG,SAASqH,KAAWA,IAAaA,EAASuN,MAAM,wBSp5DxE3O,KAAA,EACAzE,EAAA2F,OAEAga,EAAAtM,UAQArT,EAAAiH,UACAjH,EAAA2f,OAAAA,EAAAA,SAAA3Y,SAAAA,GACApK,GAAAyB,QAAA4E,UAAA4C,IACA8Z,EAAAtM,YAAAxN,KTo5DQ8Z,EAAUJ,EAASviB,EAASJ,GAC5BoD,EAAMiH,IAAI,WAAY,WUviE9B5J,GAAAsiB,EAAA3Y,UAIAxJ,EAAAI,KACAyJ,EAAA,YV0iEEhJ,QUpiEFhB,OAAA,4BAAAyD,SAAA,UAAA,WVqiEI,GUriEJtD,GAAAA,KAAAA,UVsiEM6J,YAAa,SACbuY,UAAW,mBUliEjBtb,QAAAA,EAIA1G,MAAA4D,KAAA,WACAkD,OACA3E,SAAAvC,MVoiEK8G,UU/hELjG,YAAA4E,UAAAvE,YAAAA,UAAAA,SAAAA,EAAAA,EAAAA,GVgiEI,GAAIlB,GAAWqiB,EAAQriB,QACvB,QACEkH,SU5hEN,IV6hEM3E,KU3hEN,SAAA+F,EAAAA,EAAAA,EAAAA,GV4hEQ,GU1hERlJ,GAAAkjB,QAAA9iB,KAAAQ,EV2hEQa,SUzhERA,QAAAC,OAAAwhB,KAAAA,GAAAC,SAAAA,GAEA1hB,QAAA2hB,UAAA3hB,EAAArB,MAAA+iB,EAAAA,GAAAA,EAAAA,MV0hEQ/f,EUxhER2F,OAAA/I,WVyhEU,MUxhEVqjB,GAAAC,QVyhEW,SAASra,EAAUC,GACpB,GUxhEVga,GAAA9iB,EAAAmjB,GAAAF,iBAAA,MAAArjB,EAAAgjB,UAAA,IVyhEUvhB,SUvhEV+hB,QAAAnb,EAAAY,SAAAka,GVwhEY,GUvhEZC,GAAAzW,QAAA3M,QAAAyK,GVwhEgB4Y,EUvhEhBD,EAAAvb,KAAA7H,EAAAgjB,WAAAjgB,QAAA,IAAA,MACAqgB,GAAA3N,SVwhEc4N,EAAU,IAAMA,EAAU,IAE5B,IAAIG,GAAS,GAAID,QAAOF,EAAS,IAC7BG,GAAOnb,KAAKY,GACdma,EAAUzW,SAAS3M,EAAQyK,aW/kEzChK,EAAAgV,YAAAzV,EAAAyK,sBXwlEEhJ,QW9kEFsL,OAAA,wBAAA,sBAAA,sCAAA7I,SAAA,SAAA,WX+kEI,GW9kEJnE,GAAAiB,KAAAJ,UACAL,UAAA,UACAmC,kBAAA,UACAyB,YAAA,GACA/D,YAAA,QACAqjB,YAAA,QACArf,UAAA,MACAtB,YAAA,uBACAkE,SAAA,GACA0c,iBAAA,EX+kEMvf,WAAW,EW5kEjBnD,QAAA4D,KAEA6e,UAAA/hB,EACA0C,UAAAye,EACA/f,MAAA6gB,EAEA3c,MAAA4c,EACAF,KAAAG,KX6kEI7iB,MW1kEJ4D,MAAAkf,UAAAA,aAAAA,cAAAA,WAAAA,WAAAA,OAAAA,aAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GXqlEM,QAASC,GAAaze,GAgIpB,QW1hER0e,KAEA5gB,EAAAA,MAAAgD,EAAApG,YAAAH,QAAAmkB,GACAviB,QAAA4E,UAAArG,EAAAgO,SAAAvM,QAAAgF,WAAAzG,EAAAgO,SX0hEYhO,EAAQgO,OAAOgW,GAyBnB,QWjhERL,KXkhEUvgB,EAAMgD,MAAMpG,EAAQH,YAAc,QAASmkB,GACvCviB,QAAQ4E,UAAUrG,EAAQmO,SAAW1M,QAAQgF,WAAWzG,EAAQmO,SW/gE9E6V,EAAAvV,OAAAuV,GXkhEUL,EWhhEVzc,YAAAA,EAAAA,YAAAA,SXihEclH,EWhhEda,WACAmjB,EAAAhd,YAAAA,EAAAA,YAAAA,SAAAA,EAAAA,WA2BA,QAAAid,KACAjkB,EAAAyjB,WACAS,EAAArV,GAAAA,QAAAsV,GACAC,EAAAvV,GAAAA,QAAAsV,GACAC,EAAAvV,GAAAA,QAAAwV,IAIA,QAAAtV,KACA/O,EAAAoE,WACA8f,EAAA3V,IAAA,QAAAyV,GXwgEYI,EAAgBvV,IAAI,QAASsV,GAC7BC,EAAgBvV,IAAI,QAASwV,IAGjC,QWtgERH,KXugEclkB,EAAQoE,UACV8f,EAAa3V,GAAG,QAASyV,EAAO/U,UAGpC,QWngERjP,KACAgkB,EAAA7P,UXogEY+P,EWngEZrV,IAAA,QAAAmV,EAAA/U,UXsgEQ,QAASkV,GAAoBre,GWjgErCA,EAAAue,SAAAA,EAAAA,gBACAzd,WAAAA,EAAAA,SXmgEYod,EAAO7P,QW//DnB6P,EAAAA,QXogEQ,QAASK,GAAoBve,GW9/DrCA,EAAAwe,iBXigEQ,QW//DRA,KXggEcN,EAAOjR,UAA6B,OAAjBmR,IW7/DjCD,IACAC,KXggEcI,IACFA,EAAWrR,WW5/DvBqR,EAAAN,MAMAE,IAEA9gB,EAAAA,SXy/DY8gB,EAAeF,EAAO/c,SAAW,MWpyE7C+c,GAAAA,MAGAtiB,EAAAsiB,EAAAzZ,SAAA9I,QAAAS,UAAAJ,EAAAA,GACA6L,EAAA7L,EAAAsB,SAAAtB,EAAA0R,QAAAxT,GXgkEYoD,EAAQ4gB,EAAOxe,OAASxF,EAAQoD,OAASpD,EAAQoD,MAAM+P,QAAUlO,EAAWkO,MW5jExF/P,GAAAuQ,SAAA3T,EAAAmE,YACAf,EAAAmC,UAAA,QX+jEQye,EAAO3Q,IAAMrT,EAAQ0T,IAAM1T,EAAQI,SAAWJ,EAAQI,QAAQyH,KAAK,OAAS,GAC5EnG,GAAU,QAAS,WAAa,SAASI,GW5jEjDyiB,EAAAziB,KAAAsB,EAAAtB,GAAAyR,EAAAC,YAAAxT,EAAA8B,OX+jEQsB,EW7jER4gB,MAAAhd,WX8jEU5D,EAAMmC,aAAa,WACjBye,EAAO9c,UAGX9D,EW7jER4gB,MAAAvV,WX8jEUrL,EAAMmC,aAAa,WACjBye,EAAOhd,UWvjEnB5D,EAAA8gB,QAAAA,WACA9gB,EAAAkhB,aAAAA,WACAF,EAAAA,YX6jEQJ,EW5jERjR,SAAA3P,EAAA2P,UAAA,CX6jEQ,IW7jER9C,GAAAuU,EAAA/S,EXgkEY2S,EAAkB3iB,QAAQrB,QAAQ,eAAiBJ,EAAQc,YAAc,eAwM7E,OWvwER6M,GAAA6D,KACAsC,SAAAA,QACAkQ,IAAAA,MXikEU/T,KAAM,MW9jEhB+T,OAAAhQ,MAGAvC,MAAAzR,QX+jEQ2N,EW7jERqW,KAAAhd,SAAAA,GX8jEU8M,EAAc/S,EACdijB,EAAOhQ,SWzjEjBgQ,EAAA5Z,KAAAA,WAGAqa,EAAAA,MAGArhB,EAAAghB,aAAA,WACAA,EAAAA,UX2jEQJ,EAAO5Z,QAAU,WWnjEzB4Z,IACAA,IAEAI,EAAA9P,SACA8P,EAAA/P,MXqjEUjR,EWnjEVkR,YXqjEQ0P,EAAOhd,KWnjEf,WXojEU,IWnjEVgd,EAAAhkB,SXmjEU,CACA,GWnjEVsU,GACAD,CX4kEU,IAxBI5S,QWnjEdyS,UAAAlU,EAAAmE,YXojEYmQ,EWnjEZA,EAAAnQ,UXojEYkQ,EWnjEZA,EAAArU,UAAAI,GAAAA,UAAAA,QAAAA,QAAAA,EAAAA,UAAAA,GAAAA,WAAAA,MXqjEgBJ,EAAQmE,WWhjExB+f,EAAAA,EAAAO,EAAAA,WAIAH,EAAAA,EAAAN,IAAAxe,EAAA2N,GAAAA,UAAAA,QAAAA,QAAAA,EAAAA,GAAAA,WAAAA,OAIAnT,EAAAyjB,KAEAS,EAAAA,EAAA1S,SACA4S,GAAA5S,IX8iEU8S,EW9iEVI,EAAAC,OAAAA,OX+iEUT,EAAeF,EAAO/c,SAAW6M,EAAY3Q,KAAKmhB,EAAY,SAAS5P,EAAetR,MW5iEhGwgB,EAAAA,WX8iEYM,EAAa1S,KW3iEzBpO,UAAAgD,EAAA,GAAAvG,IX8iEYukB,EAAgB5S,KW3iE5B/P,UAAA4E,EAAA5E,GAAA2S,IX8iEYwP,MWziEZpP,EAAAA,MAAAxU,EAAAH,YAAA,eAAAmkB,GAAAY,iBX2iEU,CWviEVV,QAAAA,UAAAvX,EAAA3M,eAAA6M,QAAAA,WAAAA,EAAAA,eX2iEY7M,EAAQoU,aAAa4P,GAEvBE,EWxiEV9jB,KXyiEYoU,QAAS,UWriErB7H,SAAA9L,EAAAA,WACAb,EAAAA,aXuiEYkkB,EWtiEZE,SAAAzX,EAAA3M,aAEAkkB,EAAAA,MAAAvX,EAAA3M,EAAAa,OXuiEYY,QAAQrB,QAAQqC,EAAY,gBAAiByhB,EAAa,KAAKvX,SAASmX,EAAW9jB,EAAQ0jB,OWniEvGjX,EAAAiC,YXsiEgB1O,EAAQyjB,UWjiExBhiB,EAAAojB,SAAA7kB,EAAA8kB,mBXoiEYZ,EWliEZvX,SAAA3M,EAAAa,YXoiEcb,EAAQyjB,UWhiEtBO,EAAAjR,MAAAA,EAAAA,EAAA,MAIA3C,QAAA8T,QAAAA,OAAA,EACArB,EAAAA,MAAAA,EAAAvO,EAAAD,EAAAS,GXiiEYrI,EAASiC,MAAMwV,EAAc5P,EAAQD,GAAOlU,KAAK2U,GW5hE7DkP,EAAAhkB,SAAAa,EAAAkS,UAAA,EX+hEU9M,EW9hEV0d,EX+hEU,IAAIvT,GAAK8T,EAAa,EW3hEhCa,GAAAA,WACAhW,EAAAA,UAGA4U,EAAA7O,SAAAA,EAAAA,YAAAA,SACA1R,EAAApD,WACA2jB,EAAAtd,SAAArG,EAAAgO,YAAAvM,SAAAgF,EAAAzG,WX6hEU+kB,IACAhW,OAQFiV,EAAO9c,KAAO,WWrhEtBzF,EAAAkT,WACAlI,EAAAA,MAAAuI,EAAAkP,YAAAjW,eAAAA,GAAAA,mBXyhEcxM,QAAQ4E,UAAUrG,EAAQiV,eAAiBxT,QAAQgF,WAAWzG,EAAQiV,eWphEpFjV,EAAAA,aAAAgkB,GAGAvX,QAAAuI,QAAAoP,OAAAA,EXqhEY3X,EAASuI,MAAMkP,EAAcjW,GWlhEzChI,EAAA7C,MAAAA,GAAAA,KAAAA,GAIA8L,EAAAA,WXmhEY0U,IWhhEZnX,EAAAwB,MAAAA,IAEA+V,EAAAviB,SAAA4E,EAAArG,UAAAmO,EXkhEUlI,EWjhEVkI,GXkhEU8V,IWhhEVN,OAcAK,EAAA7P,OAAA,WACA+P,EAAAA,SXghEYF,EAAO9c,OWzgEnB8c,EAAAgB,QX8gEQhB,EAAO7P,MAAQ,WACb+P,EAAa,GAAG/P,SAElB6P,EWzgERhkB,SAAAyjB,SAAA3d,GACA,KAAAoe,EAAAA,OAAAF,EAAAG,WACAC,EAAAA,OACAA,EAAAA,oBX6jEeJ,EAET,QAAS/d,GAAW7C,GWh/D1BsE,EAAAA,SAAAtE,EAAAiE,OAAAjE,EAAAiE,MAAAD,SAAAhE,EAAA2D,UAGAe,QAAAA,GAAAgO,EAAA1V,GACAgD,MAAA3B,SAAArB,SAAAA,GAAAoQ,GAAAuF,iBAAAD,IXyvDM,GW1kENmP,GAAAxjB,QAAAC,QACAwjB,EAAAlgB,EAAA6d,uBAAA7d,EAAA2a,WX2kEUgE,EAAcliB,QAAQrB,QAAQ4E,EAAQwL,SAASG,MWxkEzDiT,EAAAG,EAEAF,EAAAG,KAGAW,EAAApa,KACAuZ,GACAmB,GAAA7hB,WAEA8hB,GAAA,WXszEM,OW9+DNllB,OXg/DK0H,UWh/DLtH,WAAAA,UAAAA,OAAAA,SAAAA,SAAAA,SAAAA,EAAAA,EAAAA,EAAAA,GXi/DI,OACE0H,SAAU,MACV1E,OWl/DN3B,EXm/DM0B,KWl/DN,SAAAkD,EAAAvE,EAAA9B,EAAA8B,GXm/DQ,GAAI9B,IW/+DZoD,MAAApD,EACAA,QAAA6M,EXi/DU7F,MAAM,EW5+DhBvF,SAAAC,SAAA,WAAA,cAAA,aAAA,eAAAI,kBAAAA,YAAAA,WAAAA,WAAAA,OAAAA,YAAAA,YAAAA,oBAAAA,KAAAA,cAAAA,cAAAA,cAAAA,aAAAA,QAAAA,SAAAA,GACAL,QAAA4E,UAAAwB,EAAA/F,MAAAA,EAAAkG,GAAAA,EAAAK,MAIA5G,EAAAC,aACA1B,EAAAiI,YAAAnG,EAAAqjB,WX8+DQ,IW5+DRnlB,GAAAoD,eX6+DQ3B,SAAQC,SAAU,WAAY,WAAY,OAAQ,aAAe,SAASI,GACpEL,QAAQ4E,UAAUwB,EAAK/F,KAASkG,EAAiBK,KAAKR,EAAK/F,MAAO9B,EAAQ8B,IAAO,KAEvFL,QW1+DRoG,SAAA,eAAA,SAAA,eAAA,UAAA,SAAA/F,GX2+DU,GW1+DV+F,GAAAyE,KAAAxK,EAAAoG,OAAAe,GAAAA,cAAAC,EAAAA,MAAAA,EACA9F,SAAAtB,UAAA0R,EAAAA,MX2+DYxT,EAAQ8B,GAAOsB,EAAM+S,MAAMtO,EAAKI,OWr+D5CxG,QAAAoG,SAAA,QAAA,WAAA,SAAA/F,GACAsB,EAAA2F,IACAlB,EAAApG,SAAAmC,EAAAA,SAAAqF,EAAAC,GACAzH,EAAAA,GAAAS,EAAAkB,YAAA6F,OX4+DYpB,EWx+DZud,SXy+DUhiB,EAAM2F,OAAOlB,EAAKud,QAAS,SAASnc,EAAUC,GWr+DxDmc,QAAArB,SAAAhkB,GAGAI,QAAAyH,OAAA5D,EAAAgF,GAIAoc,EAAAA,QAAAjb,IAEAib,EXo+DQ,IAAIA,GAAQrB,EAAOhkB,EACnBI,GAAQmO,GAAG1G,EAAK5D,SAAW,QAASohB,EAAM5W,QAC1CrL,EAAMiH,IAAI,WAAY,WYn5E9B5J,GAAA4kB,EAAAjb,UAIAxJ,EAAAI,KACAH,EAAA,YZs5EEY,QYj5EFwC,OAAA,2BAAA,2BAAAC,SAAA,YAAA,WZk5EI,GYj5EJC,GAAAnD,KAAAJ,UACAwD,UAAA,UACAtB,YAAA,WACAuB,YAAA,WZk5EM0I,UAAW,cY/4EjB/L,YAAA,6BAEAiD,QAAAma,QACAja,WAAAmhB,EAEAlhB,UAAAmhB,EZ+4EMziB,MY74EN0iB,EZ84EMnhB,MY34ENrE,EZ64EIgB,MY14EJwkB,MAAAA,UAAAplB,aAAAJ,WAAAA,WAAAA,SAAAA,EAAAA,EAAAA,EAAAA,GZ64EM,QYv4ENulB,GAAAzf,EAAAgB,GZg7EQ,QAAS2e,GAAY3f,GY92E7B4B,MAAAA,GAAAoF,SAAA1M,EAAA,GAEA0F,EAAAgH,SAAA1M,EAAA,IAAAolB,EAAAte,OAFAQ,OZs0EQ,GYv4ER5B,MACAA,EAAAe,QAAAA,UAAAA,EAAAA,EZw4EQ2e,GYr4ERE,OAAAjkB,EAAArB,OAAAolB,EAAAve,MAAAkM,QAAA4C,EAAA5C,OZs4EQqS,EYr4ERE,EAAAtlB,EAAAJ,EZs4EQ,IYr4ER2lB,GAAA/f,EAAAA,QZs4EQ4f,GYr4ER9jB,WAAAgkB,SAAA5f,GZs4EU,GYr4EV,UAAAwf,KAAAA,EAAAA,SZq4EU,CACAxf,EAAIc,iBYl4Edd,EAAAA,iBAGA4f,IAAAA,GAAA9f,QAAAuO,QAAAA,EAAAA,SAAAA,GAAAA,iBAAAA,sBZk4EU,IAAKuR,EAAMlf,OAAX,CY53EV,GAAAQ,EACAwe,SAAAxe,QAAA0e,EAAA,SAAAtV,EAAAtB,GACA9H,GAAAA,EAAAA,KAAAA,EAAAA,YAAAA,EAAAA,KAIA5C,KAAA0B,EAAA9F,SAAAwlB,EAAAA,EAAAve,IAAA,KAAAue,EAAAve,SAAArB,EAAA4f,EAAAre,OAAAA,EAAAA,IAAAA,QAAAA,YAAAA,KAAAA,EAAAA,GZ43EUue,EY33EVtH,GAAA7P,GAAA,GAAA4F,UZ63EQ,IY33ERnN,GAAA2e,EAAAC,IZ43EQJ,GAAUxe,KAAO,WYz3EzBA,IACAwe,EAAAte,WACAse,EAAAA,UAAAA,EAAAve,UAAAue,EAAAve,SAAAsH,GAAA,UAAAiX,EAAAre,YACAiX,EAAApe,GAAAoE,QAAAA,IACAga,GAAAA,GACAuH,EAAAC,SAAA,aAAAD,EAAAlQ,SAAAA,QZ43EQ,IAAIvO,GAAOse,EAAUte,IYx3E7Bse,GAAApb,KAAAob,WACAA,EAAApb,WACAgU,EAAAha,UAAAqhB,EAAAA,UAAAA,EAAAA,SAAAA,IAAAA,UAAAA,EAAAA,YACArb,EAAAA,IAAAA,QAAAA,GZ03Ecub,EAASC,SAAS,aAAaD,EAASlQ,YAAY,QYr3ElEvO,KZw3EQ,IYt3ERkD,GAAA0C,EAAA1M,OAiBAgD,OZs2EQoiB,GAAUpb,QAAU,WYp3E5BgU,EAAAoH,IAAAA,QAAAA,GZs3EUpb,KYx2EVob,EZ+zEM,GY14ENpH,GAAAuH,QAAAvlB,QAAAkU,EAAAA,SAAAA,MAIAkR,EAAAre,QAAA0e,UAAA/f,iBAAAA,QAAAA,UAAAA,uBAAAA,QAAAA,UAAAA,oBAAAA,QAAAA,UAAAA,mBAAAA,QAAAA,UAAAA,gBZu7EM,OY32ENggB,OZ62EKpe,UY32EL,cAAAqe,UAAAA,OAAAC,YAAA,SAAAhhB,EAAAuO,EAAAiS,GZ42EI,OACE1d,SAAU,MACV1E,OY32EN,EZ42EMnC,QY32EN6kB,SAAAvlB,EAAAwlB,GZ42EQ,IY32ERD,EAAA/lB,WAAAA,CZ62EU,IADA,GY32EVgmB,GAAAE,EAAAC,GAAAA,YZ42EiBH,GAAwC,IAAzBA,EAAYC,UAChCD,EAAcA,EAAYA,WYt2EtC/lB,IAAAA,EAAAA,UAAAA,MAAAA,KAAAA,QAAAA,kBAAAA,IAAAoD,EAAAA,SAAAA,EAAAA,UZ02EY0iB,EAAO/lB,YAAcD,EYz2EjC2B,EAAAC,WAAAwkB,YAAAH,IZ62EQ,MYx2ER/d,UAAA5E,EAAAhD,EAAAyH,GACApG,GAAAA,IACA2B,MAAA3B,EAIAA,SAAAC,SAAA,WAAA,cAAA,aAAA,eAAA,YAAAI,YAAAA,QAAAA,UAAAA,WAAAA,OAAAA,YAAAA,KAAAA,aAAAA,SAAAA,GACAmG,QAAA5B,UAAAvE,EAAAoG,MAAAC,EAAAA,GAAArG,EAAAsG,KZw2EU,IYt2EVpI,GAAAoD,eZu2EU3B,SAAQC,SAAU,OAAQ,aAAe,SAASI,GAC5CL,QAAQ4E,UAAUwB,EAAK/F,KAASkG,EAAiBK,KAAKR,EAAK/F,MAAO9B,EAAQ8B,IAAO,KAEvFL,QYp2EVsH,SAAAlB,eAAA,SAAAoB,eAAAC,UAAAA,SAAAA,GZq2EY,GYp2EZ9F,GAAAsf,KAAAzZ,EAAAA,OAAAA,GAAAA,cAAAA,EAAAA,MAAAA,EACAxH,SAAA4E,UAAAwB,EAAAI,MZq2EcjI,EAAQ8B,GAAOsB,EAAM+S,MAAMtO,EAAKI,OY71E9C7E,EAAA2F,YZi2EY3F,EYh2EZ2F,OAAAod,EAAAA,WAAA9f,SAAA4C,EAAAC,GACA9F,EAAA3B,QAAAG,IACA,EZk2EU,IAAIukB,GYh2EdX,EAAAplB,EAAAJ,EZi2Ec6H,GYh2Edse,QZi2EY/iB,EAAM2F,OAAOlB,EAAK0O,OAAQ,SAAStN,EAAUC,GACtCid,GAAa1kB,QAAQ4E,UAAU4C,KAChCxH,QAAQG,SAASqH,KAAWA,IAAaA,EAASuN,MAAM,yBY71E1EnM,KAAA,EACA8b,EAAAA,OAEAA,EAAAjf,UZk2EU9D,EAAMiH,IAAI,WAAY,WAChB8b,GAAUA,EAAS/b,Ua/gFnC3I,EAAAojB,KACApkB,EAAA,abshFMgB,QargFNkT,QAAAkQ,MAAA,GAAApjB,QAAAkT,QAAAyR,IAAA,IbsgFI3kB,QargFJ4kB,OAAAA,MAAAA,QAAA3S,SAAAA,UAAAA,WAAAA,SAAAA,EAAAA,GbsgFM,GAAImP,GAAwB7d,EAAQ6d,uBAAyB7d,EAAQshB,6BAA+BthB,EAAQuhB,yBangFlHF,EAAA1a,EAAAA,sBAAAA,EAAAA,4BAAAA,EAAAA,yBAAAA,EAAAA,kCACA6a,IAAAphB,EACAqhB,EAAAD,EAAA,SAAA7a,GbqgFQ,GapgFRvG,GAAAA,EAAAshB,EbqgFQ,OAAO,YACLL,EAAqB3S,KahgF/B,SAAA+S,GbmgFQ,GAAIC,GAAQthB,EAASuG,EAAI,OAAO,EAChC,OAAO,YcniFflL,EAAAkmB,OAAAD,IAQA1lB,Od+hFMylB,GAAIG,UAAYJ,Ec/hFtB5hB,KdmiFEnD,Qc5hFFhB,OAAAT,0CAAAsF,SAAAA,gBAAAA,Wd6hFI,Gc5hFJkD,GAAAA,KAAAqe,Ud6hFMrD,Oc1hFNhN,+Kd4hFIxV,Mc1hFJ4D,MAAAkiB,SAAAA,KAAAA,SAAAA,EAAAA,Gd2hFM,QczhFNC,GAAAA,EAAAA,Gd2jFQ,QcjhFRplB,GAAAyB,EAAA7B,GdkhFU,McjhFVqH,GAAA4C,IAAA,SAAAgL,EAAA5Q,GdkhFY,GclhFZjE,GAAAiE,EAAAuE,IAIA3B,OdihFYjH,GAAOulB,GAAatQ,EACpBrM,EAAQ6c,EAAU5jB,EAAO7B,GACzBI,EAAQslB,EAAQ7jB,EAAO7B,IclhFnC4I,MAAA3B,EdqhFc7G,MAAOA,EcjhFrBulB,MAAAA,KAnDA,GAAAC,MAEAF,EAAAA,QAAAA,UAAAA,EAAAA,EACAze,GAAAY,UAEAZ,IAAAA,GACAA,EACAwe,EACAF,EACAC,EACAI,EACAF,CCxBA3Y,OfgjFQ9F,GcvhFR6D,KAAAmK,WdwhFUhO,EAAcM,OAAS0N,EAAQ3O,EAAK2O,MAAMxW,EAAQwjB,QcrhF5Dhb,EAAAY,EAAAA,EAAA,IAAAoN,EAAApT,IACA0jB,EAAA1kB,EAAAgH,IAAAhG,EAAAA,GduhFU2jB,EcrhFVtlB,EAAAogB,GdshFUsF,EcrhFVve,EAAAA,EAAAA,IAAAA,IdshFUqe,EAAU5a,EAAOmK,EAAM,GAAKA,EAAM,GAAKsQ,GACvC1d,EcrhFVZ,EAAAqe,EAAAA,KduhFQre,EAAcY,SAAW,SAAShG,EAAOlC,GACvC,MAAOmB,GAAGD,KAAKgH,EAAShG,EAAOlC,IAAaf,KAAK,SAASyI,GAKxD,McxhFZJ,SAAAgB,QAAAA,KACApG,MAEAoF,EAAAwe,QAAA5jB,EAAAA,OAAAA,EAAAA,EAAAA,MdqhFmBoF,EAAcqe,WAGzBre,EcjhFRjH,aAAAA,SAAAA,GdkhFU,GcjhFV6B,KdmhFU,OADAA,GcjhFVzB,GAAAA,EACAJ,EAAAulB,IC3DAnb,EAAAA,OAOA2C,EfylFM,MAAO4Y,OAGXzlB,QehlFFrB,OAAAA,wCAAAgnB,QAAA,aAAA,Wf+qFI,Qe7hFJC,GAAAC,Gf8hFM,GAAIA,GAAalnB,EAAQmnB,cephF/BxX,EAAA3P,EAAAA,cAAAonB,CACA,IAAA7lB,EAAAvB,EAAAwR,aAAAA,MAAAA,GAAAA,eACA,MAAA4V,IAAAlZ,EAAA+Y,EAAA,SAAA,WAAA1b,EAAA6F,IAAA6V,EAAA,aACA1lB,EAAA6P,EAAA6V,YfuhFM,OerhFN1lB,IAAAvB,EAAAqQ,gBfg7EI,GehlFJ9O,MfilFQ2M,EehlFRmZ,EAAAA,SAAAC,SAAAtnB,EAAAsL,GfilFM,MehlFN/J,GAAA8lB,UAAAC,EAAAtnB,SAAAwQ,gBAAAA,EAAAA,cfusFI,OArHAjF,GAAG6F,IehlFP7P,SAAAvB,EAAAwQ,EAAAA,GfilFM,GAAIjP,EAQJ,OANEA,GejlFRvB,EAAAunB,afilFgBvnB,EAAQwnB,aAAahX,GexkFrC6W,EAAAC,iBACAG,EAAAznB,iBAAAuP,GAAAA,GAEAvP,EAAA0nB,MAAAlX,GAEAb,KAAA8X,EAAA9X,WAAA3P,IAAAwR,EAAAA,Gf2kFIjG,EAAGwE,OezkFP0X,SAAA5X,Gf0kFM,GAAI4X,GAAUznB,EAAQuP,wBAClB2X,EAAalnB,EAAQmnB,ae/jF/B5b,QACAmE,MAAAiY,EAAAA,OAAAA,EAAAA,YACAhY,OAAAiY,EAAAA,QAAAA,EAAAA,aACAhY,IAAAiY,EAAAA,KAAAA,EAAAA,aAAAA,EAAAA,gBAAAA,YAAAA,EAAAA,gBAAAA,WAAAA,GACAhY,KAAAiY,EAAAA,MAAAA,EAAAA,aAAAA,EAAAA,gBAAAA,aAAAA,EAAAA,gBAAAA,YAAAA,KfmkFIvc,EehkFJyF,UAAA+W,SAAAA,EAAAA,EAAAA,GACA,GAAApX,GACAqX,EACA7W,EAGAR,EACA3Q,Ef+jFUioB,Ee5jFVC,EACAL,EAAAzW,EAAAA,IAAApR,EAAA,YACAioB,EAAA1c,QAAAvL,QAAAA,GACA+nB,IAKAA,YAAAA,IACAJ,EAAAA,MAAApc,SAAAoF,Yf2jFMuX,EezjFNP,EAAAA,OAAAA,Gf0jFME,EezjFNtc,EAAA6F,IAAApR,EAAA,Of0jFMioB,EezjFN/U,EAAAA,IAAAA,EAAA2U,Qf0jFME,GezjFNE,aAAA/U,GAAA,UAAAvC,KAAAkX,EAAAI,GAAA/c,QAAA,QAAA,Gf0jFU6c,GevjFVJ,EAAAthB,EAAAA,SAAAzG,GACAA,EAAAA,EAAAuoB,IfyjFQP,EAAUD,EAAY9X,OerjF9BsB,EAAAvB,WAAAA,IAAAsY,EfwjFQN,EAAU1U,WAAW+U,IAAe,GerjF5C9W,QAAAtB,WAAAA,KfwjFQjQ,EAAUA,EAAQuoB,KAAKnoB,EAAS0O,EAAGwZ,IepjF3CC,OAAAvoB,EAAAqR,MfujFQE,EetjFRvB,IAAAhQ,EAAAgQ,IAAAsY,EAAAtY,IAAAkY,GAEA,OAAAlY,EAAAuB,OfujFQA,EetjFRtB,KAAAsB,EAAAtB,KAAAqY,EAAArY,KAAA+X,GfwjFU,SAAWhoB,GACbA,EAAQqR,MAAMkX,KAAKH,EAAS7W,Ge5iFpC6W,EAAAI,KAAAxY,IAAAuB,EAAAvB,IAAA,KAAAC,KAAAsB,EAAAtB,KAAA,QfojFItE,Ee/iFJoF,SAAA3Q,SAAAA,GfgjFM,GepiFNqoB,GACAD,EAVArY,Gf8iFQH,Ie5iFR,EAGAyY,KAAAA,EA4BA,OfkhF0C,UAAhC9c,EAAG6F,IAAIpR,EAAS,YeriF1BooB,EAAAA,EAAAxY,yBfwiFQyY,EAAiBC,EAAoBtoB,GeniF7C+P,EAAAxE,EAAAwE,OAAA/P,GACA0P,EAAA1P,EAAA2R,UACAhC,EAAA6B,EAAAA,OAAAA,IAEA3B,EAAAA,KAAAuY,EAAAA,IAAAA,EAAAhX,kBAAA,GfqiFQgX,EAAiBvY,MAAQtE,EAAG6F,IAAIiX,EAAgB,mBAAmB,Ke1hF3E3Y,MAAAwX,EAAAlnB,YACA2P,OAAAsX,EAAAA,aACArX,IAAA1B,EAAA+Y,IAAAA,EAAArX,IAAArE,EAAA6F,IAAA8V,EAAA7W,aAAAA,GACAR,KAAAoX,EAAAA,KAAAA,EAAAA,KAAAA,EAAA7V,IAAApR,EAAAoR,cAAA6V,KfyiFI1b,EerhFJoE,OAAApO,SAAAA,EAAAA,GfshFM,GAAIA,GAAQvB,EAAQwR,YAMpB,OelhFN9B,GACAnO,GAAAA,EAAAvB,IAAAA,EAAA2R,aAAAA,GAAAA,EAAAA,IAAAA,EAAAA,gBAAAA,GAEApQ,GAAAgK,EAAA6F,IAAApR,EAAA,cAAA,GAAAuL,EAAA6F,IAAApR,EAAA,iBAAA,GAAAuL,EAAA6F,IAAApR,EAAA,kBAAA,GAAAuL,EAAA6F,IAAApR,EAAA,qBAAA,GAEAuB,Gf+gFIgK,Ee7gFJmE,MAAAnO,SAAAA,EAAAA,Gf8gFM,GAAIA,GAAQvB,EAAQ2R,WgBltF1B,ODuMAyV,Gf6gFQ7lB,GAASgK,EAAG6F,IAAIpR,EAAS,cAAc,GAAQuL,EAAG6F,IAAIpR,EAAS,eAAe,GgBttFtFuB,GAAAgK,EAAAgd,IAAAA,EAAAC,eAAAA,GAAAA,EAAAA,IAAAA,EAAAA,gBAAAA,GAAAA,EAAAA,IAAAA,EAAAA,mBAAAA,GAAAA,EAAAA,IAAAA,EAAAA,oBAAAA,GAEAjnB,GAEAgK,IhB0tFElK,QgBxtFFhB,OAAAqS,sCAAAsU,QAAA,YAAA,WAAA,SAAAhiB,GhBytFI,MgBxtFJA,UAAAuhB,EAAA7T,EAAAA,GhBytFM,GAAIA,GAAU,IACd,OgBxtFNA,YhBytFQ,GgBxtFRA,GAAA9R,KACA6nB,EAAAD,UACAD,EAAA7kB,IAAA+kB,CAkBA,OhBusFY/V,IACF1N,EgBxtFVuhB,OAAA7T,GhB0tFQA,EgBxtFRhP,EAAAglB,WhBytFUhW,EAAU,KgBvtFpBA,GhBytFY6V,EAAK7kB,MAAMglB,EAASD,IgBjtFhCzB,GAAA,GACA2B,GACAjW,EAAAA,MAAAgW,EAAAD,GAEA/V,OhBstFOsU,QgBntFPtU,YAAA,WAAA,SAAA1N,GhBotFI,MgBntFJ,UAAApF,EAAAgpB,EAAAA,GhBotFM,GAAIlW,GgBntFVhP,IhBqtFM,OADK9D,KAASA,MgBltFpB8S,WhBotFQ,GgBntFRA,GAAA9R,KACA6nB,EAAA7oB,ShBotFa8S,KACC9S,EAAQgpB,WAAY,GACtBL,EgBntFZM,MAAAH,EAAAD,GhBqtFU/V,EAAU1N,EAAS,WACjB0N,EAAU,KACN9S,EAAQkpB,YAAa,GiBtwFrCzoB,EAAAqD,MAAAglB,EAAAD,IAOAM,GAAA,SjBuwFE1nB,QiBlwFFT,OAAAia,wCAAA/W,SAAA,eAAA,kBAAA,SAAAklB,GjBmwFI,QiBlwFJC,KjBmwFMroB,KAAKmoB,KAAO,KiBhwFlBG,KAAAA,MAAAzD,EAAA7kB,KAAAqoB,IAAAA,EjBmwFMroB,KAAK8Z,MAAQ,EiBlwFnBwO,KAAAA,QAAAzD,EAAA7kB,KAAAia,QAAAtZ,EjBqwFMX,KAAKqoB,aAAe,EAwCtB,QiB3wFJE,MjB4wFI,QiB3wFJhiB,GAAA6L,GjB4wFM,OiB5wFNjC,MAAArC,WAAAA,KAAAA,SAAAA,GjB8wFI,QAAS0a,GAAuBjiB,EAAO5F,GiBzwF3C,IAAAf,GAHA6oB,GAAAliB,EAAAf,OjB8wFUkjB,EAAM/nB,EAAMgoB,WAAWvW,ciB3wFjCxS,EAAAI,EAAAJ,EAAAI,EAAAJ,IACAiX,GAAAA,EAAA/I,GAAAsE,gBAAAsW,EACAE,MAAA9a,EAKA,OAAA+a,GjBwtFIP,EiBtwFJvO,UAAApZ,gBAAAA,SAAAA,GjBuwFMX,KAAKqoB,aAAe1nB,GAEtB2nB,EiBxwFJxO,UAAAnZ,WAAAA,SAAAA,GjBywFMX,KAAKia,QAAUtZ,GAEjB2nB,EiB1wFJtoB,UAAA8Z,WAAAA,SAAAA,GjB2wFM9Z,KAAK+Z,QAAUpZ,GAEjB2nB,EiB5wFJQ,UAAAnoB,SAAAA,SAAAA,GjB6wFMX,KAAK8Z,MAAQnZ,GAEf2nB,EiB9wFJS,UAAApoB,SAAAA,WjB+wFM,MAAOX,MAAK8Z,OAEdwO,EiBhxFJH,UAAAxnB,QAAAA,SAAAA,GjBixFMX,KAAK8oB,IAAMnoB,GAEb2nB,EiBjxFJH,UAAAa,SAAAA,SAAAA,GACAhpB,KAAA+oB,MAAApoB,GjBmxFI2nB,EiBjxFJxO,UAAAnZ,YAAAsW,SAAAA,GACAjX,KAAA+Z,KAAAA,GjBmxFIuO,EiBjxFJD,UAAAA,SAAA/P,SAAAA,GAaA,MAZAtY,MAAAmoB,KAAAnoB,EAAAA,cjBkxFMA,KAAK+oB,MAAQpoB,EAAMsoB,WiB/wFzBX,KAAAA,IAAAzD,EAAAA,UACA7kB,KAAA8Z,MAAAL,EAAAzZ,WjBixFMA,KAAK+Z,QAAUpZ,EAAMyY,aiB9wF3BpZ,KAAAkpB,QAAAZ,EAAAzD,aAEA7kB,KAAAqoB,aAAAE,EAAAA,kBAGAY,MjB8wFIb,EAAUzD,UAAUuE,OAAS,WiB1wFjC,MAAAZ,IAAAA,MAAAA,KAAAA,KAAAA,KAAAjiB,MAAA5F,KAAAA,IAAAA,KAAAA,MAAAA,KAAAA,QAAAA,KAAAA,QAAAA,KAAAA,cjB6wFI,IiB3wFJuoB,GAAAvoB,EAAAgoB,UAkBA/oB,EAAA+c,KAAAA,UjBywFM9F,OiBtwFNwS,YjBuwFMT,QiBtwFNU,EjBwwFItpB,MAAK4D,MiBtwFT5E,UAAA4pB,aAAA,SAAAW,EAAAC,GjBuwFM,GiBtwFNC,GAAA,SAAAnlB,GjBk5FQ,QiBvuFRolB,GAAA7S,GACA,GAAA8S,GAAAA,EAAAC,EACA,OAAAC,GAAAC,GjByuFQ,QiBtuFRrpB,GAAAoW,GjBuuFU,GiBtuFVkT,GAAAC,EAAAnT,GACAoT,EAAAC,EAAAD,QAAAA,MAAAA,QjBuuFcP,EiBtuFd,kBAEAC,EAAAC,EAAApkB,MAAAsI,GjBsuFc+b,EiBruFdhd,OAAAgd,KAAAA,GjBsuFcM,IAWJ,OAVA1pB,SAAQC,QAAQipB,EAAa,SAASM,GiBpuFhDE,GAAAA,EAAAF,GjBsuFcA,EAAOC,EAAuBD,OAE9B,KAAK,GAAInc,GAAI,EAAGA,EAAI+b,EAAarkB,OAAQsI,IiBluFvDmc,EAAAG,EAAAA,MAAAA,EAAAC,IAAAA,KAAAA,KAAAA,EAAAA,IAaAF,GAAAH,KAAAA,KjB2tFiBG,EAAe3I,KAAK,IAE7B,QiBxtFR6I,GAAAA,GjBytFU,MAAOA,GAAKtoB,QAAQ,MAAO,UAAUA,QAAQ,KAAM,OAAOA,QAAQ,MAAO,OAAOA,QAAQ,MAAO,OAAOA,QAAQ,MAAO,OAAOA,QAAQ,MAAO,OAAOA,QAAQ,MAAO,OAAOA,QAAQ,MAAO,OAAOA,QAAQ,MAAO,OAAOA,QAAQ,OAAQ,SAEtO,QiBvtFR8nB,GAAAC,GACA,MAAAQ,SAAAC,KAAAA,GjBytFQ,QiBrtFRD,GAAAD,GjBstFU,MAAOA,GAAKtoB,QAAQ,WAAY,MAElC,QAASyoB,GAAoBD,GiBhtFrC,IAAA,GAFAV,GAAAY,OAAA5T,KAAAA,GACAyT,EAAAI,EACAC,EAAAA,EAAAA,EAAAA,EAAAL,OAAAA,IjBotFYA,EAAKA,EAAGzd,MAAM,KAAOiB,EAAI,KAAK0T,KAAK,IAAM6H,EAAUQ,EAAa/b,IAAM,IiBhtFlF,OAAA+b,IAAAA,QAAAA,IAAAe,EAAAd,KAAAT,MjBotFQ,QiBltFRwB,GAAAA,GACA,GAAAC,GAAAA,EAAAA,EACA,OAAAC,GAAAA,GjBotFQ,QiBltFRC,GAAAA,GjB0tFU,IiBvtFV,GAEAD,GACAE,EAEAD,EjBgtFcC,EiBrtFdpB,EAAAgB,OAAAK,KAAAA,GACAJ,EAAAD,GAAAA,QAAA,cAAA,KAOAG,KjB+sFqE,QAAnDH,EAAcK,EAAYC,KAAKZ,KiB5sFjD5N,EAAA3J,EAAAA,GACA+X,EAAApO,EAAAA,GjB8sFYsO,EAAgBG,EAASL,GiB1sFrCC,EAAAnC,KAAAA,EjB6sFU,OAAOmC,GArMT,GiBjtFRrO,GACA0O,EAtDAC,EAAA1C,QAAA1nB,UAAAtB,EAAA0E,GACAinB,KACAC,GACAC,IAAA,WACAC,GAAA1sB,aACA2hB,EAAA3hB,EAAA4pB,OAAA,cAAA,mBACA+C,GAAAA,aACAC,EAAAA,EAAArC,OAAAsC,cAAAC,mBACAC,GAAA,mBACAC,EAAAhtB,EAAA4pB,OAAA,iBAAA,oBACAqD,GAAAA,oBACAC,EAAAA,EAAA3C,OAAAsC,eAAAM,iBACAC,EAAAA,QACAC,KAAArtB,EAAA4pB,iBAAA0D,IAAA9K,KAAA,KACA+K,IAAAA,EAAAV,iBAAAC,SAAAtK,KAAA,KACAgL,GAAA,yBACAC,EAAAztB,EAAA4pB,OAAA,yBAAA,2BjBuwFUqD,KAAM1C,EAAQsC,iBAAiBa,MAAMlL,KAAK,KiBpwFpD0K,IAAAd,EAAAA,iBAAAA,WAAAA,KAAAA,KACA9B,GAAAA,gBACAzgB,EAAAA,EAAA+Q,OAAAA,eAAAA,iBACA+S,KAAAzD,gCACAO,GAAAP,WACAoC,EAAApC,EAAAvP,OAAAA,wBAAAA,kBAEA6R,GACAC,IAAAvC,EAAAxP,gBACAgS,GAAAxC,EAAAxP,WACAiS,EAAAA,EAAApD,WACAqD,GAAAA,EAAArD,WACAwD,EAAAA,EAAA7C,WACA8C,GAAA9C,EAAA0D,SACAjM,EAAAuI,EAAAxP,SjBswFU+R,GiBtwFVvC,EAAApP,SjBuwFU4R,EiBvwFVxC,EAAAlpB,SjBwwFU2rB,KAAMpD,EiBvwFhB0D,IAAAA,EjBywFUF,GiBzwFV7C,EAAAlpB,QjB0wFUgsB,EAAG9C,EAAM0D,QiBzwFnBV,EAAAA,SAAAvrB,GAAA,GAAAmZ,GAAA+S,KAAAA,WAAArE,EjB4wFY,OAAOxoB,MAAK0Z,SAAS/Y,EAAM6U,MAAM,OAASsE,EAAQ,GAAKA,IAEzDmS,KiB7wFV,SAAAY,GjB8wFY,MAAO7sB,MAAK6sB,SAASrE,EAAuBe,EAAQsC,iBAAiBa,MAAO/rB,KAE9EurB,IiB/wFV,SAAAW,GjBgxFY,MAAO7sB,MAAK6sB,SAASrE,EAAuBe,EAAQsC,iBAAiBM,WAAYxrB,KiB9wF7F6rB,GAAA,SAAA7rB,GAAA,MAAAX,MAAAmc,SAAAA,EAAAxb,EAAA,IACA8rB,EAAA,SAAA9rB,GAAA,MAAAX,MAAAW,SAAA,EAAAA,EAAA6E,IjBqxFU+mB,KAAMrD,EAAM/M,YiBjxFtBqQ,GAAAM,SAAAA,GACAzB,MAAAA,MAAAA,YAAAA,IAAAA,EAAAA,IAGA1O,EAAAA,SAAAoQ,GACAD,MAAAE,KAAAA,EAAAA,GAAAD,IAAApQ,EAAAA,OAAAoQ,KAAAA,YAAAA,IAAAA,EAAAA,GAAAA,KAAAA,YAAAA,EAAAA,ICnHA,OlBy4FQpQ,GiBhxFRmQ,KAAAzlB,WjBixFUsV,EAAYoQ,QAAUxD,EAAQsC,iBAAiB7sB,EAAQ6X,SAAW7X,EAAQ6X,OiB9wFpF8F,EAAAA,EAAAA,EAAAsQ,SAEA5B,EAAAxU,EAAA0S,EAAAsC,UjBgxFQlP,EiB9wFRuQ,QAAArW,SAAAmW,GACA,MAAAG,SAAAA,OAAAtW,IAAA4T,MAAAA,EAAA5T,WACA9R,EAAAA,KAAAmoB,IjBgxFQvQ,EiB7wFR1E,MAAAgV,SAAA9c,EAAA8c,EAAA5T,EAAAxD,GACAgB,IAAA/I,EAAA/I,EAAAS,iBAAAqR,IAAAA,GACApW,QAAA0sB,OAAArf,KAAAqf,EAAAA,EAAAlV,EAAAlT,GAAA4X,EAAAoQ,QAAAlX,GjB8wFU,IAAIqX,GAAcrW,EAASmW,EAAgBnW,GAAUiW,EiB3wF/DpS,EAAA0O,EAAAA,EAAAA,GAAAA,EAGA9Y,EAAA2H,EAAAkT,KAAAzQ,EjB2wFU,KiB1wFV3V,EAAA,OAAA,CAGA,KAAA,GjBwwFckT,GAAOgV,IAAa9c,MAAM8c,EAAS5T,YAAa,GAAIiP,IAAY8E,SAASH,IAAY,GAAI3E,IAAY8E,SAAS,GAAI3T,MAAK,KAAM,EAAG,EAAG,IiBxwFjJiB,EAAAA,EAAAA,EAAAA,EAAAA,OAAAA,EAAAA,IjB0wFgByS,EAAarf,IAAIqf,EAAarf,GAAGyZ,KAAKtP,EAAMlT,EAAQ+I,EAAI,GiBtwFxE,IAAAmK,GAAAA,EAAAA,QAEA,OAAAtX,UAAAA,EAAAmoB,IAAA,MAAApO,EAAA2S,WACAC,EAEA5S,GjBywFQiC,EiBvwFR4Q,oBAAA,SAAAzsB,EAAAH,GjBwwFU,GiBvwFVsX,EjBwwFU,IiBvwFVxX,UjBuwFcE,EiBvwFdC,CACAqX,GAAAA,GAAAnX,GAAA2Y,KjBwwFYxB,GiBvwFZ,GAAAwB,MAAA6T,EAAAtE,cAAAsE,EAAArE,WAAAqE,EAAAD,WAAA,YAAAvsB,EAAA,EAAA,GAAA,EAAA,EAAA,EAAA,YAAAA,EAAA,EAAA,QjBywFYmX,GiBxwFZxX,QAAAE,SAAAA,IAAAA,EAAAA,MAAAA,UjBwwFmB,GAAI8Y,MAAK9Y,EAAM6sB,OAAO,EAAG7sB,EAAM6E,OAAS,IiBrwF3DyS,EAAAA,GjBuwFmB,GAAIwB,MAAKnJ,SAAS3P,EAAO,KiBpwF5C8sB,QAAAA,SAAAA,IAAA9sB,IAAAA,EAAAG,OACA+W,YAAAA,IAAAA,EAAAA,KAAAA,EAAAA,GAGA,GAAA4B,MAAAA,EjBswFU,OiBpwFV5B,IjBswFQ8E,EiBpwFR8Q,oBAAA9sB,SAAAwb,EAAAA,GjBqwFU,GAAItE,EiB7uFd,OjB+uFYA,GiBrwFZ/W,QAAA+W,GACA,GAAA4B,OAAA0C,YAAA,KAAA,EAAA,GACAQ,QAAAA,SAAAhc,IAAA8Y,EAAAjE,MAAA,UjBqwFmB,GAAIiE,MAAK9Y,EAAM6sB,OAAO,EAAG7sB,EAAM6E,OAAS,IAAI2W,YAAY,KAAM,EAAG,GiBlwFpFtE,EAAAA,GjBowFmB,GAAI4B,MAAKnJ,SAAS3P,EAAO,KAAKwb,YAAY,KAAM,EAAG,GiBxvFtEuR,QAAAA,SAAAA,IAAAzV,IAAAtX,EAAAsX,OACA,YAAAA,IAAA/B,EAAAA,KAAAA,EAAAA,GjB2vFmByG,EAAYI,MAAMpc,EAAO,GAAI8Y,MAAK,KAAM,EAAG,EAAG,KiB9uFjEkD,EAAAE,qBAAA,SAAA5E,GACA,MAAAA,IAIAA,EAAApC,SAAAA,EAAAA,WAAA,GAAAoC,EAAAhB,WAAA,EAAA,GACAgB,GAJA,MjBuvFQ0E,EAAYE,qBAAuB,SAAS5E,EAAMpC,EAAU8X,GiBhvFpE,MAAA1V,IAYAqS,GAAAI,QAAAA,IACAzS,EAAAuS,GAAAA,MAAAA,EAAAA,WjByuFYvS,EAAK0B,WAAW1B,EAAKmB,cAAgBuU,EAAO,GAAK,GAAK1V,EAAK2V,sBiBruFvE7D,GjBiuFmB,MkB58FnB/pB,EAAA6tB,OACAtE,EAKAvpB,OAAA8tB,QlBghGErtB,QkB5gGFstB,OAAAA,2CAAAhW,QAAAA,kBAAAA,UAAAA,aAAAA,SAAAA,EAAAA,GlBshGI,QkBvgGJiW,GAAApY,GlBwgGM,MAAO,wCAAwCuV,KAAKtU,GAAQzP,MAAM,GAVpEpH,KkB5gGJ6tB,iBAAAhC,WlB6gGM,MAAOtC,GAAQ7W,IAEjB1S,KkB3gGJ8tB,kBAAA,SAAAjX,EAAAkB,GlB4gGM,MAAOwR,GAAQsC,iBAAiBhV,IAAWA,GAE7C7W,KkBzgGJ+tB,cAAAC,SAAApY,GlB0gGM,MAAO2T,GAAQsC,iBAAiBC,UAKlC9rB,KkBrgGJwY,YAAAwV,SAAApY,GlBsgGM,MAAOoY,GAAgBpY,GAAY,IAErC5V,KkBngGJ4Y,cAAAoV,SAAApY,GlBogGM,MAAOoY,GAAgBpY,GAAY,IAErC5V,KkBjgGJ6Y,cAAAmV,SAAApY,GlBkgGM,MAAOoY,GAAgBpY,GAAY,IAErC5V,KkB//FJ0Y,cAAAsV,SAAApY,GlBggGM,MAAOoY,GAAgBpY,GAAY,IAErC5V,KkB9/FJ8Y,YAAA0Q,SAAA3S,GlB+/FM,QAASmX,EAAgBpY,GAAY,IEtjG3CnV,KAAAA,OAAA,SAAAmV,GAGA,QAAA7S,EAAA1B,GAAAR,IFwjGIb,KEz/FJ4W,WAAArX,SAAA0Y,EAAApB,EAAA7X,EAAAA,GF0/FM,MEz/FNmB,GAAA8X,EAAApB,EAAAhB,OF4/FEpV,QAAQhB,OAAO,0BAA2BwuB,QAAQ,cAAelrB,GAwFjEtC,QG3oGF0C,OAAA,6BAAA,oCAAA,uCAAA,2BAAAD,SAAA,cAAA,WH4oGI,GG3oGJE,GAAApD,KAAAJ,UACAkC,UAAA,UACAuB,YAAA,aAEAqS,UAAA,cACAwY,YAAA,iCACAC,QAAAA,QACAtY,WAAA,EACAuY,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACAC,WAAAA,EACAC,SAAAA,OACAC,WAAAA,YACAC,SAAAA,KACA3Y,gBAAA,KACA4Y,UAAAzY,KACA0Y,YAAA1Y,MACA2Y,WAAA,OACAC,iBAAA,YACAC,gBAAA,OACAC,cAAAA,EACAC,WAAA,EACAC,UAAAhZ,EAAAA,GACAiZ,UAAAjZ,EAAAA,GACAkZ,UAAA,EH2oGMN,QAAS,EGxoGf9uB,UAAA4D,EAEAorB,mBAAA,GACAC,UAAAzhB,EACA0hB,UAAAtvB,EAEAuvB,SAAAE,mCHwoGMD,UGtoGNE,oCHwoGItvB,MGtoGJ4D,MAAA5E,UAAAswB,YAAA/lB,aAAAA,OAAAA,iBAAAA,kBAAAA,WAAAA,WAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GH0oGM,QGnoGN+lB,GAAAC,EAAAC,EAAAA,GAoKAF,QAAAA,GAAAlgB,GACAA,EAAAxG,SAAAoM,EAAAU,YAAAtG,EAAA6I,MH2mGQ,QGzmGR7Y,KH0mGUA,EGzmGV,GAAA+T,QAvKA,GAAA2D,GAAAyY,EAAAzY,EAAAA,QAAAA,UAAAA,EAAAA,IACA1U,EAAApD,EAAA6vB,MACAzsB,EAAAqtB,EAAAN,SACA/sB,EAAAstB,EAAA1wB,MACAoD,GAAAutB,YAAA3wB,EAAAiwB,WAAAA,EAAAA,QACA7sB,IAAAA,GAAApD,EAAAkwB,EACAI,GAAAM,OAAAN,EAAAltB,KAIAA,IAAAA,GAAAyC,EAAAoT,QHioGQ7V,GGhoGRktB,MAAA3qB,EAAAsT,UHioGQ7V,EAAMqtB,UAAYzwB,EAAQmwB,SG/nGlC/sB,EAAAytB,WAAAA,EAAAT,UHioGQhtB,EGhoGRktB,UAAAO,EAAAlvB,SHioGQyB,EAAM0tB,UAAY9wB,EAAQkwB,QG/nGlC9sB,IAAAA,GAAA2tB,EAAAC,OAAA5tB,EAAA6tB,MHioGQ7tB,GGhoGRktB,QAAAY,SAAA9tB,GHioGUktB,EAAY3qB,OAAOsT,IAErB7V,EGhoGRpD,YAAA+W,SAAApV,GHioGU2uB,EGhoGVA,YAAA3uB,IHkoGQyB,EAAM2tB,YGhoGd,WHioGUT,EGhoGVA,SAAAltB,EAAAqX,MAAA,GAAA6V,EAAAU,OAAAxqB,SHkoGQpD,EAAM+tB,UAAY,WG/nG1BC,EAAAA,WACAd,EAAAvZ,QAAAA,GACAuZ,EAAAY,OAAAA,GAAAzW,QHkoGY6V,EGhoGZ3qB,OAAA,GAAA8U,OAAA,IHmoGQrX,EAAMguB,OAAS,WG5nGvBd,EAAApqB,WAEAoqB,EAAAnW,QAAAlB,GACAqX,EAAAtV,OAAAA,OH8nGYsV,EAAY3qB,OAAO,MAAM,IGvnGrC2qB,EAAAe,OAAAA,SAAAA,GACArxB,QAAAsxB,OAAAA,KAAAC,MAAAA,EAAAA,aACAjB,EAAAtV,MAAA5X,EACA3B,EAAAC,OAAAA,KAAA0B,EAAA0L,IH4nGUwhB,EAAYhW,QAAO,IAErBgW,EGxnGR7uB,oBAAA,SAAA8vB,GHynGUvxB,EGxnGVyB,mBAAAP,CHynGU,KGxnGVA,GAAAA,GAAAA,EAAAqY,EAAAA,EAAAA,KAAA/S,OAAAyS,EAAAA,EAAAA,IHynGYxX,QAAQC,QAAQ0B,EAAM8X,KAAKpM,GAAIwhB,EAAYkB,iBAG/ClB,EAAY3qB,OAAS,SAASsT,EAAMuB,GGvnG5C/Y,QAAAwvB,OAAAA,KACA/vB,QAAAqF,OAAAA,EAAA9E,aAAAwX,MAAAA,EAAAA,WAAAA,cACA/X,EAAAiF,WAAAA,GAAAA,MAAAA,IH2nGYjF,EGznGZovB,WAAA,MH2nGeltB,EAAM6tB,OAASzW,GAClBtZ,EG1nGZqF,cAAA9E,QAAAH,KAAA2X,IACAxX,EAAAS,UAAAinB,EAAAlQ,YAAA+Q,GAAAD,EAAA9Q,WAAAA,EAAAoV,MAAAA,OHioGY5sB,QAAQS,OAAO4V,GACbqR,KAAMlQ,EAAK+Q,cG5nGzBsG,MAAAY,EAAAA,WAEA9tB,KAAA6tB,EAAAQ,YAEAnB,EAAAhW,QAAAA,EAAAA,MAAAA,GH6nGYgW,EAAYhW,WAGhBgW,EGxnGRoB,QAAA,SAAAd,GACAA,EAAAA,MAAArI,EHynGUqI,EAAUN,EAAYU,OAAO5tB,EAAM6tB,OGtnG7CX,EAAAqB,UHynGQrB,EGvnGR5uB,OAAA0B,SAAA8X,GHwnGcwW,KAAa,GAAQd,EAAQgB,QAC7BF,KAAa,GAAUd,EAAQgB,QGrnG7CtB,EAAAA,MAAAjV,KAAAA,IHwnGQiV,EAAYqB,gBAAkB,WGpnGtCrB,IAAAA,GAAAA,GAAAkB,EAAAA,EAAAA,EAAAA,KAAAhrB,OAAA4J,EAAAA,EAAAA,IACAA,QAAAxD,QAAAgkB,EAAAiB,KAAAA,GAAAzhB,IHwnGQkgB,EGpnGRwB,YAAAA,SAAAA,GAIA,MAAAnW,GAAAA,WAAAlB,IHmnGQ6V,EGlnGR3U,eAAAoW,SAAAA,GHmnGU3hB,EGnnGV2Z,SAAApO,EAAAqW,WAAAA,EAAAA,OHqnGQ1B,EAAYO,YAAc,SAASlvB,GGpnG3C2uB,GAAAA,GAAAhW,EAAAA,MHsnGcqB,EAAa,GAAIlB,MAAKA,KAAKwX,IAAIna,EAASqR,MAAQ2I,EAAM3I,MAAQ,GAAKxnB,EAAOmW,EAASiS,OAAS+H,EAAM/H,OAAS,GAAKpoB,EAAO,GGnnGrI2uB,SAAAA,OAAA3pB,GAEAb,KAAAc,EAAAA,iBACAd,MAAAe,EAAAA,cAEAoS,KAAAzK,EAAA0jB,eHonGU5B,EGlnGV1U,UHonGQ0U,EAAY3pB,aAAe,SAASb,GAGlC,GAFAA,EGlnGV8V,iBHmnGU9V,EAAIe,kBACA2H,EAAS,CGhnGvB8hB,GAAAA,GAAAnpB,QAAA/G,QAAA0F,EAAAA,OACAA,YAAA8V,EAAA,GAAAtN,SAAAjG,gBACAzB,EAAAA,EAAAA,UAGAgV,EAAA9U,eAAA,WHmnGQwpB,EGhnGRnpB,WAAA,SAAArB,GHinGU,GGhnGV1C,mBAAAiF,KAAAvC,EAAAgB,WAAAhB,EAAAqsB,WAAArsB,EAAAssB,OHgnGU,CAGA,GAFAtsB,EAAIc,iBACJd,EAAIe,kBACgB,KAAhBf,EAAIgB,QAQN,YGznGZ1D,EAAA6tB,MAKAnsB,EAAAA,OAAAiC,WHinGgBupB,EAAYY,QAAQ9tB,EAAM6tB,MAAQ,KAHpCX,EAAYppB,MAAK,GGpmG/B9G,GAAAiyB,UAAAle,GH6mGUrP,EAAYiC,WAQd,IGzmGR3G,GAAAwQ,EAAAoD,IH0mGQsc,GGzmGRzoB,KAAA,WH0mGU,MGzmGVzH,IAAAJ,EAAA0Y,WH0mGYtY,EAAQwQ,KAAK,OAAQ,YGxmGjC+H,GAAAA,IAAAA,qBAAAA,eAGA+D,IACA4T,EAAAlmB,KAAAA,OAAA,QACAhK,EAAA4V,KAAAA,WAAAU,QACAtW,EAAAyO,GAAAA,QAAA6J,QAEAgE,MAGA,IAAAC,GAAA2T,EAAAtpB,OACAspB,GAAAtpB,QAAA,WACAgP,GAAA5V,EAAAyH,WACA8U,EAAAA,IAAAA,QAAAA,GHymGUD,IAEF,IGpmGRC,GAAA3c,EAAAoE,IHqmGQksB,GGpmGRlwB,KAAA,YHqmGeoO,GAAWpO,EAAQyH,KAAK,aAAezH,EAAQyH,KAAK,cACzD8U,IACAvX,EAAS,WGlmGnBwX,EAAA0T,WACAA,EAAAppB,SAAAqH,GAAAsH,EAAAA,aAAAA,YAAAA,EAAAA,cACAya,EAAAA,UACAA,EAAArpB,GAAAA,UAAAuH,EAAArH,cAEA/G,GAAAA,IHqmGQ,IGnmGRwc,GAAA/G,EAAAA,IAmBA,OHilGQya,GAAYppB,KAAO,SAAS2O,GGjmGpCya,EAAAA,WHmmGUA,EAAYrpB,SAAS4H,IAAIL,EAAU,aAAe,YAAa8hB,EAAY3pB,cG/lGrF0pB,EAAAA,UACAjwB,EAAAiwB,IAAAA,UAAAA,EAAAA,YAMA3oB,EAAAmO,KAKAya,EH65FM,GGtoGNta,GAAAsa,6BAAA9qB,KAAAA,EAAAA,UAAAA,WACAgJ,EAAAqhB,eAAA7vB,GAAA6vB,UAAA7vB,CA2OAmD,OAvOAvC,GAAA2vB,OAAA+B,EAAAA,KAAAhC,EAAAA,oBAsOAvoB,EAAAnH,SAAAA,EACAyvB,MH2lGK3oB,UGxlGLtE,gBAAAA,UAAAA,SAAAA,KAAAA,iBAAAA,cAAAA,cAAAA,SAAAA,EAAAA,EAAAA,EAAAA,EAAAA,EAAAA,GHylGI,GAAI4S,GAAW,6BAA6B3N,KAAKrD,EAAQ6X,UAAUC,UACnE,QACEhV,SGzlGNrG,MH0lGMsG,QAAS,UACT5E,KGvlGN6E,SAAAA,EAAA5H,EAAAyH,EAAA3G,GHkpGQ,QGpkGRqxB,GAAAC,GHqkGU,MGnkGVC,IAAAC,EAAAlsB,OACAmsB,EADA,KH+kGQ,QGlkGRzxB,GAAA6b,GAEA,GAAAC,QAAA9b,OAAAA,GAAA,CHkkGU,GAAIgc,GAAa/L,MAAMwhB,EAAWpoB,SAASolB,UAAYiD,EAAWvY,WAAasY,EAAWpoB,SAASolB,QG9jG7GzuB,EAAAmc,MAAAC,EAAA/S,SAAAgT,UAAAA,EAAAA,WAAAA,EAAAA,SAAAA,QAEAtE,EAAAA,GAAAA,CAEA/X,GAAAqc,aAAA,OAAAP,GH8jGU9b,EG7jGVA,aAAAkc,MAAAF,GH8jGUhc,EG1jGVkc,aAAA,MAAAL,GH2jGcC,IAAS9b,EAAWqY,WAAaqZ,IA+CvC,QAASC,KACP,OAAQ3xB,EAAWqY,YAAcpI,MAAMjQ,EAAWqY,WAAWc,WAAa,GAAKzC,EAAW1W,EAAWqY,WAAYvZ,EAAQmvB,YGttGnI1tB,GAAAA,IACA2B,MAAA3B,EHylGQA,SAAQC,SAAU,WAAY,cAAe,aAAc,eAAgB,YAAa,YAAa,QAAS,UAAW,OAAQ,YAAa,YAAa,WAAY,aAAc,WAAY,kBAAmB,YAAa,eAAgB,YAAa,YAAa,YAAa,OAAQ,YAAa,UAAW,WAAY,YAAa,qBAAsB,KAAM,cAAe,cAAe,WAAY,YAAc,SAASI,GACxaL,QAAQ4E,UAAUwB,EAAK/F,MAAO9B,EAAQ8B,GAAO+F,EAAK/F,KAExD,IGrlGRkG,GAAAlG,eHslGQL,SGrlGRA,SAAA4E,OAAAwB,YAAA,YAAA,YAAA,WAAA,YAAA,SAAA/F,GACA9B,QAAA8B,UAAAsB,EAAA+S,KAAAlO,EAAAA,KAAAA,EAAAA,MHslGYjI,EAAQ8B,IAAO,KGhlG3B9B,QAAAA,SAAA2yB,eAAApoB,SAAAA,eAAAA,UAAAA,SAAAA,GAEA,GAAAyL,GAAAA,KAAAhW,EAAA0W,OAAAA,GAAA1W,cAAAmvB,EAAAA,MAAA,EAEApW,SAAA/Y,UAAA+Y,EAAAA,MAEAnB,EAAAA,GAAAxU,EAAA+S,MAAA8C,EAAApB,MAIA,IAAA6F,GAAAC,EAAAA,EAAAA,EAAAA,EHglGQ3d,GGhlGRA,EAAAmvB,SAAApW,GAAAA,EAAAA,YAAAA,EAAAA,WAAAA,aHklGQ,IGllGR6Q,GAAA5pB,EAAA0vB,KHmlGY9X,EAAa,SAASqB,EAAMpB,GGhlGxC,MAAAtB,GAAAqB,WAAAqB,EAAApB,EAAAkB,IAEA2E,EAAAiV,GHklGU9a,OGjlGVpW,EAAAG,WHklGUmX,KGjlGV9P,EHklGU2gB,OGjlGV+I,EAAA3rB,cHmlGYa,GGjlGZ8qB,QHklGUvvB,EAAM2F,OAAOlB,EAAK0O,OAAQ,SAAStN,EAAUC,GACtCypB,GAAelxB,QAAQ4E,UAAU4C,KAClCxH,QAAQG,SAASqH,KAAWA,IAAaA,EAASuN,MAAM,2BG9kGxE9U,KAAA,EAEAD,EAAA4E,OAGAssB,EAAApoB,UHilGQ9I,QAAQC,SAAU,UAAW,WAAa,SAASI;AAC7CL,QAAQ4E,UAAUwB,EAAK/F,KGzkGrCL,EAAAA,SAAA4E,EAAAwB,SAAAsnB,GACAtnB,EAAA0C,SAAAzI,GAAA4b,EAAAzU,oBAAAA,EAAAA,GACA0pB,MAAApoB,EAAA4kB,SAAAlmB,KAAAA,EAAAA,QAAAA,GH2kGc6pB,EAA0B5xB,EAAWqY,gBGpkGnD9X,QAAA4E,UAAAwB,EAAAsnB,aAIAtnB,EAAAyE,SAAAkmB,aAAAC,SAAAA,GACAE,EAAAF,SAAAA,WAAAxpB,IAIA7F,EAAA3B,OAAA4E,EAAAA,QAAA0sB,SAAAA,EAAA7pB,GACA9F,EAAA2F,OAAAgqB,EAAAA,cHqkGW,GAKCtxB,QAAQ4E,UAAUwB,EAAKkrB,gBACzB3vB,EAAM2F,OAAOlB,EAAKkrB,cAAe,SAASL,EAAgBH,GGjkGpEG,EAAAI,EAAAF,GACAL,EAAApY,EAAAoY,GACArV,GACAH,EAAAA,oBAAAxS,KHglGQrJ,EG1jGR0xB,SAAAA,QAAAA,SAAAA,GH2jGU,GG1jGV1xB,EH2jGU,KGxjGVqc,EAEAuV,MHujGY5xB,GAAWkc,aAAa,QAAQ,GGvjG5C0V,IH0jGU,IGvjGV7Z,GAAAyE,EAAAG,MAAAA,EAAA+U,EAAA5yB,WHwjGU,QGvjGV4yB,GAAAhb,MAAAqB,EAAAmW,eHwjGYluB,GAAWkc,aAAa,QAAQ,IAGlC0V,EGvjGVzY,GACA6U,WHujGclvB,EGvjGdA,UACAiZ,EAAAA,EAAAoB,qBAAAuY,EAAA5yB,EAAA6W,UAAA,GACAe,EAAAsX,EAAAA,EAAAE,iBAAApvB,EAAAmvB,cHyjGUlW,EAAOyE,EAAWG,qBAAqB3c,EAAWqY,WAAYvZ,EAAQ6W,UAAU,GGtjG1FoC,WAAAjZ,EAAAya,SHwjGmBxB,EAAKoB,UGpjGxB,SAAA5Q,EAAAA,SAEAwP,EAAAA,UAAAA,IACAtP,QAAAlI,EAAAsJ,SACA+S,EAAAA,cAEA7E,GAAAtP,MAAAA,OHsjGQzI,EGpjGRwc,YAAAK,KAAApU,SAAAA,GHqjGU,GAAIsP,EAaJ,OAXEA,GGrjGZA,QAAAlO,YAAApB,IAAA,OAAAA,EACAmU,IACArc,QAAAkI,OAAAA,GHqjGmBA,EG9iGnB+T,WAAAnE,EAAAA,SACAsZ,EAAAA,MAAAA,EAAAA,KAAAA,EAAAA,iBHgjG0C,SAArB7yB,EAAQkvB,SG5iG7B/oB,GAAAA,MAAA,IAAAA,GH+iGmB,GAAIsU,MAAK9Q,GGziG5BzI,EAAAA,WAAAqY,EAAApI,qBAAAoI,EAAAc,EAAAA,UH4iGiBwY,MAET3xB,EGziGRyxB,QAAAA,WACA3yB,EAAAA,IAAA6yB,MASA3uB,EAAAA,IAAA,WAAA,WAQA2J,GAAA6V,EAAAA,UACAsP,EAAAA,KACAL,EAAAnsB,YHkiGOtC,SAAS,kBAAmB,WG3hGnC,QAAA+uB,GAAAC,EAAA5G,GH8hGM,IG7hGN,GAAA0G,MH6hGaG,EAAI3sB,OAAS,GG1hG1BxF,EAAA4D,KAAAuuB,EAAA5nB,OAAA,EAAAmY,GH6hGM,OGzhGNtgB,GH2hGI,QGxhGJ2V,GAAAA,EAAA/Y,GHyhGM,OGxhGN4X,EAAAA,EAAAA,GAAA0U,EH0hGItrB,KAAK4D,MAAS,iBAAkB,cAAe,OAAQ,SAAS6U,EAAgBkE,EAAapK,GAC3F,MGxhGNmK,UAAAA,GHyhGQ,GGzhGR7F,GAAA7X,EAAAmvB,OAAApW,EAAAA,EAAAA,SAAA6Q,EAAA5pB,EAAA0vB,KH4hGY9X,EAAa,SAASqB,EAAMpB,GG1hGxC,MAAAub,GAAA3Z,WAAAsV,EAAAA,EAAAhW,IAEAsa,EAAAA,GAEAxb,OAAAG,EAAAsb,WACAva,KAAAjB,EAAAqR,OAAAnR,EAAAgS,eAAA/Q,EAAAoV,EAAAA,cAAAA,GH8hGYkF,EAAiBH,EAAYhrB,MAAMpI,EAAQ+vB,WAAWyD,OAAOJ,EAAYhrB,MAAM,EAAGpI,EAAQ+vB,YG5hGtGS,EAAAA,EAAAA,YAAAA,+BAAAA,EAAAA,KAAAA,qCAAAA,SACA3Y,EAAA7X,EAAAqvB,QAAAA,EAAAA,UAAAA,EAAAA,oBAAAA,YAAAA,EAAAA,WAAAA,GAAAA,OACAxhB,GACAikB,KAAAA,EAAAA,cH8hGU/H,MG9hGVA,EAAAE,WH+hGUhR,KAAMjB,EAAUqW,WG7hG1BmC,IHgiGU3Y,OG/hGVpW,EAAAS,UHgiGU2L,MGhiGVsb,EHiiGU2I,OACE/H,MGliGZ9Q,GHoiGU/S,OGniGVotB,SAAAhZ,EAAAA,IHoiGiBtZ,KGniGjB4wB,OAAAvD,GAAAA,EAAAvW,gBAAAmB,EAAAoV,MAAApV,EAAAgR,aAAAnS,EAAAiS,OAKAjS,QAAAA,OAAAmB,GACAqa,KAAA3B,EAAAA,MAAAA,cHgiGgB5H,MAAOuJ,EAAOtY,MAAMiP,WACpBhR,KAAMqa,EAAOtY,MAAMqT,YG7hGnCiF,EAAAG,WACAC,EAAAA,YAAAD,EAAAA,MAAA7E,IAAAA,EAAAA,aACA9W,EAAA6b,KAAAL,EAAA7Y,MAAAgZ,UACAH,EAAAM,oBHkiGUC,MG9hGVC,WACA,GAAAhK,GAAAA,GAAAA,MAAAA,EAAAA,KAAAA,EAAAA,MAAAA,GACA4J,EAAA5kB,EAAA8f,oBACA9E,EAAApM,GAAAgR,OAAAA,EAAAiF,MAAAlZ,EAAAA,EAAAuP,SAAA2J,EAAAA,UAAA1J,IACA6J,EAAApqB,EAAAA,oBAAAuP,EAAA6Q,EAAAA,qBAAAA,GAAAA,MAAAA,EAAAA,UAAAA,cAAAiK,KAAAC,IAAA1F,EAAAA,GAAAA,OAAAA,EAAAA,KAAAA,EAAAA,IHmiGY,KGniGZ2F,GAAArqB,GAAAO,KAAA8pB,EAAAnK,EAAAG,GAAAA,EAAAA,IHoiGcH,EGpiGdld,EAAAilB,qBAAA/H,GAAAA,MAAAA,EAAAA,cAAAA,EAAAA,WAAAA,EAAAA,UAAAA,IHqiGcgK,EAAKpqB,MACHuP,KAAM6Q,EGpiGtB1mB,QAAA6J,EAAA2K,iBAAA6b,EACArwB,MAAA8wB,EAAApK,EAAA9oB,KAAA6W,QACAzU,SAAA+wB,EAAAd,OAAAA,KAAAA,WAAAA,GACAjwB,MAAA8X,EAAArN,aAAAA,EAAAA,MACAzK,SAAAgxB,KAAAA,WAAAvC,IAGAwC,GAAAA,MAAAzc,EAAAqB,EAAAA,EAAAA,kBACA7V,EAAA8wB,YAAAlZ,EHsiGY5X,EAAM+wB,OAASd,EGpiG3BxB,EAAAA,KAAAhkB,EAAAoL,EAAAA,KAAAA,OACA7V,EAAAyV,gBAAAwB,KAAAA,WAAAA,GAAAA,OAGArZ,KAAA6X,OAAA7Y,GHqiGUq0B,WG/hGVr0B,SAAAsxB,GHgiGY,MG/hGZgC,GAAAxkB,OAAA9O,EAAAA,gBAAAsxB,EAAA9qB,MAAAsI,eAAAmK,EAAAgR,aAAAqJ,EAAAtY,MAAAiP,YAAAhR,EAAAoV,YAAAiF,EAAAtY,MAAAqT,WHiiGUwD,WG/hGV,SAAA5Y,GHgiGY,GAAIJ,GAAOI,EAAKoB,SAChB,IAAIxB,EAAO7Y,EAAQ2vB,SAAW9W,EAAO7Y,EAAQ4vB,QAAS,OAAO,CAC7D,IAA0D,KAAtD5vB,EAAQgwB,mBAAmB1kB,QAAQ2N,EAAKqb,UAAkB,OAAO,CG7hGjF,IAAAt0B,EAAAsxB,mBH+hGc,IAAK,GAAIxiB,GAAI,EAAGA,EAAI9O,EAAQsxB,mBAAmB9qB,OAAQsI,IG7hGrEujB,GAAAA,GAAAryB,EAAA8F,mBAAAA,GAAAA,OAAAA,GAAAA,EAAAA,mBAAAA,GAAAA,IACAwtB,OAAAtY,CAIA,QAAAU,GHgiGU2W,UGzhGVrxB,SAAA6wB,GH0hGY,GAAKyB,EAAOtY,MAAZ,CGthGZnD,GACAhK,GADAgK,EAAAyX,EAAAA,MAAAA,SAEAwC,MAAAA,EAAAA,QAAAA,EAAAA,GAAAA,MAAAA,EAAAA,OAAAA,KAAAA,EAAAA,QAAAA,EAAAA,GAAAA,MAAAA,EAAAA,QAAAA,KAAAA,EAAAA,QAAAA,EAAAA,GAAAA,MAAAA,EAAAA,OAAAA,KAAAA,EAAAA,UAAAA,EAAAA,GAAAA,MAAAA,EAAAA,SAAA3I,KAAA0I,WAAAnW,IAAA4X,EAAA3tB,OAAA+V,GAAA,OH6hGUhQ,KG3hGV,QH4hGUmM,OG3hGVpW,EAAAS,YH4hGU2L,MG5hGVsb,EH6hGU2I,OACE3I,KG9hGZlQ,GHgiGU/S,OG/hGVotB,SAAAhZ,EAAAA,GHgiGiBtZ,KG/hGjB4wB,OAAA3H,EAAAA,gBAAAF,EAAAZ,KHsiGuBlQ,EAAKgR,aAAenS,EAASiS,QGjiGpD8J,QAAA3xB,OAAA4V,GAEAyc,MAAAA,EAAAA,MAAAA,WACAxK,KAAAA,EAAAA,MAAAA,YAEAA,EAAAA,oBATAtoB,QAAAS,OAAA4V,GAAAiS,KAAAA,EAAAuJ,MAAAtY,cAAA/B,MAAAqa,EAAAtY,MAAAqT,WHkiGgBpV,KAAMqa,EAAOtY,MAAMqT,YAErBiF,EAAOhZ,WASXuZ,MGniGV1pB,WHsiGY,IAAK,GGtiGjByC,GAAAhD,KHsiGqBkF,EAAI,EAAO,GAAJA,EAAQA,IACtBib,EAAQ,GAAItP,MAAK3C,EAASqR,KAAMra,EAAG,GGriGjD1L,EAAA6J,MACA7J,KAAA8wB,EACA9wB,MAAA8X,EAAAqZ,EAAAvzB,KAAA6M,QACA7M,SAAAsyB,EAAAjY,YAAA0O,GHuiGgBnd,SAAU5L,KAAK6wB,WAAW9H,IAG9B3mB,GAAM6J,MAAQ2K,EAAWmS,EAAO/pB,EAAQyvB,iBGriGpDoC,EAAAA,YAAA5Y,EACA7V,EAAAoxB,KAAAA,EAAAD,EAAAtb,KAAA+Q,OACAhpB,KAAA4wB,OAAA4C,GAEAnC,WAAA,SAAAvsB,GACA,MAAAwtB,GAAAtY,OAAA/B,EAAA+Q,gBAAAsJ,EAAAtY,MAAAgP,eAAA/Q,EAAAgR,aAAAqJ,EAAAtY,MAAAiP,YHwiGU4H,WAAY,SAAS5Y,GGriG/B,GAAAwb,IAAAA,GAAAnB,MAAAtY,EAAAA,cAAAiP,EAAAA,WAAAA,EAAAA,EACA,OAAAvO,GAAAjB,EAAA6Y,SAAAtY,EAAAA,UAAAA,EAAAA,SHwiGUqX,UGjiGVrxB,SAAA6wB,GHkiGY,GAAKyB,EAAOtY,MAAZ,CG9hGZnD,GAAAA,GAAA0X,EAAAA,MAAAA,WACA1hB,EAAA,GAAA4M,MAAA6Y,EAAAtY,MACA8W,MAAAA,EAAAA,QAAAA,EAAAA,SAAAA,EAAAA,GAAAA,KAAAA,EAAAA,QAAAA,EAAAA,SAAAA,EAAAA,GAAAA,KAAAA,EAAAA,QAAAA,EAAAA,SAAAA,EAAAA,GAAAA,KAAAA,EAAAA,SAAAA,EAAAA,SAAAA,EAAAA,GAAA3I,KAAA0I,WAAAnW,IAAA4X,EAAA3tB,OAAA+V,GAAA,OHqiGUhQ,KGniGV,OHoiGUmM,OGniGVpW,EAAAS,WHoiGU2L,MGpiGVsb,EHqiGU2I,OACE3I,KGtiGZlQ,IHwiGU/S,OGviGVotB,SAAAhZ,EAAAA,IHwiGiBtZ,KGviGjB4wB,OAAA5H,GAAAA,SAAAlS,EAAAA,cAAA,GAAA,MAAAxG,SAAAwG,EAAAqR,KAAA,GAAA,KACA1nB,QAAAS,OAAA4V,GAAAqR,KAAAmK,EAAAtY,MAAAgP,cAAAD,MAAAuJ,EAAAtY,MAAAiP,WAAAhR,KAAAqa,EAAAtY,MAAAqT,YACAiF,EAAA3B,UH4iGuB1Y,EAAK+Q,gBAAkBlS,EAASqR,OACzC1nB,QAAQS,OAAO4V,GG1iG7B+b,KAAAP,EAAAtY,MAAAgP,cACA0K,MAAAA,EAAA5c,MAAAA,WACA6c,KAAAA,EAAAA,MAAAA,YAEArB,EAAAxkB,oBH8iGU+kB,MG5iGV5a,WHgjGY,IAAK,GGhjGjBrM,GAAAzC,EAAAyN,EAAAuR,KAAAnoB,EAAA6W,MAAAA,EAAAA,KAAAA,OAAAjO,KHgjGqBkF,EAAI,EAAO,GAAJA,EAAQA,IACtBqa,EAAO,GAAI1O,MAAKia,EAAY5lB,EAAG,EAAG,GG/iGhD1L,EAAA6J,MACA7J,KAAA8wB,EACA9wB,MAAA8X,EAAAyZ,EAAA3zB,KAAA6M,QACA7M,SAAAsyB,EAAAjY,YAAA8N,GHijGgBvc,SAAU5L,KAAK6wB,WAAW1I,IAG9B/lB,GAAM6J,MAAQ0nB,EAAM,GAAGxqB,MAAQ,IAAMwqB,EAAMA,EAAMnuB,OAAS,GAAG2D,MG/iGzE0nB,EAAAA,YAAA5Y,EACA7V,EAAAoxB,KAAAA,EAAAG,EAAA1b,KAAA+Q,OACAhpB,KAAA4wB,OAAA4C,GAEAnC,WAAA,SAAAvsB,GACA,MAAAwtB,GAAAtY,OAAA/B,EAAA+Q,gBAAAsJ,EAAAtY,MAAAgP,eHkjGU6H,WAAY,SAAS5Y,GG/iG/B,GAAA2b,IAAAA,GAAAtB,MAAAtY,EAAAgP,cAAAA,EAAAA,EAAAA,EACA,OAAAtO,GAAAjB,EAAA6Y,SAAAtY,EAAAA,UAAAA,EAAAA,SHkjGUqX,UG3iGVrxB,SAAA6wB,GH4iGY,GAAKyB,EAAOtY,MAAZ,CGviGZwV,GAAAA,GAAAV,EAAA+E,MAAAhP,cACA/N,EAAAA,GAAAA,MAAAA,EAAAA,MH2iGgC,MAAhBhS,EAAIgB,QAAgB4U,EAAQoZ,QAAQF,EAAa,GAA6B,KAAhB9uB,EAAIgB,QAAgB4U,EAAQoZ,QAAQF,EAAa,GAA6B,KAAhB9uB,EAAIgB,QAAgB4U,EAAQoZ,QAAQF,EAAa,GAA6B,KAAhB9uB,EAAIgB,SAAgB4U,EAAQoZ,QAAQF,EAAa,GAC1O5zB,KAAK6wB,WAAWnW,IAAU4X,EAAO3tB,OAAO+V,GAAS,MmBpuHlEja,QAIAb,MAAAA,EAAAA,QAAAA,MAAAA,UAAAA,MAAAA,KAAAA,EAAAA,EAAAA,SAAAA,EACA6J,SAAAqN,QnByuHErW,QmBpuHFb,OAAAA,4BAAAA,SAAAA,UAAAA,WnBquHI,GAAIA,GAAWI,KAAKJ,UAClB6J,YAAa,SmBjuHnB/C,YAAA,QnBouHI1G,MmBjuHJ8G,KAAA,WACAC,OACA9G,SAAAL,MnBouHK8G,UmBjuHLjE,kBAAAsS,WnBkuHI,OACEjO,SmBjuHNyY,InBkuHMxY,QmBjuHNwY,UnBkuHMtf,QmBjuHNsf,SAAAngB,EAAA4I,GnBkuHQ5I,EAAQyH,KAAK,cAAe,WAC5BzH,EAAQyC,WAAW,WACnB,IAAIY,GAAWrD,EAAQ,GAAG2V,iBAAiB,yBmB5tHnDrO,SAAAhG,QAAA+B,EAAA,SAAA+c,GAEA5f,GAAAA,GAAAm0B,QAAAn0B,QAAAA,EACAo0B,GAAAA,KAAAA,cAAA,IAEAzU,EAAA1Y,KAAA,WAAAA,EAAAmB,QAAA,IAAAuX,EAAA1Y,KAAA,gBnB+tHKH,UmB1tHL1H,cAAAY,UAAAA,QAAAA,SAAAA,EAAAA,GnB2tHI,GmBxtHJA,GAAAq0B,EAAA70B,SACA40B,EAAAC,oBnBytHI,QACEntB,SmBvtHNktB,InBwtHMjtB,QmBvtHNmtB,UnBwtHM/xB,KAAM,SAAkBC,EAAOhD,EAASyH,EAAM3G,GmBttHpD,GAAAi0B,GAAAA,EACAH,EAAAG,UAAAH,EAAAA,GAAA3sB,SACA8sB,EAAA/xB,EAAAyE,EAAAstB,SAAAA,EnBwtHYD,EAAYzzB,QAAQ4E,UAAUwB,EAAKqtB,WAAartB,EAAKqtB,WAAY,CmBptH7EE,GAAAA,KAAAF,EAAAA,aACAA,EAAAE,EAAAA,MAAAvtB,EAAAqtB,WnButHQ,ImBptHRC,GAAA5X,QAAA2X,UAAAC,EAAAA,YAAAA,EAAAA,YAAAA,CnBqtHYH,GAAoB3sB,KAAKR,EAAKstB,cmBltH1Cj0B,EAAAuI,EAAAA,MAAAC,EAAAyrB,YnBqtHQ,IAAIC,GAAuC,iBAAdF,IAAiD,iBAAfC,EmBhtHvE/xB,KnBktHUlC,EmBjtHVA,SAAAiF,KAAAA,SAAAA,GnBktHY,MAAOoX,GAAY2X,EAAYC,ImB7sH3Cj0B,EAAAiF,YAAAuD,KAAA,SAAAC,GAEA,MAAA0rB,SAAA5zB,OAAAiF,EAAAxF,KnBgtHUkC,EmB9sHV6xB,OAAAA,EAAA70B,QAAAk1B,SAAAD,EAAAA,GACAzV,EAAAA,aAKAxf,EAAAm1B,QAAAC,WACApyB,GAAAA,GAAA3B,QAAAiF,OAAAxF,EAAAiI,YAAA+rB,EnB6sHU/vB,GmB3sHV,WACAjE,IAAAqF,EAAAA,GAAAA,QAAAqZ,GnB4sHYA,EAAc6V,YAAYz1B,EAAQyK,YAAa4qB,MAGnDj1B,EAAQm1B,KAAKv1B,EAAQw1B,YAAa,WAChCpyB,EAAMwe,OAAO,WACNqT,GACH/zB,EAAWqF,eAAeqZ,EAAcgG,SAAS,WmBpsH/DwP,GAEAl0B,EAAAiF,mBnB2sHOuB,UmBrsHPjE,eAAA,WnBssHI,OACEqE,SmBrsHNrG,InBssHMsG,QmBrsHNtG,UnBssHMR,QAAS,SAAkBb,EAASyH,GAClCzH,EAAQyH,KAAK,cAAe,WAC5BzH,EAAQyC,WAAW,WmBhsH3B6E,IAAAA,GAAAtH,EAAA,GAAA2V,iBAAA,sBAEAnV,SAAAA,QAAAm0B,EAAAn0B,SAAAA,GACAo0B,QAAAA,QAAAA,GAAAntB,KAAA,WAAA,IAEApG,QAAArB,QAAAogB,GAAA3Y,KAAA,WAAAA,EAAAmB,enBmsHKtB,UmB9rHL1H,WAAAY,UAAAA,QAAAA,SAAAA,EAAAA,GnB+rHI,GmB5rHJA,GAAAq0B,EAAA70B,SACA40B,EAAAC,oBnB6rHI,QACEntB,SmB3rHNwE,InB4rHMvE,QmB3rHN,UnB4rHM5E,KmB3rHNxB,SAAAwU,EAAAuf,EAAAA,EAAAA,GnB4rHQ,GmBxrHRx0B,GnBwrHYlB,EmB3rHZY,EACAe,EAAA+zB,UAAAA,EAAAA,GAAAA,SnB4rHY9V,EAAgBqV,EAAU70B,EAAQkU,SAAWlU,CAEjDyH,GAAKyE,SAAS,QAAS,SAASopB,GmBtrHxC/zB,EAFAwE,iBAAAA,IAAA6uB,EAAA3sB,KAAAqtB,GAEAL,EAAA5zB,MAAAA,GAEAwzB,EnB0rHU/zB,EAAWiF,YmBprHrB/F,EAAAm1B,QAAAC,WACApyB,GAAAA,GAAA3B,QAAAiF,OAAAxF,EAAAiI,YAAAxH,EnBurHUwD,GmBrrHVjE,WACAA,IAAAiF,EAAAA,GAAAA,QAAAA,GnBsrHYyZ,EAAc6V,YAAYz1B,EAAQyK,YAAa4qB,MAGnDj1B,EAAQm1B,KAAKv1B,EAAQw1B,YAAa,WAChCpyB,EAAMwe,OAAO,WoBj2HvBnhB,EAAA8F,cAAA5E,GAIAf,EAAAI,mBpBq2HES,QAAQhB,OAAO,8BAA+ByD,SAAS,YAAa,WoB71HtE,GAAAhD,GAAAA,KAAAF,UACAH,UAAAG,cAGAsJ,gBAAA7I,EACAA,YAAAC,KpB61HMi0B,gBoB51HNtvB,EpB61HMuvB,eAAe,GoBx1HrBn0B,EAAAC,KAAAR,WAAA,SAAAsE,EAAAyB,EAAAgE,GpBi5HM,QoBp0HN4qB,GAAAC,GpBs0HQ,IAAK,GADDD,GAAgBvrB,EAAKwrB,SAAS9qB,QACzB8D,EAAI,EAAGA,EAAI+mB,EAAcrvB,OAAQsI,IACpClJ,EAAQiwB,EAAc/mB,KoBl0HpC+mB,EAAAl0B,GAAAA,EAAAA,GAAAA,GAEAk0B,EAAAvqB,KAAA3J,EAAAA,SAAA6E,SpBo0HYqvB,EAAc/mB,GAAKxE,EAAKwrB,SAAStvB,OAAS,GAIhD,QoBl0HNsvB,GAAA9qB,GpBm0HQ,GAAI+qB,GAAczrB,EAAKwrB,SAAS9qB,OAChC,OAAsC,KAA/B+qB,EAAYzqB,QAAQ3J,GAE7B,QoBj0HN2I,GAAAsrB,GpBk0HQ,GoBh0HRtrB,GAAAwrB,EAAA9qB,SAAAO,QAAAD,QAAA3J,EpBi0HsB,MAAViE,GoB9zHZ0E,EAAAA,SAAAwrB,QAAA9qB,OAAAM,EAAA3J,GpBk0HM,QAASq0B,GAAar0B,GACf2I,EAAKC,SAASqrB,eoB5zH3BhxB,EAAAA,SAAAoG,QAAAO,OAAA,EAAA,GAEA3K,KAAAq1B,EAAAr1B,SAAAA,QAAAA,QAAAA,IACAq1B,EAAAA,SAAA/0B,QAAAA,KAAAA,GpB6uHM,GoB11HNoJ,GAAA7I,IpB21HM6I,GoB11HNA,SAAAC,QAAAzI,KAAAlB,GpB21HMa,QAAQC,SAAU,YAAa,iBAAkB,cAAe,iBAAkB,iBAAmB,SAASI,GACxGL,QAAQ4E,UAAU4E,EAAOnJ,MAAOwI,EAAKC,SAASzI,GAAOmJ,EAAOnJ,KoBv1HxEwI,IAAAA,GAAAwrB,eAEAxrB,SAAA4rB,SAAAA,iBAAAA,iBAAAA,iBAAAA,SAAAA,GAEAC,QAAAA,UAAAlrB,EAAAnJ,KAAA1B,EAAAA,KAAAA,EAAAA,MACAkK,EAAA8rB,SAAA1sB,IAAAtJ,KpB01HMkK,EoBv1HNA,YpBw1HMA,EAAKwrB,YoBr1HXxrB,EAAA+rB,wBpBu1HM/rB,EoBt1HN6rB,gBAAAC,SAAA9qB,GAEAhB,EAAA8rB,SAAA7qB,KAAAA,IAEAjB,EAAAgsB,gBAAAA,SAAAl2B,GACAkK,EAAA1E,SAAA0E,KAAAwrB,IpBu1HMxrB,EoBl1HN+rB,kBAAAT,SAAAA,GpBm1HQ,GoBj1HRW,GAAAA,EAAAn2B,SAAAA,QAAAA,EpBk1HQkK,GAAK8rB,SAAS7qB,OAAO3F,EAAO,IAE9B0E,EoB90HNA,kBAAA4rB,SAAAx0B,GpB+0HQ,GoB90HRiK,GAAAA,EAAAA,SAAAA,QAAAA,EpB+0HQrB,GAAKwrB,SAASvqB,OAAO3F,EAAO,GACxB0E,EAAKC,SAASqrB,eoB30H1BtrB,EAAAU,GAEAwrB,EAAA70B,GpB60HQ2I,EoB50HRA,qBAAA3I,QAAAA,SAAAA,GpB60HUgK,OAGJrB,EoB50HN0rB,SAAAA,QAAAr0B,EAAAA,SAAAA,mBAAAA,GpB60HM2I,EAAKmB,WAAajG,EAAOiG,WAAa,SAAS9J,GoB10HrD2I,QAAA4rB,QAAAA,GACAvqB,EAAAA,SAAAA,QAAAA,GpB40HoBrB,EAAKC,SAASksB,gBAAkBpB,EAAS1zB,GACnD40B,EAAe50B,GoBx0HzBq0B,EAAAzrB,GpB40HQD,EAAK4rB,qBAAqBx0B,QAAQ,SAASiK,GoBz0HnDA,OpB60HMrB,EoBv0HNosB,eAAApsB,WACA,MAAAA,GAAAwE,SAAAA,cACAlJ,EAAAiwB,SAAAA,QpBy0HgD,IAAjCvrB,EAAKwrB,SAAS9qB,QAAQxE,OAAe8D,EAAKwrB,SAAS9qB,QAAQ,GAAK,IoBzxH/EhK,MAAA4D,KAAA,WACAmD,GAAAA,KpB4zHM,OoB3zHN7G,GAAAA,SAAAN,EACAuC,EAAAjC,WAAA0G,EAEAmE,KpB0zHKrE,UoBvzHLqE,cAAA,UAAA,WAAA,YAAA,SAAA/G,EAAAyH,EAAAwpB,GpBwzHI,OACEluB,SoBrzHNgE,WAAAxF,cpBszHMrF,YAAc,SAAU,WAAY,SAAU+0B,EAAU/0B,YACxDiC,KoBnzHN4I,SAAAtC,EAAAC,EAAAuC,EAAAtC,GpBozHQ,GoBlzHRoC,GAAA8V,EAAAlY,GpBmzHYgtB,EoBhzHZlrB,EAAA9B,EpBizHYoC,KACF4qB,EoBhzHVd,qBAAAc,KAAAD,WpBizHY3qB,EoB/yHZtK,cAAAo0B,EAAAa,oBpBizHU3qB,EoB7yHV4qB,YAAAlrB,KAAAA,SAAA9B,GpB8yHY,GAAIlI,QAAQogB,QAAQlY,GAClBgtB,EoB7yHdd,WAAAA,OACAc,CpB8yHc,GAAId,GAAgBc,EAAeD,gBAC/Bj1B,SAAQogB,QAAQgU,GoB5yHlClsB,KAAAA,EAAAA,QAAAA,EAAAA,IpB8yHkBgtB,EAAelrB,WAAwB,EAAb9B,GAEnBksB,IAA+B,EAAblsB,GAC3BgtB,EAAelrB,WAAwB,EAAb9B,GoBpyH1C5B,MAAA4B,WpB4yHOjC,UoB/xHP2C,mBAAA,WpBgyHI,OACEtC,SAAW,YAAa,eACxB5E,KoB9xHN/C,SAAAgD,EAAAhD,EAAA6L,EAAAM,GpB+xHQ,GoB9xHRoqB,GAAA/pB,EAAA,EpB+xHQxM,GoB9xHRwF,KAAAA,cAAAgxB,YpB+xHQD,EoB9xHRA,gBAAA/wB,GpB+xHQxC,EoB9xHRA,IAAAwe,WAAAA,WpB+xHU+U,EAAeN,kBAAkBj2B,KAEnCA,EAAQmO,GAAG,QAAS,WAClB,IAAKtC,EAAMW,SAAU,CoBzxH/BlF,GAAA9B,GAAAqG,EAAA2qB,kBAAAnqB,uBAAAR,EAAA2qB,iBAAAnqB,EAAAA,iBAAAA,EAAAA,SAAAA,QAAAA,EAEAkqB,GAAAlrB,WAAA,EAAA7F,GACAmC,EAAA6Z,gBpB8xHKla,UoBlxHLtH,oBAAAu2B,WAAApsB,SAAA1J,GpBmxHI,OACEkH,SoBhxHN4uB,YAAAE,epBixHM1zB,KoB9wHNC,SAAAA,EAAAhD,EAAA6L,EAAAM,GpBwxHQ,QAASC,KACP,GAAI5G,GoB7wHdA,EAAAwF,SAAAE,QAAAlL,GACA02B,EAAAH,EAAAD,iBpB8wHcI,EAAS,aoB3wHvBrqB,SAAAqqB,QAAA12B,GpB6wH0C,KAA1BgL,EAAOE,QAAQ1F,KoB1wH/B+wB,EAAAT,YpB6wHqBtwB,IAAUwF,IoB1wH/BoB,EAAAA,YpB6wHUC,EAASqqB,GAAQ12B,EAASu2B,EAAepsB,SAASE,aApBpD,GoB9wHRksB,GAAAL,EAAAA,EpB+wHQl2B,GAAQuM,SAAS,YoB5wHzBgqB,EAAAnqB,SAAAA,WACApM,EAAAwF,SAAA+wB,EAAAb,SAAAxqB,WpB+wHQqrB,EoB7wHRE,gBAAAz2B,GpB8wHQgD,EoB7wHR3B,IAAAA,WAAA2J,WpB8wHUurB,EoB7wHVrrB,kBAAAlL,KC1PAqB,EAAAy0B,qBAAAxsB,KAAA,WAIA9I,MAEAE,SrBuhIEW,QqBnhIFiB,OAAAA,wBAAA,yBAAAwB,SAAA,SAAA,WrBohII,GqBnhIJC,GAAAnD,KAAAJ,UACAR,UAAA,0BACAqjB,YAAA,QACArf,YAAA,QACAtB,UAAA,QACAkE,YAAA,uBrBohIMtE,iBAAiB,EqBjhIvB1B,WAAA4D,EAEAxE,QAAA22B,KrBkhIMtT,UqBhhINuT,ErBihIM5yB,UqB9gINpE,ErB+gIM8C,MqB7gINk0B,ErB8gIMhwB,MqB5gIN,ErB8gIIhG,MqB1gIJ4D,MAAAmyB,SAAAA,SAAAA,GrB2gIM,QAASA,GAAazxB,GqBrgI5BoC,GAAAA,MAEA1H,EAAAyB,QAAAS,UAAAtB,EAAA0E,EAEAlC,OADA0E,GAAAkc,EAAAhkB,GrBwgIM,MqBpgINA,OrBsgIK0H,UqBtgILtH,WAAAA,UAAAA,OAAAA,SAAAA,SAAAA,EAAAA,EAAAA,GrBugII,OACE0H,SAAU,MACV1E,OqBxgIN3B,ErBygIM0B,KqBxgIN,SAAAkD,EAAAvE,EAAA9B,EAAA8B,GrBygIQ,GAAI9B,IqBrgIZoD,MAAA4E,EACAvG,QAAAC,EACAsF,MAAAvF,EAIAA,SAAAC,SAAA,WAAA,cAAA,aAAA,eAAA,kBAAAI,YAAAA,WAAAA,WAAAA,OAAAA,YAAAA,aAAAA,SAAAA,GACAmG,QAAA5B,UAAAvE,EAAAoG,MAAAC,EAAAA,GAAArG,EAAAsG,KrBsgIQ,IqBpgIRpI,GAAAoD,erBqgIQ3B,SAAQC,SAAU,WAAY,WAAY,OAAQ,aAAe,SAASI,GACpEL,QAAQ4E,UAAUwB,EAAK/F,KAASkG,EAAiBK,KAAKR,EAAK/F,MAAO9B,EAAQ8B,IAAO,KAEvFL,QqBlgIRoG,SAAA,eAAA,SAAA,eAAA,UAAA,SAAA/F,GrBmgIU,GqBlgIV+F,GAAAyE,KAAAxK,EAAAoG,OAAAe,GAAAA,cAAAC,EAAAA,MAAAA,EACA9F,SAAAtB,UAAA0R,EAAAA,MrBmgIYxT,EAAQ8B,GAAOsB,EAAM+S,MAAMtO,EAAKI,OqB7/H5CxG,QAAAoG,SAAA,QAAA,WAAA,SAAA/F,GACAsB,EAAA2F,IACAlB,EAAApG,SAAAmC,EAAAA,SAAAqF,EAAAC,GACAzH,EAAAA,GAAAS,EAAAkB,YAAA6F,OrBogIYpB,EqBhgIZovB,SrBigIU7zB,EAAM2F,OAAOlB,EAAKovB,QAAS,SAAShuB,EAAUC,GqB7/HxDguB,QAAAF,SAAAh3B,GAGAI,QAAAyH,OAAA5D,EAAAgF,GAIAiuB,EAAAA,QAAA9sB,IAEA8sB,ErB4/HQ,IAAIA,GAAQF,EAAOh3B,EACnBI,GAAQmO,GAAG1G,EAAK5D,SAAW,QAASizB,EAAMzoB,QAC1CrL,EAAMiH,IAAI,WAAY,WsB5lI9B5J,GAAAy2B,EAAA9sB,UAIAxJ,EAAAI,KACAH,EAAA,YtB+lIEY,QsB1lIF0C,OAAA,wBAAA,yBAAAD,SAAA,SAAA,WtB2lII,GsB1lIJ9D,GAAAY,KAAAJ,UACA6iB,UAAA,UACArf,YAAA,QACA4C,YAAA,QAEAmwB,UAAA,KACAjqB,YAAA,uBACAkqB,WAAAA,EtB0lIMh3B,QAAS,KsBvlIfY,UAAA4D,EAEAR,UAAAizB,EtBwlIMrwB,MsBtlINswB,EtBulIMH,UsBplINn3B,EtBqlIMkN,MsBnlINoqB,EtBolIMF,asBjlIN5xB,EtBmlIIxE,MAAK4D,MsBjlITY,SAAA0H,WAAAA,SAAAA,EAAAA,GtBklIM,QAASmqB,GAAa/xB,GsB9kI5B,GAAA0B,MACAhH,EAAAm3B,QAAAj1B,UAAAtB,EAAA0E,EtBglIQgyB,GsB/kIRtwB,EAAAhH,GtBglIQs3B,EsB/kIRtwB,OAAAA,cAAAA,EAAAA,YACA5B,EAAAA,OtBglIUkyB,EsB/kIVA,OAAApwB,KAAAA,EAAAA,KtBilIQ,IAAIF,GAAOswB,EAAOtwB,IsB9jI1B5D,OtB+jIYpD,GAAQm3B,WsB7kIpBG,EAAAA,KAAAA,WtB+kIYtwB,IsB3kIZ5B,EAAAiyB,WtB6kIcC,EAAOpwB,QsBvkIrB,IAAAlH,EAAAm3B,YAIAG,EtBykIM,MsBrkINt3B,OtBukIK0H,UsBvkILtH,WAAAA,UAAAA,OAAAA,SAAAA,SAAAA,EAAAA,EAAAA,GtBwkII,OACE0H,SAAU,MACV1E,OsBzkIN3B,EtB0kIM0B,KsBzkIN,SAAAkD,EAAAvE,EAAA9B,EAAA8B,GtB0kIQ,GAAI9B,IsBtkIZoD,MAAA4E,EACAvG,QAAAC,EACAsF,MAAAvF,EAIAA,SAAAC,SAAA,WAAA,cAAA,aAAA,eAAA,YAAAI,WAAAA,OAAAA,YAAAA,YAAAA,WAAAA,eAAAA,SAAAA,GACAmG,QAAA5B,UAAAvE,EAAAoG,MAAAC,EAAAA,GAAArG,EAAAsG,KtBukIQ,IsBrkIRpI,GAAAoD,etBskIQ3B,SAAQC,SAAU,WAAY,OAAQ,YAAa,eAAiB,SAASI,GACvEL,QAAQ4E,UAAUwB,EAAK/F,KAASkG,EAAiBK,KAAKR,EAAK/F,MAAO9B,EAAQ8B,IAAO,KAEvFL,QsBlkIRwL,SAAA,eAAA,SAAA,eAAA,UAAA,SAAAnL,GtBmkIU,GAAImG,GAAQ,KAAOnG,EAAIoG,OAAO,GAAGC,cAAgBrG,EAAIsG,MAAM,EsB/jIrE3G,SAAAC,UAAAmG,EAAAI,MACAjI,EAAA8B,GAAAsB,EAAA+S,MAAAtO,EAAAI,OtBmkIa7E,EAAMiT,eAAe,WACxBjT,EAAM6J,MAAQ,IsB5jIxBxL,QAAAoG,SAAA,QAAA,UAAA,QAAA,SAAA/F,GACAsB,EAAA2F,IACAlB,EAAApG,SAAAmC,EAAAA,SAAAqF,EAAAC,GACAzH,EAAAA,GAAAS,EAAAkB,YAAA6F,OtBkkIYpB,EsB9jIZ0vB,StB+jIUn0B,EAAM2F,OAAOlB,EAAK0vB,QAAS,SAAStuB,EAAUC,GsB3jIxDsuB,QAAAF,SAAAt3B,GAGAI,QAAAyH,OAAA5D,EAAAgF,GAIAuuB,EAAAA,QAAAptB,IAEAotB,EtB0jIQ,IAAIA,GAAQF,EAAOt3B,EACnBI,GAAQmO,GAAG1G,EAAK5D,SAAW,QAASuzB,EAAM/oB,QAC1CrL,EAAMiH,IAAI,WAAY,WuBxrI9B5J,GAAA+2B,EAAAptB,UAIAxJ,EAAAI,KACA0e,EAAA,YvB2rIEje,QuBprIFyc,OAAAA,wBAAAlZ,oCAAAA,oCAAAA,SAAAA,SAAAA,WvBqrII,GuBnrIJpE,GAAA62B,KAAAA,UvBorIM/X,UuBlrINgY,OvBmrIMC,cuBhrIN33B,EvBkrIIgB,MuB9qIJ4D,MAAAgzB,UAAA,WAAA,aAAA,SAAA5yB,EAAAmZ,EAAAjO,GvBirIM,QuB9qIN2nB,GAAAA,EAAAvyB,GvBmyIQ,QuBloIRwyB,GAAAC,EAAAhnB,EAAAf,GvBmoIU,GuBloIVU,GAAAsnB,IvBmoIcC,EAAeC,GuBjoI7B,OAAAxY,IAAAhP,EvBmoImB,MuBhoInBsnB,OAAAA,GAAAA,EAAAA,GAAAA,EAAAA,IACApc,SvBkoIsC,OAAjBuc,GAAyBpnB,EAASf,IAAMooB,EAAgBC,GAAmBJ,EAAeE,EuB/nI/GD,SvBkoIiB,SuB7nIjB,QAAAR,KvBgoIU,MAAO9b,GAAS,KAAO5W,EAAUA,EAAQszB,YAAc1c,EAAS,GAAGlL,UAErE,QAASwnB,KuBxnIjBxwB,MAAAkU,GAAA,KAAA5W,EAAAA,EAAAwL,SAAAknB,KAAAA,aAAA1yB,EAAAA,GAAAA,aAzLA,GAAA0a,MACAyY,EAAAA,QAAAj2B,UAAAtB,EAAA0E,GACAizB,EAAAv4B,EAAA8M,OACA0rB,EAAA,+BAEAlkB,GAAAlU,EAEAJ,EAAAqnB,EACAwQ,EAAAxQ,EACA3H,EAAA5Q,EvB6qIYqpB,EuB5qIZ7jB,EvB6qIYikB,EAAU,KACVC,EuB5qIZ,KACAlkB,EAAA7S,EAAArB,QvB6qIQ,IAAIJ,EAAQqnB,aACV,GAAIrnB,EAAQqnB,aAAa7Q,MAAM,SuB1qIzCkhB,IAAA1jB,GAAAA,GAAA,EAAAlF,EAAA,EAAA9O,EAAAqnB,aAAA,EAAAvY,IAEA9N,EAAAy3B,EAAAA,aAKA7c,GAAArN,QAAAnO,QAAAmf,EAAAA,aAqKAxX,OvBsgIQ2vB,GuBrqIRnY,KAAAA,WACAve,KAAAqe,gBvBsqIUwY,EAAmB3nB,EAAWC,OAAO/P,EAAQ,IAAI4P,IAAMqoB,EuBlqIjEX,GAAAttB,EAAA,GAAA0d,MAAAhY,MAGA8L,EAAA/M,GAAAA,SAAA7N,KAAAA,eACA4a,EAAA/M,GAAAA,QAAA7N,KAAAA,4BACAkd,EAAArP,GAAAA,SAAA7N,KAAAA,oBvBkqIUA,KAAKue,gBuB9pIfmY,KAAArY,8BvBiqIQqY,EAAOttB,QAAU,WuBzpIzBstB,EAAAnY,IAAAA,SAAAve,KAAAue,eAGA3D,EAAAlL,IAAAA,QAAAsnB,KAAAA,4BACA9Z,EAAAnN,IAAAA,SAAAb,KAAAC,qBvB0pIQunB,EuBtpIRgB,2BAAAF,WAGA7Y,WAAA4Y,EAAAG,cAAA,IvBspIQhB,EuBnpIRgB,cAAA,WvBopIU,GuBnpIVF,GAAAR,IACAjnB,EAAA4nB,EAAAxoB,OAAA/P,EAAA,IACAA,EAAA8P,EAAAH,OAAA3P,EAAA,IvBopIcs4B,EAAQZ,EAAsBU,EAAOznB,EAAUqnB,EuBlpI7DG,KAAAZ,IvBopIUY,EuBnpIVn4B,EACAoR,QAAApR,GvBopIYo4B,EAAQ,KACJG,GuBlpIhBv4B,EAAAJ,IAAA44B,QAAAA,IvBqpIgB54B,EuBnpIhB23B,eAGAa,EAAAznB,IAAAA,WAAAL,EAAAA,aAAAA,GAAAA,YvBkpIctQ,EAAQoR,IAAI,MAAO,MuB/oIjC,WAAApR,GAEAo4B,EvBgpIgBx4B,EAAQ44B,cuBhpIxB,EAAAjB,EAAAA,aAEAnmB,EAAAxB,IAAAhQ,EvBmpIgB24B,GuBhpIhBH,EAAAhnB,IAAA,QAAA,IAEApR,EAAAoR,evBkpIcpR,EAAQoR,IAAI,WAAYxR,EAAQqnB,aAAe,GAAK,YuBhpIlEjnB,EAAAJ,IAAA23B,MAAAA,EAAAtQ,aAAA,GAAAjJ,EAAA,GAAAxM,aAAAumB,EAAAC,EAAAP,EAAA,SvBopIYW,EAAQ,KACJG,GuB9oIhBv4B,EAAAqV,IAAAA,QAAAmiB,EAAAjrB,GAAAoF,YAAA2mB,MAIAG,EAAAA,eACAnB,EAAAe,IAAAA,WAAAA,SACAf,EAAAnY,IAAAA,MAAAA,EAAAA,QAIAmY,EAAAe,YAAAA,GAAA9rB,SAAA,SAAA,WAAA+rB,EAAA,IAAAA,EAAA,OvB8oIQhB,EuB3oIR13B,UAAA23B,WvB4oIUD,EuB3oIVt3B,gBvB4oIUs3B,EAAOnY,iBAETmY,EuB1oIRoB,mBAAApZ,EAAAgY,EAAAmB,UAAA,IvB2oIQnB,EuB1oIR13B,cAAA0f,WvB2oIU,GAAIqZ,GAAkB34B,EAAQoR,IAAI,WuBzoI5CxR,GAAAA,cvB2oIYI,EuB1oIZi4B,IAAAA,WAAAr4B,EAAA0f,aAAA,GAAA,YvB4oIc1f,EuB1oId0f,YACA,SvB0oIgB1f,EuB1oIhB0f,YvB2oIc1f,EuB1oId0f,UAAAxP,MvB4oIgBlQ,EuB1oIhB0f,UAAAlJ,MAAA,cACAkJ,EAAA,GAAA1f,EAAA0f,UvB4oIgBA,EADE1f,EAAQqnB,aACEnX,EAAWC,OAAOmE,EAAO,IAAItE,IAA0B,EAApBhQ,EAAQ0f,UuBvoIvE2H,EAAAA,OAAArnB,EAAAm4B,IAAAA,IAAA3hB,EAAAhF,IAAApR,EAAA,GAAA,aAAA,GAAA,EAAAJ,EAAA0f,WAIAyY,EAAAA,EAAAA,EAAAn4B,WAKAA,EAAA23B,evBwoIcQ,EuBvoId/3B,EAAAinB,cAAA0R,EAAAA,aAAAA,MAAAA,avBuoI6Bb,KAAqBhoB,EAAWC,OAAOmE,EAAO,IAAItE,IAAME,EAAWH,OAAOuE,EAAO,KAA8B,EAAvBtU,EAAQm4B,aAAmB,EuBjoIhJpnB,EAAA+mB,EAAAA,cAIApnB,EAAAA,cACAtQ,EAAAoR,IAAA,WAAAunB,IA+BAjxB,EAAAA,OACA4vB,EvB8+HM,GuB9qINtZ,GAAAua,QAAAv4B,QAAA4E,EAAAwL,SAAAG,MACAuN,EAAAma,QAAAA,QAAArzB,EvByzIM,OuBvnINhF,OvBynIK0H,UuBznILoF,WAAAksB,SAAAA,UAAA/xB,SAAAxF,EAAArB,GvB0nII,OACE0H,SuB1nINpG,MvB2nIMqG,QuB1nINtG,kBvB2nIM0B,KuB1nIN,SAAArB,EAAAA,EAAAA,EAAAA,GvB2nIQ,GuB1nIR9B,IvB2nIUoD,MuB1nIVA,EvB2nIU0J,OuB1nIV9M,EAAAi5B,EAAAA,SAAAA,QAAAA,QAAAA,GvB4nIQx3B,SAAQC,SAAU,YAAa,eAAgB,eAAgB,cAAe,gBAAkB,SAASI,GuBxnIjH,GAAA42B,QAAAhB,UAAAt3B,EAAAJ,IAAAA,CACAoD,GAAAiH,GAAAxC,EAAA/F,EACA42B,SAAAA,KAAAtuB,KAAAA,GAAAA,GACApK,SAAAqI,KAAA4wB,KAAAA,GAAA,GACAP,EAAA52B,GAAAm3B,IvB4nIQ,IAAIP,GAAQhB,EAAOt3B,EAASJ,EuBpnIpC0H,GAAAA,IAAA,WAAA,WACAgxB,GAAAA,EAAAtuB,UACAlJ,EAAA,KACAF,EAAAiG,YCpPAxF,UAAA,gBAAA,WxB0/LGgmB,OA3oDGvmB,YAAc,WAAY,SAAS+F,GACjCjG,KAAKiG,SAAWA,OAItBxF,QAAQhB,OAAO,kBAAoB,uBAAwB,uBAAwB,uBAAwB,wBAAyB,wBAAyB,4BAA6B,4BAA6B,wBAAyB,yBAA0B,yBAA0B,0BAA2B,2BAA4B,2BAA4B,uBAAwB,qBAAsB,6BACpagnB,OAAQjX","file":"angular-strap.min.js","sourcesContent":["(function(window, document, undefined) {\n'use strict';\n\n// Source: typeahead/typeahead.js\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n function TypeaheadFactory (element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function () {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function (matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function (index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function (index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) {\n options.onSelect(value, index, $typeahead);\n }\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function () {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $typeahead.$onMouseDown = function (evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function (evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n // Navigate with keyboard\n } else if (evt.keyCode === 38 && scope.$activeIndex > 0) {\n scope.$activeIndex--;\n } else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) {\n scope.$activeIndex++;\n } else if (angular.isUndefined(scope.$activeIndex)) {\n scope.$activeIndex = 0;\n }\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function () {\n if ($typeahead.$element) {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $typeahead.$onKeyDown);\n }\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function () {\n if ($typeahead.$element) $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect) {\n $typeahead.activate(-1);\n }\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function ($filter) {\n return function (array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function (results) {\n return $filter('filter')(results, expression, comparator);\n });\n }\n return $filter('filter')(array, expression, comparator);\n };\n })\n\n .directive('bsTypeahead', function ($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Fixes firefox bug when using objects in model with typeahead\n // Yes this breaks any other directive using a 'change' event on this input,\n // but if it is using the 'change' event why is it used with typeahead?\n element.off('change');\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue', 'filter'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show, hide and select events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = angular.isDefined(options.filter) ? options.filter : defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) {\n bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n }\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function (values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (angular.isDefined(modelValue) && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = index !== -1 ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n var ss = element[0].selectionStart;\n var sd = element[0].selectionEnd;\n element.val(options.trimValue === false ? value : value.trim());\n element[0].setSelectionRange(ss, sd);\n };\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n\n// Source: tab/tab.js\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function (pane) {\n if (angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function (pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if (angular.isString(active)) {\n activeIndex = self.$panes.map(function (pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n } else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if (activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function (value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function ($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function () {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function ($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function (element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function (newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function ($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function (newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if (bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function (newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function () {\n bsTabsCtrl.$remove(scope);\n });\n\n function render () {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: tooltip/tooltip.js\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n titleTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n mouseDownPreventDefault: true,\n mouseDownStopPropagation: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n var $body = angular.element($window.document);\n\n function TooltipFactory (element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if (options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if (options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function (isEnabled) {\n scope.$$postDigest(function () {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $tooltip.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $tooltip.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout;\n var hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData;\n var tipElement;\n var tipContainer;\n var tipScope;\n promise.then(function (data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function () {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if (options.container === 'self') {\n tipContainer = element;\n } else if (angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if (options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if (options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n if (options.trigger === 'focus') {\n element[0].focus();\n } else {\n $tooltip.show();\n }\n });\n }\n\n };\n\n $tooltip.destroy = function () {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function () {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function () {\n if (hoverState === 'in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function () {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) {\n options.onBeforeShow($tooltip);\n }\n var parent;\n var after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if (tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function (clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if (options.animation) tipElement.addClass(options.animation);\n // Options: type\n if (options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if (options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n if (after) {\n after.after(tipElement);\n } else {\n parent.prepend(tipElement);\n }\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if (tipElement) tipElement.css({visibility: 'visible'});\n\n // Bind events\n if (options.keyboard) {\n if (options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n });\n\n if (options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) {\n options.onShow($tooltip);\n }\n }\n\n $tooltip.leave = function () {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function (blur) {\n\n if (!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) {\n options.onBeforeHide($tooltip);\n }\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if (options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if (options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) {\n options.onHide($tooltip);\n }\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if (_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function (evt) {\n if (evt) { evt.preventDefault(); }\n if ($tooltip.$isShown) {\n $tooltip.leave();\n } else {\n $tooltip.enter();\n }\n };\n\n $tooltip.focus = function () {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function (isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function (viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function () {\n if (!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement;\n var autoToken = /\\s?auto?\\s?/i;\n var autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition();\n var tipWidth = tipElement.prop('offsetWidth');\n var tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n if (/bottom/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (/top/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n if (/left/.test(originalPlacement) && elementPosition.left - tipWidth < viewportPosition.left) {\n placement = placement.replace('left', 'right');\n } else if (/right/.test(originalPlacement) && elementPosition.right + tipWidth > viewportPosition.width) {\n placement = placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function (evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function (evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function (evt) {\n if (options.mouseDownPreventDefault) { evt.preventDefault(); }\n if (options.mouseDownStopPropagation) { evt.stopPropagation(); }\n // Some browsers do not auto-focus buttons (eg. Safari)\n if ($tooltip.$isShown) {\n element[0].blur();\n } else {\n element[0].focus();\n }\n };\n\n // bind/unbind events\n function bindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function (trigger) {\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.on(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n });\n }\n\n function unbindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.off(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n }\n\n function bindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents () {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents () {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation (event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition ($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0];\n var isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n /* eslint-disable guard-for-in */\n for (var p in elRect) { // eslint-disable-line\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n /* eslint-enable guard-for-in */\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, {width: elRect.right - elRect.left, height: elRect.bottom - elRect.top});\n }\n var elOffset = isBody ? {top: 0, left: 0} : dimensions.offset(el);\n var scroll = {scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0};\n var outerDims = isBody ? {width: document.documentElement.clientWidth, height: $window.innerHeight} : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset (placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if (!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if (split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n break;\n default:\n break;\n }\n } else if (split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight + position.height;\n break;\n case 'bottom':\n offset.top = position.top;\n break;\n default:\n break;\n }\n }\n\n return offset;\n }\n\n function applyPlacement (offset, placement) {\n var tip = tipElement[0];\n var width = tip.offsetWidth;\n var height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10);\n var marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth;\n var actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement);\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight;\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta (placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow (delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement () {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if ($tooltip.$isShown && tipElement !== null) {\n if (options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if (options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if (tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if (tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function ($window, $location, $sce, $parse, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n var tooltip;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'titleTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function (newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }\n });\n\n attr.$observe('disabled', function (newValue) {\n if (newValue && tooltip.$isShown) {\n tooltip.hide();\n }\n });\n\n // Support scope as an object\n if (attr.bsTooltip) {\n scope.$watch(attr.bsTooltip, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n if (newValue === true) {\n tooltip.show();\n } else {\n tooltip.hide();\n }\n });\n }\n\n // Enabled binding support\n if (attr.bsEnabled) {\n scope.$watch(attr.bsEnabled, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n if (newValue === false) {\n tooltip.setEnabled(false);\n } else {\n tooltip.setEnabled(true);\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n }\n\n // Initialize popover\n tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n\n// Source: timepicker/timepicker.js\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n defaultDate: 'auto',\n // uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory (element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes (time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format);\n var timeSeparator = $dateFormatter.timeSeparator(format);\n var minutesFormat = $dateFormatter.minutesFormat(format);\n var secondsFormat = $dateFormatter.secondsFormat(format);\n var showSeconds = $dateFormatter.showSeconds(format);\n var showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function (date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function (value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function (date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function (date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function (date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n controller.$dateValue = options.defaultDate === 'today' ? new Date() : new Date(1970, 0, 1);\n }\n\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function (date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function () {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i;\n var midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [];\n var hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [];\n var minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [];\n var second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function (date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function (date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function (value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function (value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function (value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours();\n var hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes();\n var minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds();\n var secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection (start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if ($timepicker.$element) $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function (blur) {\n if (!$timepicker.$isShown) return;\n if ($timepicker.$element) $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent', 'defaultDate'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n if (newValue === true) {\n timepicker.show();\n } else {\n timepicker.hide();\n }\n });\n }\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n if (!isNaN(timepicker.$options[key])) timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n }\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime (parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n }\n validateAgainstMinMaxTime(parsedTime);\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n\n// Source: scrollspy/scrollspy.js\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function () {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function ($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName (element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory (config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if (!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if (spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded;\n var unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n /* eslint-disable no-unused-vars */\n var viewportHeight;\n /* eslint-enable no-unused-vars */\n var scrollTop;\n\n $scrollspy.init = function () {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if (scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function () {\n\n // Check internal ref counter\n this.$$count--;\n if (this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function () {\n\n // Not ready yet\n if (!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if (activeTarget === sortedElements[i].target) continue;\n if (scrollTop < sortedElements[i].offsetTop) continue;\n if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function () {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function (element) {\n if (activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if (activeElement) {\n activeElement.source.removeClass('active');\n if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function (target) {\n return trackedElements.filter(function (obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function () {\n\n angular.forEach(trackedElements, function (trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function (el) {\n return el.offsetTop !== null;\n })\n .sort(function (a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function (target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function (target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if (trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function (i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink (scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function () {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink (element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n\n// Source: select/select.js\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' <span class=\"caret\"></span>',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok',\n toggle: false\n };\n\n this.$get = function ($window, $document, $rootScope, $tooltip, $timeout) {\n\n // var bodyEl = angular.element($window.document.body);\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory (element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n } else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $select.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $select.$isVisible();\n };\n\n scope.$isActive = function (index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function (matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function (index) {\n if (options.multiple) {\n if ($select.$isActive(index)) {\n scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1);\n } else {\n scope.$activeIndex.push(index);\n }\n if (options.sort) scope.$activeIndex.sort(function (a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function (index) {\n if (angular.isUndefined(index) || index < 0 || index >= scope.$matches.length) { return; }\n var value = scope.$matches[index].value;\n scope.$apply(function () {\n $select.activate(index);\n if (options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function (index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n if (options.toggle) {\n controller.$setViewValue((value === controller.$modelValue) ? undefined : value);\n } else {\n controller.$setViewValue(value);\n }\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) {\n options.onSelect(value, index, $select);\n }\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function () {\n if (options.multiple) {\n if (angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function (value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if (angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\n }\n };\n\n $select.$isVisible = function () {\n if (!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function (index) {\n if (options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n }\n return scope.$activeIndex === index;\n };\n\n $select.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $select.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function (evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if (!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function () {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function (e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function () {\n _show();\n if (options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function () {\n if (!options.multiple && angular.isUndefined(controller.$modelValue)) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function ($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent', 'toggle'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show, hide and select events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if (angular.isDefined(dataMultiple)) {\n if (falseValueRegExp.test(dataMultiple)) {\n options.multiple = false;\n } else {\n options.multiple = dataMultiple;\n }\n }\n\n // Add support for select markup\n if (element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('<button type=\"button\" class=\"btn btn-default\"></button>');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watch(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n select.update(values);\n controller.$render();\n });\n }, true);\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected;\n var index;\n if (options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function (value) {\n index = select.$getIndex(value);\n return index !== -1 ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if (selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = index !== -1 ? select.$scope.$matches[index].label : false;\n }\n element.html((selected || options.placeholder) + (options.caretHtml || defaults.caretHtml));\n };\n\n if (options.multiple) {\n controller.$isEmpty = function (value) {\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n\n// Source: popover/popover.js\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function ($tooltip) {\n\n function PopoverFactory (element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if (options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function ($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr) {\n\n var popover;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsPopover) {\n scope.$watch(attr.bsPopover, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n if (newValue === true) {\n popover.show();\n } else {\n popover.hide();\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n }\n\n // Initialize popover\n popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n\n// Source: navbar/navbar.js\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function ($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function () {\n\n return $location.path();\n\n }, function (newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function (li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if (options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if (regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n\n// Source: modal/modal.js\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n customClass: '',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true,\n size: null\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n var backdropCount = 0;\n var dialogBaseZindex = 1050;\n var backdropBaseZindex = 1040;\n\n var validSizes = {\n lg: 'modal-lg',\n sm: 'modal-sm'\n };\n\n function ModalFactory (config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if (!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function (key) {\n if (options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $modal.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $modal.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData;\n var modalElement;\n var modalScope;\n var backdropElement = angular.element('<div class=\"' + options.prefixClass + '-backdrop\"/>');\n backdropElement.css({position: 'fixed', top: '0px', left: '0px', bottom: '0px', right: '0px'});\n promise.then(function (data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function () {\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function () {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if (backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function () {\n if ($modal.$isShown) return;\n\n var parent;\n var after;\n if (angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if (modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function (clonedElement, scope) {});\n\n if (options.backdrop) {\n // set z-index\n modalElement.css({'z-index': dialogBaseZindex + (backdropCount * 20)});\n backdropElement.css({'z-index': backdropBaseZindex + (backdropCount * 20)});\n\n // increment number of backdrops\n backdropCount++;\n }\n\n if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) {\n options.onBeforeShow($modal);\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: customClass\n if (options.customClass) {\n modalElement.addClass(options.customClass);\n }\n\n // Options: size\n if (options.size && validSizes[options.size]) {\n angular.element(findElement('.modal-dialog', modalElement[0])).addClass(validSizes[options.size]);\n }\n\n // Options: animation\n if (options.animation) {\n if (options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if (options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function () {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $modal);\n if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) {\n options.onShow($modal);\n }\n }\n\n $modal.hide = function () {\n if (!$modal.$isShown) return;\n\n if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) {\n options.onBeforeHide($modal);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if (options.backdrop) {\n // decrement number of backdrops\n backdropCount--;\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) {\n options.onHide($modal);\n }\n bodyElement.removeClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function () {\n if ($modal.$isShown) {\n $modal.hide();\n } else {\n $modal.show();\n }\n };\n\n $modal.focus = function () {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function (evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents () {\n if (options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents () {\n if (options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick (evt) {\n if (evt.target !== evt.currentTarget) return;\n if (options.backdrop === 'static') {\n $modal.focus();\n } else {\n $modal.hide();\n }\n }\n\n function preventEventDefault (evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement () {\n if ($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if (modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if (modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function ($window, $sce, $parse, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass', 'customClass', 'modalClass', 'size'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Options: alias modalClass to customClass\n if (options.modalClass) {\n options.customClass = options.modalClass;\n }\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsModal) {\n scope.$watch(attr.bsModal, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n\n// Source: dropdown/dropdown.js\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory (element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n /* var scope = */$dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function (evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function (el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if (options.keyboard && $dropdown.$element) $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n if (parentEl.hasClass('dropdown')) parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function () {\n if (!$dropdown.$isShown) return;\n if (options.keyboard && $dropdown.$element) $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n if (parentEl.hasClass('dropdown')) parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function () {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick (evt) {\n if (evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function ($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n compile: function (tElement, tAttrs) {\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling && nextSibling.className.split(' ').indexOf('dropdown-menu') >= 0) {\n tAttrs.template = nextSibling.outerHTML;\n tAttrs.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink (scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id', 'autoClose'], function (key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as an object\n if (attr.bsDropdown) {\n scope.$watch(attr.bsDropdown, function (newValue, oldValue) {\n scope.content = newValue;\n }, true);\n }\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!dropdown || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n if (newValue === true) {\n dropdown.show();\n } else {\n dropdown.hide();\n }\n });\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n };\n }\n };\n\n });\n\n// Source: helpers/raf.js\nif (angular.version.minor < 3 && angular.version.dot < 14) {\n angular.module('ng')\n\n .factory('$$rAF', function ($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function (fn) {\n var id = requestAnimationFrame(fn);\n return function () {\n cancelAnimationFrame(id);\n };\n } :\n function (fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function () {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n });\n}\n\n// Source: helpers/parse-options.js\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function () {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function ($parse, $q) {\n\n function ParseOptionsFactory (attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match;\n var displayFn;\n var valueName;\n /* eslint-disable no-unused-vars */\n var keyName;\n var groupByFn;\n /* eslint-enable no-unused-vars */\n var valueFn;\n var valuesFn;\n\n $parseOptions.init = function () {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]);\n valueName = match[4] || match[6];\n keyName = match[5];\n groupByFn = $parse(match[3] || '');\n valueFn = $parse(match[2] ? match[1] : valueName);\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function (scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function (values) {\n if (!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function (modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues (values, scope) {\n return values.map(function (match, index) {\n var locals = {};\n var label;\n var value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n\n// Source: helpers/dimensions.js\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function () {\n\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function (element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function (element, prop, extra) {\n var value;\n if (element.currentStyle) { // IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function (element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n\n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition;\n var curLeft;\n var curCSSTop;\n var curTop;\n var curOffset;\n var curCSSLeft;\n var calculatePosition;\n var position = fn.css(element, 'position');\n var curElem = angular.element(element);\n var props = {};\n\n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n\n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') &&\n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n\n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n\n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n\n if (options.top !== null) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if (options.left !== null) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function (element) {\n\n var offsetParentRect = {top: 0, left: 0};\n var offsetParentEl;\n var offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentEl\n offsetParentEl = offsetParentElement(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentEl, 'html')) {\n offsetParentRect = fn.offset(offsetParentEl);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentEl, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n function offsetParentElement (element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if (nodeName(offsetParent, '#document')) return docElement.documentElement;\n while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n }\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function (element, outer) {\n var value = element.offsetHeight;\n if (outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function (element, outer) {\n var value = element.offsetWidth;\n if (outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n\n// Source: helpers/debounce.js\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function ($timeout) {\n return function (func, wait, immediate) {\n var timeout = null;\n return function () {\n var context = this;\n var args = arguments;\n var callNow = immediate && !timeout;\n if (timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if (callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function ($timeout) {\n return function (func, wait, options) {\n var timeout = null;\n if (!options) options = {};\n return function () {\n var context = this;\n var args = arguments;\n if (!timeout) {\n if (options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n\n// Source: helpers/date-parser.js\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function ($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate () {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function (value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function (value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function (value) { this.minutes = value; };\n ParseDate.prototype.setHours = function (value) { this.hours = value; };\n ParseDate.prototype.getHours = function () { return this.hours; };\n ParseDate.prototype.setDate = function (value) { this.day = value; };\n ParseDate.prototype.setMonth = function (value) { this.month = value; };\n ParseDate.prototype.setFullYear = function (value) { this.year = value; };\n ParseDate.prototype.fromDate = function (value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function () {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop () {\n }\n\n function isNumeric (n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive (array, value) {\n var len = array.length;\n var str = value.toString().toLowerCase();\n for (var i = 0; i < len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function ($locale, dateFilter) {\n\n var DateParserFactory = function (config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n /* eslint-disable key-spacing, quote-props */\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}'\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function (value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function (value) { return this.setMonth(1 * value - 1); },\n 'M' : function (value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function (value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : function (value) { return (1 * value <= 50 && value.length === 2) ? this.setFullYear(2000 + 1 * value) : this.setFullYear(1 * value); }\n };\n /* eslint-enable key-spacing, quote-props */\n\n var regex;\n var setMap;\n\n $dateParser.init = function () {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function (date) {\n if (angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function (value, baseDate, format, timezone) {\n // check for date format special names\n if (format) format = $locale.DATETIME_FORMATS[format] || format;\n if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if (!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for (var i = 0; i < matches.length - 1; i++) {\n if (formatSetMap[i]) formatSetMap[i].call(date, matches[i + 1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function (key, value) {\n var date;\n\n if (value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if (isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && value.length === 0) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function (key, value) {\n var time;\n\n if (value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if (isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.length === 0) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function (date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function (date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function regExpForFormat (format) {\n // `format` string can contain literal values.\n // These need to be escaped by surrounding with\n // single quotes (e.g. `\"h 'in the morning'\"`).\n // In order to output a single quote, escape it - i.e.,\n // two single quotes in a sequence (e.g. `\"h 'o''clock'\"`).\n\n var re = buildDateAbstractRegex(format);\n return buildDateParseRegex(re);\n }\n\n function buildDateAbstractRegex (format) {\n var escapedFormat = escapeReservedSymbols(format);\n var escapedLiteralFormat = escapedFormat.replace(/''/g, '\\\\\\'');\n var literalRegex = /('(?:\\\\'|.)*?')/;\n var formatParts = escapedLiteralFormat.split(literalRegex);\n var dateElements = Object.keys(regExpMap);\n var dateRegexParts = [];\n\n angular.forEach(formatParts, function (part) {\n if (isFormatStringLiteral(part)) {\n part = trimLiteralEscapeChars(part);\n } else {\n // Abstract replaces to avoid collisions\n for (var i = 0; i < dateElements.length; i++) {\n part = part.split(dateElements[i]).join('${' + i + '}');\n }\n }\n dateRegexParts.push(part);\n });\n\n return dateRegexParts.join('');\n }\n\n function escapeReservedSymbols (text) {\n return text.replace(/\\\\/g, '[\\\\\\\\]')\n .replace(/-/g, '[-]')\n .replace(/\\./g, '[.]')\n .replace(/\\*/g, '[*]')\n .replace(/\\+/g, '[+]')\n .replace(/\\?/g, '[?]')\n .replace(/\\$/g, '[$]')\n .replace(/\\^/g, '[^]')\n .replace(/\\//g, '[/]')\n .replace(/\\\\s/g, '[\\\\s]');\n }\n\n function isFormatStringLiteral (text) {\n return /^'.*'$/.test(text);\n }\n\n function trimLiteralEscapeChars (text) {\n return text.replace(/^'(.*)'$/, '$1');\n }\n\n function buildDateParseRegex (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var re = abstractRegex;\n\n // Replace abstracted values\n for (var i = 0; i < dateElements.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')');\n }\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n function setMapForFormat (format) {\n var re = buildDateAbstractRegex(format);\n return buildDateParseValuesMap(re);\n }\n\n function buildDateParseValuesMap (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var valuesRegex = new RegExp('\\\\${(\\\\d+)}', 'g');\n var valuesMatch;\n var keyIndex;\n var valueKey;\n var valueFunction;\n var valuesFunctionMap = [];\n\n /* eslint-disable no-cond-assign */\n while ((valuesMatch = valuesRegex.exec(abstractRegex)) !== null) {\n keyIndex = valuesMatch[1];\n valueKey = dateElements[keyIndex];\n valueFunction = setFnMap[valueKey];\n\n valuesFunctionMap.push(valueFunction);\n }\n\n return valuesFunctionMap;\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n\n// Source: helpers/date-formatter.js\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function ($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function () {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function (format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function (lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat (format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function (timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function (date, format, lang, timezone) {\n return dateFilter(date, format, timezone);\n };\n\n });\n\n// Source: helpers/compiler.js\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService ($q, $http, $injector, $compile, $controller, $templateCache) {\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * <hljs lang=\"js\">\n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * </hljs>\n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function (options) {\n\n if (options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function (value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\n }\n\n if (options.titleTemplate) {\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.titleTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n findElement('[ng-bind=\"title\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n return templateEl[0].outerHTML;\n });\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if (!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function (locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('<div>').html(template.trim()).contents();\n var element = angular.element('<div>').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link (scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate (template) {\n if (fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function (res) {\n return res.data;\n }));\n }\n\n}\n\n// Source: datepicker/datepicker.js\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // Uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n hasToday: false,\n hasClear: false,\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory (element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if (options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n scope.$hasToday = options.hasToday;\n scope.$hasClear = options.hasClear;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function (date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function (value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function () {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n scope.$setToday = function () {\n if (options.autoclose) {\n $datepicker.setMode(0);\n $datepicker.select(new Date());\n } else {\n $datepicker.select(new Date(), true);\n }\n };\n scope.$clear = function () {\n if (options.autoclose) {\n $datepicker.setMode(0);\n $datepicker.select(null);\n } else {\n $datepicker.select(null, true);\n }\n };\n\n // Public methods\n\n $datepicker.update = function (date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function (dateRanges) {\n options.disabledDateRanges = dateRanges;\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function (date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if (angular.isDate(date)) {\n if (!angular.isDate(controller.$dateValue) || isNaN(controller.$dateValue.getTime())) {\n controller.$dateValue = new Date(date);\n }\n } else {\n controller.$dateValue = null;\n }\n if (!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function (mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function (pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if (pristine === true && $picker.built) return;\n if (pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function () {\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function (date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function (el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function (value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if (evt.keyCode === 13) {\n if (!scope.$mode) {\n $datepicker.hide(true);\n } else {\n scope.$apply(function () { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected (el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // if $datepicker is no longer showing, don't setup events\n if (!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function (blur) {\n if (!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n // var defaults = $datepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent', 'hasToday', 'hasClear'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'hasToday', 'hasClear'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!datepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n if (newValue === true) {\n datepicker.show();\n } else {\n datepicker.hide();\n }\n });\n }\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n if (!isNaN(datepicker.$options[key])) datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n }\n });\n\n // Observe date format\n if (angular.isDefined(attr.dateFormat)) {\n attr.$observe('dateFormat', function (newValue) {\n datepicker.$options.dateFormat = newValue;\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges (ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function (disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate (parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n }\n validateAgainstMinMaxDate(parsedDate);\n\n if (options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.dateType === 'number') {\n return date.getTime();\n } else if (options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.dateType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if (options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if (isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function () {\n\n // var defaults = this.defaults = {\n // dayFormat: 'dd',\n // daySplit: 7\n // };\n\n // Split array into smaller arrays\n function split (arr, size) {\n var arrays = [];\n while (arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod (n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function ($dateFormatter, $dateParser, $sce) {\n\n return function (picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('<th class=\"dow text-center\">' + weekDaysLabels.join('</th><th class=\"dow text-center\">') + '</th>');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: {month: 1},\n update: function (date, force) {\n if (!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1);\n var firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5);\n var firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if (firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [];\n var day;\n for (var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n scope.isTodayDisabled = this.isDisabled(new Date());\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function (date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if (evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if (evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if (evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if (evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: {year: 1},\n update: function (date, force) {\n if (!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n // var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [];\n var month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if (evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if (evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if (evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: {year: 12},\n update: function (date, force) {\n if (!this.built || force || parseInt(date.getFullYear() / 20, 10) !== parseInt(viewDate.year / 20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [];\n var year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if (evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if (evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if (evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n\n// Source: button/button.js\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n toggleEvent: 'click'\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if (constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if (constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if (hasExoticValues) {\n controller.$parsers.push(function (viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if (!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if (!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function (child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function (v) {\n if (typeof v !== 'boolean' && constantValueRegExp.test(v)) {\n value = scope.$eval(v);\n } else {\n value = v;\n }\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n\n// Source: collapse/collapse.js\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function () {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function (element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function (element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function (element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function (element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function (value) {\n if (angular.isArray(value)) {\n self.$targets.$active = value;\n } else if (!self.$options.disallowToggle && isActive(value)) {\n deactivateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function () {\n if (self.$options.allowMultiple) {\n return self.$targets.$active;\n }\n return self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes (index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for (var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive (value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) !== -1;\n }\n\n function deactivateItem (value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem (value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function () {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function ($window, $animate, $collapse) {\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n } else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n } else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function () {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function () {\n if (!attrs.disabled) {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n }\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function ($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if (bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render () {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n } else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n\n// Source: aside/aside.js\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function ($modal) {\n\n function AsideFactory (config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function ($window, $sce, $aside) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAside) {\n scope.$watch(attr.bsAside, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n\n// Source: alert/alert.js\n// @BUG: following snippet won't compile correctly\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function ($modal, $timeout) {\n\n function AlertFactory (config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if (options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if (options.duration) {\n $alert.show = function () {\n show();\n $timeout(function () {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function ($window, $sce, $alert) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAlert) {\n scope.$watch(attr.bsAlert, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n\n// Source: affix/affix.js\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function () {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function ($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory (element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom';\n var setWidth = false;\n var initialAffixTop = 0;\n var initialOffsetTop = 0;\n var offsetTop = 0;\n var offsetBottom = 0;\n var affixed = null;\n var unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n } else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function () {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function () {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function () {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function () {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if (affixed === affix) return;\n affixed = affix;\n\n if (affix === 'top') {\n unpin = null;\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if (affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n } else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if (setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function () {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function () {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if (options.offsetTop) {\n if (options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if (options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if (options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n } else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n } else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if (options.offsetBottom) {\n if (options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n } else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles) {\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass (_unpin, position, elementHeight) {\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if (scrollTop <= offsetTop) {\n return 'top';\n } else if (_unpin !== null && (scrollTop + _unpin <= position.top)) {\n return 'middle';\n } else if (offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n }\n return 'middle';\n }\n\n function getScrollTop () {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight () {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function ($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink (scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function (key) {\n if (angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function () {\n if (affix) affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function () {\n return {\n controller: function ($element) {\n this.$element = $element;\n }\n };\n });\n\n// Source: module.js\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n\n})(window, document);\n","'use strict';\n\nangular.module('mgcrea.ngStrap.typeahead', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$typeahead', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'typeahead',\n prefixEvent: '$typeahead',\n placement: 'bottom-left',\n templateUrl: 'typeahead/typeahead.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n minLength: 1,\n filter: 'bsAsyncFilter',\n limit: 6,\n autoSelect: false,\n comparator: '',\n trimValue: true\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $$rAF, $timeout) {\n\n function TypeaheadFactory (element, controller, config) {\n\n var $typeahead = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $typeahead = $tooltip(element, options);\n var parentScope = config.scope;\n var scope = $typeahead.$scope;\n\n scope.$resetMatches = function () {\n scope.$matches = [];\n scope.$activeIndex = options.autoSelect ? 0 : -1; // If set to 0, the first match will be highlighted\n };\n scope.$resetMatches();\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $typeahead.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $typeahead.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $typeahead.$isVisible();\n };\n\n // Public methods\n\n $typeahead.update = function (matches) {\n scope.$matches = matches;\n if (scope.$activeIndex >= matches.length) {\n scope.$activeIndex = options.autoSelect ? 0 : -1;\n }\n\n // wrap in a $timeout so the results are updated\n // before repositioning\n safeDigest(scope);\n $$rAF($typeahead.$applyPlacement);\n };\n\n $typeahead.activate = function (index) {\n scope.$activeIndex = index;\n };\n\n $typeahead.select = function (index) {\n if (index === -1) return;\n var value = scope.$matches[index].value;\n // console.log('$setViewValue', value);\n controller.$setViewValue(value);\n controller.$render();\n scope.$resetMatches();\n if (parentScope) parentScope.$digest();\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $typeahead);\n if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) {\n options.onSelect(value, index, $typeahead);\n }\n };\n\n // Protected methods\n\n $typeahead.$isVisible = function () {\n if (!options.minLength || !controller) {\n return !!scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && angular.isString(controller.$viewValue) && controller.$viewValue.length >= options.minLength;\n };\n\n $typeahead.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $typeahead.$onMouseDown = function (evt) {\n // Prevent blur on mousedown\n evt.preventDefault();\n evt.stopPropagation();\n };\n\n $typeahead.$onKeyDown = function (evt) {\n if (!/(38|40|13)/.test(evt.keyCode)) return;\n\n // Let ngSubmit pass if the typeahead tip is hidden or no option is selected\n if ($typeahead.$isVisible() && !(evt.keyCode === 13 && scope.$activeIndex === -1)) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // Select with enter\n if (evt.keyCode === 13 && scope.$matches.length) {\n $typeahead.select(scope.$activeIndex);\n // Navigate with keyboard\n } else if (evt.keyCode === 38 && scope.$activeIndex > 0) {\n scope.$activeIndex--;\n } else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) {\n scope.$activeIndex++;\n } else if (angular.isUndefined(scope.$activeIndex)) {\n scope.$activeIndex = 0;\n }\n scope.$digest();\n };\n\n // Overrides\n\n var show = $typeahead.show;\n $typeahead.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed immediately.\n $timeout(function () {\n if ($typeahead.$element) {\n $typeahead.$element.on('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $typeahead.$onKeyDown);\n }\n }\n }, 0, false);\n };\n\n var hide = $typeahead.hide;\n $typeahead.hide = function () {\n if ($typeahead.$element) $typeahead.$element.off('mousedown', $typeahead.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $typeahead.$onKeyDown);\n }\n if (!options.autoSelect) {\n $typeahead.activate(-1);\n }\n hide();\n };\n\n return $typeahead;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n TypeaheadFactory.defaults = defaults;\n return TypeaheadFactory;\n\n };\n\n })\n\n .filter('bsAsyncFilter', function ($filter) {\n return function (array, expression, comparator) {\n if (array && angular.isFunction(array.then)) {\n return array.then(function (results) {\n return $filter('filter')(results, expression, comparator);\n });\n }\n return $filter('filter')(array, expression, comparator);\n };\n })\n\n .directive('bsTypeahead', function ($window, $parse, $q, $typeahead, $parseOptions) {\n\n var defaults = $typeahead.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Fixes firefox bug when using objects in model with typeahead\n // Yes this breaks any other directive using a 'change' event on this input,\n // but if it is using the 'change' event why is it used with typeahead?\n element.off('change');\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'filter', 'limit', 'minLength', 'watchOptions', 'selectMode', 'autoSelect', 'comparator', 'id', 'prefixEvent', 'prefixClass'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'trimValue', 'filter'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show, hide and select events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Disable browser autocompletion\n if (!element.attr('autocomplete')) element.attr('autocomplete', 'off');\n\n // Build proper bsOptions\n var filter = angular.isDefined(options.filter) ? options.filter : defaults.filter;\n var limit = options.limit || defaults.limit;\n var comparator = options.comparator || defaults.comparator;\n\n var bsOptions = attr.bsOptions;\n if (filter) {\n bsOptions += ' | ' + filter + ':$viewValue';\n if (comparator) bsOptions += ':' + comparator;\n }\n if (limit) bsOptions += ' | limitTo:' + limit;\n var parsedOptions = $parseOptions(bsOptions);\n\n // Initialize typeahead\n var typeahead = $typeahead(element, controller, options);\n\n // Watch options on demand\n if (options.watchOptions) {\n // Watch bsOptions values before filtering for changes, drop function calls\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').replace(/\\(.*\\)/g, '').trim();\n scope.$watchCollection(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller).then(function (values) {\n typeahead.update(values);\n controller.$render();\n });\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('$watch', element.attr('ng-model'), newValue);\n scope.$modelValue = newValue; // Publish modelValue on scope for custom templates\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n // Prevent input with no future prospect if selectMode is truthy\n // @TODO test selectMode\n if (options.selectMode && !values.length && newValue.length > 0) {\n controller.$setViewValue(controller.$viewValue.substring(0, controller.$viewValue.length - 1));\n return;\n }\n if (values.length > limit) values = values.slice(0, limit);\n typeahead.update(values);\n // Queue a new rendering that will leverage collection loading\n controller.$render();\n });\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var displayValue = parsedOptions.displayValue(modelValue);\n\n // If we can determine the displayValue, use that\n if (displayValue) {\n return displayValue;\n }\n\n // If there's no display value, attempt to use the modelValue.\n // If the model is an object not much we can do\n if (angular.isDefined(modelValue) && typeof modelValue !== 'object') {\n return modelValue;\n }\n return '';\n });\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n if (controller.$isEmpty(controller.$viewValue)) {\n return element.val('');\n }\n var index = typeahead.$getIndex(controller.$modelValue);\n var selected = index !== -1 ? typeahead.$scope.$matches[index].label : controller.$viewValue;\n selected = angular.isObject(selected) ? parsedOptions.displayValue(selected) : selected;\n var value = selected ? selected.toString().replace(/<(?:.|\\n)*?>/gm, '') : '';\n var ss = element[0].selectionStart;\n var sd = element[0].selectionEnd;\n element.val(options.trimValue === false ? value : value.trim());\n element[0].setSelectionRange(ss, sd);\n };\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (typeahead) typeahead.destroy();\n options = null;\n typeahead = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n// NOTICE: This file was forked from the angular-material project (github.com/angular/material)\n// MIT Licensed - Copyright (c) 2014-2015 Google, Inc. http://angularjs.org\n\nangular.module('mgcrea.ngStrap.core', [])\n .service('$bsCompiler', bsCompilerService);\n\nfunction bsCompilerService ($q, $http, $injector, $compile, $controller, $templateCache) {\n\n /*\n * @ngdoc service\n * @name $bsCompiler\n * @module material.core\n * @description\n * The $bsCompiler service is an abstraction of angular's compiler, that allows the developer\n * to easily compile an element with a templateUrl, controller, and locals.\n *\n * @usage\n * <hljs lang=\"js\">\n * $bsCompiler.compile({\n * templateUrl: 'modal.html',\n * controller: 'ModalCtrl',\n * locals: {\n * modal: myModalInstance;\n * }\n * }).then(function(compileData) {\n * compileData.element; // modal.html's template in an element\n * compileData.link(myScope); //attach controller & scope to element\n * });\n * </hljs>\n */\n\n /*\n * @ngdoc method\n * @name $bsCompiler#compile\n * @description A helper to compile an HTML template/templateUrl with a given controller,\n * locals, and scope.\n * @param {object} options An options object, with the following properties:\n *\n * - `controller` - `{(string=|function()=}` Controller fn that should be associated with\n * newly created scope or the name of a registered controller if passed as a string.\n * - `controllerAs` - `{string=}` A controller alias name. If present the controller will be\n * published to scope under the `controllerAs` name.\n * - `template` - `{string=}` An html template as a string.\n * - `templateUrl` - `{string=}` A path to an html template.\n * - `transformTemplate` - `{function(template)=}` A function which transforms the template after\n * it is loaded. It will be given the template string as a parameter, and should\n * return a a new string representing the transformed template.\n * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should\n * be injected into the controller. If any of these dependencies are promises, the compiler\n * will wait for them all to be resolved, or if one is rejected before the controller is\n * instantiated `compile()` will fail..\n * * `key` - `{string}`: a name of a dependency to be injected into the controller.\n * * `factory` - `{string|function}`: If `string` then it is an alias for a service.\n * Otherwise if function, then it is injected and the return value is treated as the\n * dependency. If the result is a promise, it is resolved before its value is\n * injected into the controller.\n *\n * @returns {object=} promise A promise, which will be resolved with a `compileData` object.\n * `compileData` has the following properties:\n *\n * - `element` - `{element}`: an uncompiled element matching the provided template.\n * - `link` - `{function(scope)}`: A link function, which, when called, will compile\n * the element and instantiate the provided controller (if given).\n * - `locals` - `{object}`: The locals which will be passed into the controller once `link` is\n * called. If `bindToController` is true, they will be coppied to the ctrl instead\n * - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.\n */\n this.compile = function (options) {\n\n if (options.template && /\\.html$/.test(options.template)) {\n console.warn('Deprecated use of `template` option to pass a file. Please use the `templateUrl` option instead.');\n options.templateUrl = options.template;\n options.template = '';\n }\n\n var templateUrl = options.templateUrl;\n var template = options.template || '';\n var controller = options.controller;\n var controllerAs = options.controllerAs;\n var resolve = angular.copy(options.resolve || {});\n var locals = angular.copy(options.locals || {});\n var transformTemplate = options.transformTemplate || angular.identity;\n var bindToController = options.bindToController;\n\n // Take resolve values and invoke them.\n // Resolves can either be a string (value: 'MyRegisteredAngularConst'),\n // or an invokable 'factory' of sorts: (value: function ValueGetter($dependency) {})\n angular.forEach(resolve, function (value, key) {\n if (angular.isString(value)) {\n resolve[key] = $injector.get(value);\n } else {\n resolve[key] = $injector.invoke(value);\n }\n });\n // Add the locals, which are just straight values to inject\n // eg locals: { three: 3 }, will inject three into the controller\n angular.extend(resolve, locals);\n\n if (template) {\n resolve.$template = $q.when(template);\n } else if (templateUrl) {\n resolve.$template = fetchTemplate(templateUrl);\n } else {\n throw new Error('Missing `template` / `templateUrl` option.');\n }\n\n if (options.titleTemplate) {\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.titleTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n findElement('[ng-bind=\"title\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n return templateEl[0].outerHTML;\n });\n }\n\n if (options.contentTemplate) {\n // TODO(mgcrea): deprecate?\n resolve.$template = $q.all([resolve.$template, fetchTemplate(options.contentTemplate)])\n .then(function (templates) {\n var templateEl = angular.element(templates[0]);\n var contentEl = findElement('[ng-bind=\"content\"]', templateEl[0])\n .removeAttr('ng-bind')\n .html(templates[1]);\n // Drop the default footer as you probably don't want it if you use a custom contentTemplate\n if (!options.templateUrl) contentEl.next().remove();\n return templateEl[0].outerHTML;\n });\n }\n\n // Wait for all the resolves to finish if they are promises\n return $q.all(resolve).then(function (locals) {\n\n var template = transformTemplate(locals.$template);\n if (options.html) {\n template = template.replace(/ng-bind=\"/ig, 'ng-bind-html=\"');\n }\n // var element = options.element || angular.element('<div>').html(template.trim()).contents();\n var element = angular.element('<div>').html(template.trim()).contents();\n var linkFn = $compile(element);\n\n // Return a linking function that can be used later when the element is ready\n return {\n locals: locals,\n element: element,\n link: function link (scope) {\n locals.$scope = scope;\n\n // Instantiate controller if it exists, because we have scope\n if (controller) {\n var invokeCtrl = $controller(controller, locals, true);\n if (bindToController) {\n angular.extend(invokeCtrl.instance, locals);\n }\n // Support angular@~1.2 invokeCtrl\n var ctrl = angular.isObject(invokeCtrl) ? invokeCtrl : invokeCtrl();\n // See angular-route source for this logic\n element.data('$ngControllerController', ctrl);\n element.children().data('$ngControllerController', ctrl);\n\n if (controllerAs) {\n scope[controllerAs] = ctrl;\n }\n }\n\n return linkFn.apply(null, arguments);\n }\n };\n });\n\n };\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n var fetchPromises = {};\n function fetchTemplate (template) {\n if (fetchPromises[template]) return fetchPromises[template];\n return (fetchPromises[template] = $http.get(template, {cache: $templateCache})\n .then(function (res) {\n return res.data;\n }));\n }\n\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.datepicker', [\n 'mgcrea.ngStrap.helpers.dateParser',\n 'mgcrea.ngStrap.helpers.dateFormatter',\n 'mgcrea.ngStrap.tooltip'])\n\n .provider('$datepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n // Uncommenting the following line will break backwards compatability\n // prefixEvent: 'datepicker',\n prefixClass: 'datepicker',\n placement: 'bottom-left',\n templateUrl: 'datepicker/datepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: false,\n dateType: 'date',\n dateFormat: 'shortDate',\n timezone: null,\n modelDateFormat: null,\n dayFormat: 'dd',\n monthFormat: 'MMM',\n yearFormat: 'yyyy',\n monthTitleFormat: 'MMMM yyyy',\n yearTitleFormat: 'yyyy',\n strictFormat: false,\n autoclose: false,\n minDate: -Infinity,\n maxDate: +Infinity,\n startView: 0,\n minView: 0,\n startWeek: 0,\n daysOfWeekDisabled: '',\n hasToday: false,\n hasClear: false,\n iconLeft: 'glyphicon glyphicon-chevron-left',\n iconRight: 'glyphicon glyphicon-chevron-right'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, datepickerViews, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) defaults.lang = $dateFormatter.getDefaultLocale();\n\n function DatepickerFactory (element, controller, config) {\n\n var $datepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $datepicker.$options;\n var scope = $datepicker.$scope;\n if (options.startView) options.startView -= options.minView;\n\n // View vars\n\n var pickerViews = datepickerViews($datepicker);\n $datepicker.$views = pickerViews.views;\n var viewDate = pickerViews.viewDate;\n scope.$mode = options.startView;\n scope.$iconLeft = options.iconLeft;\n scope.$iconRight = options.iconRight;\n scope.$hasToday = options.hasToday;\n scope.$hasClear = options.hasClear;\n var $picker = $datepicker.$views[scope.$mode];\n\n // Scope methods\n\n scope.$select = function (date) {\n $datepicker.select(date);\n };\n scope.$selectPane = function (value) {\n $datepicker.$selectPane(value);\n };\n scope.$toggleMode = function () {\n $datepicker.setMode((scope.$mode + 1) % $datepicker.$views.length);\n };\n scope.$setToday = function () {\n if (options.autoclose) {\n $datepicker.setMode(0);\n $datepicker.select(new Date());\n } else {\n $datepicker.select(new Date(), true);\n }\n };\n scope.$clear = function () {\n if (options.autoclose) {\n $datepicker.setMode(0);\n $datepicker.select(null);\n } else {\n $datepicker.select(null, true);\n }\n };\n\n // Public methods\n\n $datepicker.update = function (date) {\n // console.warn('$datepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $datepicker.$date = date;\n $picker.update.call($picker, date);\n }\n // Build only if pristine\n $datepicker.$build(true);\n };\n\n $datepicker.updateDisabledDates = function (dateRanges) {\n options.disabledDateRanges = dateRanges;\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], $datepicker.$setDisabledEl);\n }\n };\n\n $datepicker.select = function (date, keep) {\n // console.warn('$datepicker.select', date, scope.$mode);\n if (angular.isDate(date)) {\n if (!angular.isDate(controller.$dateValue) || isNaN(controller.$dateValue.getTime())) {\n controller.$dateValue = new Date(date);\n }\n } else {\n controller.$dateValue = null;\n }\n if (!scope.$mode || keep) {\n controller.$setViewValue(angular.copy(date));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () { $datepicker.hide(true); });\n }\n } else {\n angular.extend(viewDate, {year: date.getFullYear(), month: date.getMonth(), date: date.getDate()});\n $datepicker.setMode(scope.$mode - 1);\n $datepicker.$build();\n }\n };\n\n $datepicker.setMode = function (mode) {\n // console.warn('$datepicker.setMode', mode);\n scope.$mode = mode;\n $picker = $datepicker.$views[scope.$mode];\n $datepicker.$build();\n };\n\n // Protected methods\n\n $datepicker.$build = function (pristine) {\n // console.warn('$datepicker.$build() viewDate=%o', viewDate);\n if (pristine === true && $picker.built) return;\n if (pristine === false && !$picker.built) return;\n $picker.build.call($picker);\n };\n\n $datepicker.$updateSelected = function () {\n for (var i = 0, l = scope.rows.length; i < l; i++) {\n angular.forEach(scope.rows[i], updateSelected);\n }\n };\n\n $datepicker.$isSelected = function (date) {\n return $picker.isSelected(date);\n };\n\n $datepicker.$setDisabledEl = function (el) {\n el.disabled = $picker.isDisabled(el.date);\n };\n\n $datepicker.$selectPane = function (value) {\n var steps = $picker.steps;\n // set targetDate to first day of month to avoid problems with\n // date values rollover. This assumes the viewDate does not\n // depend on the day of the month\n var targetDate = new Date(Date.UTC(viewDate.year + ((steps.year || 0) * value), viewDate.month + ((steps.month || 0) * value), 1));\n angular.extend(viewDate, {year: targetDate.getUTCFullYear(), month: targetDate.getUTCMonth(), date: targetDate.getUTCDate()});\n $datepicker.$build();\n };\n\n $datepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $datepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n if (evt.keyCode === 13) {\n if (!scope.$mode) {\n $datepicker.hide(true);\n } else {\n scope.$apply(function () { $datepicker.setMode(scope.$mode - 1); });\n }\n return;\n }\n\n // Navigate with keyboard\n $picker.onKeyDown(evt);\n parentScope.$digest();\n };\n\n // Private\n\n function updateSelected (el) {\n el.selected = $datepicker.$isSelected(el.date);\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $datepicker.init;\n $datepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'date');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $datepicker.destroy;\n $datepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $datepicker.show;\n $datepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // if $datepicker is no longer showing, don't setup events\n if (!$datepicker.$isShown) return;\n $datepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $datepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $datepicker.hide;\n $datepicker.hide = function (blur) {\n if (!$datepicker.$isShown) return;\n $datepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $datepicker.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $datepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $datepicker;\n\n }\n\n DatepickerFactory.defaults = defaults;\n return DatepickerFactory;\n\n };\n\n })\n\n .directive('bsDatepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $datepicker) {\n\n // var defaults = $datepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'autoclose', 'dateType', 'dateFormat', 'timezone', 'modelDateFormat', 'dayFormat', 'strictFormat', 'startWeek', 'startDate', 'useNative', 'lang', 'startView', 'minView', 'iconLeft', 'iconRight', 'daysOfWeekDisabled', 'id', 'prefixClass', 'prefixEvent', 'hasToday', 'hasClear'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'hasToday', 'hasClear'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Initialize datepicker\n var datepicker = $datepicker(element, controller, options);\n options = datepicker.$options;\n // Set expected iOS format\n if (isNative && options.useNative) options.dateFormat = 'yyyy-MM-dd';\n\n var lang = options.lang;\n\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!datepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(datepicker),?/i);\n if (newValue === true) {\n datepicker.show();\n } else {\n datepicker.hide();\n }\n });\n }\n\n // Observe attributes for changes\n angular.forEach(['minDate', 'maxDate'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n // console.warn('attr.$observe(%s)=%o', key, newValue);\n datepicker.$options[key] = dateParser.getDateForAttribute(key, newValue);\n // Build only if dirty\n if (!isNaN(datepicker.$options[key])) datepicker.$build(false);\n validateAgainstMinMaxDate(controller.$dateValue);\n });\n }\n });\n\n // Observe date format\n if (angular.isDefined(attr.dateFormat)) {\n attr.$observe('dateFormat', function (newValue) {\n datepicker.$options.dateFormat = newValue;\n });\n }\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n datepicker.update(controller.$dateValue);\n }, true);\n\n // Normalize undefined/null/empty array,\n // so that we don't treat changing from undefined->null as a change.\n function normalizeDateRanges (ranges) {\n if (!ranges || !ranges.length) return null;\n return ranges;\n }\n\n if (angular.isDefined(attr.disabledDates)) {\n scope.$watch(attr.disabledDates, function (disabledRanges, previousValue) {\n disabledRanges = normalizeDateRanges(disabledRanges);\n previousValue = normalizeDateRanges(previousValue);\n\n if (disabledRanges) {\n datepicker.updateDisabledDates(disabledRanges);\n }\n });\n }\n\n function validateAgainstMinMaxDate (parsedDate) {\n if (!angular.isDate(parsedDate)) return;\n var isMinValid = isNaN(datepicker.$options.minDate) || parsedDate.getTime() >= datepicker.$options.minDate;\n var isMaxValid = isNaN(datepicker.$options.maxDate) || parsedDate.getTime() <= datepicker.$options.maxDate;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (isValid) controller.$dateValue = parsedDate;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n controller.$setValidity('date', true);\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n return null;\n }\n var parsedDate = dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedDate || isNaN(parsedDate.getTime())) {\n controller.$setValidity('date', false);\n // return undefined, causes ngModelController to\n // invalidate model value\n return;\n }\n validateAgainstMinMaxDate(parsedDate);\n\n if (options.dateType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedDate, options.timezone, true);\n return formatDate(date, options.modelDateFormat || options.dateFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.dateType === 'number') {\n return date.getTime();\n } else if (options.dateType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.dateType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.dateType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelDateFormat);\n } else if (options.dateType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if (isNaN(date.getTime())) {\n // var today = new Date();\n // date = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0);\n // }\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getDateFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getDateFormattedString());\n };\n\n function getDateFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.dateFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (datepicker) datepicker.destroy();\n options = null;\n datepicker = null;\n });\n\n }\n };\n\n })\n\n .provider('datepickerViews', function () {\n\n // var defaults = this.defaults = {\n // dayFormat: 'dd',\n // daySplit: 7\n // };\n\n // Split array into smaller arrays\n function split (arr, size) {\n var arrays = [];\n while (arr.length > 0) {\n arrays.push(arr.splice(0, size));\n }\n return arrays;\n }\n\n // Modulus operator\n function mod (n, m) {\n return ((n % m) + m) % m;\n }\n\n this.$get = function ($dateFormatter, $dateParser, $sce) {\n\n return function (picker) {\n\n var scope = picker.$scope;\n var options = picker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format) {\n return $dateFormatter.formatDate(date, format, lang);\n };\n var dateParser = $dateParser({format: options.dateFormat, lang: lang, strict: options.strictFormat});\n\n var weekDaysMin = $dateFormatter.weekdaysShort(lang);\n var weekDaysLabels = weekDaysMin.slice(options.startWeek).concat(weekDaysMin.slice(0, options.startWeek));\n var weekDaysLabelsHtml = $sce.trustAsHtml('<th class=\"dow text-center\">' + weekDaysLabels.join('</th><th class=\"dow text-center\">') + '</th>');\n\n var startDate = picker.$date || (options.startDate ? dateParser.getDateForAttribute('startDate', options.startDate) : new Date());\n var viewDate = {year: startDate.getFullYear(), month: startDate.getMonth(), date: startDate.getDate()};\n\n var views = [{\n format: options.dayFormat,\n split: 7,\n steps: {month: 1},\n update: function (date, force) {\n if (!this.built || force || date.getFullYear() !== viewDate.year || date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getDate() !== viewDate.date || date.getDate() === 1) {\n // chaging picker current month will cause viewDate.date to be set to first day of the month,\n // in $datepicker.$selectPane, so picker would not update selected day display if\n // user picks first day of the new month.\n // As a workaround, we are always forcing update when picked date is first day of month.\n viewDate.date = picker.$date.getDate();\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstDayOfMonth = new Date(viewDate.year, viewDate.month, 1);\n var firstDayOfMonthOffset = firstDayOfMonth.getTimezoneOffset();\n var firstDate = new Date(+firstDayOfMonth - mod(firstDayOfMonth.getDay() - options.startWeek, 7) * 864e5);\n var firstDateOffset = firstDate.getTimezoneOffset();\n var today = dateParser.timezoneOffsetAdjust(new Date(), options.timezone).toDateString();\n // Handle daylight time switch\n if (firstDateOffset !== firstDayOfMonthOffset) firstDate = new Date(+firstDate + (firstDateOffset - firstDayOfMonthOffset) * 60e3);\n var days = [];\n var day;\n for (var i = 0; i < 42; i++) { // < 7 * 6\n day = dateParser.daylightSavingAdjust(new Date(firstDate.getFullYear(), firstDate.getMonth(), firstDate.getDate() + i));\n days.push({date: day, isToday: day.toDateString() === today, label: formatDate(day, this.format), selected: picker.$date && this.isSelected(day), muted: day.getMonth() !== viewDate.month, disabled: this.isDisabled(day)});\n }\n scope.title = formatDate(firstDayOfMonth, options.monthTitleFormat);\n scope.showLabels = true;\n scope.labels = weekDaysLabelsHtml;\n scope.rows = split(days, this.split);\n scope.isTodayDisabled = this.isDisabled(new Date());\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth() && date.getDate() === picker.$date.getDate();\n },\n isDisabled: function (date) {\n var time = date.getTime();\n\n // Disabled because of min/max date.\n if (time < options.minDate || time > options.maxDate) return true;\n\n // Disabled due to being a disabled day of the week\n if (options.daysOfWeekDisabled.indexOf(date.getDay()) !== -1) return true;\n\n // Disabled because of disabled date range.\n if (options.disabledDateRanges) {\n for (var i = 0; i < options.disabledDateRanges.length; i++) {\n if (time >= options.disabledDateRanges[i].start && time <= options.disabledDateRanges[i].end) {\n return true;\n }\n }\n }\n\n return false;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualTime = picker.$date.getTime();\n var newDate;\n\n if (evt.keyCode === 37) newDate = new Date(actualTime - 1 * 864e5);\n else if (evt.keyCode === 38) newDate = new Date(actualTime - 7 * 864e5);\n else if (evt.keyCode === 39) newDate = new Date(actualTime + 1 * 864e5);\n else if (evt.keyCode === 40) newDate = new Date(actualTime + 7 * 864e5);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'month',\n format: options.monthFormat,\n split: 4,\n steps: {year: 1},\n update: function (date, force) {\n if (!this.built || date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getMonth() !== viewDate.month) {\n angular.extend(viewDate, {month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n // var firstMonth = new Date(viewDate.year, 0, 1);\n var months = [];\n var month;\n for (var i = 0; i < 12; i++) {\n month = new Date(viewDate.year, i, 1);\n months.push({date: month, label: formatDate(month, this.format), selected: picker.$isSelected(month), disabled: this.isDisabled(month)});\n }\n scope.title = formatDate(month, options.yearTitleFormat);\n scope.showLabels = false;\n scope.rows = split(months, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear() && date.getMonth() === picker.$date.getMonth();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear(), date.getMonth() + 1, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualMonth = picker.$date.getMonth();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setMonth(actualMonth - 1);\n else if (evt.keyCode === 38) newDate.setMonth(actualMonth - 4);\n else if (evt.keyCode === 39) newDate.setMonth(actualMonth + 1);\n else if (evt.keyCode === 40) newDate.setMonth(actualMonth + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }, {\n name: 'year',\n format: options.yearFormat,\n split: 4,\n steps: {year: 12},\n update: function (date, force) {\n if (!this.built || force || parseInt(date.getFullYear() / 20, 10) !== parseInt(viewDate.year / 20, 10)) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$build();\n } else if (date.getFullYear() !== viewDate.year) {\n angular.extend(viewDate, {year: picker.$date.getFullYear(), month: picker.$date.getMonth(), date: picker.$date.getDate()});\n picker.$updateSelected();\n }\n },\n build: function () {\n var firstYear = viewDate.year - viewDate.year % (this.split * 3);\n var years = [];\n var year;\n for (var i = 0; i < 12; i++) {\n year = new Date(firstYear + i, 0, 1);\n years.push({date: year, label: formatDate(year, this.format), selected: picker.$isSelected(year), disabled: this.isDisabled(year)});\n }\n scope.title = years[0].label + '-' + years[years.length - 1].label;\n scope.showLabels = false;\n scope.rows = split(years, this.split);\n this.built = true;\n },\n isSelected: function (date) {\n return picker.$date && date.getFullYear() === picker.$date.getFullYear();\n },\n isDisabled: function (date) {\n var lastDate = +new Date(date.getFullYear() + 1, 0, 0);\n return lastDate < options.minDate || date.getTime() > options.maxDate;\n },\n onKeyDown: function (evt) {\n if (!picker.$date) {\n return;\n }\n var actualYear = picker.$date.getFullYear();\n var newDate = new Date(picker.$date);\n\n if (evt.keyCode === 37) newDate.setYear(actualYear - 1);\n else if (evt.keyCode === 38) newDate.setYear(actualYear - 4);\n else if (evt.keyCode === 39) newDate.setYear(actualYear + 1);\n else if (evt.keyCode === 40) newDate.setYear(actualYear + 4);\n\n if (!this.isDisabled(newDate)) picker.select(newDate, true);\n }\n }];\n\n return {\n views: options.minView ? Array.prototype.slice.call(views, options.minView) : views,\n viewDate: viewDate\n };\n\n };\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tab', [])\n\n .provider('$tab', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n template: 'tab/tab.tpl.html',\n navClass: 'nav-tabs',\n activeClass: 'active'\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'navClass', 'activeClass'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // Publish options on scope\n $scope.$navClass = self.$options.navClass;\n $scope.$activeClass = self.$options.activeClass;\n\n self.$panes = $scope.$panes = [];\n\n // Please use $activePaneChangeListeners if you use `bsActivePane`\n // Because we removed `ngModel` as default, we rename viewChangeListeners to\n // activePaneChangeListeners to make more sense.\n self.$activePaneChangeListeners = self.$viewChangeListeners = [];\n\n self.$push = function (pane) {\n if (angular.isUndefined(self.$panes.$active)) {\n $scope.$setActive(pane.name || 0);\n }\n self.$panes.push(pane);\n };\n\n self.$remove = function (pane) {\n var index = self.$panes.indexOf(pane);\n var active = self.$panes.$active;\n var activeIndex;\n if (angular.isString(active)) {\n activeIndex = self.$panes.map(function (pane) {\n return pane.name;\n }).indexOf(active);\n } else {\n activeIndex = self.$panes.$active;\n }\n\n // remove pane from $panes array\n self.$panes.splice(index, 1);\n\n if (index < activeIndex) {\n // we removed a pane before the active pane, so we need to\n // decrement the active pane index\n activeIndex--;\n } else if (index === activeIndex && activeIndex === self.$panes.length) {\n // we remove the active pane and it was the one at the end,\n // so select the previous one\n activeIndex--;\n }\n if (activeIndex >= 0 && activeIndex < self.$panes.length) {\n self.$setActive(self.$panes[activeIndex].name || activeIndex);\n } else {\n self.$setActive();\n }\n };\n\n self.$setActive = $scope.$setActive = function (value) {\n self.$panes.$active = value;\n self.$activePaneChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$isActive = $scope.$isActive = function ($pane, $index) {\n return self.$panes.$active === $pane.name || self.$panes.$active === $index;\n };\n\n };\n\n this.$get = function () {\n var $tab = {};\n $tab.defaults = defaults;\n $tab.controller = controller;\n return $tab;\n };\n\n })\n\n .directive('bsTabs', function ($window, $animate, $tab, $parse) {\n\n var defaults = $tab.defaults;\n\n return {\n require: ['?ngModel', 'bsTabs'],\n transclude: true,\n scope: true,\n controller: ['$scope', '$element', '$attrs', $tab.controller],\n templateUrl: function (element, attr) {\n return attr.template || defaults.template;\n },\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // 'ngModel' does interfere with form validation\n // and status, use `bsActivePane` instead to avoid it\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsTabsCtrl.$panes.$active);\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n bsTabsCtrl.$setActive(modelValue);\n return modelValue;\n });\n\n }\n\n if (attrs.bsActivePane) {\n // adapted from angularjs ngModelController bindings\n // https://github.com/angular/angular.js/blob/v1.3.1/src%2Fng%2Fdirective%2Finput.js#L1730\n var parsedBsActivePane = $parse(attrs.bsActivePane);\n\n // Update bsActivePane value with change\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n parsedBsActivePane.assign(scope, bsTabsCtrl.$panes.$active);\n });\n\n // watch bsActivePane for value changes\n scope.$watch(attrs.bsActivePane, function (newValue, oldValue) {\n bsTabsCtrl.$setActive(newValue);\n }, true);\n }\n }\n };\n\n })\n\n .directive('bsPane', function ($window, $animate, $sce) {\n\n return {\n require: ['^?ngModel', '^bsTabs'],\n scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsTabsCtrl = controllers[1];\n\n // Add base class\n element.addClass('tab-pane');\n\n // Observe title attribute for change\n attrs.$observe('title', function (newValue, oldValue) {\n scope.title = $sce.trustAsHtml(newValue);\n });\n\n // Save tab name into scope\n scope.name = attrs.name;\n\n // Add animation class\n if (bsTabsCtrl.$options.animation) {\n element.addClass(bsTabsCtrl.$options.animation);\n }\n\n attrs.$observe('disabled', function (newValue, oldValue) {\n scope.disabled = scope.$eval(newValue);\n });\n\n // Push pane to parent bsTabs controller\n bsTabsCtrl.$push(scope);\n\n // remove pane from tab controller when pane is destroyed\n scope.$on('$destroy', function () {\n bsTabsCtrl.$remove(scope);\n });\n\n function render () {\n var index = bsTabsCtrl.$panes.indexOf(scope);\n $animate[bsTabsCtrl.$isActive(scope, index) ? 'addClass' : 'removeClass'](element, bsTabsCtrl.$options.activeClass);\n }\n\n bsTabsCtrl.$activePaneChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.tooltip', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$tooltip', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n prefixClass: 'tooltip',\n prefixEvent: 'tooltip',\n container: false,\n target: false,\n placement: 'top',\n templateUrl: 'tooltip/tooltip.tpl.html',\n template: '',\n titleTemplate: false,\n trigger: 'hover focus',\n keyboard: false,\n html: false,\n show: false,\n title: '',\n type: '',\n delay: 0,\n autoClose: false,\n bsEnabled: true,\n mouseDownPreventDefault: true,\n mouseDownStopPropagation: true,\n viewport: {\n selector: 'body',\n padding: 0\n }\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $q, $templateCache, $http, $animate, $sce, dimensions, $$rAF, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n var $body = angular.element($window.document);\n\n function TooltipFactory (element, config) {\n\n var $tooltip = {};\n\n // Common vars\n var options = $tooltip.$options = angular.extend({}, defaults, config);\n var promise = $tooltip.$promise = $bsCompiler.compile(options);\n var scope = $tooltip.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n var nodeName = element[0].nodeName.toLowerCase();\n if (options.delay && angular.isString(options.delay)) {\n var split = options.delay.split(',').map(parseFloat);\n options.delay = split.length > 1 ? {show: split[0], hide: split[1]} : split[0];\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $tooltip.$id = options.id || element.attr('id') || '';\n\n // Support scope as string options\n if (options.title) {\n scope.title = $sce.trustAsHtml(options.title);\n }\n\n // Provide scope helpers\n scope.$setEnabled = function (isEnabled) {\n scope.$$postDigest(function () {\n $tooltip.setEnabled(isEnabled);\n });\n };\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $tooltip.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $tooltip.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $tooltip.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $tooltip.$isShown = scope.$isShown = false;\n\n // Private vars\n var timeout;\n var hoverState;\n\n // Fetch, compile then initialize tooltip\n var compileData;\n var tipElement;\n var tipContainer;\n var tipScope;\n promise.then(function (data) {\n compileData = data;\n $tooltip.init();\n });\n\n $tooltip.init = function () {\n\n // Options: delay\n if (options.delay && angular.isNumber(options.delay)) {\n options.delay = {\n show: options.delay,\n hide: options.delay\n };\n }\n\n // Replace trigger on touch devices ?\n // if(isTouch && options.trigger === defaults.trigger) {\n // options.trigger.replace(/hover/g, 'click');\n // }\n\n // Options : container\n if (options.container === 'self') {\n tipContainer = element;\n } else if (angular.isElement(options.container)) {\n tipContainer = options.container;\n } else if (options.container) {\n tipContainer = findElement(options.container);\n }\n\n // Options: trigger\n bindTriggerEvents();\n\n // Options: target\n if (options.target) {\n options.target = angular.isElement(options.target) ? options.target : findElement(options.target);\n }\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n if (options.trigger === 'focus') {\n element[0].focus();\n } else {\n $tooltip.show();\n }\n });\n }\n\n };\n\n $tooltip.destroy = function () {\n\n // Unbind events\n unbindTriggerEvents();\n\n // Remove element\n destroyTipElement();\n\n // Destroy scope\n scope.$destroy();\n\n };\n\n $tooltip.enter = function () {\n\n clearTimeout(timeout);\n hoverState = 'in';\n if (!options.delay || !options.delay.show) {\n return $tooltip.show();\n }\n\n timeout = setTimeout(function () {\n if (hoverState === 'in') $tooltip.show();\n }, options.delay.show);\n\n };\n\n $tooltip.show = function () {\n if (!options.bsEnabled || $tooltip.$isShown) return;\n\n scope.$emit(options.prefixEvent + '.show.before', $tooltip);\n if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) {\n options.onBeforeShow($tooltip);\n }\n var parent;\n var after;\n if (options.container) {\n parent = tipContainer;\n if (tipContainer[0].lastChild) {\n after = angular.element(tipContainer[0].lastChild);\n } else {\n after = null;\n }\n } else {\n parent = null;\n after = element;\n }\n\n\n // Hide any existing tipElement\n if (tipElement) destroyTipElement();\n // Fetch a cloned element linked from template\n tipScope = $tooltip.$scope.$new();\n tipElement = $tooltip.$element = compileData.link(tipScope, function (clonedElement, scope) {});\n\n // Set the initial positioning. Make the tooltip invisible\n // so IE doesn't try to focus on it off screen.\n tipElement.css({top: '-9999px', left: '-9999px', right: 'auto', display: 'block', visibility: 'hidden'});\n\n // Options: animation\n if (options.animation) tipElement.addClass(options.animation);\n // Options: type\n if (options.type) tipElement.addClass(options.prefixClass + '-' + options.type);\n // Options: custom classes\n if (options.customClass) tipElement.addClass(options.customClass);\n\n // Append the element, without any animations. If we append\n // using $animate.enter, some of the animations cause the placement\n // to be off due to the transforms.\n if (after) {\n after.after(tipElement);\n } else {\n parent.prepend(tipElement);\n }\n\n $tooltip.$isShown = scope.$isShown = true;\n safeDigest(scope);\n\n // Now, apply placement\n $tooltip.$applyPlacement();\n\n // Once placed, animate it.\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(tipElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(tipElement, parent, after).then(enterAnimateCallback);\n }\n safeDigest(scope);\n\n $$rAF(function () {\n // Once the tooltip is placed and the animation starts, make the tooltip visible\n if (tipElement) tipElement.css({visibility: 'visible'});\n\n // Bind events\n if (options.keyboard) {\n if (options.trigger !== 'focus') {\n $tooltip.focus();\n }\n bindKeyboardEvents();\n }\n });\n\n if (options.autoClose) {\n bindAutoCloseEvents();\n }\n\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $tooltip);\n if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) {\n options.onShow($tooltip);\n }\n }\n\n $tooltip.leave = function () {\n\n clearTimeout(timeout);\n hoverState = 'out';\n if (!options.delay || !options.delay.hide) {\n return $tooltip.hide();\n }\n timeout = setTimeout(function () {\n if (hoverState === 'out') {\n $tooltip.hide();\n }\n }, options.delay.hide);\n\n };\n\n var _blur;\n var _tipToHide;\n $tooltip.hide = function (blur) {\n\n if (!$tooltip.$isShown) return;\n scope.$emit(options.prefixEvent + '.hide.before', $tooltip);\n if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) {\n options.onBeforeHide($tooltip);\n }\n\n // store blur value for leaveAnimateCallback to use\n _blur = blur;\n\n // store current tipElement reference to use\n // in leaveAnimateCallback\n _tipToHide = tipElement;\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(tipElement, leaveAnimateCallback);\n } else {\n $animate.leave(tipElement).then(leaveAnimateCallback);\n }\n\n $tooltip.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n if (options.keyboard && tipElement !== null) {\n unbindKeyboardEvents();\n }\n\n if (options.autoClose && tipElement !== null) {\n unbindAutoCloseEvents();\n }\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $tooltip);\n if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) {\n options.onHide($tooltip);\n }\n\n // check if current tipElement still references\n // the same element when hide was called\n if (tipElement === _tipToHide) {\n // Allow to blur the input when hidden, like when pressing enter key\n if (_blur && options.trigger === 'focus') {\n return element[0].blur();\n }\n\n // clean up child scopes\n destroyTipElement();\n }\n }\n\n $tooltip.toggle = function (evt) {\n if (evt) { evt.preventDefault(); }\n if ($tooltip.$isShown) {\n $tooltip.leave();\n } else {\n $tooltip.enter();\n }\n };\n\n $tooltip.focus = function () {\n tipElement[0].focus();\n };\n\n $tooltip.setEnabled = function (isEnabled) {\n options.bsEnabled = isEnabled;\n };\n\n $tooltip.setViewport = function (viewport) {\n options.viewport = viewport;\n };\n\n // Protected methods\n\n $tooltip.$applyPlacement = function () {\n if (!tipElement) return;\n\n // Determine if we're doing an auto or normal placement\n var placement = options.placement;\n var autoToken = /\\s?auto?\\s?/i;\n var autoPlace = autoToken.test(placement);\n\n if (autoPlace) {\n placement = placement.replace(autoToken, '') || defaults.placement;\n }\n\n // Need to add the position class before we get\n // the offsets\n tipElement.addClass(options.placement);\n\n // Get the position of the target element\n // and the height and width of the tooltip so we can center it.\n var elementPosition = getPosition();\n var tipWidth = tipElement.prop('offsetWidth');\n var tipHeight = tipElement.prop('offsetHeight');\n\n // Refresh viewport position\n $tooltip.$viewport = options.viewport && findElement(options.viewport.selector || options.viewport);\n\n // If we're auto placing, we need to check the positioning\n if (autoPlace) {\n var originalPlacement = placement;\n var viewportPosition = getPosition($tooltip.$viewport);\n\n if (/bottom/.test(originalPlacement) && elementPosition.bottom + tipHeight > viewportPosition.bottom) {\n placement = originalPlacement.replace('bottom', 'top');\n } else if (/top/.test(originalPlacement) && elementPosition.top - tipHeight < viewportPosition.top) {\n placement = originalPlacement.replace('top', 'bottom');\n }\n\n if (/left/.test(originalPlacement) && elementPosition.left - tipWidth < viewportPosition.left) {\n placement = placement.replace('left', 'right');\n } else if (/right/.test(originalPlacement) && elementPosition.right + tipWidth > viewportPosition.width) {\n placement = placement.replace('right', 'left');\n }\n\n tipElement.removeClass(originalPlacement).addClass(placement);\n }\n\n // Get the tooltip's top and left coordinates to center it with this directive.\n var tipPosition = getCalculatedOffset(placement, elementPosition, tipWidth, tipHeight);\n applyPlacement(tipPosition, placement);\n };\n\n $tooltip.$onKeyUp = function (evt) {\n if (evt.which === 27 && $tooltip.$isShown) {\n $tooltip.hide();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusKeyUp = function (evt) {\n if (evt.which === 27) {\n element[0].blur();\n evt.stopPropagation();\n }\n };\n\n $tooltip.$onFocusElementMouseDown = function (evt) {\n if (options.mouseDownPreventDefault) { evt.preventDefault(); }\n if (options.mouseDownStopPropagation) { evt.stopPropagation(); }\n // Some browsers do not auto-focus buttons (eg. Safari)\n if ($tooltip.$isShown) {\n element[0].blur();\n } else {\n element[0].focus();\n }\n };\n\n // bind/unbind events\n function bindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n angular.forEach(triggers, function (trigger) {\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.on(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.on(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.on(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.on(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n });\n }\n\n function unbindTriggerEvents () {\n var triggers = options.trigger.split(' ');\n for (var i = triggers.length; i--;) {\n var trigger = triggers[i];\n if (trigger === 'click' || trigger === 'contextmenu') {\n element.off(trigger, $tooltip.toggle);\n } else if (trigger !== 'manual') {\n element.off(trigger === 'hover' ? 'mouseenter' : 'focus', $tooltip.enter);\n element.off(trigger === 'hover' ? 'mouseleave' : 'blur', $tooltip.leave);\n if (nodeName === 'button' && trigger !== 'hover') {\n element.off(isTouch ? 'touchstart' : 'mousedown', $tooltip.$onFocusElementMouseDown);\n }\n }\n }\n }\n\n function bindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.on('keyup', $tooltip.$onKeyUp);\n } else {\n element.on('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.trigger !== 'focus') {\n tipElement.off('keyup', $tooltip.$onKeyUp);\n } else {\n element.off('keyup', $tooltip.$onFocusKeyUp);\n }\n }\n\n var _autoCloseEventsBinded = false;\n function bindAutoCloseEvents () {\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n // Stop propagation when clicking inside tooltip\n tipElement.on('click', stopEventPropagation);\n\n // Hide when clicking outside tooltip\n $body.on('click', $tooltip.hide);\n\n _autoCloseEventsBinded = true;\n }, 0, false);\n }\n\n function unbindAutoCloseEvents () {\n if (_autoCloseEventsBinded) {\n tipElement.off('click', stopEventPropagation);\n $body.off('click', $tooltip.hide);\n _autoCloseEventsBinded = false;\n }\n }\n\n function stopEventPropagation (event) {\n event.stopPropagation();\n }\n\n // Private methods\n\n function getPosition ($element) {\n $element = $element || (options.target || element);\n\n var el = $element[0];\n var isBody = el.tagName === 'BODY';\n\n var elRect = el.getBoundingClientRect();\n var rect = {};\n\n // IE8 has issues with angular.extend and using elRect directly.\n // By coping the values of elRect into a new object, we can continue to use extend\n /* eslint-disable guard-for-in */\n for (var p in elRect) { // eslint-disable-line\n // DO NOT use hasOwnProperty when inspecting the return of getBoundingClientRect.\n rect[p] = elRect[p];\n }\n /* eslint-enable guard-for-in */\n\n if (rect.width === null) {\n // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n rect = angular.extend({}, rect, {width: elRect.right - elRect.left, height: elRect.bottom - elRect.top});\n }\n var elOffset = isBody ? {top: 0, left: 0} : dimensions.offset(el);\n var scroll = {scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.prop('scrollTop') || 0};\n var outerDims = isBody ? {width: document.documentElement.clientWidth, height: $window.innerHeight} : null;\n\n return angular.extend({}, rect, scroll, outerDims, elOffset);\n }\n\n function getCalculatedOffset (placement, position, actualWidth, actualHeight) {\n var offset;\n var split = placement.split('-');\n\n switch (split[0]) {\n case 'right':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left + position.width\n };\n break;\n case 'bottom':\n offset = {\n top: position.top + position.height,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n case 'left':\n offset = {\n top: position.top + position.height / 2 - actualHeight / 2,\n left: position.left - actualWidth\n };\n break;\n default:\n offset = {\n top: position.top - actualHeight,\n left: position.left + position.width / 2 - actualWidth / 2\n };\n break;\n }\n\n if (!split[1]) {\n return offset;\n }\n\n // Add support for corners @todo css\n if (split[0] === 'top' || split[0] === 'bottom') {\n switch (split[1]) {\n case 'left':\n offset.left = position.left;\n break;\n case 'right':\n offset.left = position.left + position.width - actualWidth;\n break;\n default:\n break;\n }\n } else if (split[0] === 'left' || split[0] === 'right') {\n switch (split[1]) {\n case 'top':\n offset.top = position.top - actualHeight + position.height;\n break;\n case 'bottom':\n offset.top = position.top;\n break;\n default:\n break;\n }\n }\n\n return offset;\n }\n\n function applyPlacement (offset, placement) {\n var tip = tipElement[0];\n var width = tip.offsetWidth;\n var height = tip.offsetHeight;\n\n // manually read margins because getBoundingClientRect includes difference\n var marginTop = parseInt(dimensions.css(tip, 'margin-top'), 10);\n var marginLeft = parseInt(dimensions.css(tip, 'margin-left'), 10);\n\n // we must check for NaN for ie 8/9\n if (isNaN(marginTop)) marginTop = 0;\n if (isNaN(marginLeft)) marginLeft = 0;\n\n offset.top = offset.top + marginTop;\n offset.left = offset.left + marginLeft;\n\n // dimensions setOffset doesn't round pixel values\n // so we use setOffset directly with our own function\n dimensions.setOffset(tip, angular.extend({\n using: function (props) {\n tipElement.css({\n top: Math.round(props.top) + 'px',\n left: Math.round(props.left) + 'px',\n right: ''\n });\n }\n }, offset), 0);\n\n // check to see if placing tip in new offset caused the tip to resize itself\n var actualWidth = tip.offsetWidth;\n var actualHeight = tip.offsetHeight;\n\n if (placement === 'top' && actualHeight !== height) {\n offset.top = offset.top + height - actualHeight;\n }\n\n // If it's an exotic placement, exit now instead of\n // applying a delta and changing the arrow\n if (/top-left|top-right|bottom-left|bottom-right/.test(placement)) return;\n\n var delta = getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);\n\n if (delta.left) {\n offset.left += delta.left;\n } else {\n offset.top += delta.top;\n }\n\n dimensions.setOffset(tip, offset);\n\n if (/top|right|bottom|left/.test(placement)) {\n var isVertical = /top|bottom/.test(placement);\n var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight;\n var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';\n\n replaceArrow(arrowDelta, tip[arrowOffsetPosition], isVertical);\n }\n }\n\n // @source https://github.com/twbs/bootstrap/blob/v3.3.5/js/tooltip.js#L380\n function getViewportAdjustedDelta (placement, position, actualWidth, actualHeight) {\n var delta = {top: 0, left: 0};\n if (!$tooltip.$viewport) return delta;\n\n var viewportPadding = options.viewport && options.viewport.padding || 0;\n var viewportDimensions = getPosition($tooltip.$viewport);\n\n if (/right|left/.test(placement)) {\n var topEdgeOffset = position.top - viewportPadding - viewportDimensions.scroll;\n var bottomEdgeOffset = position.top + viewportPadding - viewportDimensions.scroll + actualHeight;\n if (topEdgeOffset < viewportDimensions.top) { // top overflow\n delta.top = viewportDimensions.top - topEdgeOffset;\n } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;\n }\n } else {\n var leftEdgeOffset = position.left - viewportPadding;\n var rightEdgeOffset = position.left + viewportPadding + actualWidth;\n if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n delta.left = viewportDimensions.left - leftEdgeOffset;\n } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;\n }\n }\n\n return delta;\n }\n\n function replaceArrow (delta, dimension, isHorizontal) {\n var $arrow = findElement('.tooltip-arrow, .arrow', tipElement[0]);\n\n $arrow.css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n .css(isHorizontal ? 'top' : 'left', '');\n }\n\n function destroyTipElement () {\n // Cancel pending callbacks\n clearTimeout(timeout);\n\n if ($tooltip.$isShown && tipElement !== null) {\n if (options.autoClose) {\n unbindAutoCloseEvents();\n }\n\n if (options.keyboard) {\n unbindKeyboardEvents();\n }\n }\n\n if (tipScope) {\n tipScope.$destroy();\n tipScope = null;\n }\n\n if (tipElement) {\n tipElement.remove();\n tipElement = $tooltip.$element = null;\n }\n }\n\n return $tooltip;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return TooltipFactory;\n\n };\n\n })\n\n .directive('bsTooltip', function ($window, $location, $sce, $parse, $tooltip, $$rAF) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n var tooltip;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'titleTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'backdropAnimation', 'type', 'customClass', 'id'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Observe scope attributes for change\n attr.$observe('title', function (newValue) {\n if (angular.isDefined(newValue) || !scope.hasOwnProperty('title')) {\n var oldValue = scope.title;\n scope.title = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }\n });\n\n attr.$observe('disabled', function (newValue) {\n if (newValue && tooltip.$isShown) {\n tooltip.hide();\n }\n });\n\n // Support scope as an object\n if (attr.bsTooltip) {\n scope.$watch(attr.bsTooltip, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.title = newValue;\n }\n if (angular.isDefined(oldValue)) {\n $$rAF(function () {\n if (tooltip) tooltip.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(tooltip),?/i);\n if (newValue === true) {\n tooltip.show();\n } else {\n tooltip.hide();\n }\n });\n }\n\n // Enabled binding support\n if (attr.bsEnabled) {\n scope.$watch(attr.bsEnabled, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.bsEnabled, newValue, oldValue);\n if (!tooltip || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|1|,?(tooltip),?/i);\n if (newValue === false) {\n tooltip.setEnabled(false);\n } else {\n tooltip.setEnabled(true);\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!tooltip || !angular.isDefined(newValue)) return;\n tooltip.setViewport(newValue);\n });\n }\n\n // Initialize popover\n tooltip = $tooltip(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (tooltip) tooltip.destroy();\n options = null;\n tooltip = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.timepicker', ['mgcrea.ngStrap.helpers.dateParser', 'mgcrea.ngStrap.helpers.dateFormatter', 'mgcrea.ngStrap.tooltip'])\n\n .provider('$timepicker', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n defaultDate: 'auto',\n // uncommenting the following line will break backwards compatability\n // prefixEvent: 'timepicker',\n prefixClass: 'timepicker',\n placement: 'bottom-left',\n templateUrl: 'timepicker/timepicker.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n // lang: $locale.id,\n useNative: true,\n timeType: 'date',\n timeFormat: 'shortTime',\n timezone: null,\n modelTimeFormat: null,\n autoclose: false,\n minTime: -Infinity,\n maxTime: +Infinity,\n length: 5,\n hourStep: 1,\n minuteStep: 5,\n secondStep: 5,\n roundDisplay: false,\n iconUp: 'glyphicon glyphicon-chevron-up',\n iconDown: 'glyphicon glyphicon-chevron-down',\n arrowBehavior: 'pager'\n };\n\n this.$get = function ($window, $document, $rootScope, $sce, $dateFormatter, $tooltip, $timeout) {\n\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n if (!defaults.lang) {\n defaults.lang = $dateFormatter.getDefaultLocale();\n }\n\n function timepickerFactory (element, controller, config) {\n\n var $timepicker = $tooltip(element, angular.extend({}, defaults, config));\n var parentScope = config.scope;\n var options = $timepicker.$options;\n var scope = $timepicker.$scope;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n function floorMinutes (time) {\n // coeff used to floor current time to nearest minuteStep interval\n var coeff = 1000 * 60 * options.minuteStep;\n return new Date(Math.floor(time.getTime() / coeff) * coeff);\n }\n\n // View vars\n\n var selectedIndex = 0;\n var defaultDate = options.roundDisplay ? floorMinutes(new Date()) : new Date();\n var startDate = controller.$dateValue || defaultDate;\n var viewDate = {\n hour: startDate.getHours(),\n meridian: startDate.getHours() < 12,\n minute: startDate.getMinutes(),\n second: startDate.getSeconds(),\n millisecond: startDate.getMilliseconds()\n };\n\n var format = $dateFormatter.getDatetimeFormat(options.timeFormat, lang);\n\n var hoursFormat = $dateFormatter.hoursFormat(format);\n var timeSeparator = $dateFormatter.timeSeparator(format);\n var minutesFormat = $dateFormatter.minutesFormat(format);\n var secondsFormat = $dateFormatter.secondsFormat(format);\n var showSeconds = $dateFormatter.showSeconds(format);\n var showAM = $dateFormatter.showAM(format);\n\n scope.$iconUp = options.iconUp;\n scope.$iconDown = options.iconDown;\n\n // Scope methods\n\n scope.$select = function (date, index) {\n $timepicker.select(date, index);\n };\n scope.$moveIndex = function (value, index) {\n $timepicker.$moveIndex(value, index);\n };\n scope.$switchMeridian = function (date) {\n $timepicker.switchMeridian(date);\n };\n\n // Public methods\n\n $timepicker.update = function (date) {\n // console.warn('$timepicker.update() newValue=%o', date);\n if (angular.isDate(date) && !isNaN(date.getTime())) {\n $timepicker.$date = date;\n angular.extend(viewDate, {\n hour: date.getHours(),\n minute: date.getMinutes(),\n second: date.getSeconds(),\n millisecond: date.getMilliseconds()\n });\n $timepicker.$build();\n } else if (!$timepicker.$isBuilt) {\n $timepicker.$build();\n }\n };\n\n $timepicker.select = function (date, index, keep) {\n // console.warn('$timepicker.select', date, scope.$mode);\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n controller.$dateValue = options.defaultDate === 'today' ? new Date() : new Date(1970, 0, 1);\n }\n\n if (!angular.isDate(date)) date = new Date(date);\n if (index === 0) controller.$dateValue.setHours(date.getHours());\n else if (index === 1) controller.$dateValue.setMinutes(date.getMinutes());\n else if (index === 2) controller.$dateValue.setSeconds(date.getSeconds());\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n if (options.autoclose && !keep) {\n $timeout(function () {\n $timepicker.hide(true);\n });\n }\n };\n\n $timepicker.switchMeridian = function (date) {\n if (!controller.$dateValue || isNaN(controller.$dateValue.getTime())) {\n return;\n }\n var hours = (date || controller.$dateValue).getHours();\n controller.$dateValue.setHours(hours < 12 ? hours + 12 : hours - 12);\n controller.$setViewValue(angular.copy(controller.$dateValue));\n controller.$render();\n };\n\n // Protected methods\n\n $timepicker.$build = function () {\n // console.warn('$timepicker.$build() viewDate=%o', viewDate);\n var i;\n var midIndex = scope.midIndex = parseInt(options.length / 2, 10);\n var hours = [];\n var hour;\n for (i = 0; i < options.length; i++) {\n hour = new Date(1970, 0, 1, viewDate.hour - (midIndex - i) * options.hourStep);\n hours.push({\n date: hour,\n label: formatDate(hour, hoursFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(hour, 0),\n disabled: $timepicker.$isDisabled(hour, 0)\n });\n }\n var minutes = [];\n var minute;\n for (i = 0; i < options.length; i++) {\n minute = new Date(1970, 0, 1, 0, viewDate.minute - (midIndex - i) * options.minuteStep);\n minutes.push({\n date: minute,\n label: formatDate(minute, minutesFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(minute, 1),\n disabled: $timepicker.$isDisabled(minute, 1)\n });\n }\n var seconds = [];\n var second;\n for (i = 0; i < options.length; i++) {\n second = new Date(1970, 0, 1, 0, 0, viewDate.second - (midIndex - i) * options.secondStep);\n seconds.push({\n date: second,\n label: formatDate(second, secondsFormat),\n selected: $timepicker.$date && $timepicker.$isSelected(second, 2),\n disabled: $timepicker.$isDisabled(second, 2)\n });\n }\n\n var rows = [];\n for (i = 0; i < options.length; i++) {\n if (showSeconds) {\n rows.push([hours[i], minutes[i], seconds[i]]);\n } else {\n rows.push([hours[i], minutes[i]]);\n }\n }\n scope.rows = rows;\n scope.showSeconds = showSeconds;\n scope.showAM = showAM;\n scope.isAM = ($timepicker.$date || hours[midIndex].date).getHours() < 12;\n scope.timeSeparator = timeSeparator;\n $timepicker.$isBuilt = true;\n };\n\n $timepicker.$isSelected = function (date, index) {\n if (!$timepicker.$date) return false;\n else if (index === 0) {\n return date.getHours() === $timepicker.$date.getHours();\n } else if (index === 1) {\n return date.getMinutes() === $timepicker.$date.getMinutes();\n } else if (index === 2) {\n return date.getSeconds() === $timepicker.$date.getSeconds();\n }\n };\n\n $timepicker.$isDisabled = function (date, index) {\n var selectedTime;\n if (index === 0) {\n selectedTime = date.getTime() + viewDate.minute * 6e4 + viewDate.second * 1e3;\n } else if (index === 1) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.second * 1e3;\n } else if (index === 2) {\n selectedTime = date.getTime() + viewDate.hour * 36e5 + viewDate.minute * 6e4;\n }\n return selectedTime < options.minTime * 1 || selectedTime > options.maxTime * 1;\n };\n\n scope.$arrowAction = function (value, index) {\n if (options.arrowBehavior === 'picker') {\n $timepicker.$setTimeByStep(value, index);\n } else {\n $timepicker.$moveIndex(value, index);\n }\n };\n\n $timepicker.$setTimeByStep = function (value, index) {\n var newDate = new Date($timepicker.$date || startDate);\n var hours = newDate.getHours();\n var minutes = newDate.getMinutes();\n var seconds = newDate.getSeconds();\n if (index === 0) {\n newDate.setHours(hours - (parseInt(options.hourStep, 10) * value));\n } else if (index === 1) {\n newDate.setMinutes(minutes - (parseInt(options.minuteStep, 10) * value));\n } else if (index === 2) {\n newDate.setSeconds(seconds - (parseInt(options.secondStep, 10) * value));\n }\n $timepicker.select(newDate, index, true);\n };\n\n $timepicker.$moveIndex = function (value, index) {\n var targetDate;\n if (index === 0) {\n targetDate = new Date(1970, 0, 1, viewDate.hour + (value * options.length), viewDate.minute, viewDate.second);\n angular.extend(viewDate, {\n hour: targetDate.getHours()\n });\n } else if (index === 1) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute + (value * options.length * options.minuteStep), viewDate.second);\n angular.extend(viewDate, {\n minute: targetDate.getMinutes()\n });\n } else if (index === 2) {\n targetDate = new Date(1970, 0, 1, viewDate.hour, viewDate.minute, viewDate.second + (value * options.length * options.secondStep));\n angular.extend(viewDate, {\n second: targetDate.getSeconds()\n });\n }\n $timepicker.$build();\n };\n\n $timepicker.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n if (evt.target.nodeName.toLowerCase() !== 'input') evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n if (targetEl[0].nodeName.toLowerCase() !== 'button') {\n targetEl = targetEl.parent();\n }\n targetEl.triggerHandler('click');\n }\n };\n\n $timepicker.$onKeyDown = function (evt) {\n if (!/(38|37|39|40|13)/.test(evt.keyCode) || evt.shiftKey || evt.altKey) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Close on enter\n if (evt.keyCode === 13) {\n $timepicker.hide(true);\n return;\n }\n\n // Navigate with keyboard\n var newDate = new Date($timepicker.$date);\n var hours = newDate.getHours();\n var hoursLength = formatDate(newDate, hoursFormat).length;\n var minutes = newDate.getMinutes();\n var minutesLength = formatDate(newDate, minutesFormat).length;\n var seconds = newDate.getSeconds();\n var secondsLength = formatDate(newDate, secondsFormat).length;\n var sepLength = 1;\n var lateralMove = /(37|39)/.test(evt.keyCode);\n var count = 2 + showSeconds * 1 + showAM * 1;\n\n // Navigate indexes (left, right)\n if (lateralMove) {\n if (evt.keyCode === 37) selectedIndex = selectedIndex < 1 ? count - 1 : selectedIndex - 1;\n else if (evt.keyCode === 39) selectedIndex = selectedIndex < count - 1 ? selectedIndex + 1 : 0;\n }\n\n // Update values (up, down)\n var selectRange = [0, hoursLength];\n var incr = 0;\n if (evt.keyCode === 38) incr = -1;\n if (evt.keyCode === 40) incr = +1;\n var isSeconds = selectedIndex === 2 && showSeconds;\n var isMeridian = selectedIndex === 2 && !showSeconds || selectedIndex === 3 && showSeconds;\n if (selectedIndex === 0) {\n newDate.setHours(hours + incr * parseInt(options.hourStep, 10));\n // re-calculate hours length because we have changed hours value\n hoursLength = formatDate(newDate, hoursFormat).length;\n selectRange = [0, hoursLength];\n } else if (selectedIndex === 1) {\n newDate.setMinutes(minutes + incr * parseInt(options.minuteStep, 10));\n // re-calculate minutes length because we have changes minutes value\n minutesLength = formatDate(newDate, minutesFormat).length;\n selectRange = [hoursLength + sepLength, minutesLength];\n } else if (isSeconds) {\n newDate.setSeconds(seconds + incr * parseInt(options.secondStep, 10));\n // re-calculate seconds length because we have changes seconds value\n secondsLength = formatDate(newDate, secondsFormat).length;\n selectRange = [hoursLength + sepLength + minutesLength + sepLength, secondsLength];\n } else if (isMeridian) {\n if (!lateralMove) $timepicker.switchMeridian();\n selectRange = [hoursLength + sepLength + minutesLength + sepLength + (secondsLength + sepLength) * showSeconds, 2];\n }\n $timepicker.select(newDate, selectedIndex, true);\n createSelection(selectRange[0], selectRange[1]);\n parentScope.$digest();\n };\n\n // Private\n\n function createSelection (start, length) {\n var end = start + length;\n if (element[0].createTextRange) {\n var selRange = element[0].createTextRange();\n selRange.collapse(true);\n selRange.moveStart('character', start);\n selRange.moveEnd('character', end);\n selRange.select();\n } else if (element[0].setSelectionRange) {\n element[0].setSelectionRange(start, end);\n } else if (angular.isUndefined(element[0].selectionStart)) {\n element[0].selectionStart = start;\n element[0].selectionEnd = end;\n }\n }\n\n function focusElement () {\n element[0].focus();\n }\n\n // Overrides\n\n var _init = $timepicker.init;\n $timepicker.init = function () {\n if (isNative && options.useNative) {\n element.prop('type', 'time');\n element.css('-webkit-appearance', 'textfield');\n return;\n } else if (isTouch) {\n element.prop('type', 'text');\n element.attr('readonly', 'true');\n element.on('click', focusElement);\n }\n _init();\n };\n\n var _destroy = $timepicker.destroy;\n $timepicker.destroy = function () {\n if (isNative && options.useNative) {\n element.off('click', focusElement);\n }\n _destroy();\n };\n\n var _show = $timepicker.show;\n $timepicker.show = function () {\n if ((!isTouch && element.attr('readonly')) || element.attr('disabled')) return;\n _show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if ($timepicker.$element) $timepicker.$element.on(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.on('keydown', $timepicker.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $timepicker.hide;\n $timepicker.hide = function (blur) {\n if (!$timepicker.$isShown) return;\n if ($timepicker.$element) $timepicker.$element.off(isTouch ? 'touchstart' : 'mousedown', $timepicker.$onMouseDown);\n if (options.keyboard) {\n if (element) element.off('keydown', $timepicker.$onKeyDown);\n }\n _hide(blur);\n };\n\n return $timepicker;\n\n }\n\n timepickerFactory.defaults = defaults;\n return timepickerFactory;\n\n };\n\n })\n\n\n .directive('bsTimepicker', function ($window, $parse, $q, $dateFormatter, $dateParser, $timepicker) {\n\n var defaults = $timepicker.defaults;\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {\n scope: scope\n };\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'autoclose', 'timeType', 'timeFormat', 'timezone', 'modelTimeFormat', 'useNative', 'hourStep', 'minuteStep', 'secondStep', 'length', 'arrowBehavior', 'iconUp', 'iconDown', 'roundDisplay', 'id', 'prefixClass', 'prefixEvent', 'defaultDate'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoclose', 'useNative', 'roundDisplay'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Initialize timepicker\n if (isNative && (options.useNative || defaults.useNative)) options.timeFormat = 'HH:mm';\n var timepicker = $timepicker(element, controller, options);\n options = timepicker.$options;\n\n var lang = options.lang;\n var formatDate = function (date, format, timezone) {\n return $dateFormatter.formatDate(date, format, lang, timezone);\n };\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!timepicker || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(timepicker),?/i);\n if (newValue === true) {\n timepicker.show();\n } else {\n timepicker.hide();\n }\n });\n }\n\n // Initialize parser\n var dateParser = $dateParser({\n format: options.timeFormat,\n lang: lang\n });\n\n // Observe attributes for changes\n angular.forEach(['minTime', 'maxTime'], function (key) {\n // console.warn('attr.$observe(%s)', key, attr[key]);\n if (angular.isDefined(attr[key])) {\n attr.$observe(key, function (newValue) {\n timepicker.$options[key] = dateParser.getTimeForAttribute(key, newValue);\n if (!isNaN(timepicker.$options[key])) timepicker.$build();\n validateAgainstMinMaxTime(controller.$dateValue);\n });\n }\n });\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue, controller.$dateValue);\n timepicker.update(controller.$dateValue);\n }, true);\n\n function validateAgainstMinMaxTime (parsedTime) {\n if (!angular.isDate(parsedTime)) return;\n var isMinValid = isNaN(options.minTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) >= options.minTime;\n var isMaxValid = isNaN(options.maxTime) || new Date(parsedTime.getTime()).setFullYear(1970, 0, 1) <= options.maxTime;\n var isValid = isMinValid && isMaxValid;\n controller.$setValidity('date', isValid);\n controller.$setValidity('min', isMinValid);\n controller.$setValidity('max', isMaxValid);\n // Only update the model when we have a valid date\n if (!isValid) {\n return;\n }\n controller.$dateValue = parsedTime;\n }\n\n // viewValue -> $parsers -> modelValue\n controller.$parsers.unshift(function (viewValue) {\n // console.warn('$parser(\"%s\"): viewValue=%o', element.attr('ng-model'), viewValue);\n var date;\n // Null values should correctly reset the model value & validity\n if (!viewValue) {\n // BREAKING CHANGE:\n // return null (not undefined) when input value is empty, so angularjs 1.3\n // ngModelController can go ahead and run validators, like ngRequired\n controller.$setValidity('date', true);\n return null;\n }\n var parsedTime = angular.isDate(viewValue) ? viewValue : dateParser.parse(viewValue, controller.$dateValue);\n if (!parsedTime || isNaN(parsedTime.getTime())) {\n controller.$setValidity('date', false);\n // Return undefined, causes ngModelController to\n // invalidate model value\n return undefined;\n }\n validateAgainstMinMaxTime(parsedTime);\n\n if (options.timeType === 'string') {\n date = dateParser.timezoneOffsetAdjust(parsedTime, options.timezone, true);\n return formatDate(date, options.modelTimeFormat || options.timeFormat);\n }\n date = dateParser.timezoneOffsetAdjust(controller.$dateValue, options.timezone, true);\n if (options.timeType === 'number') {\n return date.getTime();\n } else if (options.timeType === 'unix') {\n return date.getTime() / 1000;\n } else if (options.timeType === 'iso') {\n return date.toISOString();\n }\n return new Date(date);\n });\n\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n var date;\n if (angular.isUndefined(modelValue) || modelValue === null) {\n date = NaN;\n } else if (angular.isDate(modelValue)) {\n date = modelValue;\n } else if (options.timeType === 'string') {\n date = dateParser.parse(modelValue, null, options.modelTimeFormat);\n } else if (options.timeType === 'unix') {\n date = new Date(modelValue * 1000);\n } else {\n date = new Date(modelValue);\n }\n // Setup default value?\n // if(isNaN(date.getTime())) date = new Date(new Date().setMinutes(0) + 36e5);\n controller.$dateValue = dateParser.timezoneOffsetAdjust(date, options.timezone);\n return getTimeFormattedString();\n });\n\n // viewValue -> element\n controller.$render = function () {\n // console.warn('$render(\"%s\"): viewValue=%o', element.attr('ng-model'), controller.$viewValue);\n element.val(getTimeFormattedString());\n };\n\n function getTimeFormattedString () {\n return !controller.$dateValue || isNaN(controller.$dateValue.getTime()) ? '' : formatDate(controller.$dateValue, options.timeFormat);\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (timepicker) timepicker.destroy();\n options = null;\n timepicker = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.scrollspy', ['mgcrea.ngStrap.helpers.debounce', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$scrollspy', function () {\n\n // Pool of registered spies\n var spies = this.$$spies = {};\n\n var defaults = this.defaults = {\n debounce: 150,\n throttle: 100,\n offset: 100\n };\n\n this.$get = function ($window, $document, $rootScope, dimensions, debounce, throttle) {\n\n var windowEl = angular.element($window);\n var docEl = angular.element($document.prop('documentElement'));\n var bodyEl = angular.element($window.document.body);\n\n // Helper functions\n\n function nodeName (element, name) {\n return element[0].nodeName && element[0].nodeName.toLowerCase() === name.toLowerCase();\n }\n\n function ScrollSpyFactory (config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n if (!options.element) options.element = bodyEl;\n var isWindowSpy = nodeName(options.element, 'body');\n var scrollEl = isWindowSpy ? windowEl : options.element;\n var scrollId = isWindowSpy ? 'window' : options.id;\n\n // Use existing spy\n if (spies[scrollId]) {\n spies[scrollId].$$count++;\n return spies[scrollId];\n }\n\n var $scrollspy = {};\n\n // Private vars\n var unbindViewContentLoaded;\n var unbindIncludeContentLoaded;\n var trackedElements = $scrollspy.$trackedElements = [];\n var sortedElements = [];\n var activeTarget;\n var debouncedCheckPosition;\n var throttledCheckPosition;\n var debouncedCheckOffsets;\n /* eslint-disable no-unused-vars */\n var viewportHeight;\n /* eslint-enable no-unused-vars */\n var scrollTop;\n\n $scrollspy.init = function () {\n\n // Setup internal ref counter\n this.$$count = 1;\n\n // Bind events\n debouncedCheckPosition = debounce(this.checkPosition, options.debounce);\n throttledCheckPosition = throttle(this.checkPosition, options.throttle);\n scrollEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', debouncedCheckPosition);\n scrollEl.on('scroll', throttledCheckPosition);\n\n debouncedCheckOffsets = debounce(this.checkOffsets, options.debounce);\n unbindViewContentLoaded = $rootScope.$on('$viewContentLoaded', debouncedCheckOffsets);\n unbindIncludeContentLoaded = $rootScope.$on('$includeContentLoaded', debouncedCheckOffsets);\n debouncedCheckOffsets();\n\n // Register spy for reuse\n if (scrollId) {\n spies[scrollId] = $scrollspy;\n }\n\n };\n\n $scrollspy.destroy = function () {\n\n // Check internal ref counter\n this.$$count--;\n if (this.$$count > 0) {\n return;\n }\n\n // Unbind events\n scrollEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', debouncedCheckPosition);\n scrollEl.off('scroll', throttledCheckPosition);\n unbindViewContentLoaded();\n unbindIncludeContentLoaded();\n if (scrollId) {\n delete spies[scrollId];\n }\n };\n\n $scrollspy.checkPosition = function () {\n\n // Not ready yet\n if (!sortedElements.length) return;\n\n // Calculate the scroll position\n scrollTop = (isWindowSpy ? $window.pageYOffset : scrollEl.prop('scrollTop')) || 0;\n\n // Calculate the viewport height for use by the components\n viewportHeight = Math.max($window.innerHeight, docEl.prop('clientHeight'));\n\n // Activate first element if scroll is smaller\n if (scrollTop < sortedElements[0].offsetTop && activeTarget !== sortedElements[0].target) {\n return $scrollspy.$activateElement(sortedElements[0]);\n }\n\n // Activate proper element\n for (var i = sortedElements.length; i--;) {\n if (angular.isUndefined(sortedElements[i].offsetTop) || sortedElements[i].offsetTop === null) continue;\n if (activeTarget === sortedElements[i].target) continue;\n if (scrollTop < sortedElements[i].offsetTop) continue;\n if (sortedElements[i + 1] && scrollTop > sortedElements[i + 1].offsetTop) continue;\n return $scrollspy.$activateElement(sortedElements[i]);\n }\n\n };\n\n $scrollspy.checkPositionWithEventLoop = function () {\n // IE 9 throws an error if we use 'this' instead of '$scrollspy'\n // in this setTimeout call\n setTimeout($scrollspy.checkPosition, 1);\n };\n\n // Protected methods\n\n $scrollspy.$activateElement = function (element) {\n if (activeTarget) {\n var activeElement = $scrollspy.$getTrackedElement(activeTarget);\n if (activeElement) {\n activeElement.source.removeClass('active');\n if (nodeName(activeElement.source, 'li') && nodeName(activeElement.source.parent().parent(), 'li')) {\n activeElement.source.parent().parent().removeClass('active');\n }\n }\n }\n activeTarget = element.target;\n element.source.addClass('active');\n if (nodeName(element.source, 'li') && nodeName(element.source.parent().parent(), 'li')) {\n element.source.parent().parent().addClass('active');\n }\n };\n\n $scrollspy.$getTrackedElement = function (target) {\n return trackedElements.filter(function (obj) {\n return obj.target === target;\n })[0];\n };\n\n // Track offsets behavior\n\n $scrollspy.checkOffsets = function () {\n\n angular.forEach(trackedElements, function (trackedElement) {\n var targetElement = document.querySelector(trackedElement.target);\n trackedElement.offsetTop = targetElement ? dimensions.offset(targetElement).top : null;\n if (options.offset && trackedElement.offsetTop !== null) trackedElement.offsetTop -= options.offset * 1;\n });\n\n sortedElements = trackedElements\n .filter(function (el) {\n return el.offsetTop !== null;\n })\n .sort(function (a, b) {\n return a.offsetTop - b.offsetTop;\n });\n\n debouncedCheckPosition();\n\n };\n\n $scrollspy.trackElement = function (target, source) {\n trackedElements.push({target: target, source: source});\n };\n\n $scrollspy.untrackElement = function (target, source) {\n var toDelete;\n for (var i = trackedElements.length; i--;) {\n if (trackedElements[i].target === target && trackedElements[i].source === source) {\n toDelete = i;\n break;\n }\n }\n trackedElements.splice(toDelete, 1);\n };\n\n $scrollspy.activate = function (i) {\n trackedElements[i].addClass('active');\n };\n\n // Initialize plugin\n\n $scrollspy.init();\n return $scrollspy;\n\n }\n\n return ScrollSpyFactory;\n\n };\n\n })\n\n .directive('bsScrollspy', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'EAC',\n link: function postLink (scope, element, attr) {\n\n var options = {scope: scope};\n angular.forEach(['offset', 'target'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n var scrollspy = $scrollspy(options);\n scrollspy.trackElement(options.target, element);\n\n scope.$on('$destroy', function () {\n if (scrollspy) {\n scrollspy.untrackElement(options.target, element);\n scrollspy.destroy();\n }\n options = null;\n scrollspy = null;\n });\n\n }\n };\n\n })\n\n\n .directive('bsScrollspyList', function ($rootScope, debounce, dimensions, $scrollspy) {\n\n return {\n restrict: 'A',\n compile: function postLink (element, attr) {\n var children = element[0].querySelectorAll('li > a[href]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.parent().attr('bs-scrollspy', '').attr('data-target', childEl.attr('href'));\n });\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.select', ['mgcrea.ngStrap.tooltip', 'mgcrea.ngStrap.helpers.parseOptions'])\n\n .provider('$select', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'select',\n prefixEvent: '$select',\n placement: 'bottom-left',\n templateUrl: 'select/select.tpl.html',\n trigger: 'focus',\n container: false,\n keyboard: true,\n html: false,\n delay: 0,\n multiple: false,\n allNoneButtons: false,\n sort: true,\n caretHtml: ' <span class=\"caret\"></span>',\n placeholder: 'Choose among the following...',\n allText: 'All',\n noneText: 'None',\n maxLength: 3,\n maxLengthHtml: 'selected',\n iconCheckmark: 'glyphicon glyphicon-ok',\n toggle: false\n };\n\n this.$get = function ($window, $document, $rootScope, $tooltip, $timeout) {\n\n // var bodyEl = angular.element($window.document.body);\n var isNative = /(ip[ao]d|iphone|android)/ig.test($window.navigator.userAgent);\n var isTouch = ('createTouch' in $window.document) && isNative;\n\n function SelectFactory (element, controller, config) {\n\n var $select = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $select = $tooltip(element, options);\n var scope = $select.$scope;\n\n scope.$matches = [];\n if (options.multiple) {\n scope.$activeIndex = [];\n } else {\n scope.$activeIndex = -1;\n }\n scope.$isMultiple = options.multiple;\n scope.$showAllNoneButtons = options.allNoneButtons && options.multiple;\n scope.$iconCheckmark = options.iconCheckmark;\n scope.$allText = options.allText;\n scope.$noneText = options.noneText;\n\n scope.$activate = function (index) {\n scope.$$postDigest(function () {\n $select.activate(index);\n });\n };\n\n scope.$select = function (index, evt) {\n scope.$$postDigest(function () {\n $select.select(index);\n });\n };\n\n scope.$isVisible = function () {\n return $select.$isVisible();\n };\n\n scope.$isActive = function (index) {\n return $select.$isActive(index);\n };\n\n scope.$selectAll = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (!scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n scope.$selectNone = function () {\n for (var i = 0; i < scope.$matches.length; i++) {\n if (scope.$isActive(i)) {\n scope.$select(i);\n }\n }\n };\n\n // Public methods\n\n $select.update = function (matches) {\n scope.$matches = matches;\n $select.$updateActiveIndex();\n };\n\n $select.activate = function (index) {\n if (options.multiple) {\n if ($select.$isActive(index)) {\n scope.$activeIndex.splice(scope.$activeIndex.indexOf(index), 1);\n } else {\n scope.$activeIndex.push(index);\n }\n if (options.sort) scope.$activeIndex.sort(function (a, b) { return a - b; }); // use numeric sort instead of default sort\n } else {\n scope.$activeIndex = index;\n }\n return scope.$activeIndex;\n };\n\n $select.select = function (index) {\n if (angular.isUndefined(index) || index < 0 || index >= scope.$matches.length) { return; }\n var value = scope.$matches[index].value;\n scope.$apply(function () {\n $select.activate(index);\n if (options.multiple) {\n controller.$setViewValue(scope.$activeIndex.map(function (index) {\n if (angular.isUndefined(scope.$matches[index])) {\n return null;\n }\n return scope.$matches[index].value;\n }));\n } else {\n if (options.toggle) {\n controller.$setViewValue((value === controller.$modelValue) ? undefined : value);\n } else {\n controller.$setViewValue(value);\n }\n // Hide if single select\n $select.hide();\n }\n });\n // Emit event\n scope.$emit(options.prefixEvent + '.select', value, index, $select);\n if (angular.isDefined(options.onSelect) && angular.isFunction(options.onSelect)) {\n options.onSelect(value, index, $select);\n }\n };\n\n // Protected methods\n\n $select.$updateActiveIndex = function () {\n if (options.multiple) {\n if (angular.isArray(controller.$modelValue)) {\n scope.$activeIndex = controller.$modelValue.map(function (value) {\n return $select.$getIndex(value);\n });\n } else {\n scope.$activeIndex = [];\n }\n } else {\n if (angular.isDefined(controller.$modelValue) && scope.$matches.length) {\n scope.$activeIndex = $select.$getIndex(controller.$modelValue);\n } else {\n scope.$activeIndex = -1;\n }\n }\n };\n\n $select.$isVisible = function () {\n if (!options.minLength || !controller) {\n return scope.$matches.length;\n }\n // minLength support\n return scope.$matches.length && controller.$viewValue.length >= options.minLength;\n };\n\n $select.$isActive = function (index) {\n if (options.multiple) {\n return scope.$activeIndex.indexOf(index) !== -1;\n }\n return scope.$activeIndex === index;\n };\n\n $select.$getIndex = function (value) {\n var index;\n for (index = scope.$matches.length; index--;) {\n if (angular.equals(scope.$matches[index].value, value)) break;\n }\n return index;\n };\n\n $select.$onMouseDown = function (evt) {\n // Prevent blur on mousedown on .dropdown-menu\n evt.preventDefault();\n evt.stopPropagation();\n // Emulate click for mobile devices\n if (isTouch) {\n var targetEl = angular.element(evt.target);\n targetEl.triggerHandler('click');\n }\n };\n\n $select.$onKeyDown = function (evt) {\n if (!/(9|13|38|40)/.test(evt.keyCode)) return;\n // Let tab propagate\n if (evt.keyCode !== 9) {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n // release focus on tab\n if (options.multiple && evt.keyCode === 9) {\n return $select.hide();\n }\n\n // Select with enter\n if (!options.multiple && (evt.keyCode === 13 || evt.keyCode === 9)) {\n return $select.select(scope.$activeIndex);\n }\n\n if (!options.multiple) {\n // Navigate with keyboard\n if (evt.keyCode === 38 && scope.$activeIndex > 0) scope.$activeIndex--;\n else if (evt.keyCode === 38 && scope.$activeIndex < 0) scope.$activeIndex = scope.$matches.length - 1;\n else if (evt.keyCode === 40 && scope.$activeIndex < scope.$matches.length - 1) scope.$activeIndex++;\n else if (angular.isUndefined(scope.$activeIndex)) scope.$activeIndex = 0;\n scope.$digest();\n }\n };\n\n $select.$isIE = function () {\n var ua = $window.navigator.userAgent;\n return ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0;\n };\n\n $select.$selectScrollFix = function (e) {\n if ($document[0].activeElement.tagName === 'UL') {\n e.preventDefault();\n e.stopImmediatePropagation();\n e.target.focus();\n }\n };\n\n // Overrides\n\n var _show = $select.show;\n $select.show = function () {\n _show();\n if (options.multiple) {\n $select.$element.addClass('select-multiple');\n }\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n $select.$element.on(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.on('keydown', $select.$onKeyDown);\n }\n }, 0, false);\n };\n\n var _hide = $select.hide;\n $select.hide = function () {\n if (!options.multiple && angular.isUndefined(controller.$modelValue)) {\n scope.$activeIndex = -1;\n }\n $select.$element.off(isTouch ? 'touchstart' : 'mousedown', $select.$onMouseDown);\n if (options.keyboard) {\n element.off('keydown', $select.$onKeyDown);\n }\n _hide(true);\n };\n\n return $select;\n\n }\n\n SelectFactory.defaults = defaults;\n return SelectFactory;\n\n };\n\n })\n\n .directive('bsSelect', function ($window, $parse, $q, $select, $parseOptions) {\n\n var defaults = $select.defaults;\n\n return {\n restrict: 'EAC',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = {scope: scope, placeholder: defaults.placeholder};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'placeholder', 'allNoneButtons', 'maxLength', 'maxLengthHtml', 'allText', 'noneText', 'iconCheckmark', 'autoClose', 'id', 'sort', 'caretHtml', 'prefixClass', 'prefixEvent', 'toggle'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'allNoneButtons', 'sort'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) {\n options[key] = false;\n }\n });\n\n // bind functions from the attrs to the show, hide and select events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide', 'onSelect'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Only parse data-multiple. Angular sets existence attributes to true (multiple/required/etc), they apply this\n // to data-multiple as well for some reason, so we'll parse this ourselves and disregard multiple\n var dataMultiple = element.attr('data-multiple');\n if (angular.isDefined(dataMultiple)) {\n if (falseValueRegExp.test(dataMultiple)) {\n options.multiple = false;\n } else {\n options.multiple = dataMultiple;\n }\n }\n\n // Add support for select markup\n if (element[0].nodeName.toLowerCase() === 'select') {\n var inputEl = element;\n inputEl.css('display', 'none');\n element = angular.element('<button type=\"button\" class=\"btn btn-default\"></button>');\n inputEl.after(element);\n }\n\n // Build proper bsOptions\n var parsedOptions = $parseOptions(attr.bsOptions);\n\n // Initialize select\n var select = $select(element, controller, options);\n\n if (select.$isIE()) {\n element[0].addEventListener('blur', select.$selectScrollFix);\n }\n\n // Watch bsOptions values before filtering for changes\n var watchedOptions = parsedOptions.$match[7].replace(/\\|.+/, '').trim();\n scope.$watch(watchedOptions, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', watchedOptions, newValue, oldValue);\n parsedOptions.valuesFn(scope, controller)\n .then(function (values) {\n select.update(values);\n controller.$render();\n });\n }, true);\n\n // Watch model for changes\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n // console.warn('scope.$watch(%s)', attr.ngModel, newValue, oldValue);\n select.$updateActiveIndex();\n controller.$render();\n }, true);\n\n // Model rendering in view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var selected;\n var index;\n if (options.multiple && angular.isArray(controller.$modelValue)) {\n selected = controller.$modelValue.map(function (value) {\n index = select.$getIndex(value);\n return index !== -1 ? select.$scope.$matches[index].label : false;\n }).filter(angular.isDefined);\n if (selected.length > (options.maxLength || defaults.maxLength)) {\n selected = selected.length + ' ' + (options.maxLengthHtml || defaults.maxLengthHtml);\n } else {\n selected = selected.join(', ');\n }\n } else {\n index = select.$getIndex(controller.$modelValue);\n selected = index !== -1 ? select.$scope.$matches[index].label : false;\n }\n element.html((selected || options.placeholder) + (options.caretHtml || defaults.caretHtml));\n };\n\n if (options.multiple) {\n controller.$isEmpty = function (value) {\n return !value || value.length === 0;\n };\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (select) select.destroy();\n options = null;\n select = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$popover', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n customClass: '',\n // uncommenting the next two lines will break backwards compatability\n // prefixClass: 'popover',\n // prefixEvent: 'popover',\n container: false,\n target: false,\n placement: 'right',\n templateUrl: 'popover/popover.tpl.html',\n contentTemplate: false,\n trigger: 'click',\n keyboard: true,\n html: false,\n title: '',\n content: '',\n delay: 0,\n autoClose: false\n };\n\n this.$get = function ($tooltip) {\n\n function PopoverFactory (element, config) {\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n var $popover = $tooltip(element, options);\n\n // Support scope as string options [/*title, */content]\n if (options.content) {\n $popover.$scope.content = options.content;\n }\n\n return $popover;\n\n }\n\n return PopoverFactory;\n\n };\n\n })\n\n .directive('bsPopover', function ($window, $sce, $popover) {\n\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr) {\n\n var popover;\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container', 'autoClose'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // should not parse target attribute (anchor tag), only data-target #1454\n var dataTarget = element.attr('data-target');\n if (angular.isDefined(dataTarget)) {\n if (falseValueRegExp.test(dataTarget)) {\n options.target = false;\n } else {\n options.target = dataTarget;\n }\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsPopover) {\n scope.$watch(attr.bsPopover, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n if (angular.isDefined(oldValue)) {\n requestAnimationFrame(function () {\n if (popover) popover.$applyPlacement();\n });\n }\n }, true);\n }\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);\n if (newValue === true) {\n popover.show();\n } else {\n popover.hide();\n }\n });\n }\n\n // Viewport support\n if (attr.viewport) {\n scope.$watch(attr.viewport, function (newValue) {\n if (!popover || !angular.isDefined(newValue)) return;\n popover.setViewport(newValue);\n });\n }\n\n // Initialize popover\n popover = $popover(element, options);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (popover) popover.destroy();\n options = null;\n popover = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.navbar', [])\n\n .provider('$navbar', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n routeAttr: 'data-match-route',\n strict: false\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsNavbar', function ($window, $location, $navbar) {\n\n var defaults = $navbar.defaults;\n\n return {\n restrict: 'A',\n link: function postLink (scope, element, attr, controller) {\n\n // Directive options\n var options = angular.copy(defaults);\n angular.forEach(Object.keys(defaults), function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Watch for the $location\n scope.$watch(function () {\n\n return $location.path();\n\n }, function (newValue, oldValue) {\n\n var liElements = element[0].querySelectorAll('li[' + options.routeAttr + ']');\n\n angular.forEach(liElements, function (li) {\n\n var liElement = angular.element(li);\n var pattern = liElement.attr(options.routeAttr).replace('/', '\\\\/');\n if (options.strict) {\n pattern = '^' + pattern + '$';\n }\n var regexp = new RegExp(pattern, 'i');\n\n if (regexp.test(newValue)) {\n liElement.addClass(options.activeClass);\n } else {\n liElement.removeClass(options.activeClass);\n }\n\n });\n\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n customClass: '',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true,\n size: null\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n var backdropCount = 0;\n var dialogBaseZindex = 1050;\n var backdropBaseZindex = 1040;\n\n var validSizes = {\n lg: 'modal-lg',\n sm: 'modal-sm'\n };\n\n function ModalFactory (config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if (!options.element && !options.container) {\n options.container = 'body';\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function (key) {\n if (options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $modal.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $modal.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData;\n var modalElement;\n var modalScope;\n var backdropElement = angular.element('<div class=\"' + options.prefixClass + '-backdrop\"/>');\n backdropElement.css({position: 'fixed', top: '0px', left: '0px', bottom: '0px', right: '0px'});\n promise.then(function (data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function () {\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function () {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if (backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function () {\n if ($modal.$isShown) return;\n\n var parent;\n var after;\n if (angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if (modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function (clonedElement, scope) {});\n\n if (options.backdrop) {\n // set z-index\n modalElement.css({'z-index': dialogBaseZindex + (backdropCount * 20)});\n backdropElement.css({'z-index': backdropBaseZindex + (backdropCount * 20)});\n\n // increment number of backdrops\n backdropCount++;\n }\n\n if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) {\n options.onBeforeShow($modal);\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: customClass\n if (options.customClass) {\n modalElement.addClass(options.customClass);\n }\n\n // Options: size\n if (options.size && validSizes[options.size]) {\n angular.element(findElement('.modal-dialog', modalElement[0])).addClass(validSizes[options.size]);\n }\n\n // Options: animation\n if (options.animation) {\n if (options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if (options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function () {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $modal);\n if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) {\n options.onShow($modal);\n }\n }\n\n $modal.hide = function () {\n if (!$modal.$isShown) return;\n\n if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) {\n options.onBeforeHide($modal);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if (options.backdrop) {\n // decrement number of backdrops\n backdropCount--;\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) {\n options.onHide($modal);\n }\n bodyElement.removeClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function () {\n if ($modal.$isShown) {\n $modal.hide();\n } else {\n $modal.show();\n }\n };\n\n $modal.focus = function () {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function (evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents () {\n if (options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents () {\n if (options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick (evt) {\n if (evt.target !== evt.currentTarget) return;\n if (options.backdrop === 'static') {\n $modal.focus();\n } else {\n $modal.hide();\n }\n }\n\n function preventEventDefault (evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement () {\n if ($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if (modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if (modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function ($window, $sce, $parse, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass', 'customClass', 'modalClass', 'size'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Options: alias modalClass to customClass\n if (options.modalClass) {\n options.customClass = options.modalClass;\n }\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsModal) {\n scope.$watch(attr.bsModal, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.dropdown', ['mgcrea.ngStrap.tooltip'])\n\n .provider('$dropdown', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'dropdown',\n prefixEvent: 'dropdown',\n placement: 'bottom-left',\n templateUrl: 'dropdown/dropdown.tpl.html',\n trigger: 'click',\n container: false,\n keyboard: true,\n html: false,\n delay: 0\n };\n\n this.$get = function ($window, $rootScope, $tooltip, $timeout) {\n\n var bodyEl = angular.element($window.document.body);\n var matchesSelector = Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector;\n\n function DropdownFactory (element, config) {\n\n var $dropdown = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n /* var scope = */$dropdown.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n $dropdown = $tooltip(element, options);\n var parentEl = element.parent();\n\n // Protected methods\n\n $dropdown.$onKeyDown = function (evt) {\n if (!/(38|40)/.test(evt.keyCode)) return;\n evt.preventDefault();\n evt.stopPropagation();\n\n // Retrieve focused index\n var items = angular.element($dropdown.$element[0].querySelectorAll('li:not(.divider) a'));\n if (!items.length) return;\n var index;\n angular.forEach(items, function (el, i) {\n if (matchesSelector && matchesSelector.call(el, ':focus')) index = i;\n });\n\n // Navigate with keyboard\n if (evt.keyCode === 38 && index > 0) index--;\n else if (evt.keyCode === 40 && index < items.length - 1) index++;\n else if (angular.isUndefined(index)) index = 0;\n items.eq(index)[0].focus();\n\n };\n\n // Overrides\n\n var show = $dropdown.show;\n $dropdown.show = function () {\n show();\n // use timeout to hookup the events to prevent\n // event bubbling from being processed imediately.\n $timeout(function () {\n if (options.keyboard && $dropdown.$element) $dropdown.$element.on('keydown', $dropdown.$onKeyDown);\n bodyEl.on('click', onBodyClick);\n }, 0, false);\n if (parentEl.hasClass('dropdown')) parentEl.addClass('open');\n };\n\n var hide = $dropdown.hide;\n $dropdown.hide = function () {\n if (!$dropdown.$isShown) return;\n if (options.keyboard && $dropdown.$element) $dropdown.$element.off('keydown', $dropdown.$onKeyDown);\n bodyEl.off('click', onBodyClick);\n if (parentEl.hasClass('dropdown')) parentEl.removeClass('open');\n hide();\n };\n\n var destroy = $dropdown.destroy;\n $dropdown.destroy = function () {\n bodyEl.off('click', onBodyClick);\n destroy();\n };\n\n // Private functions\n\n function onBodyClick (evt) {\n if (evt.target === element[0]) return;\n return evt.target !== element[0] && $dropdown.hide();\n }\n\n return $dropdown;\n\n }\n\n return DropdownFactory;\n\n };\n\n })\n\n .directive('bsDropdown', function ($window, $sce, $dropdown) {\n\n return {\n restrict: 'EAC',\n scope: true,\n compile: function (tElement, tAttrs) {\n\n // Support for inlined template (next sibling)\n // It must be fetched before compilation\n if (!tAttrs.bsDropdown) {\n var nextSibling = tElement[0].nextSibling;\n while (nextSibling && nextSibling.nodeType !== 1) {\n nextSibling = nextSibling.nextSibling;\n }\n if (nextSibling && nextSibling.className.split(' ').indexOf('dropdown-menu') >= 0) {\n tAttrs.template = nextSibling.outerHTML;\n tAttrs.templateUrl = undefined;\n nextSibling.parentNode.removeChild(nextSibling);\n }\n }\n\n return function postLink (scope, element, attr) {\n\n // Directive options\n var options = {scope: scope};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'container', 'delay', 'trigger', 'keyboard', 'html', 'animation', 'id', 'autoClose'], function (key) {\n if (angular.isDefined(tAttrs[key])) options[key] = tAttrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as an object\n if (attr.bsDropdown) {\n scope.$watch(attr.bsDropdown, function (newValue, oldValue) {\n scope.content = newValue;\n }, true);\n }\n\n // Initialize dropdown\n var dropdown = $dropdown(element, options);\n\n // Visibility binding support\n if (attr.bsShow) {\n scope.$watch(attr.bsShow, function (newValue, oldValue) {\n if (!dropdown || !angular.isDefined(newValue)) return;\n if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(dropdown),?/i);\n if (newValue === true) {\n dropdown.show();\n } else {\n dropdown.hide();\n }\n });\n }\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (dropdown) dropdown.destroy();\n options = null;\n dropdown = null;\n });\n\n };\n }\n };\n\n });\n","'use strict';\n\nif (angular.version.minor < 3 && angular.version.dot < 14) {\n angular.module('ng')\n\n .factory('$$rAF', function ($window, $timeout) {\n\n var requestAnimationFrame = $window.requestAnimationFrame ||\n $window.webkitRequestAnimationFrame ||\n $window.mozRequestAnimationFrame;\n\n var cancelAnimationFrame = $window.cancelAnimationFrame ||\n $window.webkitCancelAnimationFrame ||\n $window.mozCancelAnimationFrame ||\n $window.webkitCancelRequestAnimationFrame;\n\n var rafSupported = !!requestAnimationFrame;\n var raf = rafSupported ?\n function (fn) {\n var id = requestAnimationFrame(fn);\n return function () {\n cancelAnimationFrame(id);\n };\n } :\n function (fn) {\n var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666\n return function () {\n $timeout.cancel(timer);\n };\n };\n\n raf.supported = rafSupported;\n\n return raf;\n\n });\n}\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.parseOptions', [])\n\n .provider('$parseOptions', function () {\n\n var defaults = this.defaults = {\n regexp: /^\\s*(.*?)(?:\\s+as\\s+(.*?))?(?:\\s+group\\s+by\\s+(.*))?\\s+for\\s+(?:([\\$\\w][\\$\\w]*)|(?:\\(\\s*([\\$\\w][\\$\\w]*)\\s*,\\s*([\\$\\w][\\$\\w]*)\\s*\\)))\\s+in\\s+(.*?)(?:\\s+track\\s+by\\s+(.*?))?$/\n };\n\n this.$get = function ($parse, $q) {\n\n function ParseOptionsFactory (attr, config) {\n\n var $parseOptions = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n $parseOptions.$values = [];\n\n // Private vars\n var match;\n var displayFn;\n var valueName;\n /* eslint-disable no-unused-vars */\n var keyName;\n var groupByFn;\n /* eslint-enable no-unused-vars */\n var valueFn;\n var valuesFn;\n\n $parseOptions.init = function () {\n $parseOptions.$match = match = attr.match(options.regexp);\n displayFn = $parse(match[2] || match[1]);\n valueName = match[4] || match[6];\n keyName = match[5];\n groupByFn = $parse(match[3] || '');\n valueFn = $parse(match[2] ? match[1] : valueName);\n valuesFn = $parse(match[7]);\n };\n\n $parseOptions.valuesFn = function (scope, controller) {\n return $q.when(valuesFn(scope, controller))\n .then(function (values) {\n if (!angular.isArray(values)) {\n values = [];\n }\n $parseOptions.$values = values.length ? parseValues(values, scope) : [];\n return $parseOptions.$values;\n });\n };\n\n $parseOptions.displayValue = function (modelValue) {\n var scope = {};\n scope[valueName] = modelValue;\n return displayFn(scope);\n };\n\n // Private functions\n\n function parseValues (values, scope) {\n return values.map(function (match, index) {\n var locals = {};\n var label;\n var value;\n locals[valueName] = match;\n label = displayFn(scope, locals);\n value = valueFn(scope, locals);\n return {label: label, value: value, index: index};\n });\n }\n\n $parseOptions.init();\n return $parseOptions;\n\n }\n\n return ParseOptionsFactory;\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dimensions', [])\n\n .factory('dimensions', function () {\n\n var fn = {};\n\n /**\n * Test the element nodeName\n * @param element\n * @param name\n */\n var nodeName = fn.nodeName = function (element, name) {\n return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();\n };\n\n /**\n * Returns the element computed style\n * @param element\n * @param prop\n * @param extra\n */\n fn.css = function (element, prop, extra) {\n var value;\n if (element.currentStyle) { // IE\n value = element.currentStyle[prop];\n } else if (window.getComputedStyle) {\n value = window.getComputedStyle(element)[prop];\n } else {\n value = element.style[prop];\n }\n return extra === true ? parseFloat(value) || 0 : value;\n };\n\n /**\n * Provides read-only equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.offset = function (element) {\n var boxRect = element.getBoundingClientRect();\n var docElement = element.ownerDocument;\n return {\n width: boxRect.width || element.offsetWidth,\n height: boxRect.height || element.offsetHeight,\n top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),\n left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)\n };\n };\n\n /**\n * Provides set equivalent of jQuery's offset function:\n * @required-by bootstrap-tooltip\n * @url http://api.jquery.com/offset/\n * @param element\n * @param options\n * @param i\n */\n fn.setOffset = function (element, options, i) {\n var curPosition;\n var curLeft;\n var curCSSTop;\n var curTop;\n var curOffset;\n var curCSSLeft;\n var calculatePosition;\n var position = fn.css(element, 'position');\n var curElem = angular.element(element);\n var props = {};\n\n // Set position first, in-case top/left are set even on static elem\n if (position === 'static') {\n element.style.position = 'relative';\n }\n\n curOffset = fn.offset(element);\n curCSSTop = fn.css(element, 'top');\n curCSSLeft = fn.css(element, 'left');\n calculatePosition = (position === 'absolute' || position === 'fixed') &&\n (curCSSTop + curCSSLeft).indexOf('auto') > -1;\n\n // Need to be able to calculate position if either\n // top or left is auto and position is either absolute or fixed\n if (calculatePosition) {\n curPosition = fn.position(element);\n curTop = curPosition.top;\n curLeft = curPosition.left;\n } else {\n curTop = parseFloat(curCSSTop) || 0;\n curLeft = parseFloat(curCSSLeft) || 0;\n }\n\n if (angular.isFunction(options)) {\n options = options.call(element, i, curOffset);\n }\n\n if (options.top !== null) {\n props.top = (options.top - curOffset.top) + curTop;\n }\n if (options.left !== null) {\n props.left = (options.left - curOffset.left) + curLeft;\n }\n\n if ('using' in options) {\n options.using.call(curElem, props);\n } else {\n curElem.css({\n top: props.top + 'px',\n left: props.left + 'px'\n });\n }\n };\n\n /**\n * Provides read-only equivalent of jQuery's position function\n * @required-by bootstrap-tooltip, bootstrap-affix\n * @url http://api.jquery.com/offset/\n * @param element\n */\n fn.position = function (element) {\n\n var offsetParentRect = {top: 0, left: 0};\n var offsetParentEl;\n var offset;\n\n // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n if (fn.css(element, 'position') === 'fixed') {\n\n // We assume that getBoundingClientRect is available when computed position is fixed\n offset = element.getBoundingClientRect();\n\n } else {\n\n // Get *real* offsetParentEl\n offsetParentEl = offsetParentElement(element);\n\n // Get correct offsets\n offset = fn.offset(element);\n if (!nodeName(offsetParentEl, 'html')) {\n offsetParentRect = fn.offset(offsetParentEl);\n }\n\n // Add offsetParent borders\n offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true);\n offsetParentRect.left += fn.css(offsetParentEl, 'borderLeftWidth', true);\n }\n\n // Subtract parent offsets and element margins\n return {\n width: element.offsetWidth,\n height: element.offsetHeight,\n top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),\n left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)\n };\n\n };\n\n /**\n * Returns the closest, non-statically positioned offsetParent of a given element\n * @required-by fn.position\n * @param element\n */\n function offsetParentElement (element) {\n var docElement = element.ownerDocument;\n var offsetParent = element.offsetParent || docElement;\n if (nodeName(offsetParent, '#document')) return docElement.documentElement;\n while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {\n offsetParent = offsetParent.offsetParent;\n }\n return offsetParent || docElement.documentElement;\n }\n\n /**\n * Provides equivalent of jQuery's height function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/height/\n * @param element\n * @param outer\n */\n fn.height = function (element, outer) {\n var value = element.offsetHeight;\n if (outer) {\n value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);\n } else {\n value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);\n }\n return value;\n };\n\n /**\n * Provides equivalent of jQuery's width function\n * @required-by bootstrap-affix\n * @url http://api.jquery.com/width/\n * @param element\n * @param outer\n */\n fn.width = function (element, outer) {\n var value = element.offsetWidth;\n if (outer) {\n value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);\n } else {\n value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);\n }\n return value;\n };\n\n return fn;\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.debounce', [])\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L693\n.factory('debounce', function ($timeout) {\n return function (func, wait, immediate) {\n var timeout = null;\n return function () {\n var context = this;\n var args = arguments;\n var callNow = immediate && !timeout;\n if (timeout) {\n $timeout.cancel(timeout);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n }, wait, false);\n if (callNow) {\n func.apply(context, args);\n }\n return timeout;\n };\n };\n})\n\n\n// @source jashkenas/underscore\n// @url https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js#L661\n.factory('throttle', function ($timeout) {\n return function (func, wait, options) {\n var timeout = null;\n if (!options) options = {};\n return function () {\n var context = this;\n var args = arguments;\n if (!timeout) {\n if (options.leading !== false) {\n func.apply(context, args);\n }\n timeout = $timeout(function later () {\n timeout = null;\n if (options.trailing !== false) {\n func.apply(context, args);\n }\n }, wait, false);\n }\n };\n };\n});\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateParser', [])\n\n.provider('$dateParser', function ($localeProvider) {\n\n // define a custom ParseDate object to use instead of native Date\n // to avoid date values wrapping when setting date component values\n function ParseDate () {\n this.year = 1970;\n this.month = 0;\n this.day = 1;\n this.hours = 0;\n this.minutes = 0;\n this.seconds = 0;\n this.milliseconds = 0;\n }\n\n ParseDate.prototype.setMilliseconds = function (value) { this.milliseconds = value; };\n ParseDate.prototype.setSeconds = function (value) { this.seconds = value; };\n ParseDate.prototype.setMinutes = function (value) { this.minutes = value; };\n ParseDate.prototype.setHours = function (value) { this.hours = value; };\n ParseDate.prototype.getHours = function () { return this.hours; };\n ParseDate.prototype.setDate = function (value) { this.day = value; };\n ParseDate.prototype.setMonth = function (value) { this.month = value; };\n ParseDate.prototype.setFullYear = function (value) { this.year = value; };\n ParseDate.prototype.fromDate = function (value) {\n this.year = value.getFullYear();\n this.month = value.getMonth();\n this.day = value.getDate();\n this.hours = value.getHours();\n this.minutes = value.getMinutes();\n this.seconds = value.getSeconds();\n this.milliseconds = value.getMilliseconds();\n return this;\n };\n\n ParseDate.prototype.toDate = function () {\n return new Date(this.year, this.month, this.day, this.hours, this.minutes, this.seconds, this.milliseconds);\n };\n\n var proto = ParseDate.prototype;\n\n function noop () {\n }\n\n function isNumeric (n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n\n function indexOfCaseInsensitive (array, value) {\n var len = array.length;\n var str = value.toString().toLowerCase();\n for (var i = 0; i < len; i++) {\n if (array[i].toLowerCase() === str) { return i; }\n }\n return -1; // Return -1 per the \"Array.indexOf()\" method.\n }\n\n var defaults = this.defaults = {\n format: 'shortDate',\n strict: false\n };\n\n this.$get = function ($locale, dateFilter) {\n\n var DateParserFactory = function (config) {\n\n var options = angular.extend({}, defaults, config);\n\n var $dateParser = {};\n\n /* eslint-disable key-spacing, quote-props */\n var regExpMap = {\n 'sss' : '[0-9]{3}',\n 'ss' : '[0-5][0-9]',\n 's' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'mm' : '[0-5][0-9]',\n 'm' : options.strict ? '[1-5]?[0-9]' : '[0-9]|[0-5][0-9]',\n 'HH' : '[01][0-9]|2[0-3]',\n 'H' : options.strict ? '1?[0-9]|2[0-3]' : '[01]?[0-9]|2[0-3]',\n 'hh' : '[0][1-9]|[1][012]',\n 'h' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'a' : 'AM|PM',\n 'EEEE' : $locale.DATETIME_FORMATS.DAY.join('|'),\n 'EEE' : $locale.DATETIME_FORMATS.SHORTDAY.join('|'),\n 'dd' : '0[1-9]|[12][0-9]|3[01]',\n 'd' : options.strict ? '[1-9]|[1-2][0-9]|3[01]' : '0?[1-9]|[1-2][0-9]|3[01]',\n 'MMMM' : $locale.DATETIME_FORMATS.MONTH.join('|'),\n 'MMM' : $locale.DATETIME_FORMATS.SHORTMONTH.join('|'),\n 'MM' : '0[1-9]|1[012]',\n 'M' : options.strict ? '[1-9]|1[012]' : '0?[1-9]|1[012]',\n 'yyyy' : '[1]{1}[0-9]{3}|[2]{1}[0-9]{3}',\n 'yy' : '[0-9]{2}',\n 'y' : options.strict ? '-?(0|[1-9][0-9]{0,3})' : '-?0*[0-9]{1,4}'\n };\n\n var setFnMap = {\n 'sss' : proto.setMilliseconds,\n 'ss' : proto.setSeconds,\n 's' : proto.setSeconds,\n 'mm' : proto.setMinutes,\n 'm' : proto.setMinutes,\n 'HH' : proto.setHours,\n 'H' : proto.setHours,\n 'hh' : proto.setHours,\n 'h' : proto.setHours,\n 'EEEE' : noop,\n 'EEE' : noop,\n 'dd' : proto.setDate,\n 'd' : proto.setDate,\n 'a' : function (value) { var hours = this.getHours() % 12; return this.setHours(value.match(/pm/i) ? hours + 12 : hours); },\n 'MMMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.MONTH, value)); },\n 'MMM' : function (value) { return this.setMonth(indexOfCaseInsensitive($locale.DATETIME_FORMATS.SHORTMONTH, value)); },\n 'MM' : function (value) { return this.setMonth(1 * value - 1); },\n 'M' : function (value) { return this.setMonth(1 * value - 1); },\n 'yyyy' : proto.setFullYear,\n 'yy' : function (value) { return this.setFullYear(2000 + 1 * value); },\n 'y' : function (value) { return (1 * value <= 50 && value.length === 2) ? this.setFullYear(2000 + 1 * value) : this.setFullYear(1 * value); }\n };\n /* eslint-enable key-spacing, quote-props */\n\n var regex;\n var setMap;\n\n $dateParser.init = function () {\n $dateParser.$format = $locale.DATETIME_FORMATS[options.format] || options.format;\n regex = regExpForFormat($dateParser.$format);\n setMap = setMapForFormat($dateParser.$format);\n };\n\n $dateParser.isValid = function (date) {\n if (angular.isDate(date)) return !isNaN(date.getTime());\n return regex.test(date);\n };\n\n $dateParser.parse = function (value, baseDate, format, timezone) {\n // check for date format special names\n if (format) format = $locale.DATETIME_FORMATS[format] || format;\n if (angular.isDate(value)) value = dateFilter(value, format || $dateParser.$format, timezone);\n var formatRegex = format ? regExpForFormat(format) : regex;\n var formatSetMap = format ? setMapForFormat(format) : setMap;\n var matches = formatRegex.exec(value);\n if (!matches) return false;\n // use custom ParseDate object to set parsed values\n var date = baseDate && !isNaN(baseDate.getTime()) ? new ParseDate().fromDate(baseDate) : new ParseDate().fromDate(new Date(1970, 0, 1, 0));\n for (var i = 0; i < matches.length - 1; i++) {\n if (formatSetMap[i]) formatSetMap[i].call(date, matches[i + 1]);\n }\n // convert back to native Date object\n var newDate = date.toDate();\n\n // check new native Date object for day values overflow\n if (parseInt(date.day, 10) !== newDate.getDate()) {\n return false;\n }\n\n return newDate;\n };\n\n $dateParser.getDateForAttribute = function (key, value) {\n var date;\n\n if (value === 'today') {\n var today = new Date();\n date = new Date(today.getFullYear(), today.getMonth(), today.getDate() + (key === 'maxDate' ? 1 : 0), 0, 0, 0, (key === 'minDate' ? 0 : -1));\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) { // Support {{ dateObj }}\n date = new Date(value.substr(1, value.length - 2));\n } else if (isNumeric(value)) {\n date = new Date(parseInt(value, 10));\n } else if (angular.isString(value) && value.length === 0) { // Reset date\n date = key === 'minDate' ? -Infinity : +Infinity;\n } else {\n date = new Date(value);\n }\n\n return date;\n };\n\n $dateParser.getTimeForAttribute = function (key, value) {\n var time;\n\n if (value === 'now') {\n time = new Date().setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.match(/^\".+\"$/)) {\n time = new Date(value.substr(1, value.length - 2)).setFullYear(1970, 0, 1);\n } else if (isNumeric(value)) {\n time = new Date(parseInt(value, 10)).setFullYear(1970, 0, 1);\n } else if (angular.isString(value) && value.length === 0) { // Reset time\n time = key === 'minTime' ? -Infinity : +Infinity;\n } else {\n time = $dateParser.parse(value, new Date(1970, 0, 1, 0));\n }\n\n return time;\n };\n\n /* Handle switch to/from daylight saving.\n * Hours may be non-zero on daylight saving cut-over:\n * > 12 when midnight changeover, but then cannot generate\n * midnight datetime, so jump to 1AM, otherwise reset.\n * @param date (Date) the date to check\n * @return (Date) the corrected date\n *\n * __ copied from jquery ui datepicker __\n */\n $dateParser.daylightSavingAdjust = function (date) {\n if (!date) {\n return null;\n }\n date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n return date;\n };\n\n /* Correct the date for timezone offset.\n * @param date (Date) the date to adjust\n * @param timezone (string) the timezone to adjust for\n * @param undo (boolean) to add or subtract timezone offset\n * @return (Date) the corrected date\n */\n $dateParser.timezoneOffsetAdjust = function (date, timezone, undo) {\n if (!date) {\n return null;\n }\n // Right now, only 'UTC' is supported.\n if (timezone && timezone === 'UTC') {\n date = new Date(date.getTime());\n date.setMinutes(date.getMinutes() + (undo ? -1 : 1) * date.getTimezoneOffset());\n }\n return date;\n };\n\n // Private functions\n\n function regExpForFormat (format) {\n // `format` string can contain literal values.\n // These need to be escaped by surrounding with\n // single quotes (e.g. `\"h 'in the morning'\"`).\n // In order to output a single quote, escape it - i.e.,\n // two single quotes in a sequence (e.g. `\"h 'o''clock'\"`).\n\n var re = buildDateAbstractRegex(format);\n return buildDateParseRegex(re);\n }\n\n function buildDateAbstractRegex (format) {\n var escapedFormat = escapeReservedSymbols(format);\n var escapedLiteralFormat = escapedFormat.replace(/''/g, '\\\\\\'');\n var literalRegex = /('(?:\\\\'|.)*?')/;\n var formatParts = escapedLiteralFormat.split(literalRegex);\n var dateElements = Object.keys(regExpMap);\n var dateRegexParts = [];\n\n angular.forEach(formatParts, function (part) {\n if (isFormatStringLiteral(part)) {\n part = trimLiteralEscapeChars(part);\n } else {\n // Abstract replaces to avoid collisions\n for (var i = 0; i < dateElements.length; i++) {\n part = part.split(dateElements[i]).join('${' + i + '}');\n }\n }\n dateRegexParts.push(part);\n });\n\n return dateRegexParts.join('');\n }\n\n function escapeReservedSymbols (text) {\n return text.replace(/\\\\/g, '[\\\\\\\\]')\n .replace(/-/g, '[-]')\n .replace(/\\./g, '[.]')\n .replace(/\\*/g, '[*]')\n .replace(/\\+/g, '[+]')\n .replace(/\\?/g, '[?]')\n .replace(/\\$/g, '[$]')\n .replace(/\\^/g, '[^]')\n .replace(/\\//g, '[/]')\n .replace(/\\\\s/g, '[\\\\s]');\n }\n\n function isFormatStringLiteral (text) {\n return /^'.*'$/.test(text);\n }\n\n function trimLiteralEscapeChars (text) {\n return text.replace(/^'(.*)'$/, '$1');\n }\n\n function buildDateParseRegex (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var re = abstractRegex;\n\n // Replace abstracted values\n for (var i = 0; i < dateElements.length; i++) {\n re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')');\n }\n\n return new RegExp('^' + re + '$', ['i']);\n }\n\n function setMapForFormat (format) {\n var re = buildDateAbstractRegex(format);\n return buildDateParseValuesMap(re);\n }\n\n function buildDateParseValuesMap (abstractRegex) {\n var dateElements = Object.keys(regExpMap);\n var valuesRegex = new RegExp('\\\\${(\\\\d+)}', 'g');\n var valuesMatch;\n var keyIndex;\n var valueKey;\n var valueFunction;\n var valuesFunctionMap = [];\n\n /* eslint-disable no-cond-assign */\n while ((valuesMatch = valuesRegex.exec(abstractRegex)) !== null) {\n keyIndex = valuesMatch[1];\n valueKey = dateElements[keyIndex];\n valueFunction = setFnMap[valueKey];\n\n valuesFunctionMap.push(valueFunction);\n }\n\n return valuesFunctionMap;\n }\n\n $dateParser.init();\n return $dateParser;\n\n };\n\n return DateParserFactory;\n\n };\n\n});\n","'use strict';\n\nangular.module('mgcrea.ngStrap.helpers.dateFormatter', [])\n\n .service('$dateFormatter', function ($locale, dateFilter) {\n\n // The unused `lang` arguments are on purpose. The default implementation does not\n // use them and it always uses the locale loaded into the `$locale` service.\n // Custom implementations might use it, thus allowing different directives to\n // have different languages.\n\n this.getDefaultLocale = function () {\n return $locale.id;\n };\n\n // Format is either a data format name, e.g. \"shortTime\" or \"fullDate\", or a date format\n // Return either the corresponding date format or the given date format.\n this.getDatetimeFormat = function (format, lang) {\n return $locale.DATETIME_FORMATS[format] || format;\n };\n\n this.weekdaysShort = function (lang) {\n return $locale.DATETIME_FORMATS.SHORTDAY;\n };\n\n function splitTimeFormat (format) {\n return /(h+)([:\\.])?(m+)([:\\.])?(s*)[ ]?(a?)/i.exec(format).slice(1);\n }\n\n // h:mm a => h\n this.hoursFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[0];\n };\n\n // h:mm a => mm\n this.minutesFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[2];\n };\n\n // h:mm:ss a => ss\n this.secondsFormat = function (timeFormat) {\n return splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => :\n this.timeSeparator = function (timeFormat) {\n return splitTimeFormat(timeFormat)[1];\n };\n\n // h:mm:ss a => true, h:mm a => false\n this.showSeconds = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[4];\n };\n\n // h:mm a => true, H.mm => false\n this.showAM = function (timeFormat) {\n return !!splitTimeFormat(timeFormat)[5];\n };\n\n this.formatDate = function (date, format, lang, timezone) {\n return dateFilter(date, format, timezone);\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.button', [])\n\n .provider('$button', function () {\n\n var defaults = this.defaults = {\n activeClass: 'active',\n toggleEvent: 'click'\n };\n\n this.$get = function () {\n return {defaults: defaults};\n };\n\n })\n\n .directive('bsCheckboxGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"checkbox\"]');\n angular.forEach(children, function (child) {\n var childEl = angular.element(child);\n childEl.attr('bs-checkbox', '');\n childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value'));\n });\n }\n\n };\n\n })\n\n .directive('bsCheckbox', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support label > input[type=\"checkbox\"]\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true;\n if (constantValueRegExp.test(attr.trueValue)) {\n trueValue = scope.$eval(attr.trueValue);\n }\n var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false;\n if (constantValueRegExp.test(attr.falseValue)) {\n falseValue = scope.$eval(attr.falseValue);\n }\n\n // Parse exotic values\n var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean';\n if (hasExoticValues) {\n controller.$parsers.push(function (viewValue) {\n // console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue);\n return viewValue ? trueValue : falseValue;\n });\n // modelValue -> $formatters -> viewValue\n controller.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n return angular.equals(modelValue, trueValue);\n });\n // Fix rendering for exotic values\n scope.$watch(attr.ngModel, function (newValue, oldValue) {\n controller.$render();\n });\n }\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, trueValue);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n if (!isInput) {\n controller.$setViewValue(!activeElement.hasClass('active'));\n }\n if (!hasExoticValues) {\n controller.$render();\n }\n });\n });\n\n }\n\n };\n\n })\n\n .directive('bsRadioGroup', function () {\n\n return {\n restrict: 'A',\n require: 'ngModel',\n compile: function postLink (element, attr) {\n element.attr('data-toggle', 'buttons');\n element.removeAttr('ng-model');\n var children = element[0].querySelectorAll('input[type=\"radio\"]');\n angular.forEach(children, function (child) {\n angular.element(child).attr('bs-radio', '');\n angular.element(child).attr('ng-model', attr.ngModel);\n });\n }\n\n };\n\n })\n\n .directive('bsRadio', function ($button, $$rAF) {\n\n var defaults = $button.defaults;\n var constantValueRegExp = /^(true|false|\\d+)$/;\n\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function postLink (scope, element, attr, controller) {\n\n var options = defaults;\n\n // Support `label > input[type=\"radio\"]` markup\n var isInput = element[0].nodeName === 'INPUT';\n var activeElement = isInput ? element.parent() : element;\n\n var value;\n attr.$observe('value', function (v) {\n if (typeof v !== 'boolean' && constantValueRegExp.test(v)) {\n value = scope.$eval(v);\n } else {\n value = v;\n }\n controller.$render();\n });\n\n // model -> view\n controller.$render = function () {\n // console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue);\n var isActive = angular.equals(controller.$modelValue, value);\n $$rAF(function () {\n if (isInput) element[0].checked = isActive;\n activeElement.toggleClass(options.activeClass, isActive);\n });\n };\n\n // view -> model\n element.bind(options.toggleEvent, function () {\n scope.$apply(function () {\n // console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue);\n controller.$setViewValue(value);\n controller.$render();\n });\n });\n\n }\n\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.collapse', [])\n\n .provider('$collapse', function () {\n\n var defaults = this.defaults = {\n animation: 'am-collapse',\n disallowToggle: false,\n activeClass: 'in',\n startCollapsed: false,\n allowMultiple: false\n };\n\n var controller = this.controller = function ($scope, $element, $attrs) {\n var self = this;\n\n // Attributes options\n self.$options = angular.copy(defaults);\n angular.forEach(['animation', 'disallowToggle', 'activeClass', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key])) self.$options[key] = $attrs[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['disallowToggle', 'startCollapsed', 'allowMultiple'], function (key) {\n if (angular.isDefined($attrs[key]) && falseValueRegExp.test($attrs[key])) {\n self.$options[key] = false;\n }\n });\n\n self.$toggles = [];\n self.$targets = [];\n\n self.$viewChangeListeners = [];\n\n self.$registerToggle = function (element) {\n self.$toggles.push(element);\n };\n self.$registerTarget = function (element) {\n self.$targets.push(element);\n };\n\n self.$unregisterToggle = function (element) {\n var index = self.$toggles.indexOf(element);\n // remove toggle from $toggles array\n self.$toggles.splice(index, 1);\n };\n self.$unregisterTarget = function (element) {\n var index = self.$targets.indexOf(element);\n\n // remove element from $targets array\n self.$targets.splice(index, 1);\n\n if (self.$options.allowMultiple) {\n // remove target index from $active array values\n deactivateItem(element);\n }\n\n // fix active item indexes\n fixActiveItemIndexes(index);\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n // use array to store all the currently open panels\n self.$targets.$active = !self.$options.startCollapsed ? [0] : [];\n self.$setActive = $scope.$setActive = function (value) {\n if (angular.isArray(value)) {\n self.$targets.$active = value;\n } else if (!self.$options.disallowToggle && isActive(value)) {\n deactivateItem(value);\n } else {\n activateItem(value);\n }\n\n self.$viewChangeListeners.forEach(function (fn) {\n fn();\n });\n };\n\n self.$activeIndexes = function () {\n if (self.$options.allowMultiple) {\n return self.$targets.$active;\n }\n return self.$targets.$active.length === 1 ? self.$targets.$active[0] : -1;\n };\n\n function fixActiveItemIndexes (index) {\n // item with index was removed, so we\n // need to adjust other items index values\n var activeIndexes = self.$targets.$active;\n for (var i = 0; i < activeIndexes.length; i++) {\n if (index < activeIndexes[i]) {\n activeIndexes[i] = activeIndexes[i] - 1;\n }\n\n // the last item is active, so we need to\n // adjust its index\n if (activeIndexes[i] === self.$targets.length) {\n activeIndexes[i] = self.$targets.length - 1;\n }\n }\n }\n\n function isActive (value) {\n var activeItems = self.$targets.$active;\n return activeItems.indexOf(value) !== -1;\n }\n\n function deactivateItem (value) {\n var index = self.$targets.$active.indexOf(value);\n if (index !== -1) {\n self.$targets.$active.splice(index, 1);\n }\n }\n\n function activateItem (value) {\n if (!self.$options.allowMultiple) {\n // remove current selected item\n self.$targets.$active.splice(0, 1);\n }\n\n if (self.$targets.$active.indexOf(value) === -1) {\n self.$targets.$active.push(value);\n }\n }\n\n };\n\n this.$get = function () {\n var $collapse = {};\n $collapse.defaults = defaults;\n $collapse.controller = controller;\n return $collapse;\n };\n\n })\n\n .directive('bsCollapse', function ($window, $animate, $collapse) {\n\n return {\n require: ['?ngModel', 'bsCollapse'],\n controller: ['$scope', '$element', '$attrs', $collapse.controller],\n link: function postLink (scope, element, attrs, controllers) {\n\n var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n if (ngModelCtrl) {\n\n // Update the modelValue following\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n ngModelCtrl.$setViewValue(bsCollapseCtrl.$activeIndexes());\n });\n\n // modelValue -> $formatters -> viewValue\n ngModelCtrl.$formatters.push(function (modelValue) {\n // console.warn('$formatter(\"%s\"): modelValue=%o (%o)', element.attr('ng-model'), modelValue, typeof modelValue);\n if (angular.isArray(modelValue)) {\n // model value is an array, so just replace\n // the active items directly\n bsCollapseCtrl.$setActive(modelValue);\n } else {\n var activeIndexes = bsCollapseCtrl.$activeIndexes();\n\n if (angular.isArray(activeIndexes)) {\n // we have an array of selected indexes\n if (activeIndexes.indexOf(modelValue * 1) === -1) {\n // item with modelValue index is not active\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n } else if (activeIndexes !== modelValue * 1) {\n bsCollapseCtrl.$setActive(modelValue * 1);\n }\n }\n return modelValue;\n });\n\n }\n\n }\n };\n\n })\n\n .directive('bsCollapseToggle', function () {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base attr\n element.attr('data-toggle', 'collapse');\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerToggle(element);\n\n // remove toggle from collapse controller when toggle is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterToggle(element);\n });\n\n element.on('click', function () {\n if (!attrs.disabled) {\n var index = attrs.bsCollapseToggle && attrs.bsCollapseToggle !== 'bs-collapse-toggle' ? attrs.bsCollapseToggle : bsCollapseCtrl.$toggles.indexOf(element);\n bsCollapseCtrl.$setActive(index * 1);\n scope.$apply();\n }\n });\n\n }\n };\n\n })\n\n .directive('bsCollapseTarget', function ($animate) {\n\n return {\n require: ['^?ngModel', '^bsCollapse'],\n // scope: true,\n link: function postLink (scope, element, attrs, controllers) {\n\n // var ngModelCtrl = controllers[0];\n var bsCollapseCtrl = controllers[1];\n\n // Add base class\n element.addClass('collapse');\n\n // Add animation class\n if (bsCollapseCtrl.$options.animation) {\n element.addClass(bsCollapseCtrl.$options.animation);\n }\n\n // Push pane to parent bsCollapse controller\n bsCollapseCtrl.$registerTarget(element);\n\n // remove pane target from collapse controller when target is destroyed\n scope.$on('$destroy', function () {\n bsCollapseCtrl.$unregisterTarget(element);\n });\n\n function render () {\n var index = bsCollapseCtrl.$targets.indexOf(element);\n var active = bsCollapseCtrl.$activeIndexes();\n var action = 'removeClass';\n if (angular.isArray(active)) {\n if (active.indexOf(index) !== -1) {\n action = 'addClass';\n }\n } else if (index === active) {\n action = 'addClass';\n }\n\n $animate[action](element, bsCollapseCtrl.$options.activeClass);\n }\n\n bsCollapseCtrl.$viewChangeListeners.push(function () {\n render();\n });\n render();\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.aside', ['mgcrea.ngStrap.modal'])\n\n .provider('$aside', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade-and-slide-right',\n prefixClass: 'aside',\n prefixEvent: 'aside',\n placement: 'right',\n templateUrl: 'aside/aside.tpl.html',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true\n };\n\n this.$get = function ($modal) {\n\n function AsideFactory (config) {\n\n var $aside = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $aside = $modal(options);\n\n return $aside;\n\n }\n\n return AsideFactory;\n\n };\n\n })\n\n .directive('bsAside', function ($window, $sce, $aside) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAside) {\n scope.$watch(attr.bsAside, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize aside\n var aside = $aside(options);\n\n // Trigger\n element.on(attr.trigger || 'click', aside.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (aside) aside.destroy();\n options = null;\n aside = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\n// @BUG: following snippet won't compile correctly\n\nangular.module('mgcrea.ngStrap.alert', ['mgcrea.ngStrap.modal'])\n\n .provider('$alert', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n prefixClass: 'alert',\n prefixEvent: 'alert',\n placement: null,\n templateUrl: 'alert/alert.tpl.html',\n container: false,\n element: null,\n backdrop: false,\n keyboard: true,\n show: true,\n // Specific options\n duration: false,\n type: false,\n dismissable: true\n };\n\n this.$get = function ($modal, $timeout) {\n\n function AlertFactory (config) {\n\n var $alert = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n\n $alert = $modal(options);\n\n // Support scope as string options [/*title, content, */ type, dismissable]\n $alert.$scope.dismissable = !!options.dismissable;\n if (options.type) {\n $alert.$scope.type = options.type;\n }\n\n // Support auto-close duration\n var show = $alert.show;\n if (options.duration) {\n $alert.show = function () {\n show();\n $timeout(function () {\n $alert.hide();\n }, options.duration * 1000);\n };\n }\n\n return $alert;\n\n }\n\n return AlertFactory;\n\n };\n\n })\n\n .directive('bsAlert', function ($window, $sce, $alert) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'placement', 'keyboard', 'html', 'container', 'animation', 'duration', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['keyboard', 'html', 'container', 'dismissable'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // overwrite inherited title value when no value specified\n // fix for angular 1.3.1 531a8de72c439d8ddd064874bf364c00cedabb11\n if (!scope.hasOwnProperty('title')) {\n scope.title = '';\n }\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content', 'type'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsAlert) {\n scope.$watch(attr.bsAlert, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize alert\n var alert = $alert(options);\n\n // Trigger\n element.on(attr.trigger || 'click', alert.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (alert) alert.destroy();\n options = null;\n alert = null;\n });\n\n }\n };\n\n });\n","'use strict';\n\nangular.module('mgcrea.ngStrap.affix', ['mgcrea.ngStrap.helpers.dimensions', 'mgcrea.ngStrap.helpers.debounce'])\n\n .provider('$affix', function () {\n\n var defaults = this.defaults = {\n offsetTop: 'auto',\n inlineStyles: true\n };\n\n this.$get = function ($window, debounce, dimensions) {\n\n var bodyEl = angular.element($window.document.body);\n var windowEl = angular.element($window);\n\n function AffixFactory (element, config) {\n\n var $affix = {};\n\n // Common vars\n var options = angular.extend({}, defaults, config);\n var targetEl = options.target;\n\n // Initial private vars\n var reset = 'affix affix-top affix-bottom';\n var setWidth = false;\n var initialAffixTop = 0;\n var initialOffsetTop = 0;\n var offsetTop = 0;\n var offsetBottom = 0;\n var affixed = null;\n var unpin = null;\n\n var parent = element.parent();\n // Options: custom parent\n if (options.offsetParent) {\n if (options.offsetParent.match(/^\\d+$/)) {\n for (var i = 0; i < (options.offsetParent * 1) - 1; i++) {\n parent = parent.parent();\n }\n } else {\n parent = angular.element(options.offsetParent);\n }\n }\n\n $affix.init = function () {\n\n this.$parseOffsets();\n initialOffsetTop = dimensions.offset(element[0]).top + initialAffixTop;\n setWidth = !element[0].style.width;\n\n // Bind events\n targetEl.on('scroll', this.checkPosition);\n targetEl.on('click', this.checkPositionWithEventLoop);\n windowEl.on('resize', this.$debouncedOnResize);\n\n // Both of these checkPosition() calls are necessary for the case where\n // the user hits refresh after scrolling to the bottom of the page.\n this.checkPosition();\n this.checkPositionWithEventLoop();\n\n };\n\n $affix.destroy = function () {\n\n // Unbind events\n targetEl.off('scroll', this.checkPosition);\n targetEl.off('click', this.checkPositionWithEventLoop);\n windowEl.off('resize', this.$debouncedOnResize);\n\n };\n\n $affix.checkPositionWithEventLoop = function () {\n\n // IE 9 throws an error if we use 'this' instead of '$affix'\n // in this setTimeout call\n setTimeout($affix.checkPosition, 1);\n\n };\n\n $affix.checkPosition = function () {\n // if (!this.$element.is(':visible')) return\n\n var scrollTop = getScrollTop();\n var position = dimensions.offset(element[0]);\n var elementHeight = dimensions.height(element[0]);\n\n // Get required affix class according to position\n var affix = getRequiredAffixClass(unpin, position, elementHeight);\n\n // Did affix status changed this last check?\n if (affixed === affix) return;\n affixed = affix;\n\n if (affix === 'top') {\n unpin = null;\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', '');\n }\n } else if (affix === 'bottom') {\n if (options.offsetUnpin) {\n unpin = -(options.offsetUnpin * 1);\n } else {\n // Calculate unpin threshold when affixed to bottom.\n // Hopefully the browser scrolls pixel by pixel.\n unpin = position.top - scrollTop;\n }\n if (setWidth) {\n element.css('width', '');\n }\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n element.css('top', (options.offsetParent) ? '' : ((bodyEl[0].offsetHeight - offsetBottom - elementHeight - initialOffsetTop) + 'px'));\n }\n } else { // affix === 'middle'\n unpin = null;\n if (setWidth) {\n element.css('width', element[0].offsetWidth + 'px');\n }\n if (options.inlineStyles) {\n element.css('position', 'fixed');\n element.css('top', initialAffixTop + 'px');\n }\n }\n\n // Add proper affix class\n element.removeClass(reset).addClass('affix' + ((affix !== 'middle') ? '-' + affix : ''));\n\n };\n\n $affix.$onResize = function () {\n $affix.$parseOffsets();\n $affix.checkPosition();\n };\n $affix.$debouncedOnResize = debounce($affix.$onResize, 50);\n\n $affix.$parseOffsets = function () {\n var initialPosition = element.css('position');\n // Reset position to calculate correct offsetTop\n if (options.inlineStyles) {\n element.css('position', (options.offsetParent) ? '' : 'relative');\n }\n\n if (options.offsetTop) {\n if (options.offsetTop === 'auto') {\n options.offsetTop = '+0';\n }\n if (options.offsetTop.match(/^[-+]\\d+$/)) {\n initialAffixTop = - options.offsetTop * 1;\n if (options.offsetParent) {\n offsetTop = dimensions.offset(parent[0]).top + (options.offsetTop * 1);\n } else {\n offsetTop = dimensions.offset(element[0]).top - dimensions.css(element[0], 'marginTop', true) + (options.offsetTop * 1);\n }\n } else {\n offsetTop = options.offsetTop * 1;\n }\n }\n\n if (options.offsetBottom) {\n if (options.offsetParent && options.offsetBottom.match(/^[-+]\\d+$/)) {\n // add 1 pixel due to rounding problems...\n offsetBottom = getScrollHeight() - (dimensions.offset(parent[0]).top + dimensions.height(parent[0])) + (options.offsetBottom * 1) + 1;\n } else {\n offsetBottom = options.offsetBottom * 1;\n }\n }\n\n // Bring back the element's position after calculations\n if (options.inlineStyles) {\n element.css('position', initialPosition);\n }\n };\n\n // Private methods\n\n function getRequiredAffixClass (_unpin, position, elementHeight) {\n var scrollTop = getScrollTop();\n var scrollHeight = getScrollHeight();\n\n if (scrollTop <= offsetTop) {\n return 'top';\n } else if (_unpin !== null && (scrollTop + _unpin <= position.top)) {\n return 'middle';\n } else if (offsetBottom !== null && (position.top + elementHeight + initialAffixTop >= scrollHeight - offsetBottom)) {\n return 'bottom';\n }\n return 'middle';\n }\n\n function getScrollTop () {\n return targetEl[0] === $window ? $window.pageYOffset : targetEl[0].scrollTop;\n }\n\n function getScrollHeight () {\n return targetEl[0] === $window ? $window.document.body.scrollHeight : targetEl[0].scrollHeight;\n }\n\n $affix.init();\n return $affix;\n\n }\n\n return AffixFactory;\n\n };\n\n })\n\n .directive('bsAffix', function ($affix, $window) {\n\n return {\n restrict: 'EAC',\n require: '^?bsAffixTarget',\n link: function postLink (scope, element, attr, affixTarget) {\n\n var options = {scope: scope, target: affixTarget ? affixTarget.$element : angular.element($window)};\n angular.forEach(['offsetTop', 'offsetBottom', 'offsetParent', 'offsetUnpin', 'inlineStyles'], function (key) {\n if (angular.isDefined(attr[key])) {\n var option = attr[key];\n if (/true/i.test(option)) option = true;\n if (/false/i.test(option)) option = false;\n options[key] = option;\n }\n });\n\n var affix = $affix(element, options);\n scope.$on('$destroy', function () {\n if (affix) affix.destroy();\n options = null;\n affix = null;\n });\n\n }\n };\n\n })\n\n .directive('bsAffixTarget', function () {\n return {\n controller: function ($element) {\n this.$element = $element;\n }\n };\n });\n","\nangular.module('mgcrea.ngStrap', [\n 'mgcrea.ngStrap.modal',\n 'mgcrea.ngStrap.aside',\n 'mgcrea.ngStrap.alert',\n 'mgcrea.ngStrap.button',\n 'mgcrea.ngStrap.select',\n 'mgcrea.ngStrap.datepicker',\n 'mgcrea.ngStrap.timepicker',\n 'mgcrea.ngStrap.navbar',\n 'mgcrea.ngStrap.tooltip',\n 'mgcrea.ngStrap.popover',\n 'mgcrea.ngStrap.dropdown',\n 'mgcrea.ngStrap.typeahead',\n 'mgcrea.ngStrap.scrollspy',\n 'mgcrea.ngStrap.affix',\n 'mgcrea.ngStrap.tab',\n 'mgcrea.ngStrap.collapse'\n]);\n"],"sourceRoot":"/source/"}