7555 lines
393 KiB
JavaScript
7555 lines
393 KiB
JavaScript
// Source: public/lib/angular/angular.min.js
|
|
/*
|
|
AngularJS v1.2.32
|
|
(c) 2010-2014 Google, Inc. http://angularjs.org
|
|
License: MIT
|
|
*/
|
|
(function(V,W,v){'use strict';function z(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.2.32/"+(b?b+"/":"")+a;for(c=1;c<arguments.length;c++)a=a+(1==c?"?":"&")+"p"+(c-1)+"="+encodeURIComponent("function"==typeof arguments[c]?arguments[c].toString().replace(/ \{[\s\S]*$/,""):"undefined"==typeof arguments[c]?"undefined":"string"!=typeof arguments[c]?JSON.stringify(arguments[c]):arguments[c]);return Error(a)}}function Ra(b){if(null==b||Ha(b))return!1;
|
|
var a=b.length;return 1===b.nodeType&&a?!0:E(b)||M(b)||0===a||"number"===typeof a&&0<a&&a-1 in b}function r(b,a,c){var d;if(b)if(O(b))for(d in b)"prototype"==d||("length"==d||"name"==d||b.hasOwnProperty&&!b.hasOwnProperty(d))||a.call(c,b[d],d);else if(M(b)||Ra(b))for(d=0;d<b.length;d++)a.call(c,b[d],d);else if(b.forEach&&b.forEach!==r)b.forEach(a,c);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],d);return b}function Wb(b){var a=[],c;for(c in b)b.hasOwnProperty(c)&&a.push(c);return a.sort()}function Tc(b,
|
|
a,c){for(var d=Wb(b),e=0;e<d.length;e++)a.call(c,b[d[e]],d[e]);return d}function Xb(b){return function(a,c){b(c,a)}}function hb(){for(var b=na.length,a;b;){b--;a=na[b].charCodeAt(0);if(57==a)return na[b]="A",na.join("");if(90==a)na[b]="0";else return na[b]=String.fromCharCode(a+1),na.join("")}na.unshift("0");return na.join("")}function Yb(b,a){a?b.$$hashKey=a:delete b.$$hashKey}function F(b){var a=b.$$hashKey;r(arguments,function(a){a!==b&&r(a,function(a,c){b[c]=a})});Yb(b,a);return b}function U(b){return parseInt(b,
|
|
10)}function Zb(b,a){return F(new (F(function(){},{prototype:b})),a)}function B(){}function ga(b){return b}function Z(b){return function(){return b}}function H(b){return"undefined"===typeof b}function G(b){return"undefined"!==typeof b}function T(b){return null!=b&&"object"===typeof b}function E(b){return"string"===typeof b}function ib(b){return"number"===typeof b}function ua(b){return"[object Date]"===Aa.call(b)}function O(b){return"function"===typeof b}function jb(b){return"[object RegExp]"===Aa.call(b)}
|
|
function Ha(b){return b&&b.document&&b.location&&b.alert&&b.setInterval}function Uc(b){return!(!b||!(b.nodeName||b.prop&&b.attr&&b.find))}function Vc(b,a,c){var d=[];r(b,function(b,f,g){d.push(a.call(c,b,f,g))});return d}function Sa(b,a){if(b.indexOf)return b.indexOf(a);for(var c=0;c<b.length;c++)if(a===b[c])return c;return-1}function Ta(b,a){var c=Sa(b,a);0<=c&&b.splice(c,1);return a}function Ia(b,a,c,d){if(Ha(b)||b&&b.$evalAsync&&b.$watch)throw Ua("cpws");if(a){if(b===a)throw Ua("cpi");c=c||[];
|
|
d=d||[];if(T(b)){var e=Sa(c,b);if(-1!==e)return d[e];c.push(b);d.push(a)}if(M(b))for(var f=a.length=0;f<b.length;f++)e=Ia(b[f],null,c,d),T(b[f])&&(c.push(b[f]),d.push(e)),a.push(e);else{var g=a.$$hashKey;M(a)?a.length=0:r(a,function(b,c){delete a[c]});for(f in b)e=Ia(b[f],null,c,d),T(b[f])&&(c.push(b[f]),d.push(e)),a[f]=e;Yb(a,g)}}else if(a=b)M(b)?a=Ia(b,[],c,d):ua(b)?a=new Date(b.getTime()):jb(b)?(a=RegExp(b.source,b.toString().match(/[^\/]*$/)[0]),a.lastIndex=b.lastIndex):T(b)&&(a=Ia(b,{},c,d));
|
|
return a}function ha(b,a){if(M(b)){a=a||[];for(var c=0;c<b.length;c++)a[c]=b[c]}else if(T(b))for(c in a=a||{},b)!kb.call(b,c)||"$"===c.charAt(0)&&"$"===c.charAt(1)||(a[c]=b[c]);return a||b}function Ba(b,a){if(b===a)return!0;if(null===b||null===a)return!1;if(b!==b&&a!==a)return!0;var c=typeof b,d;if(c==typeof a&&"object"==c)if(M(b)){if(!M(a))return!1;if((c=b.length)==a.length){for(d=0;d<c;d++)if(!Ba(b[d],a[d]))return!1;return!0}}else{if(ua(b))return ua(a)?isNaN(b.getTime())&&isNaN(a.getTime())||b.getTime()===
|
|
a.getTime():!1;if(jb(b)&&jb(a))return b.toString()==a.toString();if(b&&b.$evalAsync&&b.$watch||a&&a.$evalAsync&&a.$watch||Ha(b)||Ha(a)||M(a))return!1;c={};for(d in b)if("$"!==d.charAt(0)&&!O(b[d])){if(!Ba(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c.hasOwnProperty(d)&&"$"!==d.charAt(0)&&a[d]!==v&&!O(a[d]))return!1;return!0}return!1}function Ab(b,a){var c=2<arguments.length?va.call(arguments,2):[];return!O(a)||a instanceof RegExp?a:c.length?function(){return arguments.length?a.apply(b,c.concat(va.call(arguments,
|
|
0))):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}}function Wc(b,a){var c=a;"string"===typeof b&&"$"===b.charAt(0)?c=v:Ha(a)?c="$WINDOW":a&&W===a?c="$DOCUMENT":a&&(a.$evalAsync&&a.$watch)&&(c="$SCOPE");return c}function oa(b,a){return"undefined"===typeof b?v:JSON.stringify(b,Wc,a?" ":null)}function $b(b){return E(b)?JSON.parse(b):b}function Va(b){"function"===typeof b?b=!0:b&&0!==b.length?(b=A(""+b),b=!("f"==b||"0"==b||"false"==b||"no"==b||"n"==b||"[]"==b)):b=!1;
|
|
return b}function ia(b){b=D(b).clone();try{b.empty()}catch(a){}var c=D("<div>").append(b).html();try{return 3===b[0].nodeType?A(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+A(b)})}catch(d){return A(c)}}function ac(b){try{return decodeURIComponent(b)}catch(a){}}function bc(b){var a={},c,d;r((b||"").split("&"),function(b){b&&(c=b.replace(/\+/g,"%20").split("="),d=ac(c[0]),G(d)&&(b=G(c[1])?ac(c[1]):!0,kb.call(a,d)?M(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Bb(b){var a=
|
|
[];r(b,function(b,d){M(b)?r(b,function(b){a.push(Ca(d,!0)+(!0===b?"":"="+Ca(b,!0)))}):a.push(Ca(d,!0)+(!0===b?"":"="+Ca(b,!0)))});return a.length?a.join("&"):""}function lb(b){return Ca(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Ca(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Xc(b,a){function c(a){a&&d.push(a)}var d=[b],e,f,g=["ng:app","ng-app","x-ng-app",
|
|
"data-ng-app"],h=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;r(g,function(a){g[a]=!0;c(W.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(r(b.querySelectorAll("."+a),c),r(b.querySelectorAll("."+a+"\\:"),c),r(b.querySelectorAll("["+a+"]"),c))});r(d,function(a){if(!e){var b=h.exec(" "+a.className+" ");b?(e=a,f=(b[2]||"").replace(/\s+/g,",")):r(a.attributes,function(b){!e&&g[b.name]&&(e=a,f=b.value)})}});e&&a(e,f?[f]:[])}function cc(b,a){var c=function(){b=D(b);if(b.injector()){var c=b[0]===W?
|
|
"document":ia(b);throw Ua("btstrpd",c.replace(/</,"<").replace(/>/,">"));}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=dc(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate",function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(V&&!d.test(V.name))return c();V.name=V.name.replace(d,"");Wa.resumeBootstrap=function(b){r(b,function(b){a.push(b)});c()}}function mb(b,a){a=
|
|
a||"_";return b.replace(Yc,function(b,d){return(d?a:"")+b.toLowerCase()})}function Cb(b,a,c){if(!b)throw Ua("areq",a||"?",c||"required");return b}function Xa(b,a,c){c&&M(b)&&(b=b[b.length-1]);Cb(O(b),a,"not a function, got "+(b&&"object"===typeof b?b.constructor.name||"Object":typeof b));return b}function Da(b,a){if("hasOwnProperty"===b)throw Ua("badname",a);}function ec(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g<f;g++)d=a[g],b&&(b=(e=b)[d]);return!c&&O(b)?Ab(e,b):b}function Db(b){var a=
|
|
b[0];b=b[b.length-1];if(a===b)return D(a);var c=[a];do{a=a.nextSibling;if(!a)break;c.push(a)}while(a!==b);return D(c)}function Zc(b){var a=z("$injector"),c=z("ng");b=b.angular||(b.angular={});b.$$minErr=b.$$minErr||z;return b.module||(b.module=function(){var b={};return function(e,f,g){if("hasOwnProperty"===e)throw c("badname","module");f&&b.hasOwnProperty(e)&&(b[e]=null);return b[e]||(b[e]=function(){function b(a,d,e){return function(){c[e||"push"]([a,d,arguments]);return n}}if(!f)throw a("nomod",
|
|
e);var c=[],d=[],m=b("$injector","invoke"),n={_invokeQueue:c,_runBlocks:d,requires:f,name:e,provider:b("$provide","provider"),factory:b("$provide","factory"),service:b("$provide","service"),value:b("$provide","value"),constant:b("$provide","constant","unshift"),animation:b("$animateProvider","register"),filter:b("$filterProvider","register"),controller:b("$controllerProvider","register"),directive:b("$compileProvider","directive"),config:m,run:function(a){d.push(a);return this}};g&&m(g);return n}())}}())}
|
|
function $c(b){F(b,{bootstrap:cc,copy:Ia,extend:F,equals:Ba,element:D,forEach:r,injector:dc,noop:B,bind:Ab,toJson:oa,fromJson:$b,identity:ga,isUndefined:H,isDefined:G,isString:E,isFunction:O,isObject:T,isNumber:ib,isElement:Uc,isArray:M,version:ad,isDate:ua,lowercase:A,uppercase:Ja,callbacks:{counter:0},$$minErr:z,$$csp:Ya});Za=Zc(V);try{Za("ngLocale")}catch(a){Za("ngLocale",[]).provider("$locale",bd)}Za("ng",["ngLocale"],["$provide",function(a){a.provider({$$sanitizeUri:cd});a.provider("$compile",
|
|
fc).directive({a:dd,input:gc,textarea:gc,form:ed,script:fd,select:gd,style:hd,option:id,ngBind:jd,ngBindHtml:kd,ngBindTemplate:ld,ngClass:md,ngClassEven:nd,ngClassOdd:od,ngCloak:pd,ngController:qd,ngForm:rd,ngHide:sd,ngIf:td,ngInclude:ud,ngInit:vd,ngNonBindable:wd,ngPluralize:xd,ngRepeat:yd,ngShow:zd,ngStyle:Ad,ngSwitch:Bd,ngSwitchWhen:Cd,ngSwitchDefault:Dd,ngOptions:Ed,ngTransclude:Fd,ngModel:Gd,ngList:Hd,ngChange:Id,required:hc,ngRequired:hc,ngValue:Jd}).directive({ngInclude:Kd}).directive(Eb).directive(ic);
|
|
a.provider({$anchorScroll:Ld,$animate:Md,$browser:Nd,$cacheFactory:Od,$controller:Pd,$document:Qd,$exceptionHandler:Rd,$filter:jc,$interpolate:Sd,$interval:Td,$http:Ud,$httpBackend:Vd,$location:Wd,$log:Xd,$parse:Yd,$rootScope:Zd,$q:$d,$sce:ae,$sceDelegate:be,$sniffer:ce,$templateCache:de,$timeout:ee,$window:fe,$$rAF:ge,$$asyncCallback:he})}])}function $a(b){return b.replace(ie,function(a,b,d,e){return e?d.toUpperCase():d}).replace(je,"Moz$1")}function Fb(b,a,c,d){function e(b){var e=c&&b?[this.filter(b)]:
|
|
[this],k=a,l,m,n,q,p,s;if(!d||null!=b)for(;e.length;)for(l=e.shift(),m=0,n=l.length;m<n;m++)for(q=D(l[m]),k?q.triggerHandler("$destroy"):k=!k,p=0,q=(s=q.children()).length;p<q;p++)e.push(Ea(s[p]));return f.apply(this,arguments)}var f=Ea.fn[b],f=f.$original||f;e.$original=f;Ea.fn[b]=e}function S(b){if(b instanceof S)return b;E(b)&&(b=$(b));if(!(this instanceof S)){if(E(b)&&"<"!=b.charAt(0))throw Gb("nosel");return new S(b)}if(E(b)){var a=b;b=W;var c;if(c=ke.exec(a))b=[b.createElement(c[1])];else{var d=
|
|
b,e;b=d.createDocumentFragment();c=[];if(Hb.test(a)){d=b.appendChild(d.createElement("div"));e=(le.exec(a)||["",""])[1].toLowerCase();e=ca[e]||ca._default;d.innerHTML="<div> </div>"+e[1]+a.replace(me,"<$1></$2>")+e[2];d.removeChild(d.firstChild);for(a=e[0];a--;)d=d.lastChild;a=0;for(e=d.childNodes.length;a<e;++a)c.push(d.childNodes[a]);d=b.firstChild;d.textContent=""}else c.push(d.createTextNode(a));b.textContent="";b.innerHTML="";b=c}Ib(this,b);D(W.createDocumentFragment()).append(this)}else Ib(this,
|
|
b)}function Jb(b){return b.cloneNode(!0)}function Ka(b){Kb(b);var a=0;for(b=b.childNodes||[];a<b.length;a++)Ka(b[a])}function kc(b,a,c,d){if(G(d))throw Gb("offargs");var e=pa(b,"events");pa(b,"handle")&&(H(a)?r(e,function(a,c){ab(b,c,a);delete e[c]}):r(a.split(" "),function(a){H(c)?(ab(b,a,e[a]),delete e[a]):Ta(e[a]||[],c)}))}function Kb(b,a){var c=b.ng339,d=bb[c];d&&(a?delete bb[c].data[a]:(d.handle&&(d.events.$destroy&&d.handle({},"$destroy"),kc(b)),delete bb[c],b.ng339=v))}function pa(b,a,c){var d=
|
|
b.ng339,d=bb[d||-1];if(G(c))d||(b.ng339=d=++ne,d=bb[d]={}),d[a]=c;else return d&&d[a]}function Lb(b,a,c){var d=pa(b,"data"),e=G(c),f=!e&&G(a),g=f&&!T(a);d||g||pa(b,"data",d={});if(e)d[a]=c;else if(f){if(g)return d&&d[a];F(d,a)}else return d}function Mb(b,a){return b.getAttribute?-1<(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").indexOf(" "+a+" "):!1}function nb(b,a){a&&b.setAttribute&&r(a.split(" "),function(a){b.setAttribute("class",$((" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g,
|
|
" ").replace(" "+$(a)+" "," ")))})}function ob(b,a){if(a&&b.setAttribute){var c=(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ");r(a.split(" "),function(a){a=$(a);-1===c.indexOf(" "+a+" ")&&(c+=a+" ")});b.setAttribute("class",$(c))}}function Ib(b,a){if(a){a=a.nodeName||!G(a.length)||Ha(a)?[a]:a;for(var c=0;c<a.length;c++)b.push(a[c])}}function lc(b,a){return pb(b,"$"+(a||"ngController")+"Controller")}function pb(b,a,c){9==b.nodeType&&(b=b.documentElement);for(a=M(a)?a:[a];b;){for(var d=
|
|
0,e=a.length;d<e;d++)if((c=D.data(b,a[d]))!==v)return c;b=b.parentNode||11===b.nodeType&&b.host}}function mc(b){for(var a=0,c=b.childNodes;a<c.length;a++)Ka(c[a]);for(;b.firstChild;)b.removeChild(b.firstChild)}function nc(b,a){var c=qb[a.toLowerCase()];return c&&oc[b.nodeName]&&c}function oe(b,a){var c=function(c,e){c.preventDefault||(c.preventDefault=function(){c.returnValue=!1});c.stopPropagation||(c.stopPropagation=function(){c.cancelBubble=!0});c.target||(c.target=c.srcElement||W);if(H(c.defaultPrevented)){var f=
|
|
c.preventDefault;c.preventDefault=function(){c.defaultPrevented=!0;f.call(c)};c.defaultPrevented=!1}c.isDefaultPrevented=function(){return c.defaultPrevented||!1===c.returnValue};var g=ha(a[e||c.type]||[]);r(g,function(a){a.call(b,c)});8>=u?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function La(b,a){var c=typeof b,d;"function"==c||"object"==c&&null!==b?"function"==typeof(d=
|
|
b.$$hashKey)?d=b.$$hashKey():d===v&&(d=b.$$hashKey=(a||hb)()):d=b;return c+":"+d}function cb(b,a){if(a){var c=0;this.nextUid=function(){return++c}}r(b,this.put,this)}function pc(b){var a,c;"function"===typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(pe,""),c=c.match(qe),r(c[1].split(re),function(b){b.replace(se,function(b,c,d){a.push(d)})})),b.$inject=a):M(b)?(c=b.length-1,Xa(b[c],"fn"),a=b.slice(0,c)):Xa(b,"fn",!0);return a}function dc(b){function a(a){return function(b,c){if(T(b))r(b,
|
|
Xb(a));else return a(b,c)}}function c(a,b){Da(a,"service");if(O(b)||M(b))b=n.instantiate(b);if(!b.$get)throw db("pget",a);return m[a+h]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,f,h;r(a,function(a){if(!l.get(a)){l.put(a,!0);try{if(E(a))for(c=Za(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,f=0,h=d.length;f<h;f++){var g=d[f],k=n.get(g[0]);k[g[1]].apply(k,g[2])}else O(a)?b.push(n.invoke(a)):M(a)?b.push(n.invoke(a)):Xa(a,"module")}catch(p){throw M(a)&&(a=
|
|
a[a.length-1]),p.message&&(p.stack&&-1==p.stack.indexOf(p.message))&&(p=p.message+"\n"+p.stack),db("modulerr",a,p.stack||p.message||p);}}});return b}function f(a,b){function c(d){if(a.hasOwnProperty(d)){if(a[d]===g)throw db("cdep",d+" <- "+k.join(" <- "));return a[d]}try{return k.unshift(d),a[d]=g,a[d]=b(d)}catch(e){throw a[d]===g&&delete a[d],e;}finally{k.shift()}}function d(a,b,e){var f=[],h=pc(a),g,k,p;k=0;for(g=h.length;k<g;k++){p=h[k];if("string"!==typeof p)throw db("itkn",p);f.push(e&&e.hasOwnProperty(p)?
|
|
e[p]:c(p))}M(a)&&(a=a[g]);return a.apply(b,f)}return{invoke:d,instantiate:function(a,b){var c=function(){},e;c.prototype=(M(a)?a[a.length-1]:a).prototype;c=new c;e=d(a,c,b);return T(e)||O(e)?e:c},get:c,annotate:pc,has:function(b){return m.hasOwnProperty(b+h)||a.hasOwnProperty(b)}}}var g={},h="Provider",k=[],l=new cb([],!0),m={$provide:{provider:a(c),factory:a(d),service:a(function(a,b){return d(a,["$injector",function(a){return a.instantiate(b)}])}),value:a(function(a,b){return d(a,Z(b))}),constant:a(function(a,
|
|
b){Da(a,"constant");m[a]=b;q[a]=b}),decorator:function(a,b){var c=n.get(a+h),d=c.$get;c.$get=function(){var a=p.invoke(d,c);return p.invoke(b,null,{$delegate:a})}}}},n=m.$injector=f(m,function(){throw db("unpr",k.join(" <- "));}),q={},p=q.$injector=f(q,function(a){a=n.get(a+h);return p.invoke(a.$get,a)});r(e(b),function(a){p.invoke(a||B)});return p}function Ld(){var b=!0;this.disableAutoScrolling=function(){b=!1};this.$get=["$window","$location","$rootScope",function(a,c,d){function e(a){var b=null;
|
|
r(a,function(a){b||"a"!==A(a.nodeName)||(b=a)});return b}function f(){var b=c.hash(),d;b?(d=g.getElementById(b))?d.scrollIntoView():(d=e(g.getElementsByName(b)))?d.scrollIntoView():"top"===b&&a.scrollTo(0,0):a.scrollTo(0,0)}var g=a.document;b&&d.$watch(function(){return c.hash()},function(){d.$evalAsync(f)});return f}]}function he(){this.$get=["$$rAF","$timeout",function(b,a){return b.supported?function(a){return b(a)}:function(b){return a(b,0,!1)}}]}function te(b,a,c,d){function e(a){try{a.apply(null,
|
|
va.call(arguments,1))}finally{if(s--,0===s)for(;K.length;)try{K.pop()()}catch(b){c.error(b)}}}function f(a,b){(function da(){r(w,function(a){a()});t=b(da,a)})()}function g(){x!=h.url()&&(x=h.url(),r(aa,function(a){a(h.url())}))}var h=this,k=a[0],l=b.location,m=b.history,n=b.setTimeout,q=b.clearTimeout,p={};h.isMock=!1;var s=0,K=[];h.$$completeOutstandingRequest=e;h.$$incOutstandingRequestCount=function(){s++};h.notifyWhenNoOutstandingRequests=function(a){r(w,function(a){a()});0===s?a():K.push(a)};
|
|
var w=[],t;h.addPollFn=function(a){H(t)&&f(100,n);w.push(a);return a};var x=l.href,L=a.find("base"),y=null;h.url=function(a,c){l!==b.location&&(l=b.location);m!==b.history&&(m=b.history);if(a){if(x!=a){var e=x&&Fa(x)===Fa(a);x=a;if(!e&&d.history)c?m.replaceState(null,"",a):(m.pushState(null,"",a),L.attr("href",L.attr("href")));else if(e||(y=a),c)l.replace(a);else if(e){var e=l,f;f=a.indexOf("#");f=-1===f?"":a.substr(f+1);e.hash=f}else l.href=a;return h}}else return y||l.href.replace(/%27/g,"'")};
|
|
var aa=[],P=!1;h.onUrlChange=function(a){if(!P){if(d.history)D(b).on("popstate",g);if(d.hashchange)D(b).on("hashchange",g);else h.addPollFn(g);P=!0}aa.push(a);return a};h.$$checkUrlChange=g;h.baseHref=function(){var a=L.attr("href");return a?a.replace(/^(https?\:)?\/\/[^\/]*/,""):""};var N={},ba="",Q=h.baseHref();h.cookies=function(a,b){var d,e,f,h;if(a)b===v?k.cookie=escape(a)+"=;path="+Q+";expires=Thu, 01 Jan 1970 00:00:00 GMT":E(b)&&(d=(k.cookie=escape(a)+"="+escape(b)+";path="+Q).length+1,4096<
|
|
d&&c.warn("Cookie '"+a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!"));else{if(k.cookie!==ba)for(ba=k.cookie,d=ba.split("; "),N={},f=0;f<d.length;f++)e=d[f],h=e.indexOf("="),0<h&&(a=unescape(e.substring(0,h)),N[a]===v&&(N[a]=unescape(e.substring(h+1))));return N}};h.defer=function(a,b){var c;s++;c=n(function(){delete p[c];e(a)},b||0);p[c]=!0;return c};h.defer.cancel=function(a){return p[a]?(delete p[a],q(a),e(B),!0):!1}}function Nd(){this.$get=["$window","$log",
|
|
"$sniffer","$document",function(b,a,c,d){return new te(b,d,a,c)}]}function Od(){this.$get=function(){function b(b,d){function e(a){a!=n&&(q?q==a&&(q=a.n):q=a,f(a.n,a.p),f(a,n),n=a,n.n=null)}function f(a,b){a!=b&&(a&&(a.p=b),b&&(b.n=a))}if(b in a)throw z("$cacheFactory")("iid",b);var g=0,h=F({},d,{id:b}),k={},l=d&&d.capacity||Number.MAX_VALUE,m={},n=null,q=null;return a[b]={put:function(a,b){if(l<Number.MAX_VALUE){var c=m[a]||(m[a]={key:a});e(c)}if(!H(b))return a in k||g++,k[a]=b,g>l&&this.remove(q.key),
|
|
b},get:function(a){if(l<Number.MAX_VALUE){var b=m[a];if(!b)return;e(b)}return k[a]},remove:function(a){if(l<Number.MAX_VALUE){var b=m[a];if(!b)return;b==n&&(n=b.p);b==q&&(q=b.n);f(b.n,b.p);delete m[a]}delete k[a];g--},removeAll:function(){k={};g=0;m={};n=q=null},destroy:function(){m=h=k=null;delete a[b]},info:function(){return F({},h,{size:g})}}}var a={};b.info=function(){var b={};r(a,function(a,e){b[e]=a.info()});return b};b.get=function(b){return a[b]};return b}}function de(){this.$get=["$cacheFactory",
|
|
function(b){return b("templates")}]}function fc(b,a){var c={},d="Directive",e=/^\s*directive\:\s*([\d\w_\-]+)\s+(.*)$/,f=/(([\d\w_\-]+)(?:\:([^;]+))?;?)/,g=/^(on[a-z]+|formaction)$/;this.directive=function k(a,e){Da(a,"directive");E(a)?(Cb(e,"directiveFactory"),c.hasOwnProperty(a)||(c[a]=[],b.factory(a+d,["$injector","$exceptionHandler",function(b,d){var e=[];r(c[a],function(c,f){try{var g=b.invoke(c);O(g)?g={compile:Z(g)}:!g.compile&&g.link&&(g.compile=Z(g.link));g.priority=g.priority||0;g.index=
|
|
f;g.name=g.name||a;g.require=g.require||g.controller&&g.name;g.restrict=g.restrict||"A";e.push(g)}catch(k){d(k)}});return e}])),c[a].push(e)):r(a,Xb(k));return this};this.aHrefSanitizationWhitelist=function(b){return G(b)?(a.aHrefSanitizationWhitelist(b),this):a.aHrefSanitizationWhitelist()};this.imgSrcSanitizationWhitelist=function(b){return G(b)?(a.imgSrcSanitizationWhitelist(b),this):a.imgSrcSanitizationWhitelist()};this.$get=["$injector","$interpolate","$exceptionHandler","$http","$templateCache",
|
|
"$parse","$controller","$rootScope","$document","$sce","$animate","$$sanitizeUri",function(a,b,m,n,q,p,s,K,w,t,x,L){function y(a,b,c,d,e){a instanceof D||(a=D(a));r(a,function(b,c){3==b.nodeType&&b.nodeValue.match(/\S+/)&&(a[c]=D(b).wrap("<span></span>").parent()[0])});var f=P(a,b,a,c,d,e);aa(a,"ng-scope");return function(b,c,d,e){Cb(b,"scope");var g=c?Ma.clone.call(a):a;r(d,function(a,b){g.data("$"+b+"Controller",a)});d=0;for(var k=g.length;d<k;d++){var p=g[d].nodeType;1!==p&&9!==p||g.eq(d).data("$scope",
|
|
b)}c&&c(g,b);f&&f(b,g,g,e);return g}}function aa(a,b){try{a.addClass(b)}catch(c){}}function P(a,b,c,d,e,f){function g(a,c,d,e){var f,p,m,l,q,n,w;f=c.length;var s=Array(f);for(l=0;l<f;l++)s[l]=c[l];n=l=0;for(q=k.length;l<q;n++)p=s[n],c=k[l++],f=k[l++],c?(c.scope?(m=a.$new(),D.data(p,"$scope",m)):m=a,w=c.transcludeOnThisElement?N(a,c.transclude,e):!c.templateOnThisElement&&e?e:!e&&b?N(a,b):null,c(f,m,p,d,w)):f&&f(a,p.childNodes,v,e)}for(var k=[],p,m,l,q,n=0;n<a.length;n++)p=new Nb,m=ba(a[n],[],p,0===
|
|
n?d:v,e),(f=m.length?J(m,a[n],p,b,c,null,[],[],f):null)&&f.scope&&aa(p.$$element,"ng-scope"),p=f&&f.terminal||!(l=a[n].childNodes)||!l.length?null:P(l,f?(f.transcludeOnThisElement||!f.templateOnThisElement)&&f.transclude:b),k.push(f,p),q=q||f||p,f=null;return q?g:null}function N(a,b,c){return function(d,e,f){var g=!1;d||(d=a.$new(),g=d.$$transcluded=!0);e=b(d,e,f,c);if(g)e.on("$destroy",function(){d.$destroy()});return e}}function ba(a,b,c,d,g){var k=c.$attr,p;switch(a.nodeType){case 1:p=Na(a).toLowerCase();
|
|
da(b,qa(p),"E",d,g);for(var l,m,q,n,w=a.attributes,s=0,t=w&&w.length;s<t;s++){var K=!1,x=!1;l=w[s];if(!u||8<=u||l.specified){m=l.name;q=$(l.value);l=qa(m);if(n=U.test(l))m=mb(l.substr(6),"-");var y=l.replace(/(Start|End)$/,"");l===y+"Start"&&(K=m,x=m.substr(0,m.length-5)+"end",m=m.substr(0,m.length-6));l=qa(m.toLowerCase());k[l]=m;if(n||!c.hasOwnProperty(l))c[l]=q,nc(a,l)&&(c[l]=!0);S(a,b,q,l);da(b,l,"A",d,g,K,x)}}"input"===p&&"hidden"===a.getAttribute("type")&&a.setAttribute("autocomplete","off");
|
|
a=a.className;if(E(a)&&""!==a)for(;p=f.exec(a);)l=qa(p[2]),da(b,l,"C",d,g)&&(c[l]=$(p[3])),a=a.substr(p.index+p[0].length);break;case 3:if(11===u)for(;a.parentNode&&a.nextSibling&&3===a.nextSibling.nodeType;)a.nodeValue+=a.nextSibling.nodeValue,a.parentNode.removeChild(a.nextSibling);A(b,a.nodeValue);break;case 8:try{if(p=e.exec(a.nodeValue))l=qa(p[1]),da(b,l,"M",d,g)&&(c[l]=$(p[2]))}catch(r){}}b.sort(H);return b}function Q(a,b,c){var d=[],e=0;if(b&&a.hasAttribute&&a.hasAttribute(b)){do{if(!a)throw ja("uterdir",
|
|
b,c);1==a.nodeType&&(a.hasAttribute(b)&&e++,a.hasAttribute(c)&&e--);d.push(a);a=a.nextSibling}while(0<e)}else d.push(a);return D(d)}function C(a,b,c){return function(d,e,f,g,k){e=Q(e[0],b,c);return a(d,e,f,g,k)}}function J(a,c,d,e,f,g,k,q,n){function w(a,b,c,d){if(a){c&&(a=C(a,c,d));a.require=I.require;a.directiveName=z;if(L===I||I.$$isolateScope)a=qc(a,{isolateScope:!0});k.push(a)}if(b){c&&(b=C(b,c,d));b.require=I.require;b.directiveName=z;if(L===I||I.$$isolateScope)b=qc(b,{isolateScope:!0});q.push(b)}}
|
|
function t(a,b,c,d){var e,f="data",g=!1;if(E(b)){for(;"^"==(e=b.charAt(0))||"?"==e;)b=b.substr(1),"^"==e&&(f="inheritedData"),g=g||"?"==e;e=null;d&&"data"===f&&(e=d[b]);e=e||c[f]("$"+b+"Controller");if(!e&&!g)throw ja("ctreq",b,a);}else M(b)&&(e=[],r(b,function(b){e.push(t(a,b,c,d))}));return e}function K(a,e,f,g,n){function w(a,b){var c;2>arguments.length&&(b=a,a=v);Ga&&(c=ba);return n(a,b,c)}var x,R,y,N,C,Q,ba={},ra;x=c===f?d:ha(d,new Nb(D(f),d.$attr));R=x.$$element;if(L){var ve=/^\s*([@=&])(\??)\s*(\w*)\s*$/;
|
|
Q=e.$new(!0);!J||J!==L&&J!==L.$$originalDirective?R.data("$isolateScopeNoTemplate",Q):R.data("$isolateScope",Q);aa(R,"ng-isolate-scope");r(L.scope,function(a,c){var d=a.match(ve)||[],f=d[3]||c,g="?"==d[2],d=d[1],k,m,n,q;Q.$$isolateBindings[c]=d+f;switch(d){case "@":x.$observe(f,function(a){Q[c]=a});x.$$observers[f].$$scope=e;x[f]&&(Q[c]=b(x[f])(e));break;case "=":if(g&&!x[f])break;m=p(x[f]);q=m.literal?Ba:function(a,b){return a===b||a!==a&&b!==b};n=m.assign||function(){k=Q[c]=m(e);throw ja("nonassign",
|
|
x[f],L.name);};k=Q[c]=m(e);Q.$watch(function(){var a=m(e);q(a,Q[c])||(q(a,k)?n(e,a=Q[c]):Q[c]=a);return k=a},null,m.literal);break;case "&":m=p(x[f]);Q[c]=function(a){return m(e,a)};break;default:throw ja("iscp",L.name,c,a);}})}ra=n&&w;P&&r(P,function(a){var b={$scope:a===L||a.$$isolateScope?Q:e,$element:R,$attrs:x,$transclude:ra},c;C=a.controller;"@"==C&&(C=x[a.name]);c=s(C,b);ba[a.name]=c;Ga||R.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});g=0;for(y=k.length;g<y;g++)try{N=
|
|
k[g],N(N.isolateScope?Q:e,R,x,N.require&&t(N.directiveName,N.require,R,ba),ra)}catch(u){m(u,ia(R))}g=e;L&&(L.template||null===L.templateUrl)&&(g=Q);a&&a(g,f.childNodes,v,n);for(g=q.length-1;0<=g;g--)try{N=q[g],N(N.isolateScope?Q:e,R,x,N.require&&t(N.directiveName,N.require,R,ba),ra)}catch(I){m(I,ia(R))}}n=n||{};for(var x=-Number.MAX_VALUE,N,P=n.controllerDirectives,L=n.newIsolateScopeDirective,J=n.templateDirective,da=n.nonTlbTranscludeDirective,H=!1,F=!1,Ga=n.hasElementTranscludeDirective,A=d.$$element=
|
|
D(c),I,z,u,S=e,Oa,ka=0,U=a.length;ka<U;ka++){I=a[ka];var X=I.$$start,Y=I.$$end;X&&(A=Q(c,X,Y));u=v;if(x>I.priority)break;if(u=I.scope)N=N||I,I.templateUrl||(eb("new/isolated scope",L,I,A),T(u)&&(L=I));z=I.name;!I.templateUrl&&I.controller&&(u=I.controller,P=P||{},eb("'"+z+"' controller",P[z],I,A),P[z]=I);if(u=I.transclude)H=!0,I.$$tlb||(eb("transclusion",da,I,A),da=I),"element"==u?(Ga=!0,x=I.priority,u=A,A=d.$$element=D(W.createComment(" "+z+": "+d[z]+" ")),c=A[0],ra(f,va.call(u,0),c),S=y(u,e,x,g&&
|
|
g.name,{nonTlbTranscludeDirective:da})):(u=D(Jb(c)).contents(),A.empty(),S=y(u,e));if(I.template)if(F=!0,eb("template",J,I,A),J=I,u=O(I.template)?I.template(A,d):I.template,u=V(u),I.replace){g=I;u=Hb.test(u)?D($(u)):[];c=u[0];if(1!=u.length||1!==c.nodeType)throw ja("tplrt",z,"");ra(f,A,c);U={$attr:{}};u=ba(c,[],U);var we=a.splice(ka+1,a.length-(ka+1));L&&G(u);a=a.concat(u).concat(we);B(d,U);U=a.length}else A.html(u);if(I.templateUrl)F=!0,eb("template",J,I,A),J=I,I.replace&&(g=I),K=ue(a.splice(ka,
|
|
a.length-ka),A,d,f,H&&S,k,q,{controllerDirectives:P,newIsolateScopeDirective:L,templateDirective:J,nonTlbTranscludeDirective:da}),U=a.length;else if(I.compile)try{Oa=I.compile(A,d,S),O(Oa)?w(null,Oa,X,Y):Oa&&w(Oa.pre,Oa.post,X,Y)}catch(Z){m(Z,ia(A))}I.terminal&&(K.terminal=!0,x=Math.max(x,I.priority))}K.scope=N&&!0===N.scope;K.transcludeOnThisElement=H;K.templateOnThisElement=F;K.transclude=S;n.hasElementTranscludeDirective=Ga;return K}function G(a){for(var b=0,c=a.length;b<c;b++)a[b]=Zb(a[b],{$$isolateScope:!0})}
|
|
function da(b,e,f,g,p,l,n){if(e===p)return null;p=null;if(c.hasOwnProperty(e)){var q;e=a.get(e+d);for(var w=0,s=e.length;w<s;w++)try{q=e[w],(g===v||g>q.priority)&&-1!=q.restrict.indexOf(f)&&(l&&(q=Zb(q,{$$start:l,$$end:n})),b.push(q),p=q)}catch(x){m(x)}}return p}function B(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;r(a,function(d,e){"$"!=e.charAt(0)&&(b[e]&&b[e]!==d&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});r(b,function(b,f){"class"==f?(aa(e,b),a["class"]=(a["class"]?a["class"]+" ":
|
|
"")+b):"style"==f?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==f.charAt(0)||a.hasOwnProperty(f)||(a[f]=b,d[f]=c[f])})}function ue(a,b,c,d,e,f,g,k){var p=[],l,m,w=b[0],s=a.shift(),x=F({},s,{templateUrl:null,transclude:null,replace:null,$$originalDirective:s}),K=O(s.templateUrl)?s.templateUrl(b,c):s.templateUrl;b.empty();n.get(t.getTrustedResourceUrl(K),{cache:q}).success(function(q){var n,t;q=V(q);if(s.replace){q=Hb.test(q)?D($(q)):[];n=q[0];if(1!=q.length||1!==n.nodeType)throw ja("tplrt",
|
|
s.name,K);q={$attr:{}};ra(d,b,n);var y=ba(n,[],q);T(s.scope)&&G(y);a=y.concat(a);B(c,q)}else n=w,b.html(q);a.unshift(x);l=J(a,n,c,e,b,s,f,g,k);r(d,function(a,c){a==n&&(d[c]=b[0])});for(m=P(b[0].childNodes,e);p.length;){q=p.shift();t=p.shift();var L=p.shift(),C=p.shift(),y=b[0];if(t!==w){var Q=t.className;k.hasElementTranscludeDirective&&s.replace||(y=Jb(n));ra(L,D(t),y);aa(D(y),Q)}t=l.transcludeOnThisElement?N(q,l.transclude,C):C;l(m,q,y,d,t)}p=null}).error(function(a,b,c,d){throw ja("tpload",d.url);
|
|
});return function(a,b,c,d,e){a=e;p?(p.push(b),p.push(c),p.push(d),p.push(a)):(l.transcludeOnThisElement&&(a=N(b,l.transclude,e)),l(m,b,c,d,a))}}function H(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.name<b.name?-1:1:a.index-b.index}function eb(a,b,c,d){if(b)throw ja("multidir",b.name,c.name,a,ia(d));}function A(a,c){var d=b(c,!0);d&&a.push({priority:0,compile:function(a){var b=a.parent().length;b&&aa(a.parent(),"ng-binding");return function(a,c){var e=c.parent(),f=e.data("$binding")||
|
|
[];f.push(d);e.data("$binding",f);b||aa(e,"ng-binding");a.$watch(d,function(a){c[0].nodeValue=a})}}})}function z(a,b){if("srcdoc"==b)return t.HTML;var c=Na(a);if("xlinkHref"==b||"FORM"==c&&"action"==b||"LINK"==c&&"href"==b||"IMG"!=c&&("src"==b||"ngSrc"==b))return t.RESOURCE_URL}function S(a,c,d,e){var f=b(d,!0);if(f){if("multiple"===e&&"SELECT"===Na(a))throw ja("selmulti",ia(a));c.push({priority:100,compile:function(){return{pre:function(c,d,k){d=k.$$observers||(k.$$observers={});if(g.test(e))throw ja("nodomevents");
|
|
if(f=b(k[e],!0,z(a,e)))k[e]=f(c),(d[e]||(d[e]=[])).$$inter=!0,(k.$$observers&&k.$$observers[e].$$scope||c).$watch(f,function(a,b){"class"===e&&a!=b?k.$updateClass(a,b):k.$set(e,a)})}}}})}}function ra(a,b,c){var d=b[0],e=b.length,f=d.parentNode,g,k;if(a)for(g=0,k=a.length;g<k;g++)if(a[g]==d){a[g++]=c;k=g+e-1;for(var p=a.length;g<p;g++,k++)k<p?a[g]=a[k]:delete a[g];a.length-=e-1;break}f&&f.replaceChild(c,d);a=W.createDocumentFragment();a.appendChild(d);c[D.expando]=d[D.expando];d=1;for(e=b.length;d<
|
|
e;d++)f=b[d],D(f).remove(),a.appendChild(f),delete b[d];b[0]=c;b.length=1}function qc(a,b){return F(function(){return a.apply(null,arguments)},a,b)}var Nb=function(a,b){this.$$element=a;this.$attr=b||{}};Nb.prototype={$normalize:qa,$addClass:function(a){a&&0<a.length&&x.addClass(this.$$element,a)},$removeClass:function(a){a&&0<a.length&&x.removeClass(this.$$element,a)},$updateClass:function(a,b){var c=rc(a,b),d=rc(b,a);0===c.length?x.removeClass(this.$$element,d):0===d.length?x.addClass(this.$$element,
|
|
c):x.setClass(this.$$element,c,d)},$set:function(a,b,c,d){var e=nc(this.$$element[0],a);e&&(this.$$element.prop(a,b),d=e);this[a]=b;d?this.$attr[a]=d:(d=this.$attr[a])||(this.$attr[a]=d=mb(a,"-"));e=Na(this.$$element).toUpperCase();if("A"===e&&("href"===a||"xlinkHref"===a)||"IMG"===e&&"src"===a)this[a]=b=L(b,"src"===a);!1!==c&&(null===b||b===v?this.$$element.removeAttr(d):this.$$element.attr(d,b));(c=this.$$observers)&&r(c[a],function(a){try{a(b)}catch(c){m(c)}})},$observe:function(a,b){var c=this,
|
|
d=c.$$observers||(c.$$observers={}),e=d[a]||(d[a]=[]);e.push(b);K.$evalAsync(function(){e.$$inter||b(c[a])});return b}};var ka=b.startSymbol(),Ga=b.endSymbol(),V="{{"==ka||"}}"==Ga?ga:function(a){return a.replace(/\{\{/g,ka).replace(/}}/g,Ga)},U=/^ngAttr[A-Z]/;return y}]}function qa(b){return $a(b.replace(xe,""))}function rc(b,a){var c="",d=b.split(/\s+/),e=a.split(/\s+/),f=0;a:for(;f<d.length;f++){for(var g=d[f],h=0;h<e.length;h++)if(g==e[h])continue a;c+=(0<c.length?" ":"")+g}return c}function Pd(){var b=
|
|
{},a=/^(\S+)(\s+as\s+(\w+))?$/;this.register=function(a,d){Da(a,"controller");T(a)?F(b,a):b[a]=d};this.$get=["$injector","$window",function(c,d){return function(e,f){var g,h,k;E(e)&&(g=e.match(a),h=g[1],k=g[3],e=b.hasOwnProperty(h)?b[h]:ec(f.$scope,h,!0)||ec(d,h,!0),Xa(e,h,!0));g=c.instantiate(e,f);if(k){if(!f||"object"!==typeof f.$scope)throw z("$controller")("noscp",h||e.name,k);f.$scope[k]=g}return g}}]}function Qd(){this.$get=["$window",function(b){return D(b.document)}]}function Rd(){this.$get=
|
|
["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function sc(b){var a={},c,d,e;if(!b)return a;r(b.split("\n"),function(b){e=b.indexOf(":");c=A($(b.substr(0,e)));d=$(b.substr(e+1));c&&(a[c]=a[c]?a[c]+", "+d:d)});return a}function tc(b){var a=T(b)?b:v;return function(c){a||(a=sc(b));return c?a[A(c)]||null:a}}function uc(b,a,c){if(O(c))return c(b,a);r(c,function(c){b=c(b,a)});return b}function Ud(){var b=/^\s*(\[|\{[^\{])/,a=/[\}\]]\s*$/,c=/^\)\]\}',?\n/,d={"Content-Type":"application/json;charset=utf-8"},
|
|
e=this.defaults={transformResponse:[function(d){E(d)&&(d=d.replace(c,""),b.test(d)&&a.test(d)&&(d=$b(d)));return d}],transformRequest:[function(a){return T(a)&&"[object File]"!==Aa.call(a)&&"[object Blob]"!==Aa.call(a)?oa(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"},post:ha(d),put:ha(d),patch:ha(d)},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN"},f=this.interceptors=[],g=this.responseInterceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope",
|
|
"$q","$injector",function(a,b,c,d,n,q){function p(a){function b(a){var d=F({},a,{data:uc(a.data,a.headers,c.transformResponse)});return 200<=a.status&&300>a.status?d:n.reject(d)}var c={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},d=function(a){var b=e.headers,c=F({},a.headers),d,f,b=F({},b.common,b[A(a.method)]);a:for(d in b){a=A(d);for(f in c)if(A(f)===a)continue a;c[d]=b[d]}(function(a){var b;r(a,function(c,d){O(c)&&(b=c(),null!=b?a[d]=b:delete a[d])})})(c);
|
|
return c}(a);F(c,a);c.headers=d;c.method=Ja(c.method);var f=[function(a){d=a.headers;var c=uc(a.data,tc(d),a.transformRequest);H(c)&&r(d,function(a,b){"content-type"===A(b)&&delete d[b]});H(a.withCredentials)&&!H(e.withCredentials)&&(a.withCredentials=e.withCredentials);return s(a,c,d).then(b,b)},v],g=n.when(c);for(r(t,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var h=f.shift(),
|
|
g=g.then(a,h)}g.success=function(a){g.then(function(b){a(b.data,b.status,b.headers,c)});return g};g.error=function(a){g.then(null,function(b){a(b.data,b.status,b.headers,c)});return g};return g}function s(c,f,g){function l(a,b,c,e){C&&(200<=a&&300>a?C.put(u,[a,b,sc(c),e]):C.remove(u));q(b,a,c,e);d.$$phase||d.$apply()}function q(a,b,d,e){b=Math.max(b,0);(200<=b&&300>b?t.resolve:t.reject)({data:a,status:b,headers:tc(d),config:c,statusText:e})}function s(){var a=Sa(p.pendingRequests,c);-1!==a&&p.pendingRequests.splice(a,
|
|
1)}var t=n.defer(),r=t.promise,C,J,u=K(c.url,c.params);p.pendingRequests.push(c);r.then(s,s);!c.cache&&!e.cache||(!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method)||(C=T(c.cache)?c.cache:T(e.cache)?e.cache:w);if(C)if(J=C.get(u),G(J)){if(J&&O(J.then))return J.then(s,s),J;M(J)?q(J[1],J[0],ha(J[2]),J[3]):q(J,200,{},"OK")}else C.put(u,r);H(J)&&((J=Ob(c.url)?b.cookies()[c.xsrfCookieName||e.xsrfCookieName]:v)&&(g[c.xsrfHeaderName||e.xsrfHeaderName]=J),a(c.method,u,f,l,g,c.timeout,c.withCredentials,c.responseType));
|
|
return r}function K(a,b){if(!b)return a;var c=[];Tc(b,function(a,b){null===a||H(a)||(M(a)||(a=[a]),r(a,function(a){T(a)&&(a=ua(a)?a.toISOString():oa(a));c.push(Ca(b)+"="+Ca(a))}))});0<c.length&&(a+=(-1==a.indexOf("?")?"?":"&")+c.join("&"));return a}var w=c("$http"),t=[];r(f,function(a){t.unshift(E(a)?q.get(a):q.invoke(a))});r(g,function(a,b){var c=E(a)?q.get(a):q.invoke(a);t.splice(b,0,{response:function(a){return c(n.when(a))},responseError:function(a){return c(n.reject(a))}})});p.pendingRequests=
|
|
[];(function(a){r(arguments,function(a){p[a]=function(b,c){return p(F(c||{},{method:a,url:b}))}})})("get","delete","head","jsonp");(function(a){r(arguments,function(a){p[a]=function(b,c,d){return p(F(d||{},{method:a,url:b,data:c}))}})})("post","put","patch");p.defaults=e;return p}]}function ye(b){if(8>=u&&(!b.match(/^(get|post|head|put|delete|options)$/i)||!V.XMLHttpRequest))return new V.ActiveXObject("Microsoft.XMLHTTP");if(V.XMLHttpRequest)return new V.XMLHttpRequest;throw z("$httpBackend")("noxhr");
|
|
}function Vd(){this.$get=["$browser","$window","$document",function(b,a,c){return ze(b,ye,b.defer,a.angular.callbacks,c[0])}]}function ze(b,a,c,d,e){function f(a,b,c){var f=e.createElement("script"),g=null;f.type="text/javascript";f.src=a;f.async=!0;g=function(a){ab(f,"load",g);ab(f,"error",g);e.body.removeChild(f);f=null;var h=-1,s="unknown";a&&("load"!==a.type||d[b].called||(a={type:"error"}),s=a.type,h="error"===a.type?404:200);c&&c(h,s)};rb(f,"load",g);rb(f,"error",g);8>=u&&(f.onreadystatechange=
|
|
function(){E(f.readyState)&&/loaded|complete/.test(f.readyState)&&(f.onreadystatechange=null,g({type:"load"}))});e.body.appendChild(f);return g}var g=-1;return function(e,k,l,m,n,q,p,s){function K(){t=g;L&&L();y&&y.abort()}function w(a,d,e,f,g){P&&c.cancel(P);L=y=null;0===d&&(d=e?200:"file"==wa(k).protocol?404:0);a(1223===d?204:d,e,f,g||"");b.$$completeOutstandingRequest(B)}var t;b.$$incOutstandingRequestCount();k=k||b.url();if("jsonp"==A(e)){var x="_"+(d.counter++).toString(36);d[x]=function(a){d[x].data=
|
|
a;d[x].called=!0};var L=f(k.replace("JSON_CALLBACK","angular.callbacks."+x),x,function(a,b){w(m,a,d[x].data,"",b);d[x]=B})}else{var y=a(e);y.open(e,k,!0);r(n,function(a,b){G(a)&&y.setRequestHeader(b,a)});y.onreadystatechange=function(){if(y&&4==y.readyState){var a=null,b=null,c="";t!==g&&(a=y.getAllResponseHeaders(),b="response"in y?y.response:y.responseText);t===g&&10>u||(c=y.statusText);w(m,t||y.status,b,a,c)}};p&&(y.withCredentials=!0);if(s)try{y.responseType=s}catch(aa){if("json"!==s)throw aa;
|
|
}y.send(l||null)}if(0<q)var P=c(K,q);else q&&O(q.then)&&q.then(K)}}function Sd(){var b="{{",a="}}";this.startSymbol=function(a){return a?(b=a,this):b};this.endSymbol=function(b){return b?(a=b,this):a};this.$get=["$parse","$exceptionHandler","$sce",function(c,d,e){function f(f,l,m){for(var n,q,p=0,s=[],K=f.length,w=!1,t=[];p<K;)-1!=(n=f.indexOf(b,p))&&-1!=(q=f.indexOf(a,n+g))?(p!=n&&s.push(f.substring(p,n)),s.push(p=c(w=f.substring(n+g,q))),p.exp=w,p=q+h,w=!0):(p!=K&&s.push(f.substring(p)),p=K);(K=
|
|
s.length)||(s.push(""),K=1);if(m&&1<s.length)throw vc("noconcat",f);if(!l||w)return t.length=K,p=function(a){try{for(var b=0,c=K,g;b<c;b++){if("function"==typeof(g=s[b]))if(g=g(a),g=m?e.getTrusted(m,g):e.valueOf(g),null==g)g="";else switch(typeof g){case "string":break;case "number":g=""+g;break;default:g=oa(g)}t[b]=g}return t.join("")}catch(h){a=vc("interr",f,h.toString()),d(a)}},p.exp=f,p.parts=s,p}var g=b.length,h=a.length;f.startSymbol=function(){return b};f.endSymbol=function(){return a};return f}]}
|
|
function Td(){this.$get=["$rootScope","$window","$q",function(b,a,c){function d(d,g,h,k){var l=a.setInterval,m=a.clearInterval,n=c.defer(),q=n.promise,p=0,s=G(k)&&!k;h=G(h)?h:0;q.then(null,null,d);q.$$intervalId=l(function(){n.notify(p++);0<h&&p>=h&&(n.resolve(p),m(q.$$intervalId),delete e[q.$$intervalId]);s||b.$apply()},g);e[q.$$intervalId]=n;return q}var e={};d.cancel=function(b){return b&&b.$$intervalId in e?(e[b.$$intervalId].reject("canceled"),a.clearInterval(b.$$intervalId),delete e[b.$$intervalId],
|
|
!0):!1};return d}]}function bd(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),
|
|
DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function Pb(b){b=b.split("/");for(var a=b.length;a--;)b[a]=lb(b[a]);return b.join("/")}function wc(b,a,c){b=wa(b,c);a.$$protocol=
|
|
b.protocol;a.$$host=b.hostname;a.$$port=U(b.port)||Ae[b.protocol]||null}function xc(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=wa(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=bc(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function sa(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Fa(b){var a=b.indexOf("#");return-1==a?b:b.substr(0,a)}function yc(b){return b.replace(/(#.+)|#$/,
|
|
"$1")}function Qb(b){return b.substr(0,Fa(b).lastIndexOf("/")+1)}function zc(b,a){this.$$html5=!0;a=a||"";var c=Qb(b);wc(b,this,b);this.$$parse=function(a){var e=sa(c,a);if(!E(e))throw Rb("ipthprfx",a,c);xc(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Bb(this.$$search),b=this.$$hash?"#"+lb(this.$$hash):"";this.$$url=Pb(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$parseLinkUrl=function(d,e){var f,g;(f=sa(b,d))!==v?(g=f,g=(f=
|
|
sa(a,f))!==v?c+(sa("/",f)||f):b+g):(f=sa(c,d))!==v?g=c+f:c==d+"/"&&(g=c);g&&this.$$parse(g);return!!g}}function Sb(b,a){var c=Qb(b);wc(b,this,b);this.$$parse=function(d){var e=sa(b,d)||sa(c,d),e="#"==e.charAt(0)?sa(a,e):this.$$html5?e:"";if(!E(e))throw Rb("ihshprfx",d,a);xc(e,this,b);d=this.$$path;var f=/^\/[A-Z]:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));f.exec(e)||(d=(e=f.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Bb(this.$$search),e=this.$$hash?"#"+lb(this.$$hash):
|
|
"";this.$$url=Pb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+(this.$$url?a+this.$$url:"")};this.$$parseLinkUrl=function(a,c){return Fa(b)==Fa(a)?(this.$$parse(a),!0):!1}}function Ac(b,a){this.$$html5=!0;Sb.apply(this,arguments);var c=Qb(b);this.$$parseLinkUrl=function(d,e){var f,g;b==Fa(d)?f=d:(g=sa(c,d))?f=b+a+g:c===d+"/"&&(f=c);f&&this.$$parse(f);return!!f};this.$$compose=function(){var c=Bb(this.$$search),e=this.$$hash?"#"+lb(this.$$hash):"";this.$$url=Pb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=
|
|
b+a+this.$$url}}function sb(b){return function(){return this[b]}}function Bc(b,a){return function(c){if(H(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Wd(){var b="",a=!1;this.hashPrefix=function(a){return G(a)?(b=a,this):b};this.html5Mode=function(b){return G(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,f){function g(a){c.$broadcast("$locationChangeSuccess",h.absUrl(),a)}var h,k=d.baseHref(),l=d.url();a?(k=l.substring(0,l.indexOf("/",
|
|
l.indexOf("//")+2))+(k||"/"),e=e.history?zc:Ac):(k=Fa(l),e=Sb);h=new e(k,"#"+b);h.$$parseLinkUrl(l,l);var m=/^\s*(javascript|mailto):/i;f.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var b=D(a.target);"a"!==A(b[0].nodeName);)if(b[0]===f[0]||!(b=b.parent())[0])return;var e=b.prop("href"),g=b.attr("href")||b.attr("xlink:href");T(e)&&"[object SVGAnimatedString]"===e.toString()&&(e=wa(e.animVal).href);m.test(e)||(!e||(b.attr("target")||a.isDefaultPrevented())||!h.$$parseLinkUrl(e,
|
|
g))||(a.preventDefault(),h.absUrl()!=d.url()&&(c.$apply(),V.angular["ff-684208-preventDefault"]=!0))}});h.absUrl()!=l&&d.url(h.absUrl(),!0);d.onUrlChange(function(a){h.absUrl()!=a&&(c.$evalAsync(function(){var b=h.absUrl();h.$$parse(a);c.$broadcast("$locationChangeStart",a,b).defaultPrevented?(h.$$parse(b),d.url(b)):g(b)}),c.$$phase||c.$digest())});var n=0;c.$watch(function(){var a=yc(d.url()),b=yc(h.absUrl()),e=h.$$replace;n&&a==b||(n++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",
|
|
h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),e),g(a))}));h.$$replace=!1;return n});return h}]}function Xd(){var b=!0,a=this;this.debugEnabled=function(a){return G(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||B;a=!1;try{a=!!e.apply}catch(k){}return a?
|
|
function(){var a=[];r(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function la(b,a){if("__defineGetter__"===b||"__defineSetter__"===b||"__lookupGetter__"===b||"__lookupSetter__"===b||"__proto__"===b)throw ea("isecfld",a);return b}function Cc(b,a){b+="";if(!E(b))throw ea("iseccst",a);return b}function ma(b,
|
|
a){if(b){if(b.constructor===b)throw ea("isecfn",a);if(b.document&&b.location&&b.alert&&b.setInterval)throw ea("isecwindow",a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw ea("isecdom",a);if(b===Object)throw ea("isecobj",a);}return b}function tb(b,a,c,d,e){ma(b,d);e=e||{};a=a.split(".");for(var f,g=0;1<a.length;g++){f=la(a.shift(),d);var h=ma(b[f],d);h||(h={},b[f]=h);b=h;b.then&&e.unwrapPromises&&(xa(d),"$$v"in b||function(a){a.then(function(b){a.$$v=b})}(b),b.$$v===v&&(b.$$v={}),b=b.$$v)}f=
|
|
la(a.shift(),d);ma(b[f],d);return b[f]=c}function Pa(b){return"constructor"==b}function Dc(b,a,c,d,e,f,g){la(b,f);la(a,f);la(c,f);la(d,f);la(e,f);var h=function(a){return ma(a,f)},k=g.expensiveChecks,l=k||Pa(b)?h:ga,m=k||Pa(a)?h:ga,n=k||Pa(c)?h:ga,q=k||Pa(d)?h:ga,p=k||Pa(e)?h:ga;return g.unwrapPromises?function(g,h){var k=h&&h.hasOwnProperty(b)?h:g,t;if(null==k)return k;(k=l(k[b]))&&k.then&&(xa(f),"$$v"in k||(t=k,t.$$v=v,t.then(function(a){t.$$v=l(a)})),k=l(k.$$v));if(!a)return k;if(null==k)return v;
|
|
(k=m(k[a]))&&k.then&&(xa(f),"$$v"in k||(t=k,t.$$v=v,t.then(function(a){t.$$v=m(a)})),k=m(k.$$v));if(!c)return k;if(null==k)return v;(k=n(k[c]))&&k.then&&(xa(f),"$$v"in k||(t=k,t.$$v=v,t.then(function(a){t.$$v=n(a)})),k=n(k.$$v));if(!d)return k;if(null==k)return v;(k=q(k[d]))&&k.then&&(xa(f),"$$v"in k||(t=k,t.$$v=v,t.then(function(a){t.$$v=q(a)})),k=q(k.$$v));if(!e)return k;if(null==k)return v;(k=p(k[e]))&&k.then&&(xa(f),"$$v"in k||(t=k,t.$$v=v,t.then(function(a){t.$$v=p(a)})),k=p(k.$$v));return k}:
|
|
function(f,g){var h=g&&g.hasOwnProperty(b)?g:f;if(null==h)return h;h=l(h[b]);if(!a)return h;if(null==h)return v;h=m(h[a]);if(!c)return h;if(null==h)return v;h=n(h[c]);if(!d)return h;if(null==h)return v;h=q(h[d]);return e?null==h?v:h=p(h[e]):h}}function Be(b,a){return function(c,d){return b(c,d,xa,ma,a)}}function Ec(b,a,c){var d=a.expensiveChecks,e=d?Ce:De;if(e.hasOwnProperty(b))return e[b];var f=b.split("."),g=f.length,h;if(a.csp)h=6>g?Dc(f[0],f[1],f[2],f[3],f[4],c,a):function(b,d){var e=0,h;do h=
|
|
Dc(f[e++],f[e++],f[e++],f[e++],f[e++],c,a)(b,d),d=v,b=h;while(e<g);return h};else{var k="var p;\n";d&&(k+="s = eso(s, fe);\nl = eso(l, fe);\n");var l=d;r(f,function(b,e){la(b,c);var f=(e?"s":'((l&&l.hasOwnProperty("'+b+'"))?l:s)')+'["'+b+'"]',g=d||Pa(b);g&&(f="eso("+f+", fe)",l=!0);k+="if(s == null) return undefined;\ns="+f+";\n";a.unwrapPromises&&(k+='if (s && s.then) {\n pw("'+c.replace(/(["\r\n])/g,"\\$1")+'");\n if (!("$$v" in s)) {\n p=s;\n p.$$v = undefined;\n p.then(function(v) {p.$$v='+(g?
|
|
"eso(v)":"v")+";});\n}\n s="+(g?"eso(s.$$v)":"s.$$v")+"\n}\n")});k+="return s;";h=new Function("s","l","pw","eso","fe",k);h.toString=Z(k);if(l||a.unwrapPromises)h=Be(h,c)}"hasOwnProperty"!==b&&(e[b]=h);return h}function Yd(){var b={},a={},c={csp:!1,unwrapPromises:!1,logPromiseWarnings:!0,expensiveChecks:!1};this.unwrapPromises=function(a){return G(a)?(c.unwrapPromises=!!a,this):c.unwrapPromises};this.logPromiseWarnings=function(a){return G(a)?(c.logPromiseWarnings=a,this):c.logPromiseWarnings};this.$get=
|
|
["$filter","$sniffer","$log",function(d,e,f){c.csp=e.csp;var g={csp:c.csp,unwrapPromises:c.unwrapPromises,logPromiseWarnings:c.logPromiseWarnings,expensiveChecks:!0};xa=function(a){c.logPromiseWarnings&&!Fc.hasOwnProperty(a)&&(Fc[a]=!0,f.warn("[$parse] Promise found in the expression `"+a+"`. Automatic unwrapping of promises in Angular expressions is deprecated."))};return function(e,f){var l;switch(typeof e){case "string":var m=f?a:b;if(m.hasOwnProperty(e))return m[e];l=f?g:c;var n=new Tb(l);l=(new fb(n,
|
|
d,l)).parse(e);"hasOwnProperty"!==e&&(m[e]=l);return l;case "function":return e;default:return B}}}]}function $d(){this.$get=["$rootScope","$exceptionHandler",function(b,a){return Ee(function(a){b.$evalAsync(a)},a)}]}function Ee(b,a){function c(a){return a}function d(a){return g(a)}var e=function(){var g=[],l,m;return m={resolve:function(a){if(g){var c=g;g=v;l=f(a);c.length&&b(function(){for(var a,b=0,d=c.length;b<d;b++)a=c[b],l.then(a[0],a[1],a[2])})}},reject:function(a){m.resolve(h(a))},notify:function(a){if(g){var c=
|
|
g;g.length&&b(function(){for(var b,d=0,e=c.length;d<e;d++)b=c[d],b[2](a)})}},promise:{then:function(b,f,h){var m=e(),K=function(d){try{m.resolve((O(b)?b:c)(d))}catch(e){m.reject(e),a(e)}},w=function(b){try{m.resolve((O(f)?f:d)(b))}catch(c){m.reject(c),a(c)}},t=function(b){try{m.notify((O(h)?h:c)(b))}catch(d){a(d)}};g?g.push([K,w,t]):l.then(K,w,t);return m.promise},"catch":function(a){return this.then(null,a)},"finally":function(a){function b(a,c){var d=e();c?d.resolve(a):d.reject(a);return d.promise}
|
|
function d(e,f){var g=null;try{g=(a||c)()}catch(h){return b(h,!1)}return g&&O(g.then)?g.then(function(){return b(e,f)},function(a){return b(a,!1)}):b(e,f)}return this.then(function(a){return d(a,!0)},function(a){return d(a,!1)})}}}},f=function(a){return a&&O(a.then)?a:{then:function(c){var d=e();b(function(){d.resolve(c(a))});return d.promise}}},g=function(a){var b=e();b.reject(a);return b.promise},h=function(c){return{then:function(f,g){var h=e();b(function(){try{h.resolve((O(g)?g:d)(c))}catch(b){h.reject(b),
|
|
a(b)}});return h.promise}}};return{defer:e,reject:g,when:function(h,l,m,n){var q=e(),p,s=function(b){try{return(O(l)?l:c)(b)}catch(d){return a(d),g(d)}},K=function(b){try{return(O(m)?m:d)(b)}catch(c){return a(c),g(c)}},w=function(b){try{return(O(n)?n:c)(b)}catch(d){a(d)}};b(function(){f(h).then(function(a){p||(p=!0,q.resolve(f(a).then(s,K,w)))},function(a){p||(p=!0,q.resolve(K(a)))},function(a){p||q.notify(w(a))})});return q.promise},all:function(a){var b=e(),c=0,d=M(a)?[]:{};r(a,function(a,e){c++;
|
|
f(a).then(function(a){d.hasOwnProperty(e)||(d[e]=a,--c||b.resolve(d))},function(a){d.hasOwnProperty(e)||b.reject(a)})});0===c&&b.resolve(d);return b.promise}}}function ge(){this.$get=["$window","$timeout",function(b,a){var c=b.requestAnimationFrame||b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame,d=b.cancelAnimationFrame||b.webkitCancelAnimationFrame||b.mozCancelAnimationFrame||b.webkitCancelRequestAnimationFrame,e=!!c,f=e?function(a){var b=c(a);return function(){d(b)}}:function(b){var c=
|
|
a(b,16.66,!1);return function(){a.cancel(c)}};f.supported=e;return f}]}function Zd(){var b=10,a=z("$rootScope"),c=null;this.digestTtl=function(a){arguments.length&&(b=a);return b};this.$get=["$injector","$exceptionHandler","$parse","$browser",function(d,e,f,g){function h(){this.$id=hb();this.$$phase=this.$parent=this.$$watchers=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null;this["this"]=this.$root=this;this.$$destroyed=!1;this.$$asyncQueue=[];this.$$postDigestQueue=[];
|
|
this.$$listeners={};this.$$listenerCount={};this.$$isolateBindings={}}function k(b){if(q.$$phase)throw a("inprog",q.$$phase);q.$$phase=b}function l(a,b){var c=f(a);Xa(c,b);return c}function m(a,b,c){do a.$$listenerCount[c]-=b,0===a.$$listenerCount[c]&&delete a.$$listenerCount[c];while(a=a.$parent)}function n(){}h.prototype={constructor:h,$new:function(a){a?(a=new h,a.$root=this.$root,a.$$asyncQueue=this.$$asyncQueue,a.$$postDigestQueue=this.$$postDigestQueue):(this.$$childScopeClass||(this.$$childScopeClass=
|
|
function(){this.$$watchers=this.$$nextSibling=this.$$childHead=this.$$childTail=null;this.$$listeners={};this.$$listenerCount={};this.$id=hb();this.$$childScopeClass=null},this.$$childScopeClass.prototype=this),a=new this.$$childScopeClass);a["this"]=a;a.$parent=this;a.$$prevSibling=this.$$childTail;this.$$childHead?this.$$childTail=this.$$childTail.$$nextSibling=a:this.$$childHead=this.$$childTail=a;return a},$watch:function(a,b,d){var e=l(a,"watch"),f=this.$$watchers,g={fn:b,last:n,get:e,exp:a,
|
|
eq:!!d};c=null;if(!O(b)){var h=l(b||B,"listener");g.fn=function(a,b,c){h(c)}}if("string"==typeof a&&e.constant){var k=g.fn;g.fn=function(a,b,c){k.call(this,a,b,c);Ta(f,g)}}f||(f=this.$$watchers=[]);f.unshift(g);return function(){Ta(f,g);c=null}},$watchCollection:function(a,b){var c=this,d,e,g,h=1<b.length,k=0,l=f(a),m=[],n={},q=!0,r=0;return this.$watch(function(){d=l(c);var a,b,f;if(T(d))if(Ra(d))for(e!==m&&(e=m,r=e.length=0,k++),a=d.length,r!==a&&(k++,e.length=r=a),b=0;b<a;b++)f=e[b]!==e[b]&&d[b]!==
|
|
d[b],f||e[b]===d[b]||(k++,e[b]=d[b]);else{e!==n&&(e=n={},r=0,k++);a=0;for(b in d)d.hasOwnProperty(b)&&(a++,e.hasOwnProperty(b)?(f=e[b]!==e[b]&&d[b]!==d[b],f||e[b]===d[b]||(k++,e[b]=d[b])):(r++,e[b]=d[b],k++));if(r>a)for(b in k++,e)e.hasOwnProperty(b)&&!d.hasOwnProperty(b)&&(r--,delete e[b])}else e!==d&&(e=d,k++);return k},function(){q?(q=!1,b(d,d,c)):b(d,g,c);if(h)if(T(d))if(Ra(d)){g=Array(d.length);for(var a=0;a<d.length;a++)g[a]=d[a]}else for(a in g={},d)kb.call(d,a)&&(g[a]=d[a]);else g=d})},$digest:function(){var d,
|
|
f,h,l,m=this.$$asyncQueue,r=this.$$postDigestQueue,L,y,v=b,P,N=[],u,Q,C;k("$digest");g.$$checkUrlChange();c=null;do{y=!1;for(P=this;m.length;){try{C=m.shift(),C.scope.$eval(C.expression)}catch(J){q.$$phase=null,e(J)}c=null}a:do{if(l=P.$$watchers)for(L=l.length;L--;)try{if(d=l[L])if((f=d.get(P))!==(h=d.last)&&!(d.eq?Ba(f,h):"number"===typeof f&&"number"===typeof h&&isNaN(f)&&isNaN(h)))y=!0,c=d,d.last=d.eq?Ia(f,null):f,d.fn(f,h===n?f:h,P),5>v&&(u=4-v,N[u]||(N[u]=[]),Q=O(d.exp)?"fn: "+(d.exp.name||d.exp.toString()):
|
|
d.exp,Q+="; newVal: "+oa(f)+"; oldVal: "+oa(h),N[u].push(Q));else if(d===c){y=!1;break a}}catch(D){q.$$phase=null,e(D)}if(!(l=P.$$childHead||P!==this&&P.$$nextSibling))for(;P!==this&&!(l=P.$$nextSibling);)P=P.$parent}while(P=l);if((y||m.length)&&!v--)throw q.$$phase=null,a("infdig",b,oa(N));}while(y||m.length);for(q.$$phase=null;r.length;)try{r.shift()()}catch(G){e(G)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this!==q&&(r(this.$$listenerCount,
|
|
Ab(null,m,this)),a.$$childHead==this&&(a.$$childHead=this.$$nextSibling),a.$$childTail==this&&(a.$$childTail=this.$$prevSibling),this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling),this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling),this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=null,this.$$listeners={},this.$$watchers=this.$$asyncQueue=this.$$postDigestQueue=[],this.$destroy=this.$digest=this.$apply=B,this.$on=
|
|
this.$watch=function(){return B})}},$eval:function(a,b){return f(a)(this,b)},$evalAsync:function(a){q.$$phase||q.$$asyncQueue.length||g.defer(function(){q.$$asyncQueue.length&&q.$digest()});this.$$asyncQueue.push({scope:this,expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return k("$apply"),this.$eval(a)}catch(b){e(b)}finally{q.$$phase=null;try{q.$digest()}catch(c){throw e(c),c;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=
|
|
c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){var d=Sa(c,b);-1!==d&&(c[d]=null,m(e,1,a))}},$emit:function(a,b){var c=[],d,f=this,g=!1,h={name:a,targetScope:f,stopPropagation:function(){g=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},k=[h].concat(va.call(arguments,1)),l,m;do{d=f.$$listeners[a]||c;h.currentScope=f;l=0;for(m=d.length;l<m;l++)if(d[l])try{d[l].apply(null,k)}catch(n){e(n)}else d.splice(l,
|
|
1),l--,m--;if(g)break;f=f.$parent}while(f);return h},$broadcast:function(a,b){for(var c=this,d=this,f={name:a,targetScope:this,preventDefault:function(){f.defaultPrevented=!0},defaultPrevented:!1},g=[f].concat(va.call(arguments,1)),h,k;c=d;){f.currentScope=c;d=c.$$listeners[a]||[];h=0;for(k=d.length;h<k;h++)if(d[h])try{d[h].apply(null,g)}catch(l){e(l)}else d.splice(h,1),h--,k--;if(!(d=c.$$listenerCount[a]&&c.$$childHead||c!==this&&c.$$nextSibling))for(;c!==this&&!(d=c.$$nextSibling);)c=c.$parent}return f}};
|
|
var q=new h;return q}]}function cd(){var b=/^\s*(https?|ftp|mailto|tel|file):/,a=/^\s*((https?|ftp|file):|data:image\/)/;this.aHrefSanitizationWhitelist=function(a){return G(a)?(b=a,this):b};this.imgSrcSanitizationWhitelist=function(b){return G(b)?(a=b,this):a};this.$get=function(){return function(c,d){var e=d?a:b,f;if(!u||8<=u)if(f=wa(c).href,""!==f&&!f.match(e))return"unsafe:"+f;return c}}}function Fe(b){if("self"===b)return b;if(E(b)){if(-1<b.indexOf("***"))throw ya("iwcard",b);b=b.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,
|
|
"\\$1").replace(/\x08/g,"\\x08").replace("\\*\\*",".*").replace("\\*","[^:/.?&;]*");return RegExp("^"+b+"$")}if(jb(b))return RegExp("^"+b.source+"$");throw ya("imatcher");}function Gc(b){var a=[];G(b)&&r(b,function(b){a.push(Fe(b))});return a}function be(){this.SCE_CONTEXTS=fa;var b=["self"],a=[];this.resourceUrlWhitelist=function(a){arguments.length&&(b=Gc(a));return b};this.resourceUrlBlacklist=function(b){arguments.length&&(a=Gc(b));return a};this.$get=["$injector",function(c){function d(a){var b=
|
|
function(a){this.$$unwrapTrustedValue=function(){return a}};a&&(b.prototype=new a);b.prototype.valueOf=function(){return this.$$unwrapTrustedValue()};b.prototype.toString=function(){return this.$$unwrapTrustedValue().toString()};return b}var e=function(a){throw ya("unsafe");};c.has("$sanitize")&&(e=c.get("$sanitize"));var f=d(),g={};g[fa.HTML]=d(f);g[fa.CSS]=d(f);g[fa.URL]=d(f);g[fa.JS]=d(f);g[fa.RESOURCE_URL]=d(g[fa.URL]);return{trustAs:function(a,b){var c=g.hasOwnProperty(a)?g[a]:null;if(!c)throw ya("icontext",
|
|
a,b);if(null===b||b===v||""===b)return b;if("string"!==typeof b)throw ya("itype",a);return new c(b)},getTrusted:function(c,d){if(null===d||d===v||""===d)return d;var f=g.hasOwnProperty(c)?g[c]:null;if(f&&d instanceof f)return d.$$unwrapTrustedValue();if(c===fa.RESOURCE_URL){var f=wa(d.toString()),m,n,q=!1;m=0;for(n=b.length;m<n;m++)if("self"===b[m]?Ob(f):b[m].exec(f.href)){q=!0;break}if(q)for(m=0,n=a.length;m<n;m++)if("self"===a[m]?Ob(f):a[m].exec(f.href)){q=!1;break}if(q)return d;throw ya("insecurl",
|
|
d.toString());}if(c===fa.HTML)return e(d);throw ya("unsafe");},valueOf:function(a){return a instanceof f?a.$$unwrapTrustedValue():a}}}]}function ae(){var b=!0;this.enabled=function(a){arguments.length&&(b=!!a);return b};this.$get=["$parse","$sniffer","$sceDelegate",function(a,c,d){if(b&&c.msie&&8>c.msieDocumentMode)throw ya("iequirks");var e=ha(fa);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b},
|
|
e.valueOf=ga);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:function(a,c){return e.getTrusted(b,d(a,c))}};var f=e.parseAs,g=e.getTrusted,h=e.trustAs;r(fa,function(a,b){var c=A(b);e[$a("parse_as_"+c)]=function(b){return f(a,b)};e[$a("get_trusted_"+c)]=function(b){return g(a,b)};e[$a("trust_as_"+c)]=function(b){return h(a,b)}});return e}]}function ce(){this.$get=["$window","$document",function(b,a){var c={},d=U((/android (\d+)/.exec(A((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||
|
|
{}).userAgent),f=a[0]||{},g=f.documentMode,h,k=/^(Moz|webkit|O|ms)(?=[A-Z])/,l=f.body&&f.body.style,m=!1,n=!1;if(l){for(var q in l)if(m=k.exec(q)){h=m[0];h=h.substr(0,1).toUpperCase()+h.substr(1);break}h||(h="WebkitOpacity"in l&&"webkit");m=!!("transition"in l||h+"Transition"in l);n=!!("animation"in l||h+"Animation"in l);!d||m&&n||(m=E(f.body.style.webkitTransition),n=E(f.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!g||7<
|
|
g),hasEvent:function(a){if("input"==a&&9==u)return!1;if(H(c[a])){var b=f.createElement("div");c[a]="on"+a in b}return c[a]},csp:Ya(),vendorPrefix:h,transitions:m,animations:n,android:d,msie:u,msieDocumentMode:g}}]}function ee(){this.$get=["$rootScope","$browser","$q","$exceptionHandler",function(b,a,c,d){function e(e,h,k){var l=c.defer(),m=l.promise,n=G(k)&&!k;h=a.defer(function(){try{l.resolve(e())}catch(a){l.reject(a),d(a)}finally{delete f[m.$$timeoutId]}n||b.$apply()},h);m.$$timeoutId=h;f[h]=l;
|
|
return m}var f={};e.cancel=function(b){return b&&b.$$timeoutId in f?(f[b.$$timeoutId].reject("canceled"),delete f[b.$$timeoutId],a.defer.cancel(b.$$timeoutId)):!1};return e}]}function wa(b,a){var c=b;u&&(X.setAttribute("href",c),c=X.href);X.setAttribute("href",c);return{href:X.href,protocol:X.protocol?X.protocol.replace(/:$/,""):"",host:X.host,search:X.search?X.search.replace(/^\?/,""):"",hash:X.hash?X.hash.replace(/^#/,""):"",hostname:X.hostname,port:X.port,pathname:"/"===X.pathname.charAt(0)?X.pathname:
|
|
"/"+X.pathname}}function Ob(b){b=E(b)?wa(b):b;return b.protocol===Hc.protocol&&b.host===Hc.host}function fe(){this.$get=Z(V)}function jc(b){function a(d,e){if(T(d)){var f={};r(d,function(b,c){f[c]=a(c,b)});return f}return b.factory(d+c,e)}var c="Filter";this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+c)}}];a("currency",Ic);a("date",Jc);a("filter",Ge);a("json",He);a("limitTo",Ie);a("lowercase",Je);a("number",Kc);a("orderBy",Lc);a("uppercase",Ke)}function Ge(){return function(b,
|
|
a,c){if(!M(b))return b;var d=typeof c,e=[];e.check=function(a){for(var b=0;b<e.length;b++)if(!e[b](a))return!1;return!0};"function"!==d&&(c="boolean"===d&&c?function(a,b){return Wa.equals(a,b)}:function(a,b){if(a&&b&&"object"===typeof a&&"object"===typeof b){for(var d in a)if("$"!==d.charAt(0)&&kb.call(a,d)&&c(a[d],b[d]))return!0;return!1}b=(""+b).toLowerCase();return-1<(""+a).toLowerCase().indexOf(b)});var f=function(a,b){if("string"===typeof b&&"!"===b.charAt(0))return!f(a,b.substr(1));switch(typeof a){case "boolean":case "number":case "string":return c(a,
|
|
b);case "object":switch(typeof b){case "object":return c(a,b);default:for(var d in a)if("$"!==d.charAt(0)&&f(a[d],b))return!0}return!1;case "array":for(d=0;d<a.length;d++)if(f(a[d],b))return!0;return!1;default:return!1}};switch(typeof a){case "boolean":case "number":case "string":a={$:a};case "object":for(var g in a)(function(b){"undefined"!==typeof a[b]&&e.push(function(c){return f("$"==b?c:c&&c[b],a[b])})})(g);break;case "function":e.push(a);break;default:return b}d=[];for(g=0;g<b.length;g++){var h=
|
|
b[g];e.check(h)&&d.push(h)}return d}}function Ic(b){var a=b.NUMBER_FORMATS;return function(b,d){H(d)&&(d=a.CURRENCY_SYM);return Mc(b,a.PATTERNS[1],a.GROUP_SEP,a.DECIMAL_SEP,2).replace(/\u00A4/g,d)}}function Kc(b){var a=b.NUMBER_FORMATS;return function(b,d){return Mc(b,a.PATTERNS[0],a.GROUP_SEP,a.DECIMAL_SEP,d)}}function Mc(b,a,c,d,e){if(null==b||!isFinite(b)||T(b))return"";var f=0>b;b=Math.abs(b);var g=b+"",h="",k=[],l=!1;if(-1!==g.indexOf("e")){var m=g.match(/([\d\.]+)e(-?)(\d+)/);m&&"-"==m[2]&&
|
|
m[3]>e+1?(g="0",b=0):(h=g,l=!0)}if(l)0<e&&(-1<b&&1>b)&&(h=b.toFixed(e));else{g=(g.split(Nc)[1]||"").length;H(e)&&(e=Math.min(Math.max(a.minFrac,g),a.maxFrac));b=+(Math.round(+(b.toString()+"e"+e)).toString()+"e"+-e);0===b&&(f=!1);b=(""+b).split(Nc);g=b[0];b=b[1]||"";var m=0,n=a.lgSize,q=a.gSize;if(g.length>=n+q)for(m=g.length-n,l=0;l<m;l++)0===(m-l)%q&&0!==l&&(h+=c),h+=g.charAt(l);for(l=m;l<g.length;l++)0===(g.length-l)%n&&0!==l&&(h+=c),h+=g.charAt(l);for(;b.length<e;)b+="0";e&&"0"!==e&&(h+=d+b.substr(0,
|
|
e))}k.push(f?a.negPre:a.posPre);k.push(h);k.push(f?a.negSuf:a.posSuf);return k.join("")}function Ub(b,a,c){var d="";0>b&&(d="-",b=-b);for(b=""+b;b.length<a;)b="0"+b;c&&(b=b.substr(b.length-a));return d+b}function Y(b,a,c,d){c=c||0;return function(e){e=e["get"+b]();if(0<c||e>-c)e+=c;0===e&&-12==c&&(e=12);return Ub(e,a,d)}}function ub(b,a){return function(c,d){var e=c["get"+b](),f=Ja(a?"SHORT"+b:b);return d[f][e]}}function Jc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var f=0,g=0,h=b[8]?
|
|
a.setUTCFullYear:a.setFullYear,k=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=U(b[9]+b[10]),g=U(b[9]+b[11]));h.call(a,U(b[1]),U(b[2])-1,U(b[3]));f=U(b[4]||0)-f;g=U(b[5]||0)-g;h=U(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));k.call(a,f,g,h,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var f="",g=[],h,k;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;E(c)&&(c=Le.test(c)?U(c):a(c));ib(c)&&(c=new Date(c));
|
|
if(!ua(c))return c;for(;e;)(k=Me.exec(e))?(g=g.concat(va.call(k,1)),e=g.pop()):(g.push(e),e=null);r(g,function(a){h=Ne[a];f+=h?h(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return f}}function He(){return function(b){return oa(b,!0)}}function Ie(){return function(b,a){return M(b)||E(b)?(a=Infinity===Math.abs(Number(a))?Number(a):U(a))?0<a?b.slice(0,a):b.slice(a):E(b)?"":[]:b}}function Lc(b){return function(a,c,d){function e(a,b){return Va(b)?function(b,c){return a(c,b)}:a}function f(a,
|
|
b){var c=typeof a,d=typeof b;return c==d?(ua(a)&&ua(b)&&(a=a.valueOf(),b=b.valueOf()),"string"==c&&(a=a.toLowerCase(),b=b.toLowerCase()),a===b?0:a<b?-1:1):c<d?-1:1}if(!Ra(a))return a;c=M(c)?c:[c];0===c.length&&(c=["+"]);c=Vc(c,function(a){var c=!1,d=a||ga;if(E(a)){if("+"==a.charAt(0)||"-"==a.charAt(0))c="-"==a.charAt(0),a=a.substring(1);if(""===a)return e(function(a,b){return f(a,b)},c);d=b(a);if(d.constant){var l=d();return e(function(a,b){return f(a[l],b[l])},c)}}return e(function(a,b){return f(d(a),
|
|
d(b))},c)});return va.call(a).sort(e(function(a,b){for(var d=0;d<c.length;d++){var e=c[d](a,b);if(0!==e)return e}return 0},d))}}function za(b){O(b)&&(b={link:b});b.restrict=b.restrict||"AC";return Z(b)}function Oc(b,a,c,d){function e(a,c){c=c?"-"+mb(c,"-"):"";d.setClass(b,(a?vb:wb)+c,(a?wb:vb)+c)}var f=this,g=b.parent().controller("form")||xb,h=0,k=f.$error={},l=[];f.$name=a.name||a.ngForm;f.$dirty=!1;f.$pristine=!0;f.$valid=!0;f.$invalid=!1;g.$addControl(f);b.addClass(Qa);e(!0);f.$addControl=function(a){Da(a.$name,
|
|
"input");l.push(a);a.$name&&(f[a.$name]=a)};f.$removeControl=function(a){a.$name&&f[a.$name]===a&&delete f[a.$name];r(k,function(b,c){f.$setValidity(c,!0,a)});Ta(l,a)};f.$setValidity=function(a,b,c){var d=k[a];if(b)d&&(Ta(d,c),d.length||(h--,h||(e(b),f.$valid=!0,f.$invalid=!1),k[a]=!1,e(!0,a),g.$setValidity(a,!0,f)));else{h||e(b);if(d){if(-1!=Sa(d,c))return}else k[a]=d=[],h++,e(!1,a),g.$setValidity(a,!1,f);d.push(c);f.$valid=!1;f.$invalid=!0}};f.$setDirty=function(){d.removeClass(b,Qa);d.addClass(b,
|
|
yb);f.$dirty=!0;f.$pristine=!1;g.$setDirty()};f.$setPristine=function(){d.removeClass(b,yb);d.addClass(b,Qa);f.$dirty=!1;f.$pristine=!0;r(l,function(a){a.$setPristine()})}}function ta(b,a,c,d){b.$setValidity(a,c);return c?d:v}function Pc(b,a){var c,d;if(a)for(c=0;c<a.length;++c)if(d=a[c],b[d])return!0;return!1}function Oe(b,a,c,d,e){T(e)&&(b.$$hasNativeValidators=!0,b.$parsers.push(function(f){if(b.$error[a]||Pc(e,d)||!Pc(e,c))return f;b.$setValidity(a,!1)}))}function zb(b,a,c,d,e,f){var g=a.prop(Pe),
|
|
h=a[0].placeholder,k={},l=A(a[0].type);d.$$validityState=g;if(!e.android){var m=!1;a.on("compositionstart",function(a){m=!0});a.on("compositionend",function(){m=!1;n()})}var n=function(e){if(!m){var f=a.val();if(u&&"input"===(e||k).type&&a[0].placeholder!==h)h=a[0].placeholder;else if("password"!==l&&Va(c.ngTrim||"T")&&(f=$(f)),e=g&&d.$$hasNativeValidators,d.$viewValue!==f||""===f&&e)b.$root.$$phase?d.$setViewValue(f):b.$apply(function(){d.$setViewValue(f)})}};if(e.hasEvent("input"))a.on("input",
|
|
n);else{var q,p=function(){q||(q=f.defer(function(){n();q=null}))};a.on("keydown",function(a){a=a.keyCode;91===a||(15<a&&19>a||37<=a&&40>=a)||p()});if(e.hasEvent("paste"))a.on("paste cut",p)}a.on("change",n);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)};var s=c.ngPattern;s&&((e=s.match(/^\/(.*)\/([gim]*)$/))?(s=RegExp(e[1],e[2]),e=function(a){return ta(d,"pattern",d.$isEmpty(a)||s.test(a),a)}):e=function(c){var e=b.$eval(s);if(!e||!e.test)throw z("ngPattern")("noregexp",s,
|
|
e,ia(a));return ta(d,"pattern",d.$isEmpty(c)||e.test(c),c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var r=U(c.ngMinlength);e=function(a){return ta(d,"minlength",d.$isEmpty(a)||a.length>=r,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var w=U(c.ngMaxlength);e=function(a){return ta(d,"maxlength",d.$isEmpty(a)||a.length<=w,a)};d.$parsers.push(e);d.$formatters.push(e)}}function Vb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;d<
|
|
a.length;d++){for(var e=a[d],m=0;m<b.length;m++)if(e==b[m])continue a;c.push(e)}return c}function e(a){if(!M(a)){if(E(a))return a.split(" ");if(T(a)){var b=[];r(a,function(a,c){a&&(b=b.concat(c.split(" ")))});return b}}return a}return{restrict:"AC",link:function(f,g,h){function k(a,b){var c=g.data("$classCounts")||{},d=[];r(a,function(a){if(0<b||c[a])c[a]=(c[a]||0)+b,c[a]===+(0<b)&&d.push(a)});g.data("$classCounts",c);return d.join(" ")}function l(b){if(!0===a||f.$index%2===a){var l=e(b||[]);if(!m){var p=
|
|
k(l,1);h.$addClass(p)}else if(!Ba(b,m)){var s=e(m),p=d(l,s),l=d(s,l),l=k(l,-1),p=k(p,1);0===p.length?c.removeClass(g,l):0===l.length?c.addClass(g,p):c.setClass(g,p,l)}}m=ha(b)}var m;f.$watch(h[b],l,!0);h.$observe("class",function(a){l(f.$eval(h[b]))});"ngClass"!==b&&f.$watch("$index",function(c,d){var g=c&1;if(g!==(d&1)){var l=e(f.$eval(h[b]));g===a?(g=k(l,1),h.$addClass(g)):(g=k(l,-1),h.$removeClass(g))}})}}}]}var Pe="validity",A=function(b){return E(b)?b.toLowerCase():b},kb=Object.prototype.hasOwnProperty,
|
|
Ja=function(b){return E(b)?b.toUpperCase():b},u,D,Ea,va=[].slice,Qe=[].push,Aa=Object.prototype.toString,Ua=z("ng"),Wa=V.angular||(V.angular={}),Za,Na,na=["0","0","0"];u=U((/msie (\d+)/.exec(A(navigator.userAgent))||[])[1]);isNaN(u)&&(u=U((/trident\/.*; rv:(\d+)/.exec(A(navigator.userAgent))||[])[1]));B.$inject=[];ga.$inject=[];var M=function(){return O(Array.isArray)?Array.isArray:function(b){return"[object Array]"===Aa.call(b)}}(),$=function(){return String.prototype.trim?function(b){return E(b)?
|
|
b.trim():b}:function(b){return E(b)?b.replace(/^\s\s*/,"").replace(/\s\s*$/,""):b}}();Na=9>u?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?Ja(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Ya=function(){if(G(Ya.isActive_))return Ya.isActive_;var b=!(!W.querySelector("[ng-csp]")&&!W.querySelector("[data-ng-csp]"));if(!b)try{new Function("")}catch(a){b=!0}return Ya.isActive_=b},Yc=/[A-Z]/g,ad={full:"1.2.32",major:1,minor:2,
|
|
dot:32,codeName:"alternation-intention"};S.expando="ng339";var bb=S.cache={},ne=1,rb=V.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},ab=V.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)};S._data=function(b){return this.cache[b[this.expando]]||{}};var ie=/([\:\-\_]+(.))/g,je=/^moz([A-Z])/,Gb=z("jqLite"),ke=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Hb=/<|&#?\w+;/,le=/<([\w:]+)/,me=
|
|
/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ca={option:[1,'<select multiple="multiple">',"</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ca.optgroup=ca.option;ca.tbody=ca.tfoot=ca.colgroup=ca.caption=ca.thead;ca.th=ca.td;var Ma=S.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===W.readyState?
|
|
setTimeout(a):(this.on("DOMContentLoaded",a),S(V).on("load",a))},toString:function(){var b=[];r(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?D(this[b]):D(this[this.length+b])},length:0,push:Qe,sort:[].sort,splice:[].splice},qb={};r("multiple selected checked disabled readOnly required open".split(" "),function(b){qb[A(b)]=b});var oc={};r("input select option textarea button form details".split(" "),function(b){oc[Ja(b)]=!0});r({data:Lb,removeData:Kb},function(b,
|
|
a){S[a]=b});r({data:Lb,inheritedData:pb,scope:function(b){return D.data(b,"$scope")||pb(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return D.data(b,"$isolateScope")||D.data(b,"$isolateScopeNoTemplate")},controller:lc,injector:function(b){return pb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Mb,css:function(b,a,c){a=$a(a);if(G(c))b.style[a]=c;else{var d;8>=u&&(d=b.currentStyle&&b.currentStyle[a],""===d&&(d="auto"));d=d||b.style[a];8>=u&&(d=""===
|
|
d?v:d);return d}},attr:function(b,a,c){var d=A(a);if(qb[d])if(G(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||B).specified?d:v;else if(G(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?v:b},prop:function(b,a,c){if(G(c))b[a]=c;else return b[a]},text:function(){function b(b,d){var e=a[b.nodeType];if(H(d))return e?b[e]:"";b[e]=d}var a=[];9>u?(a[1]="innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";
|
|
b.$dv="";return b}(),val:function(b,a){if(H(a)){if("SELECT"===Na(b)&&b.multiple){var c=[];r(b.options,function(a){a.selected&&c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(H(a))return b.innerHTML;for(var c=0,d=b.childNodes;c<d.length;c++)Ka(d[c]);b.innerHTML=a},empty:mc},function(b,a){S.prototype[a]=function(a,d){var e,f,g=this.length;if(b!==mc&&(2==b.length&&b!==Mb&&b!==lc?a:d)===v){if(T(a)){for(e=0;e<g;e++)if(b===Lb)b(this[e],a);else for(f in a)b(this[e],
|
|
f,a[f]);return this}e=b.$dv;g=e===v?Math.min(g,1):g;for(f=0;f<g;f++){var h=b(this[f],a,d);e=e?e+h:h}return e}for(e=0;e<g;e++)b(this[e],a,d);return this}});r({removeData:Kb,dealoc:Ka,on:function a(c,d,e,f){if(G(f))throw Gb("onargs");var g=pa(c,"events"),h=pa(c,"handle");g||pa(c,"events",g={});h||pa(c,"handle",h=oe(c,g));r(d.split(" "),function(d){var f=g[d];if(!f){if("mouseenter"==d||"mouseleave"==d){var m=W.body.contains||W.body.compareDocumentPosition?function(a,c){var d=9===a.nodeType?a.documentElement:
|
|
a,e=c&&c.parentNode;return a===e||!!(e&&1===e.nodeType&&(d.contains?d.contains(e):a.compareDocumentPosition&&a.compareDocumentPosition(e)&16))}:function(a,c){if(c)for(;c=c.parentNode;)if(c===a)return!0;return!1};g[d]=[];a(c,{mouseleave:"mouseout",mouseenter:"mouseover"}[d],function(a){var c=a.relatedTarget;c&&(c===this||m(this,c))||h(a,d)})}else rb(c,d,h),g[d]=[];f=g[d]}f.push(e)})},off:kc,one:function(a,c,d){a=D(a);a.on(c,function f(){a.off(c,d);a.off(c,f)});a.on(c,d)},replaceWith:function(a,c){var d,
|
|
e=a.parentNode;Ka(a);r(new S(c),function(c){d?e.insertBefore(c,d.nextSibling):e.replaceChild(c,a);d=c})},children:function(a){var c=[];r(a.childNodes,function(a){1===a.nodeType&&c.push(a)});return c},contents:function(a){return a.contentDocument||a.childNodes||[]},append:function(a,c){r(new S(c),function(c){1!==a.nodeType&&11!==a.nodeType||a.appendChild(c)})},prepend:function(a,c){if(1===a.nodeType){var d=a.firstChild;r(new S(c),function(c){a.insertBefore(c,d)})}},wrap:function(a,c){c=D(c)[0];var d=
|
|
a.parentNode;d&&d.replaceChild(c,a);c.appendChild(a)},remove:function(a){Ka(a);var c=a.parentNode;c&&c.removeChild(a)},after:function(a,c){var d=a,e=a.parentNode;r(new S(c),function(a){e.insertBefore(a,d.nextSibling);d=a})},addClass:ob,removeClass:nb,toggleClass:function(a,c,d){c&&r(c.split(" "),function(c){var f=d;H(f)&&(f=!Mb(a,c));(f?ob:nb)(a,c)})},parent:function(a){return(a=a.parentNode)&&11!==a.nodeType?a:null},next:function(a){if(a.nextElementSibling)return a.nextElementSibling;for(a=a.nextSibling;null!=
|
|
a&&1!==a.nodeType;)a=a.nextSibling;return a},find:function(a,c){return a.getElementsByTagName?a.getElementsByTagName(c):[]},clone:Jb,triggerHandler:function(a,c,d){var e,f;e=c.type||c;var g=(pa(a,"events")||{})[e];g&&(e={preventDefault:function(){this.defaultPrevented=!0},isDefaultPrevented:function(){return!0===this.defaultPrevented},stopPropagation:B,type:e,target:a},c.type&&(e=F(e,c)),c=ha(g),f=d?[e].concat(d):[e],r(c,function(c){c.apply(a,f)}))}},function(a,c){S.prototype[c]=function(c,e,f){for(var g,
|
|
h=0;h<this.length;h++)H(g)?(g=a(this[h],c,e,f),G(g)&&(g=D(g))):Ib(g,a(this[h],c,e,f));return G(g)?g:this};S.prototype.bind=S.prototype.on;S.prototype.unbind=S.prototype.off});cb.prototype={put:function(a,c){this[La(a,this.nextUid)]=c},get:function(a){return this[La(a,this.nextUid)]},remove:function(a){var c=this[a=La(a,this.nextUid)];delete this[a];return c}};var qe=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,re=/,/,se=/^\s*(_?)(\S+?)\1\s*$/,pe=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,db=z("$injector"),Re=z("$animate"),
|
|
Md=["$provide",function(a){this.$$selectors={};this.register=function(c,d){var e=c+"-animation";if(c&&"."!=c.charAt(0))throw Re("notcsel",c);this.$$selectors[c.substr(1)]=e;a.factory(e,d)};this.classNameFilter=function(a){1===arguments.length&&(this.$$classNameFilter=a instanceof RegExp?a:null);return this.$$classNameFilter};this.$get=["$timeout","$$asyncCallback",function(a,d){return{enter:function(a,c,g,h){g?g.after(a):(c&&c[0]||(c=g.parent()),c.append(a));h&&d(h)},leave:function(a,c){a.remove();
|
|
c&&d(c)},move:function(a,c,d,h){this.enter(a,c,d,h)},addClass:function(a,c,g){c=E(c)?c:M(c)?c.join(" "):"";r(a,function(a){ob(a,c)});g&&d(g)},removeClass:function(a,c,g){c=E(c)?c:M(c)?c.join(" "):"";r(a,function(a){nb(a,c)});g&&d(g)},setClass:function(a,c,g,h){r(a,function(a){ob(a,c);nb(a,g)});h&&d(h)},enabled:B}}]}],ja=z("$compile");fc.$inject=["$provide","$$sanitizeUriProvider"];var xe=/^(x[\:\-_]|data[\:\-_])/i,vc=z("$interpolate"),Se=/^([^\?#]*)(\?([^#]*))?(#(.*))?$/,Ae={http:80,https:443,ftp:21},
|
|
Rb=z("$location");Ac.prototype=Sb.prototype=zc.prototype={$$html5:!1,$$replace:!1,absUrl:sb("$$absUrl"),url:function(a){if(H(a))return this.$$url;a=Se.exec(a);a[1]&&this.path(decodeURIComponent(a[1]));(a[2]||a[1])&&this.search(a[3]||"");this.hash(a[5]||"");return this},protocol:sb("$$protocol"),host:sb("$$host"),port:sb("$$port"),path:Bc("$$path",function(a){a=null!==a?a.toString():"";return"/"==a.charAt(0)?a:"/"+a}),search:function(a,c){switch(arguments.length){case 0:return this.$$search;case 1:if(E(a)||
|
|
ib(a))a=a.toString(),this.$$search=bc(a);else if(T(a))r(a,function(c,e){null==c&&delete a[e]}),this.$$search=a;else throw Rb("isrcharg");break;default:H(c)||null===c?delete this.$$search[a]:this.$$search[a]=c}this.$$compose();return this},hash:Bc("$$hash",function(a){return null!==a?a.toString():""}),replace:function(){this.$$replace=!0;return this}};var ea=z("$parse"),Fc={},xa,Te=Function.prototype.call,Ue=Function.prototype.apply,Qc=Function.prototype.bind,gb={"null":function(){return null},"true":function(){return!0},
|
|
"false":function(){return!1},undefined:B,"+":function(a,c,d,e){d=d(a,c);e=e(a,c);return G(d)?G(e)?d+e:d:G(e)?e:v},"-":function(a,c,d,e){d=d(a,c);e=e(a,c);return(G(d)?d:0)-(G(e)?e:0)},"*":function(a,c,d,e){return d(a,c)*e(a,c)},"/":function(a,c,d,e){return d(a,c)/e(a,c)},"%":function(a,c,d,e){return d(a,c)%e(a,c)},"^":function(a,c,d,e){return d(a,c)^e(a,c)},"=":B,"===":function(a,c,d,e){return d(a,c)===e(a,c)},"!==":function(a,c,d,e){return d(a,c)!==e(a,c)},"==":function(a,c,d,e){return d(a,c)==e(a,
|
|
c)},"!=":function(a,c,d,e){return d(a,c)!=e(a,c)},"<":function(a,c,d,e){return d(a,c)<e(a,c)},">":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Ve={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'},
|
|
Tb=function(a){this.options=a};Tb.prototype={constructor:Tb,lex:function(a){this.text=a;this.index=0;this.ch=v;this.lastCh=":";for(this.tokens=[];this.index<this.text.length;){this.ch=this.text.charAt(this.index);if(this.is("\"'"))this.readString(this.ch);else if(this.isNumber(this.ch)||this.is(".")&&this.isNumber(this.peek()))this.readNumber();else if(this.isIdent(this.ch))this.readIdent();else if(this.is("(){}[].,;:?"))this.tokens.push({index:this.index,text:this.ch}),this.index++;else if(this.isWhitespace(this.ch)){this.index++;
|
|
continue}else{a=this.ch+this.peek();var c=a+this.peek(2),d=gb[this.ch],e=gb[a],f=gb[c];f?(this.tokens.push({index:this.index,text:c,fn:f}),this.index+=3):e?(this.tokens.push({index:this.index,text:a,fn:e}),this.index+=2):d?(this.tokens.push({index:this.index,text:this.ch,fn:d}),this.index+=1):this.throwError("Unexpected next character ",this.index,this.index+1)}this.lastCh=this.ch}return this.tokens},is:function(a){return-1!==a.indexOf(this.ch)},was:function(a){return-1!==a.indexOf(this.lastCh)},
|
|
peek:function(a){a=a||1;return this.index+a<this.text.length?this.text.charAt(this.index+a):!1},isNumber:function(a){return"0"<=a&&"9">=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=G(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw ea("lexerr",
|
|
a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index<this.text.length;){var d=A(this.text.charAt(this.index));if("."==d||this.isNumber(d))a+=d;else{var e=this.peek();if("e"==d&&this.isExpOperator(e))a+=d;else if(this.isExpOperator(d)&&e&&this.isNumber(e)&&"e"==a.charAt(a.length-1))a+=d;else if(!this.isExpOperator(d)||e&&this.isNumber(e)||"e"!=a.charAt(a.length-1))break;else this.throwError("Invalid exponent")}this.index++}a*=1;this.tokens.push({index:c,text:a,literal:!0,constant:!0,
|
|
fn:function(){return a}})},readIdent:function(){for(var a=this,c="",d=this.index,e,f,g,h;this.index<this.text.length;){h=this.text.charAt(this.index);if("."===h||this.isIdent(h)||this.isNumber(h))"."===h&&(e=this.index),c+=h;else break;this.index++}if(e)for(f=this.index;f<this.text.length;){h=this.text.charAt(f);if("("===h){g=c.substr(e-d+1);c=c.substr(0,e-d);this.index=f;break}if(this.isWhitespace(h))f++;else break}d={index:d,text:c};if(gb.hasOwnProperty(c))d.fn=gb[c],d.literal=!0,d.constant=!0;
|
|
else{var k=Ec(c,this.options,this.text);d.fn=F(function(a,c){return k(a,c)},{assign:function(d,e){return tb(d,c,e,a.text,a.options)}})}this.tokens.push(d);g&&(this.tokens.push({index:e,text:"."}),this.tokens.push({index:e+1,text:g}))},readString:function(a){var c=this.index;this.index++;for(var d="",e=a,f=!1;this.index<this.text.length;){var g=this.text.charAt(this.index),e=e+g;if(f)"u"===g?(f=this.text.substring(this.index+1,this.index+5),f.match(/[\da-f]{4}/i)||this.throwError("Invalid unicode escape [\\u"+
|
|
f+"]"),this.index+=4,d+=String.fromCharCode(parseInt(f,16))):d+=Ve[g]||g,f=!1;else if("\\"===g)f=!0;else{if(g===a){this.index++;this.tokens.push({index:c,text:e,string:d,literal:!0,constant:!0,fn:function(){return d}});return}d+=g}this.index++}this.throwError("Unterminated quote",c)}};var fb=function(a,c,d){this.lexer=a;this.$filter=c;this.options=d};fb.ZERO=F(function(){return 0},{constant:!0});fb.prototype={constructor:fb,parse:function(a){this.text=a;this.tokens=this.lexer.lex(a);a=this.statements();
|
|
0!==this.tokens.length&&this.throwError("is an unexpected token",this.tokens[0]);a.literal=!!a.literal;a.constant=!!a.constant;return a},primary:function(){var a;if(this.expect("("))a=this.filterChain(),this.consume(")");else if(this.expect("["))a=this.arrayDeclaration();else if(this.expect("{"))a=this.object();else{var c=this.expect();(a=c.fn)||this.throwError("not a primary expression",c);a.literal=!!c.literal;a.constant=!!c.constant}for(var d;c=this.expect("(","[",".");)"("===c.text?(a=this.functionCall(a,
|
|
d),d=null):"["===c.text?(d=a,a=this.objectIndex(a)):"."===c.text?(d=a,a=this.fieldAccess(a)):this.throwError("IMPOSSIBLE");return a},throwError:function(a,c){throw ea("syntax",c.text,a,c.index+1,this.text,this.text.substring(c.index));},peekToken:function(){if(0===this.tokens.length)throw ea("ueoe",this.text);return this.tokens[0]},peek:function(a,c,d,e){if(0<this.tokens.length){var f=this.tokens[0],g=f.text;if(g===a||g===c||g===d||g===e||!(a||c||d||e))return f}return!1},expect:function(a,c,d,e){return(a=
|
|
this.peek(a,c,d,e))?(this.tokens.shift(),a):!1},consume:function(a){this.expect(a)||this.throwError("is unexpected, expecting ["+a+"]",this.peek())},unaryFn:function(a,c){return F(function(d,e){return a(d,e,c)},{constant:c.constant})},ternaryFn:function(a,c,d){return F(function(e,f){return a(e,f)?c(e,f):d(e,f)},{constant:a.constant&&c.constant&&d.constant})},binaryFn:function(a,c,d){return F(function(e,f){return c(e,f,a,d)},{constant:a.constant&&d.constant})},statements:function(){for(var a=[];;)if(0<
|
|
this.tokens.length&&!this.peek("}",")",";","]")&&a.push(this.filterChain()),!this.expect(";"))return 1===a.length?a[0]:function(c,d){for(var e,f=0;f<a.length;f++){var g=a[f];g&&(e=g(c,d))}return e}},filterChain:function(){for(var a=this.expression(),c;;)if(c=this.expect("|"))a=this.binaryFn(a,c.fn,this.filter());else return a},filter:function(){for(var a=this.expect(),c=this.$filter(a.text),d=[];;)if(a=this.expect(":"))d.push(this.expression());else{var e=function(a,e,h){h=[h];for(var k=0;k<d.length;k++)h.push(d[k](a,
|
|
e));return c.apply(a,h)};return function(){return e}}},expression:function(){return this.assignment()},assignment:function(){var a=this.ternary(),c,d;return(d=this.expect("="))?(a.assign||this.throwError("implies assignment but ["+this.text.substring(0,d.index)+"] can not be assigned to",d),c=this.ternary(),function(d,f){return a.assign(d,c(d,f),f)}):a},ternary:function(){var a=this.logicalOR(),c,d;if(this.expect("?")){c=this.assignment();if(d=this.expect(":"))return this.ternaryFn(a,c,this.assignment());
|
|
this.throwError("expected :",d)}else return a},logicalOR:function(){for(var a=this.logicalAND(),c;;)if(c=this.expect("||"))a=this.binaryFn(a,c.fn,this.logicalAND());else return a},logicalAND:function(){var a=this.equality(),c;if(c=this.expect("&&"))a=this.binaryFn(a,c.fn,this.logicalAND());return a},equality:function(){var a=this.relational(),c;if(c=this.expect("==","!=","===","!=="))a=this.binaryFn(a,c.fn,this.equality());return a},relational:function(){var a=this.additive(),c;if(c=this.expect("<",
|
|
">","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn(fb.ZERO,a.fn,this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):
|
|
this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=Ec(d,this.options,this.text);return F(function(c,d,h){return e(h||a(c,d))},{assign:function(e,g,h){(h=a(e,h))||a.assign(e,h={});return tb(h,d,g,c.text,c.options)}})},objectIndex:function(a){var c=this,d=this.expression();this.consume("]");return F(function(e,f){var g=a(e,f),h=Cc(d(e,f),c.text),k;la(h,c.text);if(!g)return v;(g=ma(g[h],c.text))&&(g.then&&c.options.unwrapPromises)&&(k=g,"$$v"in g||(k.$$v=v,k.then(function(a){k.$$v=
|
|
a})),g=g.$$v);return g},{assign:function(e,f,g){var h=la(Cc(d(e,g),c.text),c.text);(g=ma(a(e,g),c.text))||a.assign(e,g={});return g[h]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(f,g){for(var h=[],k=c?c(f,g):f,l=0;l<d.length;l++)h.push(ma(d[l](f,g),e.text));l=a(f,g,k)||B;ma(k,e.text);var m=e.text;if(l){if(l.constructor===l)throw ea("isecfn",m);if(l===Te||l===Ue||Qc&&l===
|
|
Qc)throw ea("isecff",m);}h=l.apply?l.apply(k,h):l(h[0],h[1],h[2],h[3],h[4]);return ma(h,e.text)}},arrayDeclaration:function(){var a=[],c=!0;if("]"!==this.peekToken().text){do{if(this.peek("]"))break;var d=this.expression();a.push(d);d.constant||(c=!1)}while(this.expect(","))}this.consume("]");return F(function(c,d){for(var g=[],h=0;h<a.length;h++)g.push(a[h](c,d));return g},{literal:!0,constant:c})},object:function(){var a=[],c=!0;if("}"!==this.peekToken().text){do{if(this.peek("}"))break;var d=this.expect(),
|
|
d=d.string||d.text;this.consume(":");var e=this.expression();a.push({key:d,value:e});e.constant||(c=!1)}while(this.expect(","))}this.consume("}");return F(function(c,d){for(var e={},k=0;k<a.length;k++){var l=a[k];e[l.key]=l.value(c,d)}return e},{literal:!0,constant:c})}};var De={},Ce={},ya=z("$sce"),fa={HTML:"html",CSS:"css",URL:"url",RESOURCE_URL:"resourceUrl",JS:"js"},X=W.createElement("a"),Hc=wa(V.location.href,!0);jc.$inject=["$provide"];Ic.$inject=["$locale"];Kc.$inject=["$locale"];var Nc=".",
|
|
Ne={yyyy:Y("FullYear",4),yy:Y("FullYear",2,0,!0),y:Y("FullYear",1),MMMM:ub("Month"),MMM:ub("Month",!0),MM:Y("Month",2,1),M:Y("Month",1,1),dd:Y("Date",2),d:Y("Date",1),HH:Y("Hours",2),H:Y("Hours",1),hh:Y("Hours",2,-12),h:Y("Hours",1,-12),mm:Y("Minutes",2),m:Y("Minutes",1),ss:Y("Seconds",2),s:Y("Seconds",1),sss:Y("Milliseconds",3),EEEE:ub("Day"),EEE:ub("Day",!0),a:function(a,c){return 12>a.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Ub(Math[0<a?
|
|
"floor":"ceil"](a/60),2)+Ub(Math.abs(a%60),2))}},Me=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,Le=/^\-?\d+$/;Jc.$inject=["$locale"];var Je=Z(A),Ke=Z(Ja);Lc.$inject=["$parse"];var dd=Z({restrict:"E",compile:function(a,c){8>=u&&(c.href||c.name||c.$set("href",""),a.append(W.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var f="[object SVGAnimatedString]"===Aa.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(f)||
|
|
a.preventDefault()})}}}),Eb={};r(qb,function(a,c){if("multiple"!=a){var d=qa("ng-"+c);Eb[d]=function(){return{priority:100,link:function(a,f,g){a.$watch(g[d],function(a){g.$set(c,!!a)})}}}}});r(["src","srcset","href"],function(a){var c=qa("ng-"+a);Eb[c]=function(){return{priority:99,link:function(d,e,f){var g=a,h=a;"href"===a&&"[object SVGAnimatedString]"===Aa.call(e.prop("href"))&&(h="xlinkHref",f.$attr[h]="xlink:href",g=null);f.$observe(c,function(c){c?(f.$set(h,c),u&&g&&e.prop(g,f[h])):"href"===
|
|
a&&f.$set(h,null)})}}}});var xb={$addControl:B,$removeControl:B,$setValidity:B,$setDirty:B,$setPristine:B};Oc.$inject=["$element","$attrs","$scope","$animate"];var Rc=function(a){return["$timeout",function(c){return{name:"form",restrict:a?"EAC":"E",controller:Oc,compile:function(){return{pre:function(a,e,f,g){if(!f.action){var h=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};rb(e[0],"submit",h);e.on("$destroy",function(){c(function(){ab(e[0],"submit",h)},0,!1)})}var k=e.parent().controller("form"),
|
|
l=f.name||f.ngForm;l&&tb(a,l,g,l);if(k)e.on("$destroy",function(){k.$removeControl(g);l&&tb(a,l,v,l);F(g,xb)})}}}}}]},ed=Rc(),rd=Rc(!0),We=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,Xe=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,Ye=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Sc={text:zb,number:function(a,c,d,e,f,g){zb(a,c,d,e,f,g);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Ye.test(a))return e.$setValidity("number",
|
|
!0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return v});Oe(e,"number",Ze,null,e.$$validityState);e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);return ta(e,"min",e.$isEmpty(a)||a>=c,a)},e.$parsers.push(a),e.$formatters.push(a));d.max&&(a=function(a){var c=parseFloat(d.max);return ta(e,"max",e.$isEmpty(a)||a<=c,a)},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){return ta(e,"number",e.$isEmpty(a)||
|
|
ib(a),a)})},url:function(a,c,d,e,f,g){zb(a,c,d,e,f,g);a=function(a){return ta(e,"url",e.$isEmpty(a)||We.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,f,g){zb(a,c,d,e,f,g);a=function(a){return ta(e,"email",e.$isEmpty(a)||Xe.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){H(d.name)&&c.attr("name",hb());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};
|
|
d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var f=d.ngTrueValue,g=d.ngFalseValue;E(f)||(f=!0);E(g)||(g=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==f};e.$formatters.push(function(a){return a===f});e.$parsers.push(function(a){return a?f:g})},hidden:B,button:B,submit:B,reset:B,file:B},Ze=["badInput"],gc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",
|
|
link:function(d,e,f,g){g&&(Sc[A(f.type)]||Sc.text)(d,e,f,g,c,a)}}}],vb="ng-valid",wb="ng-invalid",Qa="ng-pristine",yb="ng-dirty",$e=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate",function(a,c,d,e,f,g){function h(a,c){c=c?"-"+mb(c,"-"):"";g.removeClass(e,(a?wb:vb)+c);g.addClass(e,(a?vb:wb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=
|
|
d.name;var k=f(d.ngModel),l=k.assign;if(!l)throw z("ngModel")("nonassign",d.ngModel,ia(e));this.$render=B;this.$isEmpty=function(a){return H(a)||""===a||null===a||a!==a};var m=e.inheritedData("$formController")||xb,n=0,q=this.$error={};e.addClass(Qa);h(!0);this.$setValidity=function(a,c){q[a]!==!c&&(c?(q[a]&&n--,n||(h(!0),this.$valid=!0,this.$invalid=!1)):(h(!1),this.$invalid=!0,this.$valid=!1,n++),q[a]=!c,h(c,a),m.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine=
|
|
!0;g.removeClass(e,yb);g.addClass(e,Qa)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,g.removeClass(e,Qa),g.addClass(e,yb),m.$setDirty());r(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,l(a,d),r(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}}))};var p=this;a.$watch(function(){var c=k(a);if(p.$modelValue!==c){var d=p.$formatters,e=d.length;for(p.$modelValue=c;e--;)c=d[e](c);p.$viewValue!==c&&(p.$viewValue=
|
|
c,p.$render())}return c})}],Gd=function(){return{require:["ngModel","^?form"],controller:$e,link:function(a,c,d,e){var f=e[0],g=e[1]||xb;g.$addControl(f);a.$on("$destroy",function(){g.$removeControl(f)})}}},Id=Z({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),hc=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var f=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required",
|
|
!0),a};e.$formatters.push(f);e.$parsers.unshift(f);d.$observe("required",function(){f(e.$viewValue)})}}}},Hd=function(){return{require:"ngModel",link:function(a,c,d,e){var f=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!H(a)){var c=[];a&&r(a.split(f),function(a){a&&c.push($(a))});return c}});e.$formatters.push(function(a){return M(a)?a.join(", "):v});e.$isEmpty=function(a){return!a||!a.length}}}},af=/^(true|false|\d+)$/,Jd=function(){return{priority:100,
|
|
compile:function(a,c){return af.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue,function(a){f.$set("value",a)})}}}},jd=za({compile:function(a){a.addClass("ng-binding");return function(a,d,e){d.data("$binding",e.ngBind);a.$watch(e.ngBind,function(a){d.text(a==v?"":a)})}}}),ld=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}],
|
|
kd=["$sce","$parse",function(a,c){return{compile:function(d){d.addClass("ng-binding");return function(d,f,g){f.data("$binding",g.ngBindHtml);var h=c(g.ngBindHtml);d.$watch(function(){return(h(d)||"").toString()},function(c){f.html(a.getTrustedHtml(h(d))||"")})}}}}],md=Vb("",!0),od=Vb("Odd",0),nd=Vb("Even",1),pd=za({compile:function(a,c){c.$set("ngCloak",v);a.removeClass("ng-cloak")}}),qd=[function(){return{scope:!0,controller:"@",priority:500}}],ic={},bf={blur:!0,focus:!0};r("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),
|
|
function(a){var c=qa("ng-"+a);ic[c]=["$parse","$rootScope",function(d,e){return{compile:function(f,g){var h=d(g[c],!0);return function(c,d){d.on(a,function(d){var f=function(){h(c,{$event:d})};bf[a]&&e.$$phase?c.$evalAsync(f):c.$apply(f)})}}}}]});var td=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(c,d,e,f,g){var h,k,l;c.$watch(e.ngIf,function(f){Va(f)?k||(k=c.$new(),g(k,function(c){c[c.length++]=W.createComment(" end ngIf: "+e.ngIf+
|
|
" ");h={clone:c};a.enter(c,d.parent(),d)})):(l&&(l.remove(),l=null),k&&(k.$destroy(),k=null),h&&(l=Db(h.clone),a.leave(l,function(){l=null}),h=null))})}}}],ud=["$http","$templateCache","$anchorScroll","$animate","$sce",function(a,c,d,e,f){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:Wa.noop,compile:function(g,h){var k=h.ngInclude||h.src,l=h.onload||"",m=h.autoscroll;return function(g,h,p,r,K){var w=0,t,x,u,y=function(){x&&(x.remove(),x=null);t&&(t.$destroy(),t=null);
|
|
u&&(e.leave(u,function(){x=null}),x=u,u=null)};g.$watch(f.parseAsResourceUrl(k),function(f){var k=function(){!G(m)||m&&!g.$eval(m)||d()},p=++w;f?(a.get(f,{cache:c}).success(function(a){if(p===w){var c=g.$new();r.template=a;a=K(c,function(a){y();e.enter(a,null,h,k)});t=c;u=a;t.$emit("$includeContentLoaded");g.$eval(l)}}).error(function(){p===w&&y()}),g.$emit("$includeContentRequested")):(y(),r.template=null)})}}}}],Kd=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",
|
|
link:function(c,d,e,f){d.html(f.template);a(d.contents())(c)}}}],vd=za({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),wd=za({terminal:!0,priority:1E3}),xd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,f,g){var h=g.count,k=g.$attr.when&&f.attr(g.$attr.when),l=g.offset||0,m=e.$eval(k)||{},n={},q=c.startSymbol(),p=c.endSymbol(),s=/^when(Minus)?(.+)$/;r(g,function(a,c){s.test(c)&&(m[A(c.replace("when","").replace("Minus","-"))]=
|
|
f.attr(g.$attr[c]))});r(m,function(a,e){n[e]=c(a.replace(d,q+h+"-"+l+p))});e.$watch(function(){var c=parseFloat(e.$eval(h));if(isNaN(c))return"";c in m||(c=a.pluralCat(c-l));return n[c](e,f,!0)},function(a){f.text(a)})}}}],yd=["$parse","$animate",function(a,c){var d=z("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0,link:function(e,f,g,h,k){var l=g.ngRepeat,m=l.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),n,q,p,s,u,v,t={$id:La};if(!m)throw d("iexp",
|
|
l);g=m[1];h=m[2];(m=m[3])?(n=a(m),q=function(a,c,d){v&&(t[v]=a);t[u]=c;t.$index=d;return n(e,t)}):(p=function(a,c){return La(c)},s=function(a){return a});m=g.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!m)throw d("iidexp",g);u=m[3]||m[1];v=m[2];var x={};e.$watchCollection(h,function(a){var g,h,m=f[0],n,t={},G,C,J,A,E,B,z,H=[];if(Ra(a))B=a,E=q||p;else{E=q||s;B=[];for(J in a)a.hasOwnProperty(J)&&"$"!=J.charAt(0)&&B.push(J);B.sort()}G=B.length;h=H.length=B.length;for(g=0;g<h;g++)if(J=a===
|
|
B?g:B[g],A=a[J],n=E(J,A,g),Da(n,"`track by` id"),x.hasOwnProperty(n))z=x[n],delete x[n],t[n]=z,H[g]=z;else{if(t.hasOwnProperty(n))throw r(H,function(a){a&&a.scope&&(x[a.id]=a)}),d("dupes",l,n,oa(A));H[g]={id:n};t[n]=!1}for(J in x)x.hasOwnProperty(J)&&(z=x[J],g=Db(z.clone),c.leave(g),r(g,function(a){a.$$NG_REMOVED=!0}),z.scope.$destroy());g=0;for(h=B.length;g<h;g++){J=a===B?g:B[g];A=a[J];z=H[g];H[g-1]&&(m=H[g-1].clone[H[g-1].clone.length-1]);if(z.scope){C=z.scope;n=m;do n=n.nextSibling;while(n&&n.$$NG_REMOVED);
|
|
z.clone[0]!=n&&c.move(Db(z.clone),null,D(m));m=z.clone[z.clone.length-1]}else C=e.$new();C[u]=A;v&&(C[v]=J);C.$index=g;C.$first=0===g;C.$last=g===G-1;C.$middle=!(C.$first||C.$last);C.$odd=!(C.$even=0===(g&1));z.scope||k(C,function(a){a[a.length++]=W.createComment(" end ngRepeat: "+l+" ");c.enter(a,null,D(m));m=a;z.scope=C;z.clone=a;t[z.id]=z})}x=t})}}}],zd=["$animate",function(a){return function(c,d,e){c.$watch(e.ngShow,function(c){a[Va(c)?"removeClass":"addClass"](d,"ng-hide")})}}],sd=["$animate",
|
|
function(a){return function(c,d,e){c.$watch(e.ngHide,function(c){a[Va(c)?"addClass":"removeClass"](d,"ng-hide")})}}],Ad=za(function(a,c,d){a.$watch(d.ngStyle,function(a,d){d&&a!==d&&r(d,function(a,d){c.css(d,"")});a&&c.css(a)},!0)}),Bd=["$animate",function(a){return{restrict:"EA",require:"ngSwitch",controller:["$scope",function(){this.cases={}}],link:function(c,d,e,f){var g=[],h=[],k=[],l=[];c.$watch(e.ngSwitch||e.on,function(d){var n,q;n=0;for(q=k.length;n<q;++n)k[n].remove();n=k.length=0;for(q=
|
|
l.length;n<q;++n){var p=h[n];l[n].$destroy();k[n]=p;a.leave(p,function(){k.splice(n,1)})}h.length=0;l.length=0;if(g=f.cases["!"+d]||f.cases["?"])c.$eval(e.change),r(g,function(d){var e=c.$new();l.push(e);d.transclude(e,function(c){var e=d.element;h.push(c);a.enter(c,e.parent(),e)})})})}}}],Cd=za({transclude:"element",priority:800,require:"^ngSwitch",link:function(a,c,d,e,f){e.cases["!"+d.ngSwitchWhen]=e.cases["!"+d.ngSwitchWhen]||[];e.cases["!"+d.ngSwitchWhen].push({transclude:f,element:c})}}),Dd=
|
|
za({transclude:"element",priority:800,require:"^ngSwitch",link:function(a,c,d,e,f){e.cases["?"]=e.cases["?"]||[];e.cases["?"].push({transclude:f,element:c})}}),Fd=za({link:function(a,c,d,e,f){if(!f)throw z("ngTransclude")("orphan",ia(c));f(function(a){c.empty();c.append(a)})}}),fd=["$templateCache",function(a){return{restrict:"E",terminal:!0,compile:function(c,d){"text/ng-template"==d.type&&a.put(d.id,c[0].text)}}}],cf=z("ngOptions"),Ed=Z({terminal:!0}),gd=["$compile","$parse",function(a,c){var d=
|
|
/^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/,e={$setViewValue:B};return{restrict:"E",require:["select","?ngModel"],controller:["$element","$scope","$attrs",function(a,c,d){var k=this,l={},m=e,n;k.databound=d.ngModel;k.init=function(a,c,d){m=a;n=d};k.addOption=function(c){Da(c,'"option value"');l[c]=!0;m.$viewValue==c&&(a.val(c),n.parent()&&n.remove())};
|
|
k.removeOption=function(a){this.hasOption(a)&&(delete l[a],m.$viewValue==a&&this.renderUnknownOption(a))};k.renderUnknownOption=function(c){c="? "+La(c)+" ?";n.val(c);a.prepend(n);a.val(c);n.prop("selected",!0)};k.hasOption=function(a){return l.hasOwnProperty(a)};c.$on("$destroy",function(){k.renderUnknownOption=B})}],link:function(e,g,h,k){function l(a,c,d,e){d.$render=function(){var a=d.$viewValue;e.hasOption(a)?(B.parent()&&B.remove(),c.val(a),""===a&&A.prop("selected",!0)):H(a)&&A?c.val(""):e.renderUnknownOption(a)};
|
|
c.on("change",function(){a.$apply(function(){B.parent()&&B.remove();d.$setViewValue(c.val())})})}function m(a,c,d){var e;d.$render=function(){var a=new cb(d.$viewValue);r(c.find("option"),function(c){c.selected=G(a.get(c.value))})};a.$watch(function(){Ba(e,d.$viewValue)||(e=ha(d.$viewValue),d.$render())});c.on("change",function(){a.$apply(function(){var a=[];r(c.find("option"),function(c){c.selected&&a.push(c.value)});d.$setViewValue(a)})})}function n(e,f,g){function h(){var a={"":[]},c=[""],d,k,
|
|
s,v,w;s=g.$modelValue;v=B(e)||[];var E=n?Wb(v):v,H,R,C;R={};C=!1;if(p)if(k=g.$modelValue,y&&M(k))for(C=new cb([]),d={},w=0;w<k.length;w++)d[m]=k[w],C.put(y(e,d),k[w]);else C=new cb(k);w=C;var F,L;for(C=0;H=E.length,C<H;C++){k=C;if(n){k=E[C];if("$"===k.charAt(0))continue;R[n]=k}R[m]=v[k];d=r(e,R)||"";(k=a[d])||(k=a[d]=[],c.push(d));p?d=G(w.remove(y?y(e,R):A(e,R))):(y?(d={},d[m]=s,d=y(e,d)===y(e,R)):d=s===A(e,R),w=w||d);F=l(e,R);F=G(F)?F:"";k.push({id:y?y(e,R):n?E[C]:C,label:F,selected:d})}p||(z||null===
|
|
s?a[""].unshift({id:"",label:"",selected:!w}):w||a[""].unshift({id:"?",label:"",selected:!0}));R=0;for(E=c.length;R<E;R++){d=c[R];k=a[d];D.length<=R?(s={element:x.clone().attr("label",d),label:k.label},v=[s],D.push(v),f.append(s.element)):(v=D[R],s=v[0],s.label!=d&&s.element.attr("label",s.label=d));F=null;C=0;for(H=k.length;C<H;C++)d=k[C],(w=v[C+1])?(F=w.element,w.label!==d.label&&(F.text(w.label=d.label),F.prop("label",w.label)),w.id!==d.id&&F.val(w.id=d.id),F[0].selected!==d.selected&&(F.prop("selected",
|
|
w.selected=d.selected),u&&F.prop("selected",w.selected))):(""===d.id&&z?L=z:(L=t.clone()).val(d.id).prop("selected",d.selected).attr("selected",d.selected).prop("label",d.label).text(d.label),v.push({element:L,label:d.label,id:d.id,selected:d.selected}),q.addOption(d.label,L),F?F.after(L):s.element.append(L),F=L);for(C++;v.length>C;)d=v.pop(),q.removeOption(d.label),d.element.remove()}for(;D.length>R;)D.pop()[0].element.remove()}var k;if(!(k=s.match(d)))throw cf("iexp",s,ia(f));var l=c(k[2]||k[1]),
|
|
m=k[4]||k[6],n=k[5],r=c(k[3]||""),A=c(k[2]?k[1]:m),B=c(k[7]),y=k[8]?c(k[8]):null,D=[[{element:f,label:""}]];z&&(a(z)(e),z.removeClass("ng-scope"),z.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=B(e)||[],d={},k,l,q,r,s,t,u;if(p)for(l=[],r=0,t=D.length;r<t;r++)for(a=D[r],q=1,s=a.length;q<s;q++){if((k=a[q].element)[0].selected){k=k.val();n&&(d[n]=k);if(y)for(u=0;u<c.length&&(d[m]=c[u],y(e,d)!=k);u++);else d[m]=c[k];l.push(A(e,d))}}else if(k=f.val(),"?"==k)l=v;else if(""===
|
|
k)l=null;else if(y)for(u=0;u<c.length;u++){if(d[m]=c[u],y(e,d)==k){l=A(e,d);break}}else d[m]=c[k],n&&(d[n]=k),l=A(e,d);g.$setViewValue(l);h()})});g.$render=h;e.$watchCollection(B,h);e.$watchCollection(function(){var a={},c=B(e);if(c){for(var d=Array(c.length),f=0,g=c.length;f<g;f++)a[m]=c[f],d[f]=l(e,a);return d}},h);p&&e.$watchCollection(function(){return g.$modelValue},h)}if(k[1]){var q=k[0];k=k[1];var p=h.multiple,s=h.ngOptions,z=!1,A,t=D(W.createElement("option")),x=D(W.createElement("optgroup")),
|
|
B=t.clone();h=0;for(var y=g.children(),E=y.length;h<E;h++)if(""===y[h].value){A=z=y.eq(h);break}q.init(k,z,B);p&&(k.$isEmpty=function(a){return!a||0===a.length});s?n(e,g,k):p?m(e,g,k):l(e,g,k,q)}}}}],id=["$interpolate",function(a){var c={addOption:B,removeOption:B};return{restrict:"E",priority:100,compile:function(d,e){if(H(e.value)){var f=a(d.text(),!0);f||e.$set("value",d.text())}return function(a,d,e){var l=d.parent(),m=l.data("$selectController")||l.parent().data("$selectController");m&&m.databound?
|
|
d.prop("selected",!1):m=c;f?a.$watch(f,function(a,c){e.$set("value",a);a!==c&&m.removeOption(c);m.addOption(a)}):m.addOption(e.value);d.on("$destroy",function(){m.removeOption(e.value)})}}}}],hd=Z({restrict:"E",terminal:!0});V.angular.bootstrap?console.log("WARNING: Tried to load angular more than once."):((Ea=V.jQuery)&&Ea.fn.on?(D=Ea,F(Ea.fn,{scope:Ma.scope,isolateScope:Ma.isolateScope,controller:Ma.controller,injector:Ma.injector,inheritedData:Ma.inheritedData}),Fb("remove",!0,!0,!1),Fb("empty",
|
|
!1,!1,!1),Fb("html",!1,!1,!0)):D=S,Wa.element=D,$c(Wa),D(W).ready(function(){Xc(W,cc)}))})(window,document);!window.angular.$$csp()&&window.angular.element(document).find("head").prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}.ng-hide-add-active,.ng-hide-remove{display:block!important;}</style>');
|
|
//# sourceMappingURL=angular.min.js.map
|
|
|
|
// Source: public/lib/angular-resource/angular-resource.min.js
|
|
/*
|
|
AngularJS v1.2.32
|
|
(c) 2010-2014 Google, Inc. http://angularjs.org
|
|
License: MIT
|
|
*/
|
|
(function(H,a,A){'use strict';function D(p,g){g=g||{};a.forEach(g,function(a,c){delete g[c]});for(var c in p)!p.hasOwnProperty(c)||"$"===c.charAt(0)&&"$"===c.charAt(1)||(g[c]=p[c]);return g}var v=a.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;a.module("ngResource",["ng"]).factory("$resource",["$http","$q",function(p,g){function c(a,c){this.template=a;this.defaults=c||{};this.urlParams={}}function t(n,w,l){function r(h,d){var e={};d=x({},w,d);s(d,function(b,d){u(b)&&(b=b());var k;if(b&&
|
|
b.charAt&&"@"==b.charAt(0)){k=h;var a=b.substr(1);if(null==a||""===a||"hasOwnProperty"===a||!C.test("."+a))throw v("badmember",a);for(var a=a.split("."),f=0,c=a.length;f<c&&k!==A;f++){var g=a[f];k=null!==k?k[g]:A}}else k=b;e[d]=k});return e}function e(a){return a.resource}function f(a){D(a||{},this)}var F=new c(n);l=x({},B,l);s(l,function(h,d){var c=/^(POST|PUT|PATCH)$/i.test(h.method);f[d]=function(b,d,k,w){var q={},n,l,y;switch(arguments.length){case 4:y=w,l=k;case 3:case 2:if(u(d)){if(u(b)){l=
|
|
b;y=d;break}l=d;y=k}else{q=b;n=d;l=k;break}case 1:u(b)?l=b:c?n=b:q=b;break;case 0:break;default:throw v("badargs",arguments.length);}var t=this instanceof f,m=t?n:h.isArray?[]:new f(n),z={},B=h.interceptor&&h.interceptor.response||e,C=h.interceptor&&h.interceptor.responseError||A;s(h,function(a,b){"params"!=b&&("isArray"!=b&&"interceptor"!=b)&&(z[b]=G(a))});c&&(z.data=n);F.setUrlParams(z,x({},r(n,h.params||{}),q),h.url);q=p(z).then(function(b){var d=b.data,k=m.$promise;if(d){if(a.isArray(d)!==!!h.isArray)throw v("badcfg",
|
|
h.isArray?"array":"object",a.isArray(d)?"array":"object");h.isArray?(m.length=0,s(d,function(b){"object"===typeof b?m.push(new f(b)):m.push(b)})):(D(d,m),m.$promise=k)}m.$resolved=!0;b.resource=m;return b},function(b){m.$resolved=!0;(y||E)(b);return g.reject(b)});q=q.then(function(b){var a=B(b);(l||E)(a,b.headers);return a},C);return t?q:(m.$promise=q,m.$resolved=!1,m)};f.prototype["$"+d]=function(b,a,k){u(b)&&(k=a,a=b,b={});b=f[d].call(this,b,this,a,k);return b.$promise||b}});f.bind=function(a){return t(n,
|
|
x({},w,a),l)};return f}var B={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},E=a.noop,s=a.forEach,x=a.extend,G=a.copy,u=a.isFunction;c.prototype={setUrlParams:function(c,g,l){var r=this,e=l||r.template,f,p,h=r.urlParams={};s(e.split(/\W/),function(a){if("hasOwnProperty"===a)throw v("badname");!/^\d+$/.test(a)&&(a&&RegExp("(^|[^\\\\]):"+a+"(\\W|$)").test(e))&&(h[a]=!0)});e=e.replace(/\\:/g,":");g=g||{};s(r.urlParams,function(d,
|
|
c){f=g.hasOwnProperty(c)?g[c]:r.defaults[c];a.isDefined(f)&&null!==f?(p=encodeURIComponent(f).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),e=e.replace(RegExp(":"+c+"(\\W|$)","g"),function(a,c){return p+c})):e=e.replace(RegExp("(/?):"+c+"(\\W|$)","g"),function(a,c,d){return"/"==d.charAt(0)?d:c+d})});e=e.replace(/\/+$/,"")||"/";e=e.replace(/\/\.(?=\w+($|\?))/,".");c.url=e.replace(/\/\\\./,
|
|
"/.");s(g,function(a,e){r.urlParams[e]||(c.params=c.params||{},c.params[e]=a)})}};return t}])})(window,window.angular);
|
|
//# sourceMappingURL=angular-resource.min.js.map
|
|
|
|
// Source: public/lib/angular-route/angular-route.min.js
|
|
/*
|
|
AngularJS v1.2.32
|
|
(c) 2010-2014 Google, Inc. http://angularjs.org
|
|
License: MIT
|
|
*/
|
|
(function(n,e,A){'use strict';function x(s,g,h){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,w){function y(){p&&(p.remove(),p=null);k&&(k.$destroy(),k=null);l&&(h.leave(l,function(){p=null}),p=l,l=null)}function v(){var b=s.current&&s.current.locals;if(e.isDefined(b&&b.$template)){var b=a.$new(),d=s.current;l=w(b,function(d){h.enter(d,null,l||c,function(){!e.isDefined(t)||t&&!a.$eval(t)||g()});y()});k=d.scope=b;k.$emit("$viewContentLoaded");k.$eval(u)}else y()}
|
|
var k,l,p,t=b.autoscroll,u=b.onload||"";a.$on("$routeChangeSuccess",v);v()}}}function z(e,g,h){return{restrict:"ECA",priority:-400,link:function(a,c){var b=h.current,f=b.locals;c.html(f.$template);var w=e(c.contents());b.controller&&(f.$scope=a,f=g(b.controller,f),b.controllerAs&&(a[b.controllerAs]=f),c.data("$ngControllerController",f),c.children().data("$ngControllerController",f));w(a)}}}n=e.module("ngRoute",["ng"]).provider("$route",function(){function s(a,c){return e.extend(new (e.extend(function(){},
|
|
{prototype:a})),c)}function g(a,e){var b=e.caseInsensitiveMatch,f={originalPath:a,regexp:a},h=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,e,b,c){a="?"===c?c:null;c="*"===c?c:null;h.push({name:b,optional:!!a});e=e||"";return""+(a?"":e)+"(?:"+(a?e:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=RegExp("^"+a+"$",b?"i":"");return f}var h={};this.when=function(a,c){h[a]=e.extend({reloadOnSearch:!0},c,a&&g(a,c));if(a){var b=
|
|
"/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";h[b]=e.extend({redirectTo:a},g(b,c))}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache","$sce",function(a,c,b,f,g,n,v,k){function l(){var d=p(),m=r.current;if(d&&m&&d.$$route===m.$$route&&e.equals(d.pathParams,m.pathParams)&&!d.reloadOnSearch&&!u)m.params=d.params,e.copy(m.params,b),a.$broadcast("$routeUpdate",m);else if(d||m)u=!1,a.$broadcast("$routeChangeStart",
|
|
d,m),(r.current=d)&&d.redirectTo&&(e.isString(d.redirectTo)?c.path(t(d.redirectTo,d.params)).search(d.params).replace():c.url(d.redirectTo(d.pathParams,c.path(),c.search())).replace()),f.when(d).then(function(){if(d){var a=e.extend({},d.resolve),c,b;e.forEach(a,function(d,c){a[c]=e.isString(d)?g.get(d):g.invoke(d)});e.isDefined(c=d.template)?e.isFunction(c)&&(c=c(d.params)):e.isDefined(b=d.templateUrl)&&(e.isFunction(b)&&(b=b(d.params)),b=k.getTrustedResourceUrl(b),e.isDefined(b)&&(d.loadedTemplateUrl=
|
|
b,c=n.get(b,{cache:v}).then(function(a){return a.data})));e.isDefined(c)&&(a.$template=c);return f.all(a)}}).then(function(c){d==r.current&&(d&&(d.locals=c,e.copy(d.params,b)),a.$broadcast("$routeChangeSuccess",d,m))},function(c){d==r.current&&a.$broadcast("$routeChangeError",d,m,c)})}function p(){var a,b;e.forEach(h,function(f,h){var q;if(q=!b){var g=c.path();q=f.keys;var l={};if(f.regexp)if(g=f.regexp.exec(g)){for(var k=1,p=g.length;k<p;++k){var n=q[k-1],r=g[k];n&&r&&(l[n.name]=r)}q=l}else q=null;
|
|
else q=null;q=a=q}q&&(b=s(f,{params:e.extend({},c.search(),a),pathParams:a}),b.$$route=f)});return b||h[null]&&s(h[null],{params:{},pathParams:{}})}function t(a,c){var b=[];e.forEach((a||"").split(":"),function(a,d){if(0===d)b.push(a);else{var e=a.match(/(\w+)(?:[?*])?(.*)/),f=e[1];b.push(c[f]);b.push(e[2]||"");delete c[f]}});return b.join("")}var u=!1,r={routes:h,reload:function(){u=!0;a.$evalAsync(l)}};a.$on("$locationChangeSuccess",l);return r}]});n.provider("$routeParams",function(){this.$get=
|
|
function(){return{}}});n.directive("ngView",x);n.directive("ngView",z);x.$inject=["$route","$anchorScroll","$animate"];z.$inject=["$compile","$controller","$route"]})(window,window.angular);
|
|
//# sourceMappingURL=angular-route.min.js.map
|
|
|
|
// Source: public/lib/angular-qrcode/qrcode.js
|
|
/*
|
|
* angular-qrcode v3.1.0
|
|
* (c) 2013 Monospaced http://monospaced.com
|
|
* License: MIT
|
|
*/
|
|
|
|
angular.module('monospaced.qrcode', [])
|
|
.directive('qrcode', ['$window', function($window) {
|
|
|
|
var canvas2D = !!$window.CanvasRenderingContext2D,
|
|
levels = {
|
|
'L': 'Low',
|
|
'M': 'Medium',
|
|
'Q': 'Quartile',
|
|
'H': 'High'
|
|
},
|
|
draw = function(context, qr, modules, tile) {
|
|
for (var row = 0; row < modules; row++) {
|
|
for (var col = 0; col < modules; col++) {
|
|
var w = (Math.ceil((col + 1) * tile) - Math.floor(col * tile)),
|
|
h = (Math.ceil((row + 1) * tile) - Math.floor(row * tile));
|
|
|
|
context.fillStyle = qr.isDark(row, col) ? '#000' : '#fff';
|
|
context.fillRect(Math.round(col * tile),
|
|
Math.round(row * tile), w, h);
|
|
}
|
|
}
|
|
};
|
|
|
|
return {
|
|
restrict: 'E',
|
|
template: '<canvas></canvas>',
|
|
link: function(scope, element, attrs) {
|
|
var domElement = element[0],
|
|
canvas = element.find('canvas')[0],
|
|
context = canvas2D ? canvas.getContext('2d') : null,
|
|
trim = /^\s+|\s+$/g,
|
|
error,
|
|
version,
|
|
errorCorrectionLevel,
|
|
data,
|
|
size,
|
|
modules,
|
|
tile,
|
|
qr,
|
|
setVersion = function(value) {
|
|
version = Math.max(1, Math.min(parseInt(value, 10), 10)) || 4;
|
|
},
|
|
setErrorCorrectionLevel = function(value) {
|
|
errorCorrectionLevel = value in levels ? value : 'M';
|
|
},
|
|
setData = function(value) {
|
|
if (!value) {
|
|
return;
|
|
}
|
|
|
|
data = value.replace(trim, '');
|
|
qr = qrcode(version, errorCorrectionLevel);
|
|
qr.addData(data);
|
|
|
|
try {
|
|
qr.make();
|
|
} catch(e) {
|
|
error = e.message;
|
|
return;
|
|
}
|
|
|
|
error = false;
|
|
modules = qr.getModuleCount();
|
|
},
|
|
setSize = function(value) {
|
|
size = parseInt(value, 10) || modules * 2;
|
|
tile = size / modules;
|
|
canvas.width = canvas.height = size;
|
|
},
|
|
render = function() {
|
|
if (!qr) {
|
|
return;
|
|
}
|
|
|
|
if (error) {
|
|
if (!canvas2D) {
|
|
domElement.innerHTML = '<img src width="' + size + '"' +
|
|
'height="' + size + '">';
|
|
}
|
|
scope.$emit('qrcode:error', error);
|
|
return;
|
|
}
|
|
|
|
if (canvas2D) {
|
|
draw(context, qr, modules, tile);
|
|
} else {
|
|
domElement.innerHTML = qr.createImgTag(tile, 0);
|
|
}
|
|
};
|
|
|
|
setVersion(attrs.version);
|
|
setErrorCorrectionLevel(attrs.errorCorrectionLevel);
|
|
setSize(attrs.size);
|
|
|
|
attrs.$observe('version', function(value) {
|
|
if (!value) {
|
|
return;
|
|
}
|
|
|
|
setVersion(value);
|
|
setData(data);
|
|
setSize(size);
|
|
render();
|
|
});
|
|
|
|
attrs.$observe('errorCorrectionLevel', function(value) {
|
|
if (!value) {
|
|
return;
|
|
}
|
|
|
|
setErrorCorrectionLevel(value);
|
|
setData(data);
|
|
setSize(size);
|
|
render();
|
|
});
|
|
|
|
attrs.$observe('data', function(value) {
|
|
if (!value) {
|
|
return;
|
|
}
|
|
|
|
setData(value);
|
|
setSize(size);
|
|
render();
|
|
});
|
|
|
|
attrs.$observe('size', function(value) {
|
|
if (!value) {
|
|
return;
|
|
}
|
|
|
|
setSize(value);
|
|
render();
|
|
});
|
|
}
|
|
};
|
|
}]);
|
|
|
|
// Source: public/lib/angular-animate/angular-animate.min.js
|
|
/*
|
|
AngularJS v1.2.32
|
|
(c) 2010-2014 Google, Inc. http://angularjs.org
|
|
License: MIT
|
|
*/
|
|
(function(G,d,P){'use strict';d.module("ngAnimate",["ng"]).directive("ngAnimateChildren",function(){return function(H,k,e){e=e.ngAnimateChildren;d.isString(e)&&0===e.length?k.data("$$ngAnimateChildren",!0):H.$watch(e,function(d){k.data("$$ngAnimateChildren",!!d)})}}).factory("$$animateReflow",["$$rAF","$document",function(d,k){var e=k[0].body;return function(k){return d(function(){k(e.offsetWidth)})}}]).config(["$provide","$animateProvider",function(H,k){function e(d){for(var e=0;e<d.length;e++){var g=
|
|
d[e];if(g.nodeType==aa)return g}}function D(g){return d.element(e(g))}var p=d.noop,x=d.forEach,Q=k.$$selectors,aa=1,g="$$ngAnimateState",ga="$$ngAnimateChildren",I="ng-animate",h={running:!0};H.decorator("$animate",["$delegate","$injector","$sniffer","$rootElement","$$asyncCallback","$rootScope","$document",function(w,G,$,J,K,l,P){function R(a){var b=a.data(g)||{};b.running=!0;a.data(g,b)}function ha(a){if(a){var b=[],c={};a=a.substr(1).split(".");($.transitions||$.animations)&&b.push(G.get(Q[""]));
|
|
for(var f=0;f<a.length;f++){var d=a[f],e=Q[d];e&&!c[d]&&(b.push(G.get(e)),c[d]=!0)}return b}}function M(a,b,c){function f(a,b){var c=a[b],d=a["before"+b.charAt(0).toUpperCase()+b.substr(1)];if(c||d)return"leave"==b&&(d=c,c=null),l.push({event:b,fn:c}),m.push({event:b,fn:d}),!0}function e(b,d,f){var g=[];x(b,function(a){a.fn&&g.push(a)});var q=0;x(g,function(b,e){var B=function(){a:{if(d){(d[e]||p)();if(++q<g.length)break a;d=null}f()}};switch(b.event){case "setClass":d.push(b.fn(a,r,E,B));break;case "addClass":d.push(b.fn(a,
|
|
r||c,B));break;case "removeClass":d.push(b.fn(a,E||c,B));break;default:d.push(b.fn(a,B))}});d&&0===d.length&&f()}var g=a[0];if(g){var n="setClass"==b,k=n||"addClass"==b||"removeClass"==b,r,E;d.isArray(c)&&(r=c[0],E=c[1],c=r+" "+E);var h=a.attr("class")+" "+c;if(T(h)){var u=p,y=[],m=[],z=p,v=[],l=[],h=(" "+h).replace(/\s+/g,".");x(ha(h),function(a){!f(a,b)&&n&&(f(a,"addClass"),f(a,"removeClass"))});return{node:g,event:b,className:c,isClassBased:k,isSetClassOperation:n,before:function(a){u=a;e(m,y,
|
|
function(){u=p;a()})},after:function(a){z=a;e(l,v,function(){z=p;a()})},cancel:function(){y&&(x(y,function(a){(a||p)(!0)}),u(!0));v&&(x(v,function(a){(a||p)(!0)}),z(!0))}}}}}function F(a,b,c,f,e,s,n){function h(d){var e="$animate:"+d;z&&(z[e]&&0<z[e].length)&&K(function(){c.triggerHandler(e,{event:a,className:b})})}function r(){h("before")}function l(){h("after")}function k(){h("close");n&&K(function(){n()})}function u(){u.hasBeenRun||(u.hasBeenRun=!0,s())}function y(){if(!y.hasBeenRun){y.hasBeenRun=
|
|
!0;var e=c.data(g);e&&(m&&m.isClassBased?A(c,b):(K(function(){var e=c.data(g)||{};t==e.index&&A(c,b,a)}),c.data(g,e)));k()}}var m=M(c,a,b);if(m){b=m.className;var z=d.element._data(m.node),z=z&&z.events;f||(f=e?e.parent():c.parent());var v=c.data(g)||{};e=v.active||{};var p=v.totalActive||0,B=v.last,C;m.isClassBased&&(C=v.running||v.disabled||B&&!B.isClassBased);if(C||N(c,f))u(),r(),l(),y();else{f=!1;if(0<p){C=[];if(m.isClassBased)"setClass"==B.event?(C.push(B),A(c,b)):e[b]&&(w=e[b],w.event==a?f=
|
|
!0:(C.push(w),A(c,b)));else if("leave"==a&&e["ng-leave"])f=!0;else{for(var w in e)C.push(e[w]),A(c,w);e={};p=0}0<C.length&&x(C,function(a){a.cancel()})}!m.isClassBased||(m.isSetClassOperation||f)||(f="addClass"==a==c.hasClass(b));if(f)u(),r(),l(),k();else{if("leave"==a)c.one("$destroy",function(a){a=d.element(this);var b=a.data(g);b&&(b=b.active["ng-leave"])&&(b.cancel(),A(a,"ng-leave"))});c.addClass(I);var t=O++;p++;e[b]=m;c.data(g,{last:m,active:e,index:t,totalActive:p});r();m.before(function(e){var d=
|
|
c.data(g);e=e||!d||!d.active[b]||m.isClassBased&&d.active[b].event!=a;u();!0===e?y():(l(),m.after(y))})}}}else u(),r(),l(),y()}function U(a){if(a=e(a))a=d.isFunction(a.getElementsByClassName)?a.getElementsByClassName(I):a.querySelectorAll("."+I),x(a,function(a){a=d.element(a);(a=a.data(g))&&a.active&&x(a.active,function(a){a.cancel()})})}function A(a,b){if(e(a)==e(J))h.disabled||(h.running=!1,h.structural=!1);else if(b){var c=a.data(g)||{},d=!0===b;!d&&(c.active&&c.active[b])&&(c.totalActive--,delete c.active[b]);
|
|
if(d||!c.totalActive)a.removeClass(I),a.removeData(g)}}function N(a,b){if(h.disabled)return!0;if(e(a)==e(J))return h.running;var c,f,l;do{if(0===b.length)break;var s=e(b)==e(J),n=s?h:b.data(g)||{};if(n.disabled)return!0;s&&(l=!0);!1!==c&&(s=b.data(ga),d.isDefined(s)&&(c=s));f=f||n.running||n.last&&!n.last.isClassBased}while(b=b.parent());return!l||!c&&f}var O=0;J.data(g,h);l.$$postDigest(function(){l.$$postDigest(function(){h.running=!1})});var V=k.classNameFilter(),T=V?function(a){return V.test(a)}:
|
|
function(){return!0};return{enter:function(a,b,c,e){a=d.element(a);b=b&&d.element(b);c=c&&d.element(c);R(a);w.enter(a,b,c);l.$$postDigest(function(){a=D(a);F("enter","ng-enter",a,b,c,p,e)})},leave:function(a,b){a=d.element(a);U(a);R(a);l.$$postDigest(function(){F("leave","ng-leave",D(a),null,null,function(){w.leave(a)},b)})},move:function(a,b,c,e){a=d.element(a);b=b&&d.element(b);c=c&&d.element(c);U(a);R(a);w.move(a,b,c);l.$$postDigest(function(){a=D(a);F("move","ng-move",a,b,c,p,e)})},addClass:function(a,
|
|
b,c){a=d.element(a);a=D(a);F("addClass",b,a,null,null,function(){w.addClass(a,b)},c)},removeClass:function(a,b,c){a=d.element(a);a=D(a);F("removeClass",b,a,null,null,function(){w.removeClass(a,b)},c)},setClass:function(a,b,c,e){a=d.element(a);a=D(a);F("setClass",[b,c],a,null,null,function(){w.setClass(a,b,c)},e)},enabled:function(a,b){switch(arguments.length){case 2:if(a)A(b);else{var c=b.data(g)||{};c.disabled=!0;b.data(g,c)}break;case 1:h.disabled=!a;break;default:a=!h.disabled}return!!a}}}]);k.register("",
|
|
["$window","$sniffer","$timeout","$$animateReflow",function(g,h,k,J){function K(){L||(L=J(function(){S=[];L=null;t={}}))}function l(a,W){L&&L();S.push(W);L=J(function(){x(S,function(a){a()});S=[];L=null;t={}})}function D(a,W){var b=e(a);a=d.element(b);X.push(a);b=Date.now()+W;b<=fa||(k.cancel(ea),fa=b,ea=k(function(){R(X);X=[]},W,!1))}function R(a){x(a,function(a){(a=a.data(v))&&(a.closeAnimationFn||p)()})}function I(a,b){var c=b?t[b]:null;if(!c){var e=0,d=0,f=0,l=0,h,Y,Z,k;x(a,function(a){if(a.nodeType==
|
|
aa){a=g.getComputedStyle(a)||{};Z=a[n+Q];e=Math.max(M(Z),e);k=a[n+u];h=a[n+y];d=Math.max(M(h),d);Y=a[r+y];l=Math.max(M(Y),l);var b=M(a[r+Q]);0<b&&(b*=parseInt(a[r+m],10)||1);f=Math.max(b,f)}});c={total:0,transitionPropertyStyle:k,transitionDurationStyle:Z,transitionDelayStyle:h,transitionDelay:d,transitionDuration:e,animationDelayStyle:Y,animationDelay:l,animationDuration:f};b&&(t[b]=c)}return c}function M(a){var b=0;a=d.isString(a)?a.split(/\s*,\s*/):[];x(a,function(a){b=Math.max(parseFloat(a)||
|
|
0,b)});return b}function F(a){var b=a.parent(),c=b.data(z);c||(b.data(z,++da),c=da);return c+"-"+e(a).getAttribute("class")}function U(a,b,c,d){var f=F(b),g=f+" "+c,l=t[g]?++t[g].total:0,h={};if(0<l){var k=c+"-stagger",h=f+" "+k;(f=!t[h])&&b.addClass(k);h=I(b,h);f&&b.removeClass(k)}d=d||function(a){return a()};b.addClass(c);var k=b.data(v)||{},m=d(function(){return I(b,g)});d=m.transitionDuration;f=m.animationDuration;if(0===d&&0===f)return b.removeClass(c),!1;b.data(v,{running:k.running||0,itemIndex:l,
|
|
stagger:h,timings:m,closeAnimationFn:p});a=0<k.running||"setClass"==a;0<d&&A(b,c,a);0<f&&(0<h.animationDelay&&0===h.animationDuration)&&(e(b).style[r]="none 0s");return!0}function A(a,b,c){"ng-enter"!=b&&("ng-move"!=b&&"ng-leave"!=b)&&c?a.addClass(ca):e(a).style[n+u]="none"}function N(a,b){var c=n+u,d=e(a);d.style[c]&&0<d.style[c].length&&(d.style[c]="");a.removeClass(ca)}function O(a){var b=r;a=e(a);a.style[b]&&0<a.style[b].length&&(a.style[b]="")}function V(a,b,c,d){function g(a){b.off(w,h);b.removeClass(l);
|
|
f(b,c);a=e(b);for(var d in t)a.style.removeProperty(t[d])}function h(a){a.stopPropagation();var b=a.originalEvent||a;a=b.$manualTimeStamp||Date.now();b=parseFloat(b.elapsedTime.toFixed(B));Math.max(a-z,0)>=y&&b>=r&&d()}var k=e(b);a=b.data(v);if(-1!=k.getAttribute("class").indexOf(c)&&a){var l="";x(c.split(" "),function(a,b){l+=(0<b?" ":"")+a+"-active"});var m=a.stagger,n=a.timings,p=a.itemIndex,r=Math.max(n.transitionDuration,n.animationDuration),u=Math.max(n.transitionDelay,n.animationDelay),y=u*
|
|
ba,z=Date.now(),w=E+" "+H,q="",t=[];if(0<n.transitionDuration){var A=n.transitionPropertyStyle;-1==A.indexOf("all")&&(q+=s+"transition-property: "+A+";",q+=s+"transition-duration: "+n.transitionDurationStyle+";",t.push(s+"transition-property"),t.push(s+"transition-duration"))}0<p&&(0<m.transitionDelay&&0===m.transitionDuration&&(q+=s+"transition-delay: "+T(n.transitionDelayStyle,m.transitionDelay,p)+"; ",t.push(s+"transition-delay")),0<m.animationDelay&&0===m.animationDuration&&(q+=s+"animation-delay: "+
|
|
T(n.animationDelayStyle,m.animationDelay,p)+"; ",t.push(s+"animation-delay")));0<t.length&&(n=k.getAttribute("style")||"",k.setAttribute("style",n+"; "+q));b.on(w,h);b.addClass(l);a.closeAnimationFn=function(){g();d()};k=(p*(Math.max(m.animationDelay,m.transitionDelay)||0)+(u+r)*C)*ba;a.running++;D(b,k);return g}d()}function T(a,b,c){var d="";x(a.split(","),function(a,e){d+=(0<e?",":"")+(c*b+parseInt(a,10))+"s"});return d}function a(a,b,c,d){if(U(a,b,c,d))return function(a){a&&f(b,c)}}function b(a,
|
|
b,c,d){if(b.data(v))return V(a,b,c,d);f(b,c);d()}function c(c,d,e,f){var g=a(c,d,e);if(g){var h=g;l(d,function(){N(d,e);O(d);h=b(c,d,e,f)});return function(a){(h||p)(a)}}K();f()}function f(a,b){a.removeClass(b);var c=a.data(v);c&&(c.running&&c.running--,c.running&&0!==c.running||a.removeData(v))}function q(a,b){var c="";a=d.isArray(a)?a:a.split(/\s+/);x(a,function(a,d){a&&0<a.length&&(c+=(0<d?" ":"")+a+b)});return c}var s="",n,H,r,E;G.ontransitionend===P&&G.onwebkittransitionend!==P?(s="-webkit-",
|
|
n="WebkitTransition",H="webkitTransitionEnd transitionend"):(n="transition",H="transitionend");G.onanimationend===P&&G.onwebkitanimationend!==P?(s="-webkit-",r="WebkitAnimation",E="webkitAnimationEnd animationend"):(r="animation",E="animationend");var Q="Duration",u="Property",y="Delay",m="IterationCount",z="$$ngAnimateKey",v="$$ngAnimateCSS3Data",ca="ng-animate-block-transitions",B=3,C=1.5,ba=1E3,t={},da=0,S=[],L,ea=null,fa=0,X=[];return{enter:function(a,b){return c("enter",a,"ng-enter",b)},leave:function(a,
|
|
b){return c("leave",a,"ng-leave",b)},move:function(a,b){return c("move",a,"ng-move",b)},beforeSetClass:function(b,c,d,e){var f=q(d,"-remove")+" "+q(c,"-add"),g=a("setClass",b,f,function(a){var e=b.attr("class");b.removeClass(d);b.addClass(c);a=a();b.attr("class",e);return a});if(g)return l(b,function(){N(b,f);O(b);e()}),g;K();e()},beforeAddClass:function(b,c,d){var e=a("addClass",b,q(c,"-add"),function(a){b.addClass(c);a=a();b.removeClass(c);return a});if(e)return l(b,function(){N(b,c);O(b);d()}),
|
|
e;K();d()},setClass:function(a,c,d,e){d=q(d,"-remove");c=q(c,"-add");return b("setClass",a,d+" "+c,e)},addClass:function(a,c,d){return b("addClass",a,q(c,"-add"),d)},beforeRemoveClass:function(b,c,d){var e=a("removeClass",b,q(c,"-remove"),function(a){var d=b.attr("class");b.removeClass(c);a=a();b.attr("class",d);return a});if(e)return l(b,function(){N(b,c);O(b);d()}),e;d()},removeClass:function(a,c,d){return b("removeClass",a,q(c,"-remove"),d)}}}])}])})(window,window.angular);
|
|
//# sourceMappingURL=angular-animate.min.js.map
|
|
|
|
// Source: public/lib/angular-bootstrap/ui-bootstrap.js
|
|
/*
|
|
* angular-ui-bootstrap
|
|
* http://angular-ui.github.io/bootstrap/
|
|
|
|
* Version: 0.10.0 - 2014-01-13
|
|
* License: MIT
|
|
*/
|
|
angular.module("ui.bootstrap", ["ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdownToggle","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);
|
|
angular.module('ui.bootstrap.transition', [])
|
|
|
|
/**
|
|
* $transition service provides a consistent interface to trigger CSS 3 transitions and to be informed when they complete.
|
|
* @param {DOMElement} element The DOMElement that will be animated.
|
|
* @param {string|object|function} trigger The thing that will cause the transition to start:
|
|
* - As a string, it represents the css class to be added to the element.
|
|
* - As an object, it represents a hash of style attributes to be applied to the element.
|
|
* - As a function, it represents a function to be called that will cause the transition to occur.
|
|
* @return {Promise} A promise that is resolved when the transition finishes.
|
|
*/
|
|
.factory('$transition', ['$q', '$timeout', '$rootScope', function($q, $timeout, $rootScope) {
|
|
|
|
var $transition = function(element, trigger, options) {
|
|
options = options || {};
|
|
var deferred = $q.defer();
|
|
var endEventName = $transition[options.animation ? "animationEndEventName" : "transitionEndEventName"];
|
|
|
|
var transitionEndHandler = function(event) {
|
|
$rootScope.$apply(function() {
|
|
element.unbind(endEventName, transitionEndHandler);
|
|
deferred.resolve(element);
|
|
});
|
|
};
|
|
|
|
if (endEventName) {
|
|
element.bind(endEventName, transitionEndHandler);
|
|
}
|
|
|
|
// Wrap in a timeout to allow the browser time to update the DOM before the transition is to occur
|
|
$timeout(function() {
|
|
if ( angular.isString(trigger) ) {
|
|
element.addClass(trigger);
|
|
} else if ( angular.isFunction(trigger) ) {
|
|
trigger(element);
|
|
} else if ( angular.isObject(trigger) ) {
|
|
element.css(trigger);
|
|
}
|
|
//If browser does not support transitions, instantly resolve
|
|
if ( !endEventName ) {
|
|
deferred.resolve(element);
|
|
}
|
|
});
|
|
|
|
// Add our custom cancel function to the promise that is returned
|
|
// We can call this if we are about to run a new transition, which we know will prevent this transition from ending,
|
|
// i.e. it will therefore never raise a transitionEnd event for that transition
|
|
deferred.promise.cancel = function() {
|
|
if ( endEventName ) {
|
|
element.unbind(endEventName, transitionEndHandler);
|
|
}
|
|
deferred.reject('Transition cancelled');
|
|
};
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
// Work out the name of the transitionEnd event
|
|
var transElement = document.createElement('trans');
|
|
var transitionEndEventNames = {
|
|
'WebkitTransition': 'webkitTransitionEnd',
|
|
'MozTransition': 'transitionend',
|
|
'OTransition': 'oTransitionEnd',
|
|
'transition': 'transitionend'
|
|
};
|
|
var animationEndEventNames = {
|
|
'WebkitTransition': 'webkitAnimationEnd',
|
|
'MozTransition': 'animationend',
|
|
'OTransition': 'oAnimationEnd',
|
|
'transition': 'animationend'
|
|
};
|
|
function findEndEventName(endEventNames) {
|
|
for (var name in endEventNames){
|
|
if (transElement.style[name] !== undefined) {
|
|
return endEventNames[name];
|
|
}
|
|
}
|
|
}
|
|
$transition.transitionEndEventName = findEndEventName(transitionEndEventNames);
|
|
$transition.animationEndEventName = findEndEventName(animationEndEventNames);
|
|
return $transition;
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.collapse', ['ui.bootstrap.transition'])
|
|
|
|
.directive('collapse', ['$transition', function ($transition, $timeout) {
|
|
|
|
return {
|
|
link: function (scope, element, attrs) {
|
|
|
|
var initialAnimSkip = true;
|
|
var currentTransition;
|
|
|
|
function doTransition(change) {
|
|
var newTransition = $transition(element, change);
|
|
if (currentTransition) {
|
|
currentTransition.cancel();
|
|
}
|
|
currentTransition = newTransition;
|
|
newTransition.then(newTransitionDone, newTransitionDone);
|
|
return newTransition;
|
|
|
|
function newTransitionDone() {
|
|
// Make sure it's this transition, otherwise, leave it alone.
|
|
if (currentTransition === newTransition) {
|
|
currentTransition = undefined;
|
|
}
|
|
}
|
|
}
|
|
|
|
function expand() {
|
|
if (initialAnimSkip) {
|
|
initialAnimSkip = false;
|
|
expandDone();
|
|
} else {
|
|
element.removeClass('collapse').addClass('collapsing');
|
|
doTransition({ height: element[0].scrollHeight + 'px' }).then(expandDone);
|
|
}
|
|
}
|
|
|
|
function expandDone() {
|
|
element.removeClass('collapsing');
|
|
element.addClass('collapse in');
|
|
element.css({height: 'auto'});
|
|
}
|
|
|
|
function collapse() {
|
|
if (initialAnimSkip) {
|
|
initialAnimSkip = false;
|
|
collapseDone();
|
|
element.css({height: 0});
|
|
} else {
|
|
// CSS transitions don't work with height: auto, so we have to manually change the height to a specific value
|
|
element.css({ height: element[0].scrollHeight + 'px' });
|
|
//trigger reflow so a browser realizes that height was updated from auto to a specific value
|
|
var x = element[0].offsetWidth;
|
|
|
|
element.removeClass('collapse in').addClass('collapsing');
|
|
|
|
doTransition({ height: 0 }).then(collapseDone);
|
|
}
|
|
}
|
|
|
|
function collapseDone() {
|
|
element.removeClass('collapsing');
|
|
element.addClass('collapse');
|
|
}
|
|
|
|
scope.$watch(attrs.collapse, function (shouldCollapse) {
|
|
if (shouldCollapse) {
|
|
collapse();
|
|
} else {
|
|
expand();
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
|
|
.constant('accordionConfig', {
|
|
closeOthers: true
|
|
})
|
|
|
|
.controller('AccordionController', ['$scope', '$attrs', 'accordionConfig', function ($scope, $attrs, accordionConfig) {
|
|
|
|
// This array keeps track of the accordion groups
|
|
this.groups = [];
|
|
|
|
// Ensure that all the groups in this accordion are closed, unless close-others explicitly says not to
|
|
this.closeOthers = function(openGroup) {
|
|
var closeOthers = angular.isDefined($attrs.closeOthers) ? $scope.$eval($attrs.closeOthers) : accordionConfig.closeOthers;
|
|
if ( closeOthers ) {
|
|
angular.forEach(this.groups, function (group) {
|
|
if ( group !== openGroup ) {
|
|
group.isOpen = false;
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
// This is called from the accordion-group directive to add itself to the accordion
|
|
this.addGroup = function(groupScope) {
|
|
var that = this;
|
|
this.groups.push(groupScope);
|
|
|
|
groupScope.$on('$destroy', function (event) {
|
|
that.removeGroup(groupScope);
|
|
});
|
|
};
|
|
|
|
// This is called from the accordion-group directive when to remove itself
|
|
this.removeGroup = function(group) {
|
|
var index = this.groups.indexOf(group);
|
|
if ( index !== -1 ) {
|
|
this.groups.splice(this.groups.indexOf(group), 1);
|
|
}
|
|
};
|
|
|
|
}])
|
|
|
|
// The accordion directive simply sets up the directive controller
|
|
// and adds an accordion CSS class to itself element.
|
|
.directive('accordion', function () {
|
|
return {
|
|
restrict:'EA',
|
|
controller:'AccordionController',
|
|
transclude: true,
|
|
replace: false,
|
|
templateUrl: 'template/accordion/accordion.html'
|
|
};
|
|
})
|
|
|
|
// The accordion-group directive indicates a block of html that will expand and collapse in an accordion
|
|
.directive('accordionGroup', ['$parse', function($parse) {
|
|
return {
|
|
require:'^accordion', // We need this directive to be inside an accordion
|
|
restrict:'EA',
|
|
transclude:true, // It transcludes the contents of the directive into the template
|
|
replace: true, // The element containing the directive will be replaced with the template
|
|
templateUrl:'template/accordion/accordion-group.html',
|
|
scope:{ heading:'@' }, // Create an isolated scope and interpolate the heading attribute onto this scope
|
|
controller: function() {
|
|
this.setHeading = function(element) {
|
|
this.heading = element;
|
|
};
|
|
},
|
|
link: function(scope, element, attrs, accordionCtrl) {
|
|
var getIsOpen, setIsOpen;
|
|
|
|
accordionCtrl.addGroup(scope);
|
|
|
|
scope.isOpen = false;
|
|
|
|
if ( attrs.isOpen ) {
|
|
getIsOpen = $parse(attrs.isOpen);
|
|
setIsOpen = getIsOpen.assign;
|
|
|
|
scope.$parent.$watch(getIsOpen, function(value) {
|
|
scope.isOpen = !!value;
|
|
});
|
|
}
|
|
|
|
scope.$watch('isOpen', function(value) {
|
|
if ( value ) {
|
|
accordionCtrl.closeOthers(scope);
|
|
}
|
|
if ( setIsOpen ) {
|
|
setIsOpen(scope.$parent, value);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}])
|
|
|
|
// Use accordion-heading below an accordion-group to provide a heading containing HTML
|
|
// <accordion-group>
|
|
// <accordion-heading>Heading containing HTML - <img src="..."></accordion-heading>
|
|
// </accordion-group>
|
|
.directive('accordionHeading', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
transclude: true, // Grab the contents to be used as the heading
|
|
template: '', // In effect remove this element!
|
|
replace: true,
|
|
require: '^accordionGroup',
|
|
compile: function(element, attr, transclude) {
|
|
return function link(scope, element, attr, accordionGroupCtrl) {
|
|
// Pass the heading to the accordion-group controller
|
|
// so that it can be transcluded into the right place in the template
|
|
// [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
|
|
accordionGroupCtrl.setHeading(transclude(scope, function() {}));
|
|
};
|
|
}
|
|
};
|
|
})
|
|
|
|
// Use in the accordion-group template to indicate where you want the heading to be transcluded
|
|
// You must provide the property on the accordion-group controller that will hold the transcluded element
|
|
// <div class="accordion-group">
|
|
// <div class="accordion-heading" ><a ... accordion-transclude="heading">...</a></div>
|
|
// ...
|
|
// </div>
|
|
.directive('accordionTransclude', function() {
|
|
return {
|
|
require: '^accordionGroup',
|
|
link: function(scope, element, attr, controller) {
|
|
scope.$watch(function() { return controller[attr.accordionTransclude]; }, function(heading) {
|
|
if ( heading ) {
|
|
element.html('');
|
|
element.append(heading);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
});
|
|
|
|
angular.module("ui.bootstrap.alert", [])
|
|
|
|
.controller('AlertController', ['$scope', '$attrs', function ($scope, $attrs) {
|
|
$scope.closeable = 'close' in $attrs;
|
|
}])
|
|
|
|
.directive('alert', function () {
|
|
return {
|
|
restrict:'EA',
|
|
controller:'AlertController',
|
|
templateUrl:'template/alert/alert.html',
|
|
transclude:true,
|
|
replace:true,
|
|
scope: {
|
|
type: '=',
|
|
close: '&'
|
|
}
|
|
};
|
|
});
|
|
|
|
angular.module('ui.bootstrap.bindHtml', [])
|
|
|
|
.directive('bindHtmlUnsafe', function () {
|
|
return function (scope, element, attr) {
|
|
element.addClass('ng-binding').data('$binding', attr.bindHtmlUnsafe);
|
|
scope.$watch(attr.bindHtmlUnsafe, function bindHtmlUnsafeWatchAction(value) {
|
|
element.html(value || '');
|
|
});
|
|
};
|
|
});
|
|
angular.module('ui.bootstrap.buttons', [])
|
|
|
|
.constant('buttonConfig', {
|
|
activeClass: 'active',
|
|
toggleEvent: 'click'
|
|
})
|
|
|
|
.controller('ButtonsController', ['buttonConfig', function(buttonConfig) {
|
|
this.activeClass = buttonConfig.activeClass || 'active';
|
|
this.toggleEvent = buttonConfig.toggleEvent || 'click';
|
|
}])
|
|
|
|
.directive('btnRadio', function () {
|
|
return {
|
|
require: ['btnRadio', 'ngModel'],
|
|
controller: 'ButtonsController',
|
|
link: function (scope, element, attrs, ctrls) {
|
|
var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
|
|
|
//model -> UI
|
|
ngModelCtrl.$render = function () {
|
|
element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, scope.$eval(attrs.btnRadio)));
|
|
};
|
|
|
|
//ui->model
|
|
element.bind(buttonsCtrl.toggleEvent, function () {
|
|
if (!element.hasClass(buttonsCtrl.activeClass)) {
|
|
scope.$apply(function () {
|
|
ngModelCtrl.$setViewValue(scope.$eval(attrs.btnRadio));
|
|
ngModelCtrl.$render();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
};
|
|
})
|
|
|
|
.directive('btnCheckbox', function () {
|
|
return {
|
|
require: ['btnCheckbox', 'ngModel'],
|
|
controller: 'ButtonsController',
|
|
link: function (scope, element, attrs, ctrls) {
|
|
var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
|
|
|
function getTrueValue() {
|
|
return getCheckboxValue(attrs.btnCheckboxTrue, true);
|
|
}
|
|
|
|
function getFalseValue() {
|
|
return getCheckboxValue(attrs.btnCheckboxFalse, false);
|
|
}
|
|
|
|
function getCheckboxValue(attributeValue, defaultValue) {
|
|
var val = scope.$eval(attributeValue);
|
|
return angular.isDefined(val) ? val : defaultValue;
|
|
}
|
|
|
|
//model -> UI
|
|
ngModelCtrl.$render = function () {
|
|
element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, getTrueValue()));
|
|
};
|
|
|
|
//ui->model
|
|
element.bind(buttonsCtrl.toggleEvent, function () {
|
|
scope.$apply(function () {
|
|
ngModelCtrl.$setViewValue(element.hasClass(buttonsCtrl.activeClass) ? getFalseValue() : getTrueValue());
|
|
ngModelCtrl.$render();
|
|
});
|
|
});
|
|
}
|
|
};
|
|
});
|
|
|
|
/**
|
|
* @ngdoc overview
|
|
* @name ui.bootstrap.carousel
|
|
*
|
|
* @description
|
|
* AngularJS version of an image carousel.
|
|
*
|
|
*/
|
|
angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
|
|
.controller('CarouselController', ['$scope', '$timeout', '$transition', '$q', function ($scope, $timeout, $transition, $q) {
|
|
var self = this,
|
|
slides = self.slides = [],
|
|
currentIndex = -1,
|
|
currentTimeout, isPlaying;
|
|
self.currentSlide = null;
|
|
|
|
var destroyed = false;
|
|
/* direction: "prev" or "next" */
|
|
self.select = function(nextSlide, direction) {
|
|
var nextIndex = slides.indexOf(nextSlide);
|
|
//Decide direction if it's not given
|
|
if (direction === undefined) {
|
|
direction = nextIndex > currentIndex ? "next" : "prev";
|
|
}
|
|
if (nextSlide && nextSlide !== self.currentSlide) {
|
|
if ($scope.$currentTransition) {
|
|
$scope.$currentTransition.cancel();
|
|
//Timeout so ng-class in template has time to fix classes for finished slide
|
|
$timeout(goNext);
|
|
} else {
|
|
goNext();
|
|
}
|
|
}
|
|
function goNext() {
|
|
// Scope has been destroyed, stop here.
|
|
if (destroyed) { return; }
|
|
//If we have a slide to transition from and we have a transition type and we're allowed, go
|
|
if (self.currentSlide && angular.isString(direction) && !$scope.noTransition && nextSlide.$element) {
|
|
//We shouldn't do class manip in here, but it's the same weird thing bootstrap does. need to fix sometime
|
|
nextSlide.$element.addClass(direction);
|
|
var reflow = nextSlide.$element[0].offsetWidth; //force reflow
|
|
|
|
//Set all other slides to stop doing their stuff for the new transition
|
|
angular.forEach(slides, function(slide) {
|
|
angular.extend(slide, {direction: '', entering: false, leaving: false, active: false});
|
|
});
|
|
angular.extend(nextSlide, {direction: direction, active: true, entering: true});
|
|
angular.extend(self.currentSlide||{}, {direction: direction, leaving: true});
|
|
|
|
$scope.$currentTransition = $transition(nextSlide.$element, {});
|
|
//We have to create new pointers inside a closure since next & current will change
|
|
(function(next,current) {
|
|
$scope.$currentTransition.then(
|
|
function(){ transitionDone(next, current); },
|
|
function(){ transitionDone(next, current); }
|
|
);
|
|
}(nextSlide, self.currentSlide));
|
|
} else {
|
|
transitionDone(nextSlide, self.currentSlide);
|
|
}
|
|
self.currentSlide = nextSlide;
|
|
currentIndex = nextIndex;
|
|
//every time you change slides, reset the timer
|
|
restartTimer();
|
|
}
|
|
function transitionDone(next, current) {
|
|
angular.extend(next, {direction: '', active: true, leaving: false, entering: false});
|
|
angular.extend(current||{}, {direction: '', active: false, leaving: false, entering: false});
|
|
$scope.$currentTransition = null;
|
|
}
|
|
};
|
|
$scope.$on('$destroy', function () {
|
|
destroyed = true;
|
|
});
|
|
|
|
/* Allow outside people to call indexOf on slides array */
|
|
self.indexOfSlide = function(slide) {
|
|
return slides.indexOf(slide);
|
|
};
|
|
|
|
$scope.next = function() {
|
|
var newIndex = (currentIndex + 1) % slides.length;
|
|
|
|
//Prevent this user-triggered transition from occurring if there is already one in progress
|
|
if (!$scope.$currentTransition) {
|
|
return self.select(slides[newIndex], 'next');
|
|
}
|
|
};
|
|
|
|
$scope.prev = function() {
|
|
var newIndex = currentIndex - 1 < 0 ? slides.length - 1 : currentIndex - 1;
|
|
|
|
//Prevent this user-triggered transition from occurring if there is already one in progress
|
|
if (!$scope.$currentTransition) {
|
|
return self.select(slides[newIndex], 'prev');
|
|
}
|
|
};
|
|
|
|
$scope.select = function(slide) {
|
|
self.select(slide);
|
|
};
|
|
|
|
$scope.isActive = function(slide) {
|
|
return self.currentSlide === slide;
|
|
};
|
|
|
|
$scope.slides = function() {
|
|
return slides;
|
|
};
|
|
|
|
$scope.$watch('interval', restartTimer);
|
|
$scope.$on('$destroy', resetTimer);
|
|
|
|
function restartTimer() {
|
|
resetTimer();
|
|
var interval = +$scope.interval;
|
|
if (!isNaN(interval) && interval>=0) {
|
|
currentTimeout = $timeout(timerFn, interval);
|
|
}
|
|
}
|
|
|
|
function resetTimer() {
|
|
if (currentTimeout) {
|
|
$timeout.cancel(currentTimeout);
|
|
currentTimeout = null;
|
|
}
|
|
}
|
|
|
|
function timerFn() {
|
|
if (isPlaying) {
|
|
$scope.next();
|
|
restartTimer();
|
|
} else {
|
|
$scope.pause();
|
|
}
|
|
}
|
|
|
|
$scope.play = function() {
|
|
if (!isPlaying) {
|
|
isPlaying = true;
|
|
restartTimer();
|
|
}
|
|
};
|
|
$scope.pause = function() {
|
|
if (!$scope.noPause) {
|
|
isPlaying = false;
|
|
resetTimer();
|
|
}
|
|
};
|
|
|
|
self.addSlide = function(slide, element) {
|
|
slide.$element = element;
|
|
slides.push(slide);
|
|
//if this is the first slide or the slide is set to active, select it
|
|
if(slides.length === 1 || slide.active) {
|
|
self.select(slides[slides.length-1]);
|
|
if (slides.length == 1) {
|
|
$scope.play();
|
|
}
|
|
} else {
|
|
slide.active = false;
|
|
}
|
|
};
|
|
|
|
self.removeSlide = function(slide) {
|
|
//get the index of the slide inside the carousel
|
|
var index = slides.indexOf(slide);
|
|
slides.splice(index, 1);
|
|
if (slides.length > 0 && slide.active) {
|
|
if (index >= slides.length) {
|
|
self.select(slides[index-1]);
|
|
} else {
|
|
self.select(slides[index]);
|
|
}
|
|
} else if (currentIndex > index) {
|
|
currentIndex--;
|
|
}
|
|
};
|
|
|
|
}])
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name ui.bootstrap.carousel.directive:carousel
|
|
* @restrict EA
|
|
*
|
|
* @description
|
|
* Carousel is the outer container for a set of image 'slides' to showcase.
|
|
*
|
|
* @param {number=} interval The time, in milliseconds, that it will take the carousel to go to the next slide.
|
|
* @param {boolean=} noTransition Whether to disable transitions on the carousel.
|
|
* @param {boolean=} noPause Whether to disable pausing on the carousel (by default, the carousel interval pauses on hover).
|
|
*
|
|
* @example
|
|
<example module="ui.bootstrap">
|
|
<file name="index.html">
|
|
<carousel>
|
|
<slide>
|
|
<img src="http://placekitten.com/150/150" style="margin:auto;">
|
|
<div class="carousel-caption">
|
|
<p>Beautiful!</p>
|
|
</div>
|
|
</slide>
|
|
<slide>
|
|
<img src="http://placekitten.com/100/150" style="margin:auto;">
|
|
<div class="carousel-caption">
|
|
<p>D'aww!</p>
|
|
</div>
|
|
</slide>
|
|
</carousel>
|
|
</file>
|
|
<file name="demo.css">
|
|
.carousel-indicators {
|
|
top: auto;
|
|
bottom: 15px;
|
|
}
|
|
</file>
|
|
</example>
|
|
*/
|
|
.directive('carousel', [function() {
|
|
return {
|
|
restrict: 'EA',
|
|
transclude: true,
|
|
replace: true,
|
|
controller: 'CarouselController',
|
|
require: 'carousel',
|
|
templateUrl: 'template/carousel/carousel.html',
|
|
scope: {
|
|
interval: '=',
|
|
noTransition: '=',
|
|
noPause: '='
|
|
}
|
|
};
|
|
}])
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name ui.bootstrap.carousel.directive:slide
|
|
* @restrict EA
|
|
*
|
|
* @description
|
|
* Creates a slide inside a {@link ui.bootstrap.carousel.directive:carousel carousel}. Must be placed as a child of a carousel element.
|
|
*
|
|
* @param {boolean=} active Model binding, whether or not this slide is currently active.
|
|
*
|
|
* @example
|
|
<example module="ui.bootstrap">
|
|
<file name="index.html">
|
|
<div ng-controller="CarouselDemoCtrl">
|
|
<carousel>
|
|
<slide ng-repeat="slide in slides" active="slide.active">
|
|
<img ng-src="{{slide.image}}" style="margin:auto;">
|
|
<div class="carousel-caption">
|
|
<h4>Slide {{$index}}</h4>
|
|
<p>{{slide.text}}</p>
|
|
</div>
|
|
</slide>
|
|
</carousel>
|
|
<div class="row-fluid">
|
|
<div class="span6">
|
|
<ul>
|
|
<li ng-repeat="slide in slides">
|
|
<button class="btn btn-mini" ng-class="{'btn-info': !slide.active, 'btn-success': slide.active}" ng-disabled="slide.active" ng-click="slide.active = true">select</button>
|
|
{{$index}}: {{slide.text}}
|
|
</li>
|
|
</ul>
|
|
<a class="btn" ng-click="addSlide()">Add Slide</a>
|
|
</div>
|
|
<div class="span6">
|
|
Interval, in milliseconds: <input type="number" ng-model="myInterval">
|
|
<br />Enter a negative number to stop the interval.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</file>
|
|
<file name="script.js">
|
|
function CarouselDemoCtrl($scope) {
|
|
$scope.myInterval = 5000;
|
|
var slides = $scope.slides = [];
|
|
$scope.addSlide = function() {
|
|
var newWidth = 200 + ((slides.length + (25 * slides.length)) % 150);
|
|
slides.push({
|
|
image: 'http://placekitten.com/' + newWidth + '/200',
|
|
text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' '
|
|
['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
|
|
});
|
|
};
|
|
for (var i=0; i<4; i++) $scope.addSlide();
|
|
}
|
|
</file>
|
|
<file name="demo.css">
|
|
.carousel-indicators {
|
|
top: auto;
|
|
bottom: 15px;
|
|
}
|
|
</file>
|
|
</example>
|
|
*/
|
|
|
|
.directive('slide', ['$parse', function($parse) {
|
|
return {
|
|
require: '^carousel',
|
|
restrict: 'EA',
|
|
transclude: true,
|
|
replace: true,
|
|
templateUrl: 'template/carousel/slide.html',
|
|
scope: {
|
|
},
|
|
link: function (scope, element, attrs, carouselCtrl) {
|
|
//Set up optional 'active' = binding
|
|
if (attrs.active) {
|
|
var getActive = $parse(attrs.active);
|
|
var setActive = getActive.assign;
|
|
var lastValue = scope.active = getActive(scope.$parent);
|
|
scope.$watch(function parentActiveWatch() {
|
|
var parentActive = getActive(scope.$parent);
|
|
|
|
if (parentActive !== scope.active) {
|
|
// we are out of sync and need to copy
|
|
if (parentActive !== lastValue) {
|
|
// parent changed and it has precedence
|
|
lastValue = scope.active = parentActive;
|
|
} else {
|
|
// if the parent can be assigned then do so
|
|
setActive(scope.$parent, parentActive = lastValue = scope.active);
|
|
}
|
|
}
|
|
return parentActive;
|
|
});
|
|
}
|
|
|
|
carouselCtrl.addSlide(scope, element);
|
|
//when the scope is destroyed then remove the slide from the current slides array
|
|
scope.$on('$destroy', function() {
|
|
carouselCtrl.removeSlide(scope);
|
|
});
|
|
|
|
scope.$watch('active', function(active) {
|
|
if (active) {
|
|
carouselCtrl.select(scope);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.position', [])
|
|
|
|
/**
|
|
* A set of utility methods that can be use to retrieve position of DOM elements.
|
|
* It is meant to be used where we need to absolute-position DOM elements in
|
|
* relation to other, existing elements (this is the case for tooltips, popovers,
|
|
* typeahead suggestions etc.).
|
|
*/
|
|
.factory('$position', ['$document', '$window', function ($document, $window) {
|
|
|
|
function getStyle(el, cssprop) {
|
|
if (el.currentStyle) { //IE
|
|
return el.currentStyle[cssprop];
|
|
} else if ($window.getComputedStyle) {
|
|
return $window.getComputedStyle(el)[cssprop];
|
|
}
|
|
// finally try and get inline style
|
|
return el.style[cssprop];
|
|
}
|
|
|
|
/**
|
|
* Checks if a given element is statically positioned
|
|
* @param element - raw DOM element
|
|
*/
|
|
function isStaticPositioned(element) {
|
|
return (getStyle(element, "position") || 'static' ) === 'static';
|
|
}
|
|
|
|
/**
|
|
* returns the closest, non-statically positioned parentOffset of a given element
|
|
* @param element
|
|
*/
|
|
var parentOffsetEl = function (element) {
|
|
var docDomEl = $document[0];
|
|
var offsetParent = element.offsetParent || docDomEl;
|
|
while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent) ) {
|
|
offsetParent = offsetParent.offsetParent;
|
|
}
|
|
return offsetParent || docDomEl;
|
|
};
|
|
|
|
return {
|
|
/**
|
|
* Provides read-only equivalent of jQuery's position function:
|
|
* http://api.jquery.com/position/
|
|
*/
|
|
position: function (element) {
|
|
var elBCR = this.offset(element);
|
|
var offsetParentBCR = { top: 0, left: 0 };
|
|
var offsetParentEl = parentOffsetEl(element[0]);
|
|
if (offsetParentEl != $document[0]) {
|
|
offsetParentBCR = this.offset(angular.element(offsetParentEl));
|
|
offsetParentBCR.top += offsetParentEl.clientTop - offsetParentEl.scrollTop;
|
|
offsetParentBCR.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft;
|
|
}
|
|
|
|
var boundingClientRect = element[0].getBoundingClientRect();
|
|
return {
|
|
width: boundingClientRect.width || element.prop('offsetWidth'),
|
|
height: boundingClientRect.height || element.prop('offsetHeight'),
|
|
top: elBCR.top - offsetParentBCR.top,
|
|
left: elBCR.left - offsetParentBCR.left
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Provides read-only equivalent of jQuery's offset function:
|
|
* http://api.jquery.com/offset/
|
|
*/
|
|
offset: function (element) {
|
|
var boundingClientRect = element[0].getBoundingClientRect();
|
|
return {
|
|
width: boundingClientRect.width || element.prop('offsetWidth'),
|
|
height: boundingClientRect.height || element.prop('offsetHeight'),
|
|
top: boundingClientRect.top + ($window.pageYOffset || $document[0].body.scrollTop || $document[0].documentElement.scrollTop),
|
|
left: boundingClientRect.left + ($window.pageXOffset || $document[0].body.scrollLeft || $document[0].documentElement.scrollLeft)
|
|
};
|
|
}
|
|
};
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.position'])
|
|
|
|
.constant('datepickerConfig', {
|
|
dayFormat: 'dd',
|
|
monthFormat: 'MMMM',
|
|
yearFormat: 'yyyy',
|
|
dayHeaderFormat: 'EEE',
|
|
dayTitleFormat: 'MMMM yyyy',
|
|
monthTitleFormat: 'yyyy',
|
|
showWeeks: true,
|
|
startingDay: 0,
|
|
yearRange: 20,
|
|
minDate: null,
|
|
maxDate: null
|
|
})
|
|
|
|
.controller('DatepickerController', ['$scope', '$attrs', 'dateFilter', 'datepickerConfig', function($scope, $attrs, dateFilter, dtConfig) {
|
|
var format = {
|
|
day: getValue($attrs.dayFormat, dtConfig.dayFormat),
|
|
month: getValue($attrs.monthFormat, dtConfig.monthFormat),
|
|
year: getValue($attrs.yearFormat, dtConfig.yearFormat),
|
|
dayHeader: getValue($attrs.dayHeaderFormat, dtConfig.dayHeaderFormat),
|
|
dayTitle: getValue($attrs.dayTitleFormat, dtConfig.dayTitleFormat),
|
|
monthTitle: getValue($attrs.monthTitleFormat, dtConfig.monthTitleFormat)
|
|
},
|
|
startingDay = getValue($attrs.startingDay, dtConfig.startingDay),
|
|
yearRange = getValue($attrs.yearRange, dtConfig.yearRange);
|
|
|
|
this.minDate = dtConfig.minDate ? new Date(dtConfig.minDate) : null;
|
|
this.maxDate = dtConfig.maxDate ? new Date(dtConfig.maxDate) : null;
|
|
|
|
function getValue(value, defaultValue) {
|
|
return angular.isDefined(value) ? $scope.$parent.$eval(value) : defaultValue;
|
|
}
|
|
|
|
function getDaysInMonth( year, month ) {
|
|
return new Date(year, month, 0).getDate();
|
|
}
|
|
|
|
function getDates(startDate, n) {
|
|
var dates = new Array(n);
|
|
var current = startDate, i = 0;
|
|
while (i < n) {
|
|
dates[i++] = new Date(current);
|
|
current.setDate( current.getDate() + 1 );
|
|
}
|
|
return dates;
|
|
}
|
|
|
|
function makeDate(date, format, isSelected, isSecondary) {
|
|
return { date: date, label: dateFilter(date, format), selected: !!isSelected, secondary: !!isSecondary };
|
|
}
|
|
|
|
this.modes = [
|
|
{
|
|
name: 'day',
|
|
getVisibleDates: function(date, selected) {
|
|
var year = date.getFullYear(), month = date.getMonth(), firstDayOfMonth = new Date(year, month, 1);
|
|
var difference = startingDay - firstDayOfMonth.getDay(),
|
|
numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : - difference,
|
|
firstDate = new Date(firstDayOfMonth), numDates = 0;
|
|
|
|
if ( numDisplayedFromPreviousMonth > 0 ) {
|
|
firstDate.setDate( - numDisplayedFromPreviousMonth + 1 );
|
|
numDates += numDisplayedFromPreviousMonth; // Previous
|
|
}
|
|
numDates += getDaysInMonth(year, month + 1); // Current
|
|
numDates += (7 - numDates % 7) % 7; // Next
|
|
|
|
var days = getDates(firstDate, numDates), labels = new Array(7);
|
|
for (var i = 0; i < numDates; i ++) {
|
|
var dt = new Date(days[i]);
|
|
days[i] = makeDate(dt, format.day, (selected && selected.getDate() === dt.getDate() && selected.getMonth() === dt.getMonth() && selected.getFullYear() === dt.getFullYear()), dt.getMonth() !== month);
|
|
}
|
|
for (var j = 0; j < 7; j++) {
|
|
labels[j] = dateFilter(days[j].date, format.dayHeader);
|
|
}
|
|
return { objects: days, title: dateFilter(date, format.dayTitle), labels: labels };
|
|
},
|
|
compare: function(date1, date2) {
|
|
return (new Date( date1.getFullYear(), date1.getMonth(), date1.getDate() ) - new Date( date2.getFullYear(), date2.getMonth(), date2.getDate() ) );
|
|
},
|
|
split: 7,
|
|
step: { months: 1 }
|
|
},
|
|
{
|
|
name: 'month',
|
|
getVisibleDates: function(date, selected) {
|
|
var months = new Array(12), year = date.getFullYear();
|
|
for ( var i = 0; i < 12; i++ ) {
|
|
var dt = new Date(year, i, 1);
|
|
months[i] = makeDate(dt, format.month, (selected && selected.getMonth() === i && selected.getFullYear() === year));
|
|
}
|
|
return { objects: months, title: dateFilter(date, format.monthTitle) };
|
|
},
|
|
compare: function(date1, date2) {
|
|
return new Date( date1.getFullYear(), date1.getMonth() ) - new Date( date2.getFullYear(), date2.getMonth() );
|
|
},
|
|
split: 3,
|
|
step: { years: 1 }
|
|
},
|
|
{
|
|
name: 'year',
|
|
getVisibleDates: function(date, selected) {
|
|
var years = new Array(yearRange), year = date.getFullYear(), startYear = parseInt((year - 1) / yearRange, 10) * yearRange + 1;
|
|
for ( var i = 0; i < yearRange; i++ ) {
|
|
var dt = new Date(startYear + i, 0, 1);
|
|
years[i] = makeDate(dt, format.year, (selected && selected.getFullYear() === dt.getFullYear()));
|
|
}
|
|
return { objects: years, title: [years[0].label, years[yearRange - 1].label].join(' - ') };
|
|
},
|
|
compare: function(date1, date2) {
|
|
return date1.getFullYear() - date2.getFullYear();
|
|
},
|
|
split: 5,
|
|
step: { years: yearRange }
|
|
}
|
|
];
|
|
|
|
this.isDisabled = function(date, mode) {
|
|
var currentMode = this.modes[mode || 0];
|
|
return ((this.minDate && currentMode.compare(date, this.minDate) < 0) || (this.maxDate && currentMode.compare(date, this.maxDate) > 0) || ($scope.dateDisabled && $scope.dateDisabled({date: date, mode: currentMode.name})));
|
|
};
|
|
}])
|
|
|
|
.directive( 'datepicker', ['dateFilter', '$parse', 'datepickerConfig', '$log', function (dateFilter, $parse, datepickerConfig, $log) {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
templateUrl: 'template/datepicker/datepicker.html',
|
|
scope: {
|
|
dateDisabled: '&'
|
|
},
|
|
require: ['datepicker', '?^ngModel'],
|
|
controller: 'DatepickerController',
|
|
link: function(scope, element, attrs, ctrls) {
|
|
var datepickerCtrl = ctrls[0], ngModel = ctrls[1];
|
|
|
|
if (!ngModel) {
|
|
return; // do nothing if no ng-model
|
|
}
|
|
|
|
// Configuration parameters
|
|
var mode = 0, selected = new Date(), showWeeks = datepickerConfig.showWeeks;
|
|
|
|
if (attrs.showWeeks) {
|
|
scope.$parent.$watch($parse(attrs.showWeeks), function(value) {
|
|
showWeeks = !! value;
|
|
updateShowWeekNumbers();
|
|
});
|
|
} else {
|
|
updateShowWeekNumbers();
|
|
}
|
|
|
|
if (attrs.min) {
|
|
scope.$parent.$watch($parse(attrs.min), function(value) {
|
|
datepickerCtrl.minDate = value ? new Date(value) : null;
|
|
refill();
|
|
});
|
|
}
|
|
if (attrs.max) {
|
|
scope.$parent.$watch($parse(attrs.max), function(value) {
|
|
datepickerCtrl.maxDate = value ? new Date(value) : null;
|
|
refill();
|
|
});
|
|
}
|
|
|
|
function updateShowWeekNumbers() {
|
|
scope.showWeekNumbers = mode === 0 && showWeeks;
|
|
}
|
|
|
|
// Split array into smaller arrays
|
|
function split(arr, size) {
|
|
var arrays = [];
|
|
while (arr.length > 0) {
|
|
arrays.push(arr.splice(0, size));
|
|
}
|
|
return arrays;
|
|
}
|
|
|
|
function refill( updateSelected ) {
|
|
var date = null, valid = true;
|
|
|
|
if ( ngModel.$modelValue ) {
|
|
date = new Date( ngModel.$modelValue );
|
|
|
|
if ( isNaN(date) ) {
|
|
valid = false;
|
|
$log.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
|
|
} else if ( updateSelected ) {
|
|
selected = date;
|
|
}
|
|
}
|
|
ngModel.$setValidity('date', valid);
|
|
|
|
var currentMode = datepickerCtrl.modes[mode], data = currentMode.getVisibleDates(selected, date);
|
|
angular.forEach(data.objects, function(obj) {
|
|
obj.disabled = datepickerCtrl.isDisabled(obj.date, mode);
|
|
});
|
|
|
|
ngModel.$setValidity('date-disabled', (!date || !datepickerCtrl.isDisabled(date)));
|
|
|
|
scope.rows = split(data.objects, currentMode.split);
|
|
scope.labels = data.labels || [];
|
|
scope.title = data.title;
|
|
}
|
|
|
|
function setMode(value) {
|
|
mode = value;
|
|
updateShowWeekNumbers();
|
|
refill();
|
|
}
|
|
|
|
ngModel.$render = function() {
|
|
refill( true );
|
|
};
|
|
|
|
scope.select = function( date ) {
|
|
if ( mode === 0 ) {
|
|
var dt = ngModel.$modelValue ? new Date( ngModel.$modelValue ) : new Date(0, 0, 0, 0, 0, 0, 0);
|
|
dt.setFullYear( date.getFullYear(), date.getMonth(), date.getDate() );
|
|
ngModel.$setViewValue( dt );
|
|
refill( true );
|
|
} else {
|
|
selected = date;
|
|
setMode( mode - 1 );
|
|
}
|
|
};
|
|
scope.move = function(direction) {
|
|
var step = datepickerCtrl.modes[mode].step;
|
|
selected.setMonth( selected.getMonth() + direction * (step.months || 0) );
|
|
selected.setFullYear( selected.getFullYear() + direction * (step.years || 0) );
|
|
refill();
|
|
};
|
|
scope.toggleMode = function() {
|
|
setMode( (mode + 1) % datepickerCtrl.modes.length );
|
|
};
|
|
scope.getWeekNumber = function(row) {
|
|
return ( mode === 0 && scope.showWeekNumbers && row.length === 7 ) ? getISO8601WeekNumber(row[0].date) : null;
|
|
};
|
|
|
|
function getISO8601WeekNumber(date) {
|
|
var checkDate = new Date(date);
|
|
checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); // Thursday
|
|
var time = checkDate.getTime();
|
|
checkDate.setMonth(0); // Compare with Jan 1
|
|
checkDate.setDate(1);
|
|
return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
|
|
}
|
|
}
|
|
};
|
|
}])
|
|
|
|
.constant('datepickerPopupConfig', {
|
|
dateFormat: 'yyyy-MM-dd',
|
|
currentText: 'Today',
|
|
toggleWeeksText: 'Weeks',
|
|
clearText: 'Clear',
|
|
closeText: 'Done',
|
|
closeOnDateSelection: true,
|
|
appendToBody: false,
|
|
showButtonBar: true
|
|
})
|
|
|
|
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'datepickerPopupConfig', 'datepickerConfig',
|
|
function ($compile, $parse, $document, $position, dateFilter, datepickerPopupConfig, datepickerConfig) {
|
|
return {
|
|
restrict: 'EA',
|
|
require: 'ngModel',
|
|
link: function(originalScope, element, attrs, ngModel) {
|
|
var scope = originalScope.$new(), // create a child scope so we are not polluting original one
|
|
dateFormat,
|
|
closeOnDateSelection = angular.isDefined(attrs.closeOnDateSelection) ? originalScope.$eval(attrs.closeOnDateSelection) : datepickerPopupConfig.closeOnDateSelection,
|
|
appendToBody = angular.isDefined(attrs.datepickerAppendToBody) ? originalScope.$eval(attrs.datepickerAppendToBody) : datepickerPopupConfig.appendToBody;
|
|
|
|
attrs.$observe('datepickerPopup', function(value) {
|
|
dateFormat = value || datepickerPopupConfig.dateFormat;
|
|
ngModel.$render();
|
|
});
|
|
|
|
scope.showButtonBar = angular.isDefined(attrs.showButtonBar) ? originalScope.$eval(attrs.showButtonBar) : datepickerPopupConfig.showButtonBar;
|
|
|
|
originalScope.$on('$destroy', function() {
|
|
$popup.remove();
|
|
scope.$destroy();
|
|
});
|
|
|
|
attrs.$observe('currentText', function(text) {
|
|
scope.currentText = angular.isDefined(text) ? text : datepickerPopupConfig.currentText;
|
|
});
|
|
attrs.$observe('toggleWeeksText', function(text) {
|
|
scope.toggleWeeksText = angular.isDefined(text) ? text : datepickerPopupConfig.toggleWeeksText;
|
|
});
|
|
attrs.$observe('clearText', function(text) {
|
|
scope.clearText = angular.isDefined(text) ? text : datepickerPopupConfig.clearText;
|
|
});
|
|
attrs.$observe('closeText', function(text) {
|
|
scope.closeText = angular.isDefined(text) ? text : datepickerPopupConfig.closeText;
|
|
});
|
|
|
|
var getIsOpen, setIsOpen;
|
|
if ( attrs.isOpen ) {
|
|
getIsOpen = $parse(attrs.isOpen);
|
|
setIsOpen = getIsOpen.assign;
|
|
|
|
originalScope.$watch(getIsOpen, function updateOpen(value) {
|
|
scope.isOpen = !! value;
|
|
});
|
|
}
|
|
scope.isOpen = getIsOpen ? getIsOpen(originalScope) : false; // Initial state
|
|
|
|
function setOpen( value ) {
|
|
if (setIsOpen) {
|
|
setIsOpen(originalScope, !!value);
|
|
} else {
|
|
scope.isOpen = !!value;
|
|
}
|
|
}
|
|
|
|
var documentClickBind = function(event) {
|
|
if (scope.isOpen && event.target !== element[0]) {
|
|
scope.$apply(function() {
|
|
setOpen(false);
|
|
});
|
|
}
|
|
};
|
|
|
|
var elementFocusBind = function() {
|
|
scope.$apply(function() {
|
|
setOpen( true );
|
|
});
|
|
};
|
|
|
|
// popup element used to display calendar
|
|
var popupEl = angular.element('<div datepicker-popup-wrap><div datepicker></div></div>');
|
|
popupEl.attr({
|
|
'ng-model': 'date',
|
|
'ng-change': 'dateSelection()'
|
|
});
|
|
var datepickerEl = angular.element(popupEl.children()[0]),
|
|
datepickerOptions = {};
|
|
if (attrs.datepickerOptions) {
|
|
datepickerOptions = originalScope.$eval(attrs.datepickerOptions);
|
|
datepickerEl.attr(angular.extend({}, datepickerOptions));
|
|
}
|
|
|
|
// TODO: reverse from dateFilter string to Date object
|
|
function parseDate(viewValue) {
|
|
if (!viewValue) {
|
|
ngModel.$setValidity('date', true);
|
|
return null;
|
|
} else if (angular.isDate(viewValue)) {
|
|
ngModel.$setValidity('date', true);
|
|
return viewValue;
|
|
} else if (angular.isString(viewValue)) {
|
|
var date = new Date(viewValue);
|
|
if (isNaN(date)) {
|
|
ngModel.$setValidity('date', false);
|
|
return undefined;
|
|
} else {
|
|
ngModel.$setValidity('date', true);
|
|
return date;
|
|
}
|
|
} else {
|
|
ngModel.$setValidity('date', false);
|
|
return undefined;
|
|
}
|
|
}
|
|
ngModel.$parsers.unshift(parseDate);
|
|
|
|
// Inner change
|
|
scope.dateSelection = function(dt) {
|
|
if (angular.isDefined(dt)) {
|
|
scope.date = dt;
|
|
}
|
|
ngModel.$setViewValue(scope.date);
|
|
ngModel.$render();
|
|
|
|
if (closeOnDateSelection) {
|
|
setOpen( false );
|
|
}
|
|
};
|
|
|
|
element.bind('input change keyup', function() {
|
|
scope.$apply(function() {
|
|
scope.date = ngModel.$modelValue;
|
|
});
|
|
});
|
|
|
|
// Outter change
|
|
ngModel.$render = function() {
|
|
var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
|
|
element.val(date);
|
|
scope.date = ngModel.$modelValue;
|
|
};
|
|
|
|
function addWatchableAttribute(attribute, scopeProperty, datepickerAttribute) {
|
|
if (attribute) {
|
|
originalScope.$watch($parse(attribute), function(value){
|
|
scope[scopeProperty] = value;
|
|
});
|
|
datepickerEl.attr(datepickerAttribute || scopeProperty, scopeProperty);
|
|
}
|
|
}
|
|
addWatchableAttribute(attrs.min, 'min');
|
|
addWatchableAttribute(attrs.max, 'max');
|
|
if (attrs.showWeeks) {
|
|
addWatchableAttribute(attrs.showWeeks, 'showWeeks', 'show-weeks');
|
|
} else {
|
|
scope.showWeeks = 'show-weeks' in datepickerOptions ? datepickerOptions['show-weeks'] : datepickerConfig.showWeeks;
|
|
datepickerEl.attr('show-weeks', 'showWeeks');
|
|
}
|
|
if (attrs.dateDisabled) {
|
|
datepickerEl.attr('date-disabled', attrs.dateDisabled);
|
|
}
|
|
|
|
function updatePosition() {
|
|
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
|
|
scope.position.top = scope.position.top + element.prop('offsetHeight');
|
|
}
|
|
|
|
var documentBindingInitialized = false, elementFocusInitialized = false;
|
|
scope.$watch('isOpen', function(value) {
|
|
if (value) {
|
|
updatePosition();
|
|
$document.bind('click', documentClickBind);
|
|
if(elementFocusInitialized) {
|
|
element.unbind('focus', elementFocusBind);
|
|
}
|
|
element[0].focus();
|
|
documentBindingInitialized = true;
|
|
} else {
|
|
if(documentBindingInitialized) {
|
|
$document.unbind('click', documentClickBind);
|
|
}
|
|
element.bind('focus', elementFocusBind);
|
|
elementFocusInitialized = true;
|
|
}
|
|
|
|
if ( setIsOpen ) {
|
|
setIsOpen(originalScope, value);
|
|
}
|
|
});
|
|
|
|
scope.today = function() {
|
|
scope.dateSelection(new Date());
|
|
};
|
|
scope.clear = function() {
|
|
scope.dateSelection(null);
|
|
};
|
|
|
|
var $popup = $compile(popupEl)(scope);
|
|
if ( appendToBody ) {
|
|
$document.find('body').append($popup);
|
|
} else {
|
|
element.after($popup);
|
|
}
|
|
}
|
|
};
|
|
}])
|
|
|
|
.directive('datepickerPopupWrap', function() {
|
|
return {
|
|
restrict:'EA',
|
|
replace: true,
|
|
transclude: true,
|
|
templateUrl: 'template/datepicker/popup.html',
|
|
link:function (scope, element, attrs) {
|
|
element.bind('click', function(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
});
|
|
}
|
|
};
|
|
});
|
|
|
|
/*
|
|
* dropdownToggle - Provides dropdown menu functionality in place of bootstrap js
|
|
* @restrict class or attribute
|
|
* @example:
|
|
<li class="dropdown">
|
|
<a class="dropdown-toggle">My Dropdown Menu</a>
|
|
<ul class="dropdown-menu">
|
|
<li ng-repeat="choice in dropChoices">
|
|
<a ng-href="{{choice.href}}">{{choice.text}}</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
*/
|
|
|
|
angular.module('ui.bootstrap.dropdownToggle', []).directive('dropdownToggle', ['$document', '$location', function ($document, $location) {
|
|
var openElement = null,
|
|
closeMenu = angular.noop;
|
|
return {
|
|
restrict: 'CA',
|
|
link: function(scope, element, attrs) {
|
|
scope.$watch('$location.path', function() { closeMenu(); });
|
|
element.parent().bind('click', function() { closeMenu(); });
|
|
element.bind('click', function (event) {
|
|
|
|
var elementWasOpen = (element === openElement);
|
|
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
if (!!openElement) {
|
|
closeMenu();
|
|
}
|
|
|
|
if (!elementWasOpen && !element.hasClass('disabled') && !element.prop('disabled')) {
|
|
element.parent().addClass('open');
|
|
openElement = element;
|
|
closeMenu = function (event) {
|
|
if (event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
$document.unbind('click', closeMenu);
|
|
element.parent().removeClass('open');
|
|
closeMenu = angular.noop;
|
|
openElement = null;
|
|
};
|
|
$document.bind('click', closeMenu);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
|
|
|
/**
|
|
* A helper, internal data structure that acts as a map but also allows getting / removing
|
|
* elements in the LIFO order
|
|
*/
|
|
.factory('$$stackedMap', function () {
|
|
return {
|
|
createNew: function () {
|
|
var stack = [];
|
|
|
|
return {
|
|
add: function (key, value) {
|
|
stack.push({
|
|
key: key,
|
|
value: value
|
|
});
|
|
},
|
|
get: function (key) {
|
|
for (var i = 0; i < stack.length; i++) {
|
|
if (key == stack[i].key) {
|
|
return stack[i];
|
|
}
|
|
}
|
|
},
|
|
keys: function() {
|
|
var keys = [];
|
|
for (var i = 0; i < stack.length; i++) {
|
|
keys.push(stack[i].key);
|
|
}
|
|
return keys;
|
|
},
|
|
top: function () {
|
|
return stack[stack.length - 1];
|
|
},
|
|
remove: function (key) {
|
|
var idx = -1;
|
|
for (var i = 0; i < stack.length; i++) {
|
|
if (key == stack[i].key) {
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
return stack.splice(idx, 1)[0];
|
|
},
|
|
removeTop: function () {
|
|
return stack.splice(stack.length - 1, 1)[0];
|
|
},
|
|
length: function () {
|
|
return stack.length;
|
|
}
|
|
};
|
|
}
|
|
};
|
|
})
|
|
|
|
/**
|
|
* A helper directive for the $modal service. It creates a backdrop element.
|
|
*/
|
|
.directive('modalBackdrop', ['$timeout', function ($timeout) {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
templateUrl: 'template/modal/backdrop.html',
|
|
link: function (scope) {
|
|
|
|
scope.animate = false;
|
|
|
|
//trigger CSS transitions
|
|
$timeout(function () {
|
|
scope.animate = true;
|
|
});
|
|
}
|
|
};
|
|
}])
|
|
|
|
.directive('modalWindow', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
|
|
return {
|
|
restrict: 'EA',
|
|
scope: {
|
|
index: '@',
|
|
animate: '='
|
|
},
|
|
replace: true,
|
|
transclude: true,
|
|
templateUrl: 'template/modal/window.html',
|
|
link: function (scope, element, attrs) {
|
|
scope.windowClass = attrs.windowClass || '';
|
|
|
|
$timeout(function () {
|
|
// trigger CSS transitions
|
|
scope.animate = true;
|
|
// focus a freshly-opened modal
|
|
element[0].focus();
|
|
});
|
|
|
|
scope.close = function (evt) {
|
|
var modal = $modalStack.getTop();
|
|
if (modal && modal.value.backdrop && modal.value.backdrop != 'static' && (evt.target === evt.currentTarget)) {
|
|
evt.preventDefault();
|
|
evt.stopPropagation();
|
|
$modalStack.dismiss(modal.key, 'backdrop click');
|
|
}
|
|
};
|
|
}
|
|
};
|
|
}])
|
|
|
|
.factory('$modalStack', ['$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap',
|
|
function ($transition, $timeout, $document, $compile, $rootScope, $$stackedMap) {
|
|
|
|
var OPENED_MODAL_CLASS = 'modal-open';
|
|
|
|
var backdropDomEl, backdropScope;
|
|
var openedWindows = $$stackedMap.createNew();
|
|
var $modalStack = {};
|
|
|
|
function backdropIndex() {
|
|
var topBackdropIndex = -1;
|
|
var opened = openedWindows.keys();
|
|
for (var i = 0; i < opened.length; i++) {
|
|
if (openedWindows.get(opened[i]).value.backdrop) {
|
|
topBackdropIndex = i;
|
|
}
|
|
}
|
|
return topBackdropIndex;
|
|
}
|
|
|
|
$rootScope.$watch(backdropIndex, function(newBackdropIndex){
|
|
if (backdropScope) {
|
|
backdropScope.index = newBackdropIndex;
|
|
}
|
|
});
|
|
|
|
function removeModalWindow(modalInstance) {
|
|
|
|
var body = $document.find('body').eq(0);
|
|
var modalWindow = openedWindows.get(modalInstance).value;
|
|
|
|
//clean up the stack
|
|
openedWindows.remove(modalInstance);
|
|
|
|
//remove window DOM element
|
|
removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, 300, checkRemoveBackdrop);
|
|
body.toggleClass(OPENED_MODAL_CLASS, openedWindows.length() > 0);
|
|
}
|
|
|
|
function checkRemoveBackdrop() {
|
|
//remove backdrop if no longer needed
|
|
if (backdropDomEl && backdropIndex() == -1) {
|
|
var backdropScopeRef = backdropScope;
|
|
removeAfterAnimate(backdropDomEl, backdropScope, 150, function () {
|
|
backdropScopeRef.$destroy();
|
|
backdropScopeRef = null;
|
|
});
|
|
backdropDomEl = undefined;
|
|
backdropScope = undefined;
|
|
}
|
|
}
|
|
|
|
function removeAfterAnimate(domEl, scope, emulateTime, done) {
|
|
// Closing animation
|
|
scope.animate = false;
|
|
|
|
var transitionEndEventName = $transition.transitionEndEventName;
|
|
if (transitionEndEventName) {
|
|
// transition out
|
|
var timeout = $timeout(afterAnimating, emulateTime);
|
|
|
|
domEl.bind(transitionEndEventName, function () {
|
|
$timeout.cancel(timeout);
|
|
afterAnimating();
|
|
scope.$apply();
|
|
});
|
|
} else {
|
|
// Ensure this call is async
|
|
$timeout(afterAnimating, 0);
|
|
}
|
|
|
|
function afterAnimating() {
|
|
if (afterAnimating.done) {
|
|
return;
|
|
}
|
|
afterAnimating.done = true;
|
|
|
|
domEl.remove();
|
|
if (done) {
|
|
done();
|
|
}
|
|
}
|
|
}
|
|
|
|
$document.bind('keydown', function (evt) {
|
|
var modal;
|
|
|
|
if (evt.which === 27) {
|
|
modal = openedWindows.top();
|
|
if (modal && modal.value.keyboard) {
|
|
$rootScope.$apply(function () {
|
|
$modalStack.dismiss(modal.key);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
$modalStack.open = function (modalInstance, modal) {
|
|
|
|
openedWindows.add(modalInstance, {
|
|
deferred: modal.deferred,
|
|
modalScope: modal.scope,
|
|
backdrop: modal.backdrop,
|
|
keyboard: modal.keyboard
|
|
});
|
|
|
|
var body = $document.find('body').eq(0),
|
|
currBackdropIndex = backdropIndex();
|
|
|
|
if (currBackdropIndex >= 0 && !backdropDomEl) {
|
|
backdropScope = $rootScope.$new(true);
|
|
backdropScope.index = currBackdropIndex;
|
|
backdropDomEl = $compile('<div modal-backdrop></div>')(backdropScope);
|
|
body.append(backdropDomEl);
|
|
}
|
|
|
|
var angularDomEl = angular.element('<div modal-window></div>');
|
|
angularDomEl.attr('window-class', modal.windowClass);
|
|
angularDomEl.attr('index', openedWindows.length() - 1);
|
|
angularDomEl.attr('animate', 'animate');
|
|
angularDomEl.html(modal.content);
|
|
|
|
var modalDomEl = $compile(angularDomEl)(modal.scope);
|
|
openedWindows.top().value.modalDomEl = modalDomEl;
|
|
body.append(modalDomEl);
|
|
body.addClass(OPENED_MODAL_CLASS);
|
|
};
|
|
|
|
$modalStack.close = function (modalInstance, result) {
|
|
var modalWindow = openedWindows.get(modalInstance).value;
|
|
if (modalWindow) {
|
|
modalWindow.deferred.resolve(result);
|
|
removeModalWindow(modalInstance);
|
|
}
|
|
};
|
|
|
|
$modalStack.dismiss = function (modalInstance, reason) {
|
|
var modalWindow = openedWindows.get(modalInstance).value;
|
|
if (modalWindow) {
|
|
modalWindow.deferred.reject(reason);
|
|
removeModalWindow(modalInstance);
|
|
}
|
|
};
|
|
|
|
$modalStack.dismissAll = function (reason) {
|
|
var topModal = this.getTop();
|
|
while (topModal) {
|
|
this.dismiss(topModal.key, reason);
|
|
topModal = this.getTop();
|
|
}
|
|
};
|
|
|
|
$modalStack.getTop = function () {
|
|
return openedWindows.top();
|
|
};
|
|
|
|
return $modalStack;
|
|
}])
|
|
|
|
.provider('$modal', function () {
|
|
|
|
var $modalProvider = {
|
|
options: {
|
|
backdrop: true, //can be also false or 'static'
|
|
keyboard: true
|
|
},
|
|
$get: ['$injector', '$rootScope', '$q', '$http', '$templateCache', '$controller', '$modalStack',
|
|
function ($injector, $rootScope, $q, $http, $templateCache, $controller, $modalStack) {
|
|
|
|
var $modal = {};
|
|
|
|
function getTemplatePromise(options) {
|
|
return options.template ? $q.when(options.template) :
|
|
$http.get(options.templateUrl, {cache: $templateCache}).then(function (result) {
|
|
return result.data;
|
|
});
|
|
}
|
|
|
|
function getResolvePromises(resolves) {
|
|
var promisesArr = [];
|
|
angular.forEach(resolves, function (value, key) {
|
|
if (angular.isFunction(value) || angular.isArray(value)) {
|
|
promisesArr.push($q.when($injector.invoke(value)));
|
|
}
|
|
});
|
|
return promisesArr;
|
|
}
|
|
|
|
$modal.open = function (modalOptions) {
|
|
|
|
var modalResultDeferred = $q.defer();
|
|
var modalOpenedDeferred = $q.defer();
|
|
|
|
//prepare an instance of a modal to be injected into controllers and returned to a caller
|
|
var modalInstance = {
|
|
result: modalResultDeferred.promise,
|
|
opened: modalOpenedDeferred.promise,
|
|
close: function (result) {
|
|
$modalStack.close(modalInstance, result);
|
|
},
|
|
dismiss: function (reason) {
|
|
$modalStack.dismiss(modalInstance, reason);
|
|
}
|
|
};
|
|
|
|
//merge and clean up options
|
|
modalOptions = angular.extend({}, $modalProvider.options, modalOptions);
|
|
modalOptions.resolve = modalOptions.resolve || {};
|
|
|
|
//verify options
|
|
if (!modalOptions.template && !modalOptions.templateUrl) {
|
|
throw new Error('One of template or templateUrl options is required.');
|
|
}
|
|
|
|
var templateAndResolvePromise =
|
|
$q.all([getTemplatePromise(modalOptions)].concat(getResolvePromises(modalOptions.resolve)));
|
|
|
|
|
|
templateAndResolvePromise.then(function resolveSuccess(tplAndVars) {
|
|
|
|
var modalScope = (modalOptions.scope || $rootScope).$new();
|
|
modalScope.$close = modalInstance.close;
|
|
modalScope.$dismiss = modalInstance.dismiss;
|
|
|
|
var ctrlInstance, ctrlLocals = {};
|
|
var resolveIter = 1;
|
|
|
|
//controllers
|
|
if (modalOptions.controller) {
|
|
ctrlLocals.$scope = modalScope;
|
|
ctrlLocals.$modalInstance = modalInstance;
|
|
angular.forEach(modalOptions.resolve, function (value, key) {
|
|
ctrlLocals[key] = tplAndVars[resolveIter++];
|
|
});
|
|
|
|
ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
|
|
}
|
|
|
|
$modalStack.open(modalInstance, {
|
|
scope: modalScope,
|
|
deferred: modalResultDeferred,
|
|
content: tplAndVars[0],
|
|
backdrop: modalOptions.backdrop,
|
|
keyboard: modalOptions.keyboard,
|
|
windowClass: modalOptions.windowClass
|
|
});
|
|
|
|
}, function resolveError(reason) {
|
|
modalResultDeferred.reject(reason);
|
|
});
|
|
|
|
templateAndResolvePromise.then(function () {
|
|
modalOpenedDeferred.resolve(true);
|
|
}, function () {
|
|
modalOpenedDeferred.reject(false);
|
|
});
|
|
|
|
return modalInstance;
|
|
};
|
|
|
|
return $modal;
|
|
}]
|
|
};
|
|
|
|
return $modalProvider;
|
|
});
|
|
|
|
angular.module('ui.bootstrap.pagination', [])
|
|
|
|
.controller('PaginationController', ['$scope', '$attrs', '$parse', '$interpolate', function ($scope, $attrs, $parse, $interpolate) {
|
|
var self = this,
|
|
setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop;
|
|
|
|
this.init = function(defaultItemsPerPage) {
|
|
if ($attrs.itemsPerPage) {
|
|
$scope.$parent.$watch($parse($attrs.itemsPerPage), function(value) {
|
|
self.itemsPerPage = parseInt(value, 10);
|
|
$scope.totalPages = self.calculateTotalPages();
|
|
});
|
|
} else {
|
|
this.itemsPerPage = defaultItemsPerPage;
|
|
}
|
|
};
|
|
|
|
this.noPrevious = function() {
|
|
return this.page === 1;
|
|
};
|
|
this.noNext = function() {
|
|
return this.page === $scope.totalPages;
|
|
};
|
|
|
|
this.isActive = function(page) {
|
|
return this.page === page;
|
|
};
|
|
|
|
this.calculateTotalPages = function() {
|
|
var totalPages = this.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / this.itemsPerPage);
|
|
return Math.max(totalPages || 0, 1);
|
|
};
|
|
|
|
this.getAttributeValue = function(attribute, defaultValue, interpolate) {
|
|
return angular.isDefined(attribute) ? (interpolate ? $interpolate(attribute)($scope.$parent) : $scope.$parent.$eval(attribute)) : defaultValue;
|
|
};
|
|
|
|
this.render = function() {
|
|
this.page = parseInt($scope.page, 10) || 1;
|
|
if (this.page > 0 && this.page <= $scope.totalPages) {
|
|
$scope.pages = this.getPages(this.page, $scope.totalPages);
|
|
}
|
|
};
|
|
|
|
$scope.selectPage = function(page) {
|
|
if ( ! self.isActive(page) && page > 0 && page <= $scope.totalPages) {
|
|
$scope.page = page;
|
|
$scope.onSelectPage({ page: page });
|
|
}
|
|
};
|
|
|
|
$scope.$watch('page', function() {
|
|
self.render();
|
|
});
|
|
|
|
$scope.$watch('totalItems', function() {
|
|
$scope.totalPages = self.calculateTotalPages();
|
|
});
|
|
|
|
$scope.$watch('totalPages', function(value) {
|
|
setNumPages($scope.$parent, value); // Readonly variable
|
|
|
|
if ( self.page > value ) {
|
|
$scope.selectPage(value);
|
|
} else {
|
|
self.render();
|
|
}
|
|
});
|
|
}])
|
|
|
|
.constant('paginationConfig', {
|
|
itemsPerPage: 10,
|
|
boundaryLinks: false,
|
|
directionLinks: true,
|
|
firstText: 'First',
|
|
previousText: 'Previous',
|
|
nextText: 'Next',
|
|
lastText: 'Last',
|
|
rotate: true
|
|
})
|
|
|
|
.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) {
|
|
return {
|
|
restrict: 'EA',
|
|
scope: {
|
|
page: '=',
|
|
totalItems: '=',
|
|
onSelectPage:' &'
|
|
},
|
|
controller: 'PaginationController',
|
|
templateUrl: 'template/pagination/pagination.html',
|
|
replace: true,
|
|
link: function(scope, element, attrs, paginationCtrl) {
|
|
|
|
// Setup configuration parameters
|
|
var maxSize,
|
|
boundaryLinks = paginationCtrl.getAttributeValue(attrs.boundaryLinks, config.boundaryLinks ),
|
|
directionLinks = paginationCtrl.getAttributeValue(attrs.directionLinks, config.directionLinks ),
|
|
firstText = paginationCtrl.getAttributeValue(attrs.firstText, config.firstText, true),
|
|
previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
|
|
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
|
|
lastText = paginationCtrl.getAttributeValue(attrs.lastText, config.lastText, true),
|
|
rotate = paginationCtrl.getAttributeValue(attrs.rotate, config.rotate);
|
|
|
|
paginationCtrl.init(config.itemsPerPage);
|
|
|
|
if (attrs.maxSize) {
|
|
scope.$parent.$watch($parse(attrs.maxSize), function(value) {
|
|
maxSize = parseInt(value, 10);
|
|
paginationCtrl.render();
|
|
});
|
|
}
|
|
|
|
// Create page object used in template
|
|
function makePage(number, text, isActive, isDisabled) {
|
|
return {
|
|
number: number,
|
|
text: text,
|
|
active: isActive,
|
|
disabled: isDisabled
|
|
};
|
|
}
|
|
|
|
paginationCtrl.getPages = function(currentPage, totalPages) {
|
|
var pages = [];
|
|
|
|
// Default page limits
|
|
var startPage = 1, endPage = totalPages;
|
|
var isMaxSized = ( angular.isDefined(maxSize) && maxSize < totalPages );
|
|
|
|
// recompute if maxSize
|
|
if ( isMaxSized ) {
|
|
if ( rotate ) {
|
|
// Current page is displayed in the middle of the visible ones
|
|
startPage = Math.max(currentPage - Math.floor(maxSize/2), 1);
|
|
endPage = startPage + maxSize - 1;
|
|
|
|
// Adjust if limit is exceeded
|
|
if (endPage > totalPages) {
|
|
endPage = totalPages;
|
|
startPage = endPage - maxSize + 1;
|
|
}
|
|
} else {
|
|
// Visible pages are paginated with maxSize
|
|
startPage = ((Math.ceil(currentPage / maxSize) - 1) * maxSize) + 1;
|
|
|
|
// Adjust last page if limit is exceeded
|
|
endPage = Math.min(startPage + maxSize - 1, totalPages);
|
|
}
|
|
}
|
|
|
|
// Add page number links
|
|
for (var number = startPage; number <= endPage; number++) {
|
|
var page = makePage(number, number, paginationCtrl.isActive(number), false);
|
|
pages.push(page);
|
|
}
|
|
|
|
// Add links to move between page sets
|
|
if ( isMaxSized && ! rotate ) {
|
|
if ( startPage > 1 ) {
|
|
var previousPageSet = makePage(startPage - 1, '...', false, false);
|
|
pages.unshift(previousPageSet);
|
|
}
|
|
|
|
if ( endPage < totalPages ) {
|
|
var nextPageSet = makePage(endPage + 1, '...', false, false);
|
|
pages.push(nextPageSet);
|
|
}
|
|
}
|
|
|
|
// Add previous & next links
|
|
if (directionLinks) {
|
|
var previousPage = makePage(currentPage - 1, previousText, false, paginationCtrl.noPrevious());
|
|
pages.unshift(previousPage);
|
|
|
|
var nextPage = makePage(currentPage + 1, nextText, false, paginationCtrl.noNext());
|
|
pages.push(nextPage);
|
|
}
|
|
|
|
// Add first & last links
|
|
if (boundaryLinks) {
|
|
var firstPage = makePage(1, firstText, false, paginationCtrl.noPrevious());
|
|
pages.unshift(firstPage);
|
|
|
|
var lastPage = makePage(totalPages, lastText, false, paginationCtrl.noNext());
|
|
pages.push(lastPage);
|
|
}
|
|
|
|
return pages;
|
|
};
|
|
}
|
|
};
|
|
}])
|
|
|
|
.constant('pagerConfig', {
|
|
itemsPerPage: 10,
|
|
previousText: '« Previous',
|
|
nextText: 'Next »',
|
|
align: true
|
|
})
|
|
|
|
.directive('pager', ['pagerConfig', function(config) {
|
|
return {
|
|
restrict: 'EA',
|
|
scope: {
|
|
page: '=',
|
|
totalItems: '=',
|
|
onSelectPage:' &'
|
|
},
|
|
controller: 'PaginationController',
|
|
templateUrl: 'template/pagination/pager.html',
|
|
replace: true,
|
|
link: function(scope, element, attrs, paginationCtrl) {
|
|
|
|
// Setup configuration parameters
|
|
var previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
|
|
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
|
|
align = paginationCtrl.getAttributeValue(attrs.align, config.align);
|
|
|
|
paginationCtrl.init(config.itemsPerPage);
|
|
|
|
// Create page object used in template
|
|
function makePage(number, text, isDisabled, isPrevious, isNext) {
|
|
return {
|
|
number: number,
|
|
text: text,
|
|
disabled: isDisabled,
|
|
previous: ( align && isPrevious ),
|
|
next: ( align && isNext )
|
|
};
|
|
}
|
|
|
|
paginationCtrl.getPages = function(currentPage) {
|
|
return [
|
|
makePage(currentPage - 1, previousText, paginationCtrl.noPrevious(), true, false),
|
|
makePage(currentPage + 1, nextText, paginationCtrl.noNext(), false, true)
|
|
];
|
|
};
|
|
}
|
|
};
|
|
}]);
|
|
|
|
/**
|
|
* The following features are still outstanding: animation as a
|
|
* function, placement as a function, inside, support for more triggers than
|
|
* just mouse enter/leave, html tooltips, and selector delegation.
|
|
*/
|
|
angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap.bindHtml' ] )
|
|
|
|
/**
|
|
* The $tooltip service creates tooltip- and popover-like directives as well as
|
|
* houses global options for them.
|
|
*/
|
|
.provider( '$tooltip', function () {
|
|
// The default options tooltip and popover.
|
|
var defaultOptions = {
|
|
placement: 'top',
|
|
animation: true,
|
|
popupDelay: 0
|
|
};
|
|
|
|
// Default hide triggers for each show trigger
|
|
var triggerMap = {
|
|
'mouseenter': 'mouseleave',
|
|
'click': 'click',
|
|
'focus': 'blur'
|
|
};
|
|
|
|
// The options specified to the provider globally.
|
|
var globalOptions = {};
|
|
|
|
/**
|
|
* `options({})` allows global configuration of all tooltips in the
|
|
* application.
|
|
*
|
|
* var app = angular.module( 'App', ['ui.bootstrap.tooltip'], function( $tooltipProvider ) {
|
|
* // place tooltips left instead of top by default
|
|
* $tooltipProvider.options( { placement: 'left' } );
|
|
* });
|
|
*/
|
|
this.options = function( value ) {
|
|
angular.extend( globalOptions, value );
|
|
};
|
|
|
|
/**
|
|
* This allows you to extend the set of trigger mappings available. E.g.:
|
|
*
|
|
* $tooltipProvider.setTriggers( 'openTrigger': 'closeTrigger' );
|
|
*/
|
|
this.setTriggers = function setTriggers ( triggers ) {
|
|
angular.extend( triggerMap, triggers );
|
|
};
|
|
|
|
/**
|
|
* This is a helper function for translating camel-case to snake-case.
|
|
*/
|
|
function snake_case(name){
|
|
var regexp = /[A-Z]/g;
|
|
var separator = '-';
|
|
return name.replace(regexp, function(letter, pos) {
|
|
return (pos ? separator : '') + letter.toLowerCase();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns the actual instance of the $tooltip service.
|
|
* TODO support multiple triggers
|
|
*/
|
|
this.$get = [ '$window', '$compile', '$timeout', '$parse', '$document', '$position', '$interpolate', function ( $window, $compile, $timeout, $parse, $document, $position, $interpolate ) {
|
|
return function $tooltip ( type, prefix, defaultTriggerShow ) {
|
|
var options = angular.extend( {}, defaultOptions, globalOptions );
|
|
|
|
/**
|
|
* Returns an object of show and hide triggers.
|
|
*
|
|
* If a trigger is supplied,
|
|
* it is used to show the tooltip; otherwise, it will use the `trigger`
|
|
* option passed to the `$tooltipProvider.options` method; else it will
|
|
* default to the trigger supplied to this directive factory.
|
|
*
|
|
* The hide trigger is based on the show trigger. If the `trigger` option
|
|
* was passed to the `$tooltipProvider.options` method, it will use the
|
|
* mapped trigger from `triggerMap` or the passed trigger if the map is
|
|
* undefined; otherwise, it uses the `triggerMap` value of the show
|
|
* trigger; else it will just use the show trigger.
|
|
*/
|
|
function getTriggers ( trigger ) {
|
|
var show = trigger || options.trigger || defaultTriggerShow;
|
|
var hide = triggerMap[show] || show;
|
|
return {
|
|
show: show,
|
|
hide: hide
|
|
};
|
|
}
|
|
|
|
var directiveName = snake_case( type );
|
|
|
|
var startSym = $interpolate.startSymbol();
|
|
var endSym = $interpolate.endSymbol();
|
|
var template =
|
|
'<div '+ directiveName +'-popup '+
|
|
'title="'+startSym+'tt_title'+endSym+'" '+
|
|
'content="'+startSym+'tt_content'+endSym+'" '+
|
|
'placement="'+startSym+'tt_placement'+endSym+'" '+
|
|
'animation="tt_animation" '+
|
|
'is-open="tt_isOpen"'+
|
|
'>'+
|
|
'</div>';
|
|
|
|
return {
|
|
restrict: 'EA',
|
|
scope: true,
|
|
compile: function (tElem, tAttrs) {
|
|
var tooltipLinker = $compile( template );
|
|
|
|
return function link ( scope, element, attrs ) {
|
|
var tooltip;
|
|
var transitionTimeout;
|
|
var popupTimeout;
|
|
var appendToBody = angular.isDefined( options.appendToBody ) ? options.appendToBody : false;
|
|
var triggers = getTriggers( undefined );
|
|
var hasRegisteredTriggers = false;
|
|
var hasEnableExp = angular.isDefined(attrs[prefix+'Enable']);
|
|
|
|
var positionTooltip = function (){
|
|
var position,
|
|
ttWidth,
|
|
ttHeight,
|
|
ttPosition;
|
|
// Get the position of the directive element.
|
|
position = appendToBody ? $position.offset( element ) : $position.position( element );
|
|
|
|
// Get the height and width of the tooltip so we can center it.
|
|
ttWidth = tooltip.prop( 'offsetWidth' );
|
|
ttHeight = tooltip.prop( 'offsetHeight' );
|
|
|
|
// Calculate the tooltip's top and left coordinates to center it with
|
|
// this directive.
|
|
switch ( scope.tt_placement ) {
|
|
case 'right':
|
|
ttPosition = {
|
|
top: position.top + position.height / 2 - ttHeight / 2,
|
|
left: position.left + position.width
|
|
};
|
|
break;
|
|
case 'bottom':
|
|
ttPosition = {
|
|
top: position.top + position.height,
|
|
left: position.left + position.width / 2 - ttWidth / 2
|
|
};
|
|
break;
|
|
case 'left':
|
|
ttPosition = {
|
|
top: position.top + position.height / 2 - ttHeight / 2,
|
|
left: position.left - ttWidth
|
|
};
|
|
break;
|
|
default:
|
|
ttPosition = {
|
|
top: position.top - ttHeight,
|
|
left: position.left + position.width / 2 - ttWidth / 2
|
|
};
|
|
break;
|
|
}
|
|
|
|
ttPosition.top += 'px';
|
|
ttPosition.left += 'px';
|
|
|
|
// Now set the calculated positioning.
|
|
tooltip.css( ttPosition );
|
|
|
|
};
|
|
|
|
// By default, the tooltip is not open.
|
|
// TODO add ability to start tooltip opened
|
|
scope.tt_isOpen = false;
|
|
|
|
function toggleTooltipBind () {
|
|
if ( ! scope.tt_isOpen ) {
|
|
showTooltipBind();
|
|
} else {
|
|
hideTooltipBind();
|
|
}
|
|
}
|
|
|
|
// Show the tooltip with delay if specified, otherwise show it immediately
|
|
function showTooltipBind() {
|
|
if(hasEnableExp && !scope.$eval(attrs[prefix+'Enable'])) {
|
|
return;
|
|
}
|
|
if ( scope.tt_popupDelay ) {
|
|
popupTimeout = $timeout( show, scope.tt_popupDelay, false );
|
|
popupTimeout.then(function(reposition){reposition();});
|
|
} else {
|
|
show()();
|
|
}
|
|
}
|
|
|
|
function hideTooltipBind () {
|
|
scope.$apply(function () {
|
|
hide();
|
|
});
|
|
}
|
|
|
|
// Show the tooltip popup element.
|
|
function show() {
|
|
|
|
|
|
// Don't show empty tooltips.
|
|
if ( ! scope.tt_content ) {
|
|
return angular.noop;
|
|
}
|
|
|
|
createTooltip();
|
|
|
|
// If there is a pending remove transition, we must cancel it, lest the
|
|
// tooltip be mysteriously removed.
|
|
if ( transitionTimeout ) {
|
|
$timeout.cancel( transitionTimeout );
|
|
}
|
|
|
|
// Set the initial positioning.
|
|
tooltip.css({ top: 0, left: 0, display: 'block' });
|
|
|
|
// Now we add it to the DOM because need some info about it. But it's not
|
|
// visible yet anyway.
|
|
if ( appendToBody ) {
|
|
$document.find( 'body' ).append( tooltip );
|
|
} else {
|
|
element.after( tooltip );
|
|
}
|
|
|
|
positionTooltip();
|
|
|
|
// And show the tooltip.
|
|
scope.tt_isOpen = true;
|
|
scope.$digest(); // digest required as $apply is not called
|
|
|
|
// Return positioning function as promise callback for correct
|
|
// positioning after draw.
|
|
return positionTooltip;
|
|
}
|
|
|
|
// Hide the tooltip popup element.
|
|
function hide() {
|
|
// First things first: we don't show it anymore.
|
|
scope.tt_isOpen = false;
|
|
|
|
//if tooltip is going to be shown after delay, we must cancel this
|
|
$timeout.cancel( popupTimeout );
|
|
|
|
// And now we remove it from the DOM. However, if we have animation, we
|
|
// need to wait for it to expire beforehand.
|
|
// FIXME: this is a placeholder for a port of the transitions library.
|
|
if ( scope.tt_animation ) {
|
|
transitionTimeout = $timeout(removeTooltip, 500);
|
|
} else {
|
|
removeTooltip();
|
|
}
|
|
}
|
|
|
|
function createTooltip() {
|
|
// There can only be one tooltip element per directive shown at once.
|
|
if (tooltip) {
|
|
removeTooltip();
|
|
}
|
|
tooltip = tooltipLinker(scope, function () {});
|
|
|
|
// Get contents rendered into the tooltip
|
|
scope.$digest();
|
|
}
|
|
|
|
function removeTooltip() {
|
|
if (tooltip) {
|
|
tooltip.remove();
|
|
tooltip = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Observe the relevant attributes.
|
|
*/
|
|
attrs.$observe( type, function ( val ) {
|
|
scope.tt_content = val;
|
|
|
|
if (!val && scope.tt_isOpen ) {
|
|
hide();
|
|
}
|
|
});
|
|
|
|
attrs.$observe( prefix+'Title', function ( val ) {
|
|
scope.tt_title = val;
|
|
});
|
|
|
|
attrs.$observe( prefix+'Placement', function ( val ) {
|
|
scope.tt_placement = angular.isDefined( val ) ? val : options.placement;
|
|
});
|
|
|
|
attrs.$observe( prefix+'PopupDelay', function ( val ) {
|
|
var delay = parseInt( val, 10 );
|
|
scope.tt_popupDelay = ! isNaN(delay) ? delay : options.popupDelay;
|
|
});
|
|
|
|
var unregisterTriggers = function() {
|
|
if (hasRegisteredTriggers) {
|
|
element.unbind( triggers.show, showTooltipBind );
|
|
element.unbind( triggers.hide, hideTooltipBind );
|
|
}
|
|
};
|
|
|
|
attrs.$observe( prefix+'Trigger', function ( val ) {
|
|
unregisterTriggers();
|
|
|
|
triggers = getTriggers( val );
|
|
|
|
if ( triggers.show === triggers.hide ) {
|
|
element.bind( triggers.show, toggleTooltipBind );
|
|
} else {
|
|
element.bind( triggers.show, showTooltipBind );
|
|
element.bind( triggers.hide, hideTooltipBind );
|
|
}
|
|
|
|
hasRegisteredTriggers = true;
|
|
});
|
|
|
|
var animation = scope.$eval(attrs[prefix + 'Animation']);
|
|
scope.tt_animation = angular.isDefined(animation) ? !!animation : options.animation;
|
|
|
|
attrs.$observe( prefix+'AppendToBody', function ( val ) {
|
|
appendToBody = angular.isDefined( val ) ? $parse( val )( scope ) : appendToBody;
|
|
});
|
|
|
|
// if a tooltip is attached to <body> we need to remove it on
|
|
// location change as its parent scope will probably not be destroyed
|
|
// by the change.
|
|
if ( appendToBody ) {
|
|
scope.$on('$locationChangeSuccess', function closeTooltipOnLocationChangeSuccess () {
|
|
if ( scope.tt_isOpen ) {
|
|
hide();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Make sure tooltip is destroyed and removed.
|
|
scope.$on('$destroy', function onDestroyTooltip() {
|
|
$timeout.cancel( transitionTimeout );
|
|
$timeout.cancel( popupTimeout );
|
|
unregisterTriggers();
|
|
removeTooltip();
|
|
});
|
|
};
|
|
}
|
|
};
|
|
};
|
|
}];
|
|
})
|
|
|
|
.directive( 'tooltipPopup', function () {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
|
|
templateUrl: 'template/tooltip/tooltip-popup.html'
|
|
};
|
|
})
|
|
|
|
.directive( 'tooltip', [ '$tooltip', function ( $tooltip ) {
|
|
return $tooltip( 'tooltip', 'tooltip', 'mouseenter' );
|
|
}])
|
|
|
|
.directive( 'tooltipHtmlUnsafePopup', function () {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
|
|
templateUrl: 'template/tooltip/tooltip-html-unsafe-popup.html'
|
|
};
|
|
})
|
|
|
|
.directive( 'tooltipHtmlUnsafe', [ '$tooltip', function ( $tooltip ) {
|
|
return $tooltip( 'tooltipHtmlUnsafe', 'tooltip', 'mouseenter' );
|
|
}]);
|
|
|
|
/**
|
|
* The following features are still outstanding: popup delay, animation as a
|
|
* function, placement as a function, inside, support for more triggers than
|
|
* just mouse enter/leave, html popovers, and selector delegatation.
|
|
*/
|
|
angular.module( 'ui.bootstrap.popover', [ 'ui.bootstrap.tooltip' ] )
|
|
|
|
.directive( 'popoverPopup', function () {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' },
|
|
templateUrl: 'template/popover/popover.html'
|
|
};
|
|
})
|
|
|
|
.directive( 'popover', [ '$tooltip', function ( $tooltip ) {
|
|
return $tooltip( 'popover', 'popover', 'click' );
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.progressbar', ['ui.bootstrap.transition'])
|
|
|
|
.constant('progressConfig', {
|
|
animate: true,
|
|
max: 100
|
|
})
|
|
|
|
.controller('ProgressController', ['$scope', '$attrs', 'progressConfig', '$transition', function($scope, $attrs, progressConfig, $transition) {
|
|
var self = this,
|
|
bars = [],
|
|
max = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : progressConfig.max,
|
|
animate = angular.isDefined($attrs.animate) ? $scope.$parent.$eval($attrs.animate) : progressConfig.animate;
|
|
|
|
this.addBar = function(bar, element) {
|
|
var oldValue = 0, index = bar.$parent.$index;
|
|
if ( angular.isDefined(index) && bars[index] ) {
|
|
oldValue = bars[index].value;
|
|
}
|
|
bars.push(bar);
|
|
|
|
this.update(element, bar.value, oldValue);
|
|
|
|
bar.$watch('value', function(value, oldValue) {
|
|
if (value !== oldValue) {
|
|
self.update(element, value, oldValue);
|
|
}
|
|
});
|
|
|
|
bar.$on('$destroy', function() {
|
|
self.removeBar(bar);
|
|
});
|
|
};
|
|
|
|
// Update bar element width
|
|
this.update = function(element, newValue, oldValue) {
|
|
var percent = this.getPercentage(newValue);
|
|
|
|
if (animate) {
|
|
element.css('width', this.getPercentage(oldValue) + '%');
|
|
$transition(element, {width: percent + '%'});
|
|
} else {
|
|
element.css({'transition': 'none', 'width': percent + '%'});
|
|
}
|
|
};
|
|
|
|
this.removeBar = function(bar) {
|
|
bars.splice(bars.indexOf(bar), 1);
|
|
};
|
|
|
|
this.getPercentage = function(value) {
|
|
return Math.round(100 * value / max);
|
|
};
|
|
}])
|
|
|
|
.directive('progress', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
transclude: true,
|
|
controller: 'ProgressController',
|
|
require: 'progress',
|
|
scope: {},
|
|
template: '<div class="progress" ng-transclude></div>'
|
|
//templateUrl: 'template/progressbar/progress.html' // Works in AngularJS 1.2
|
|
};
|
|
})
|
|
|
|
.directive('bar', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
transclude: true,
|
|
require: '^progress',
|
|
scope: {
|
|
value: '=',
|
|
type: '@'
|
|
},
|
|
templateUrl: 'template/progressbar/bar.html',
|
|
link: function(scope, element, attrs, progressCtrl) {
|
|
progressCtrl.addBar(scope, element);
|
|
}
|
|
};
|
|
})
|
|
|
|
.directive('progressbar', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
transclude: true,
|
|
controller: 'ProgressController',
|
|
scope: {
|
|
value: '=',
|
|
type: '@'
|
|
},
|
|
templateUrl: 'template/progressbar/progressbar.html',
|
|
link: function(scope, element, attrs, progressCtrl) {
|
|
progressCtrl.addBar(scope, angular.element(element.children()[0]));
|
|
}
|
|
};
|
|
});
|
|
angular.module('ui.bootstrap.rating', [])
|
|
|
|
.constant('ratingConfig', {
|
|
max: 5,
|
|
stateOn: null,
|
|
stateOff: null
|
|
})
|
|
|
|
.controller('RatingController', ['$scope', '$attrs', '$parse', 'ratingConfig', function($scope, $attrs, $parse, ratingConfig) {
|
|
|
|
this.maxRange = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max;
|
|
this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
|
|
this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;
|
|
|
|
this.createRateObjects = function(states) {
|
|
var defaultOptions = {
|
|
stateOn: this.stateOn,
|
|
stateOff: this.stateOff
|
|
};
|
|
|
|
for (var i = 0, n = states.length; i < n; i++) {
|
|
states[i] = angular.extend({ index: i }, defaultOptions, states[i]);
|
|
}
|
|
return states;
|
|
};
|
|
|
|
// Get objects used in template
|
|
$scope.range = angular.isDefined($attrs.ratingStates) ? this.createRateObjects(angular.copy($scope.$parent.$eval($attrs.ratingStates))): this.createRateObjects(new Array(this.maxRange));
|
|
|
|
$scope.rate = function(value) {
|
|
if ( $scope.value !== value && !$scope.readonly ) {
|
|
$scope.value = value;
|
|
}
|
|
};
|
|
|
|
$scope.enter = function(value) {
|
|
if ( ! $scope.readonly ) {
|
|
$scope.val = value;
|
|
}
|
|
$scope.onHover({value: value});
|
|
};
|
|
|
|
$scope.reset = function() {
|
|
$scope.val = angular.copy($scope.value);
|
|
$scope.onLeave();
|
|
};
|
|
|
|
$scope.$watch('value', function(value) {
|
|
$scope.val = value;
|
|
});
|
|
|
|
$scope.readonly = false;
|
|
if ($attrs.readonly) {
|
|
$scope.$parent.$watch($parse($attrs.readonly), function(value) {
|
|
$scope.readonly = !!value;
|
|
});
|
|
}
|
|
}])
|
|
|
|
.directive('rating', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
scope: {
|
|
value: '=',
|
|
onHover: '&',
|
|
onLeave: '&'
|
|
},
|
|
controller: 'RatingController',
|
|
templateUrl: 'template/rating/rating.html',
|
|
replace: true
|
|
};
|
|
});
|
|
|
|
/**
|
|
* @ngdoc overview
|
|
* @name ui.bootstrap.tabs
|
|
*
|
|
* @description
|
|
* AngularJS version of the tabs directive.
|
|
*/
|
|
|
|
angular.module('ui.bootstrap.tabs', [])
|
|
|
|
.controller('TabsetController', ['$scope', function TabsetCtrl($scope) {
|
|
var ctrl = this,
|
|
tabs = ctrl.tabs = $scope.tabs = [];
|
|
|
|
ctrl.select = function(tab) {
|
|
angular.forEach(tabs, function(tab) {
|
|
tab.active = false;
|
|
});
|
|
tab.active = true;
|
|
};
|
|
|
|
ctrl.addTab = function addTab(tab) {
|
|
tabs.push(tab);
|
|
if (tabs.length === 1 || tab.active) {
|
|
ctrl.select(tab);
|
|
}
|
|
};
|
|
|
|
ctrl.removeTab = function removeTab(tab) {
|
|
var index = tabs.indexOf(tab);
|
|
//Select a new tab if the tab to be removed is selected
|
|
if (tab.active && tabs.length > 1) {
|
|
//If this is the last tab, select the previous tab. else, the next tab.
|
|
var newActiveIndex = index == tabs.length - 1 ? index - 1 : index + 1;
|
|
ctrl.select(tabs[newActiveIndex]);
|
|
}
|
|
tabs.splice(index, 1);
|
|
};
|
|
}])
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name ui.bootstrap.tabs.directive:tabset
|
|
* @restrict EA
|
|
*
|
|
* @description
|
|
* Tabset is the outer container for the tabs directive
|
|
*
|
|
* @param {boolean=} vertical Whether or not to use vertical styling for the tabs.
|
|
* @param {boolean=} justified Whether or not to use justified styling for the tabs.
|
|
*
|
|
* @example
|
|
<example module="ui.bootstrap">
|
|
<file name="index.html">
|
|
<tabset>
|
|
<tab heading="Tab 1"><b>First</b> Content!</tab>
|
|
<tab heading="Tab 2"><i>Second</i> Content!</tab>
|
|
</tabset>
|
|
<hr />
|
|
<tabset vertical="true">
|
|
<tab heading="Vertical Tab 1"><b>First</b> Vertical Content!</tab>
|
|
<tab heading="Vertical Tab 2"><i>Second</i> Vertical Content!</tab>
|
|
</tabset>
|
|
<tabset justified="true">
|
|
<tab heading="Justified Tab 1"><b>First</b> Justified Content!</tab>
|
|
<tab heading="Justified Tab 2"><i>Second</i> Justified Content!</tab>
|
|
</tabset>
|
|
</file>
|
|
</example>
|
|
*/
|
|
.directive('tabset', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
transclude: true,
|
|
replace: true,
|
|
scope: {},
|
|
controller: 'TabsetController',
|
|
templateUrl: 'template/tabs/tabset.html',
|
|
link: function(scope, element, attrs) {
|
|
scope.vertical = angular.isDefined(attrs.vertical) ? scope.$parent.$eval(attrs.vertical) : false;
|
|
scope.justified = angular.isDefined(attrs.justified) ? scope.$parent.$eval(attrs.justified) : false;
|
|
scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs';
|
|
}
|
|
};
|
|
})
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name ui.bootstrap.tabs.directive:tab
|
|
* @restrict EA
|
|
*
|
|
* @param {string=} heading The visible heading, or title, of the tab. Set HTML headings with {@link ui.bootstrap.tabs.directive:tabHeading tabHeading}.
|
|
* @param {string=} select An expression to evaluate when the tab is selected.
|
|
* @param {boolean=} active A binding, telling whether or not this tab is selected.
|
|
* @param {boolean=} disabled A binding, telling whether or not this tab is disabled.
|
|
*
|
|
* @description
|
|
* Creates a tab with a heading and content. Must be placed within a {@link ui.bootstrap.tabs.directive:tabset tabset}.
|
|
*
|
|
* @example
|
|
<example module="ui.bootstrap">
|
|
<file name="index.html">
|
|
<div ng-controller="TabsDemoCtrl">
|
|
<button class="btn btn-small" ng-click="items[0].active = true">
|
|
Select item 1, using active binding
|
|
</button>
|
|
<button class="btn btn-small" ng-click="items[1].disabled = !items[1].disabled">
|
|
Enable/disable item 2, using disabled binding
|
|
</button>
|
|
<br />
|
|
<tabset>
|
|
<tab heading="Tab 1">First Tab</tab>
|
|
<tab select="alertMe()">
|
|
<tab-heading><i class="icon-bell"></i> Alert me!</tab-heading>
|
|
Second Tab, with alert callback and html heading!
|
|
</tab>
|
|
<tab ng-repeat="item in items"
|
|
heading="{{item.title}}"
|
|
disabled="item.disabled"
|
|
active="item.active">
|
|
{{item.content}}
|
|
</tab>
|
|
</tabset>
|
|
</div>
|
|
</file>
|
|
<file name="script.js">
|
|
function TabsDemoCtrl($scope) {
|
|
$scope.items = [
|
|
{ title:"Dynamic Title 1", content:"Dynamic Item 0" },
|
|
{ title:"Dynamic Title 2", content:"Dynamic Item 1", disabled: true }
|
|
];
|
|
|
|
$scope.alertMe = function() {
|
|
setTimeout(function() {
|
|
alert("You've selected the alert tab!");
|
|
});
|
|
};
|
|
};
|
|
</file>
|
|
</example>
|
|
*/
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name ui.bootstrap.tabs.directive:tabHeading
|
|
* @restrict EA
|
|
*
|
|
* @description
|
|
* Creates an HTML heading for a {@link ui.bootstrap.tabs.directive:tab tab}. Must be placed as a child of a tab element.
|
|
*
|
|
* @example
|
|
<example module="ui.bootstrap">
|
|
<file name="index.html">
|
|
<tabset>
|
|
<tab>
|
|
<tab-heading><b>HTML</b> in my titles?!</tab-heading>
|
|
And some content, too!
|
|
</tab>
|
|
<tab>
|
|
<tab-heading><i class="icon-heart"></i> Icon heading?!?</tab-heading>
|
|
That's right.
|
|
</tab>
|
|
</tabset>
|
|
</file>
|
|
</example>
|
|
*/
|
|
.directive('tab', ['$parse', function($parse) {
|
|
return {
|
|
require: '^tabset',
|
|
restrict: 'EA',
|
|
replace: true,
|
|
templateUrl: 'template/tabs/tab.html',
|
|
transclude: true,
|
|
scope: {
|
|
heading: '@',
|
|
onSelect: '&select', //This callback is called in contentHeadingTransclude
|
|
//once it inserts the tab's content into the dom
|
|
onDeselect: '&deselect'
|
|
},
|
|
controller: function() {
|
|
//Empty controller so other directives can require being 'under' a tab
|
|
},
|
|
compile: function(elm, attrs, transclude) {
|
|
return function postLink(scope, elm, attrs, tabsetCtrl) {
|
|
var getActive, setActive;
|
|
if (attrs.active) {
|
|
getActive = $parse(attrs.active);
|
|
setActive = getActive.assign;
|
|
scope.$parent.$watch(getActive, function updateActive(value, oldVal) {
|
|
// Avoid re-initializing scope.active as it is already initialized
|
|
// below. (watcher is called async during init with value ===
|
|
// oldVal)
|
|
if (value !== oldVal) {
|
|
scope.active = !!value;
|
|
}
|
|
});
|
|
scope.active = getActive(scope.$parent);
|
|
} else {
|
|
setActive = getActive = angular.noop;
|
|
}
|
|
|
|
scope.$watch('active', function(active) {
|
|
// Note this watcher also initializes and assigns scope.active to the
|
|
// attrs.active expression.
|
|
setActive(scope.$parent, active);
|
|
if (active) {
|
|
tabsetCtrl.select(scope);
|
|
scope.onSelect();
|
|
} else {
|
|
scope.onDeselect();
|
|
}
|
|
});
|
|
|
|
scope.disabled = false;
|
|
if ( attrs.disabled ) {
|
|
scope.$parent.$watch($parse(attrs.disabled), function(value) {
|
|
scope.disabled = !! value;
|
|
});
|
|
}
|
|
|
|
scope.select = function() {
|
|
if ( ! scope.disabled ) {
|
|
scope.active = true;
|
|
}
|
|
};
|
|
|
|
tabsetCtrl.addTab(scope);
|
|
scope.$on('$destroy', function() {
|
|
tabsetCtrl.removeTab(scope);
|
|
});
|
|
|
|
|
|
//We need to transclude later, once the content container is ready.
|
|
//when this link happens, we're inside a tab heading.
|
|
scope.$transcludeFn = transclude;
|
|
};
|
|
}
|
|
};
|
|
}])
|
|
|
|
.directive('tabHeadingTransclude', [function() {
|
|
return {
|
|
restrict: 'A',
|
|
require: '^tab',
|
|
link: function(scope, elm, attrs, tabCtrl) {
|
|
scope.$watch('headingElement', function updateHeadingElement(heading) {
|
|
if (heading) {
|
|
elm.html('');
|
|
elm.append(heading);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}])
|
|
|
|
.directive('tabContentTransclude', function() {
|
|
return {
|
|
restrict: 'A',
|
|
require: '^tabset',
|
|
link: function(scope, elm, attrs) {
|
|
var tab = scope.$eval(attrs.tabContentTransclude);
|
|
|
|
//Now our tab is ready to be transcluded: both the tab heading area
|
|
//and the tab content area are loaded. Transclude 'em both.
|
|
tab.$transcludeFn(tab.$parent, function(contents) {
|
|
angular.forEach(contents, function(node) {
|
|
if (isTabHeading(node)) {
|
|
//Let tabHeadingTransclude know.
|
|
tab.headingElement = node;
|
|
} else {
|
|
elm.append(node);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
};
|
|
function isTabHeading(node) {
|
|
return node.tagName && (
|
|
node.hasAttribute('tab-heading') ||
|
|
node.hasAttribute('data-tab-heading') ||
|
|
node.tagName.toLowerCase() === 'tab-heading' ||
|
|
node.tagName.toLowerCase() === 'data-tab-heading'
|
|
);
|
|
}
|
|
})
|
|
|
|
;
|
|
|
|
angular.module('ui.bootstrap.timepicker', [])
|
|
|
|
.constant('timepickerConfig', {
|
|
hourStep: 1,
|
|
minuteStep: 1,
|
|
showMeridian: true,
|
|
meridians: null,
|
|
readonlyInput: false,
|
|
mousewheel: true
|
|
})
|
|
|
|
.directive('timepicker', ['$parse', '$log', 'timepickerConfig', '$locale', function ($parse, $log, timepickerConfig, $locale) {
|
|
return {
|
|
restrict: 'EA',
|
|
require:'?^ngModel',
|
|
replace: true,
|
|
scope: {},
|
|
templateUrl: 'template/timepicker/timepicker.html',
|
|
link: function(scope, element, attrs, ngModel) {
|
|
if ( !ngModel ) {
|
|
return; // do nothing if no ng-model
|
|
}
|
|
|
|
var selected = new Date(),
|
|
meridians = angular.isDefined(attrs.meridians) ? scope.$parent.$eval(attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS;
|
|
|
|
var hourStep = timepickerConfig.hourStep;
|
|
if (attrs.hourStep) {
|
|
scope.$parent.$watch($parse(attrs.hourStep), function(value) {
|
|
hourStep = parseInt(value, 10);
|
|
});
|
|
}
|
|
|
|
var minuteStep = timepickerConfig.minuteStep;
|
|
if (attrs.minuteStep) {
|
|
scope.$parent.$watch($parse(attrs.minuteStep), function(value) {
|
|
minuteStep = parseInt(value, 10);
|
|
});
|
|
}
|
|
|
|
// 12H / 24H mode
|
|
scope.showMeridian = timepickerConfig.showMeridian;
|
|
if (attrs.showMeridian) {
|
|
scope.$parent.$watch($parse(attrs.showMeridian), function(value) {
|
|
scope.showMeridian = !!value;
|
|
|
|
if ( ngModel.$error.time ) {
|
|
// Evaluate from template
|
|
var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate();
|
|
if (angular.isDefined( hours ) && angular.isDefined( minutes )) {
|
|
selected.setHours( hours );
|
|
refresh();
|
|
}
|
|
} else {
|
|
updateTemplate();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Get scope.hours in 24H mode if valid
|
|
function getHoursFromTemplate ( ) {
|
|
var hours = parseInt( scope.hours, 10 );
|
|
var valid = ( scope.showMeridian ) ? (hours > 0 && hours < 13) : (hours >= 0 && hours < 24);
|
|
if ( !valid ) {
|
|
return undefined;
|
|
}
|
|
|
|
if ( scope.showMeridian ) {
|
|
if ( hours === 12 ) {
|
|
hours = 0;
|
|
}
|
|
if ( scope.meridian === meridians[1] ) {
|
|
hours = hours + 12;
|
|
}
|
|
}
|
|
return hours;
|
|
}
|
|
|
|
function getMinutesFromTemplate() {
|
|
var minutes = parseInt(scope.minutes, 10);
|
|
return ( minutes >= 0 && minutes < 60 ) ? minutes : undefined;
|
|
}
|
|
|
|
function pad( value ) {
|
|
return ( angular.isDefined(value) && value.toString().length < 2 ) ? '0' + value : value;
|
|
}
|
|
|
|
// Input elements
|
|
var inputs = element.find('input'), hoursInputEl = inputs.eq(0), minutesInputEl = inputs.eq(1);
|
|
|
|
// Respond on mousewheel spin
|
|
var mousewheel = (angular.isDefined(attrs.mousewheel)) ? scope.$eval(attrs.mousewheel) : timepickerConfig.mousewheel;
|
|
if ( mousewheel ) {
|
|
|
|
var isScrollingUp = function(e) {
|
|
if (e.originalEvent) {
|
|
e = e.originalEvent;
|
|
}
|
|
//pick correct delta variable depending on event
|
|
var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY;
|
|
return (e.detail || delta > 0);
|
|
};
|
|
|
|
hoursInputEl.bind('mousewheel wheel', function(e) {
|
|
scope.$apply( (isScrollingUp(e)) ? scope.incrementHours() : scope.decrementHours() );
|
|
e.preventDefault();
|
|
});
|
|
|
|
minutesInputEl.bind('mousewheel wheel', function(e) {
|
|
scope.$apply( (isScrollingUp(e)) ? scope.incrementMinutes() : scope.decrementMinutes() );
|
|
e.preventDefault();
|
|
});
|
|
}
|
|
|
|
scope.readonlyInput = (angular.isDefined(attrs.readonlyInput)) ? scope.$eval(attrs.readonlyInput) : timepickerConfig.readonlyInput;
|
|
if ( ! scope.readonlyInput ) {
|
|
|
|
var invalidate = function(invalidHours, invalidMinutes) {
|
|
ngModel.$setViewValue( null );
|
|
ngModel.$setValidity('time', false);
|
|
if (angular.isDefined(invalidHours)) {
|
|
scope.invalidHours = invalidHours;
|
|
}
|
|
if (angular.isDefined(invalidMinutes)) {
|
|
scope.invalidMinutes = invalidMinutes;
|
|
}
|
|
};
|
|
|
|
scope.updateHours = function() {
|
|
var hours = getHoursFromTemplate();
|
|
|
|
if ( angular.isDefined(hours) ) {
|
|
selected.setHours( hours );
|
|
refresh( 'h' );
|
|
} else {
|
|
invalidate(true);
|
|
}
|
|
};
|
|
|
|
hoursInputEl.bind('blur', function(e) {
|
|
if ( !scope.validHours && scope.hours < 10) {
|
|
scope.$apply( function() {
|
|
scope.hours = pad( scope.hours );
|
|
});
|
|
}
|
|
});
|
|
|
|
scope.updateMinutes = function() {
|
|
var minutes = getMinutesFromTemplate();
|
|
|
|
if ( angular.isDefined(minutes) ) {
|
|
selected.setMinutes( minutes );
|
|
refresh( 'm' );
|
|
} else {
|
|
invalidate(undefined, true);
|
|
}
|
|
};
|
|
|
|
minutesInputEl.bind('blur', function(e) {
|
|
if ( !scope.invalidMinutes && scope.minutes < 10 ) {
|
|
scope.$apply( function() {
|
|
scope.minutes = pad( scope.minutes );
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
scope.updateHours = angular.noop;
|
|
scope.updateMinutes = angular.noop;
|
|
}
|
|
|
|
ngModel.$render = function() {
|
|
var date = ngModel.$modelValue ? new Date( ngModel.$modelValue ) : null;
|
|
|
|
if ( isNaN(date) ) {
|
|
ngModel.$setValidity('time', false);
|
|
$log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
|
|
} else {
|
|
if ( date ) {
|
|
selected = date;
|
|
}
|
|
makeValid();
|
|
updateTemplate();
|
|
}
|
|
};
|
|
|
|
// Call internally when we know that model is valid.
|
|
function refresh( keyboardChange ) {
|
|
makeValid();
|
|
ngModel.$setViewValue( new Date(selected) );
|
|
updateTemplate( keyboardChange );
|
|
}
|
|
|
|
function makeValid() {
|
|
ngModel.$setValidity('time', true);
|
|
scope.invalidHours = false;
|
|
scope.invalidMinutes = false;
|
|
}
|
|
|
|
function updateTemplate( keyboardChange ) {
|
|
var hours = selected.getHours(), minutes = selected.getMinutes();
|
|
|
|
if ( scope.showMeridian ) {
|
|
hours = ( hours === 0 || hours === 12 ) ? 12 : hours % 12; // Convert 24 to 12 hour system
|
|
}
|
|
scope.hours = keyboardChange === 'h' ? hours : pad(hours);
|
|
scope.minutes = keyboardChange === 'm' ? minutes : pad(minutes);
|
|
scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
|
|
}
|
|
|
|
function addMinutes( minutes ) {
|
|
var dt = new Date( selected.getTime() + minutes * 60000 );
|
|
selected.setHours( dt.getHours(), dt.getMinutes() );
|
|
refresh();
|
|
}
|
|
|
|
scope.incrementHours = function() {
|
|
addMinutes( hourStep * 60 );
|
|
};
|
|
scope.decrementHours = function() {
|
|
addMinutes( - hourStep * 60 );
|
|
};
|
|
scope.incrementMinutes = function() {
|
|
addMinutes( minuteStep );
|
|
};
|
|
scope.decrementMinutes = function() {
|
|
addMinutes( - minuteStep );
|
|
};
|
|
scope.toggleMeridian = function() {
|
|
addMinutes( 12 * 60 * (( selected.getHours() < 12 ) ? 1 : -1) );
|
|
};
|
|
}
|
|
};
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap.bindHtml'])
|
|
|
|
/**
|
|
* A helper service that can parse typeahead's syntax (string provided by users)
|
|
* Extracted to a separate service for ease of unit testing
|
|
*/
|
|
.factory('typeaheadParser', ['$parse', function ($parse) {
|
|
|
|
// 00000111000000000000022200000000000000003333333333333330000000000044000
|
|
var TYPEAHEAD_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;
|
|
|
|
return {
|
|
parse:function (input) {
|
|
|
|
var match = input.match(TYPEAHEAD_REGEXP), modelMapper, viewMapper, source;
|
|
if (!match) {
|
|
throw new Error(
|
|
"Expected typeahead specification in form of '_modelValue_ (as _label_)? for _item_ in _collection_'" +
|
|
" but got '" + input + "'.");
|
|
}
|
|
|
|
return {
|
|
itemName:match[3],
|
|
source:$parse(match[4]),
|
|
viewMapper:$parse(match[2] || match[1]),
|
|
modelMapper:$parse(match[1])
|
|
};
|
|
}
|
|
};
|
|
}])
|
|
|
|
.directive('typeahead', ['$compile', '$parse', '$q', '$timeout', '$document', '$position', 'typeaheadParser',
|
|
function ($compile, $parse, $q, $timeout, $document, $position, typeaheadParser) {
|
|
|
|
var HOT_KEYS = [9, 13, 27, 38, 40];
|
|
|
|
return {
|
|
require:'ngModel',
|
|
link:function (originalScope, element, attrs, modelCtrl) {
|
|
|
|
//SUPPORTED ATTRIBUTES (OPTIONS)
|
|
|
|
//minimal no of characters that needs to be entered before typeahead kicks-in
|
|
var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 1;
|
|
|
|
//minimal wait time after last character typed before typehead kicks-in
|
|
var waitTime = originalScope.$eval(attrs.typeaheadWaitMs) || 0;
|
|
|
|
//should it restrict model values to the ones selected from the popup only?
|
|
var isEditable = originalScope.$eval(attrs.typeaheadEditable) !== false;
|
|
|
|
//binding to a variable that indicates if matches are being retrieved asynchronously
|
|
var isLoadingSetter = $parse(attrs.typeaheadLoading).assign || angular.noop;
|
|
|
|
//a callback executed when a match is selected
|
|
var onSelectCallback = $parse(attrs.typeaheadOnSelect);
|
|
|
|
var inputFormatter = attrs.typeaheadInputFormatter ? $parse(attrs.typeaheadInputFormatter) : undefined;
|
|
|
|
var appendToBody = attrs.typeaheadAppendToBody ? $parse(attrs.typeaheadAppendToBody) : false;
|
|
|
|
//INTERNAL VARIABLES
|
|
|
|
//model setter executed upon match selection
|
|
var $setModelValue = $parse(attrs.ngModel).assign;
|
|
|
|
//expressions used by typeahead
|
|
var parserResult = typeaheadParser.parse(attrs.typeahead);
|
|
|
|
var hasFocus;
|
|
|
|
//pop-up element used to display matches
|
|
var popUpEl = angular.element('<div typeahead-popup></div>');
|
|
popUpEl.attr({
|
|
matches: 'matches',
|
|
active: 'activeIdx',
|
|
select: 'select(activeIdx)',
|
|
query: 'query',
|
|
position: 'position'
|
|
});
|
|
//custom item template
|
|
if (angular.isDefined(attrs.typeaheadTemplateUrl)) {
|
|
popUpEl.attr('template-url', attrs.typeaheadTemplateUrl);
|
|
}
|
|
|
|
//create a child scope for the typeahead directive so we are not polluting original scope
|
|
//with typeahead-specific data (matches, query etc.)
|
|
var scope = originalScope.$new();
|
|
originalScope.$on('$destroy', function(){
|
|
scope.$destroy();
|
|
});
|
|
|
|
var resetMatches = function() {
|
|
scope.matches = [];
|
|
scope.activeIdx = -1;
|
|
};
|
|
|
|
var getMatchesAsync = function(inputValue) {
|
|
|
|
var locals = {$viewValue: inputValue};
|
|
isLoadingSetter(originalScope, true);
|
|
$q.when(parserResult.source(originalScope, locals)).then(function(matches) {
|
|
|
|
//it might happen that several async queries were in progress if a user were typing fast
|
|
//but we are interested only in responses that correspond to the current view value
|
|
if (inputValue === modelCtrl.$viewValue && hasFocus) {
|
|
if (matches.length > 0) {
|
|
|
|
scope.activeIdx = 0;
|
|
scope.matches.length = 0;
|
|
|
|
//transform labels
|
|
for(var i=0; i<matches.length; i++) {
|
|
locals[parserResult.itemName] = matches[i];
|
|
scope.matches.push({
|
|
label: parserResult.viewMapper(scope, locals),
|
|
model: matches[i]
|
|
});
|
|
}
|
|
|
|
scope.query = inputValue;
|
|
//position pop-up with matches - we need to re-calculate its position each time we are opening a window
|
|
//with matches as a pop-up might be absolute-positioned and position of an input might have changed on a page
|
|
//due to other elements being rendered
|
|
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
|
|
scope.position.top = scope.position.top + element.prop('offsetHeight');
|
|
|
|
} else {
|
|
resetMatches();
|
|
}
|
|
isLoadingSetter(originalScope, false);
|
|
}
|
|
}, function(){
|
|
resetMatches();
|
|
isLoadingSetter(originalScope, false);
|
|
});
|
|
};
|
|
|
|
resetMatches();
|
|
|
|
//we need to propagate user's query so we can higlight matches
|
|
scope.query = undefined;
|
|
|
|
//Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later
|
|
var timeoutPromise;
|
|
|
|
//plug into $parsers pipeline to open a typeahead on view changes initiated from DOM
|
|
//$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue
|
|
modelCtrl.$parsers.unshift(function (inputValue) {
|
|
|
|
hasFocus = true;
|
|
|
|
if (inputValue && inputValue.length >= minSearch) {
|
|
if (waitTime > 0) {
|
|
if (timeoutPromise) {
|
|
$timeout.cancel(timeoutPromise);//cancel previous timeout
|
|
}
|
|
timeoutPromise = $timeout(function () {
|
|
getMatchesAsync(inputValue);
|
|
}, waitTime);
|
|
} else {
|
|
getMatchesAsync(inputValue);
|
|
}
|
|
} else {
|
|
isLoadingSetter(originalScope, false);
|
|
resetMatches();
|
|
}
|
|
|
|
if (isEditable) {
|
|
return inputValue;
|
|
} else {
|
|
if (!inputValue) {
|
|
// Reset in case user had typed something previously.
|
|
modelCtrl.$setValidity('editable', true);
|
|
return inputValue;
|
|
} else {
|
|
modelCtrl.$setValidity('editable', false);
|
|
return undefined;
|
|
}
|
|
}
|
|
});
|
|
|
|
modelCtrl.$formatters.push(function (modelValue) {
|
|
|
|
var candidateViewValue, emptyViewValue;
|
|
var locals = {};
|
|
|
|
if (inputFormatter) {
|
|
|
|
locals['$model'] = modelValue;
|
|
return inputFormatter(originalScope, locals);
|
|
|
|
} else {
|
|
|
|
//it might happen that we don't have enough info to properly render input value
|
|
//we need to check for this situation and simply return model value if we can't apply custom formatting
|
|
locals[parserResult.itemName] = modelValue;
|
|
candidateViewValue = parserResult.viewMapper(originalScope, locals);
|
|
locals[parserResult.itemName] = undefined;
|
|
emptyViewValue = parserResult.viewMapper(originalScope, locals);
|
|
|
|
return candidateViewValue!== emptyViewValue ? candidateViewValue : modelValue;
|
|
}
|
|
});
|
|
|
|
scope.select = function (activeIdx) {
|
|
//called from within the $digest() cycle
|
|
var locals = {};
|
|
var model, item;
|
|
|
|
locals[parserResult.itemName] = item = scope.matches[activeIdx].model;
|
|
model = parserResult.modelMapper(originalScope, locals);
|
|
$setModelValue(originalScope, model);
|
|
modelCtrl.$setValidity('editable', true);
|
|
|
|
onSelectCallback(originalScope, {
|
|
$item: item,
|
|
$model: model,
|
|
$label: parserResult.viewMapper(originalScope, locals)
|
|
});
|
|
|
|
resetMatches();
|
|
|
|
//return focus to the input element if a mach was selected via a mouse click event
|
|
element[0].focus();
|
|
};
|
|
|
|
//bind keyboard events: arrows up(38) / down(40), enter(13) and tab(9), esc(27)
|
|
element.bind('keydown', function (evt) {
|
|
|
|
//typeahead is open and an "interesting" key was pressed
|
|
if (scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1) {
|
|
return;
|
|
}
|
|
|
|
evt.preventDefault();
|
|
|
|
if (evt.which === 40) {
|
|
scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length;
|
|
scope.$digest();
|
|
|
|
} else if (evt.which === 38) {
|
|
scope.activeIdx = (scope.activeIdx ? scope.activeIdx : scope.matches.length) - 1;
|
|
scope.$digest();
|
|
|
|
} else if (evt.which === 13 || evt.which === 9) {
|
|
scope.$apply(function () {
|
|
scope.select(scope.activeIdx);
|
|
});
|
|
|
|
} else if (evt.which === 27) {
|
|
evt.stopPropagation();
|
|
|
|
resetMatches();
|
|
scope.$digest();
|
|
}
|
|
});
|
|
|
|
element.bind('blur', function (evt) {
|
|
hasFocus = false;
|
|
});
|
|
|
|
// Keep reference to click handler to unbind it.
|
|
var dismissClickHandler = function (evt) {
|
|
if (element[0] !== evt.target) {
|
|
resetMatches();
|
|
scope.$digest();
|
|
}
|
|
};
|
|
|
|
$document.bind('click', dismissClickHandler);
|
|
|
|
originalScope.$on('$destroy', function(){
|
|
$document.unbind('click', dismissClickHandler);
|
|
});
|
|
|
|
var $popup = $compile(popUpEl)(scope);
|
|
if ( appendToBody ) {
|
|
$document.find('body').append($popup);
|
|
} else {
|
|
element.after($popup);
|
|
}
|
|
}
|
|
};
|
|
|
|
}])
|
|
|
|
.directive('typeaheadPopup', function () {
|
|
return {
|
|
restrict:'EA',
|
|
scope:{
|
|
matches:'=',
|
|
query:'=',
|
|
active:'=',
|
|
position:'=',
|
|
select:'&'
|
|
},
|
|
replace:true,
|
|
templateUrl:'template/typeahead/typeahead-popup.html',
|
|
link:function (scope, element, attrs) {
|
|
|
|
scope.templateUrl = attrs.templateUrl;
|
|
|
|
scope.isOpen = function () {
|
|
return scope.matches.length > 0;
|
|
};
|
|
|
|
scope.isActive = function (matchIdx) {
|
|
return scope.active == matchIdx;
|
|
};
|
|
|
|
scope.selectActive = function (matchIdx) {
|
|
scope.active = matchIdx;
|
|
};
|
|
|
|
scope.selectMatch = function (activeIdx) {
|
|
scope.select({activeIdx:activeIdx});
|
|
};
|
|
}
|
|
};
|
|
})
|
|
|
|
.directive('typeaheadMatch', ['$http', '$templateCache', '$compile', '$parse', function ($http, $templateCache, $compile, $parse) {
|
|
return {
|
|
restrict:'EA',
|
|
scope:{
|
|
index:'=',
|
|
match:'=',
|
|
query:'='
|
|
},
|
|
link:function (scope, element, attrs) {
|
|
var tplUrl = $parse(attrs.templateUrl)(scope.$parent) || 'template/typeahead/typeahead-match.html';
|
|
$http.get(tplUrl, {cache: $templateCache}).success(function(tplContent){
|
|
element.replaceWith($compile(tplContent.trim())(scope));
|
|
});
|
|
}
|
|
};
|
|
}])
|
|
|
|
.filter('typeaheadHighlight', function() {
|
|
|
|
function escapeRegexp(queryToEscape) {
|
|
return queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
|
|
}
|
|
|
|
return function(matchItem, query) {
|
|
return query ? matchItem.replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchItem;
|
|
};
|
|
});
|
|
// Source: public/lib/angular-bootstrap/ui-bootstrap-tpls.js
|
|
/*
|
|
* angular-ui-bootstrap
|
|
* http://angular-ui.github.io/bootstrap/
|
|
|
|
* Version: 0.10.0 - 2014-01-13
|
|
* License: MIT
|
|
*/
|
|
angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdownToggle","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);
|
|
angular.module("ui.bootstrap.tpls", ["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/datepicker/popup.html","template/modal/backdrop.html","template/modal/window.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/progressbar/progressbar.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"]);
|
|
angular.module('ui.bootstrap.transition', [])
|
|
|
|
/**
|
|
* $transition service provides a consistent interface to trigger CSS 3 transitions and to be informed when they complete.
|
|
* @param {DOMElement} element The DOMElement that will be animated.
|
|
* @param {string|object|function} trigger The thing that will cause the transition to start:
|
|
* - As a string, it represents the css class to be added to the element.
|
|
* - As an object, it represents a hash of style attributes to be applied to the element.
|
|
* - As a function, it represents a function to be called that will cause the transition to occur.
|
|
* @return {Promise} A promise that is resolved when the transition finishes.
|
|
*/
|
|
.factory('$transition', ['$q', '$timeout', '$rootScope', function($q, $timeout, $rootScope) {
|
|
|
|
var $transition = function(element, trigger, options) {
|
|
options = options || {};
|
|
var deferred = $q.defer();
|
|
var endEventName = $transition[options.animation ? "animationEndEventName" : "transitionEndEventName"];
|
|
|
|
var transitionEndHandler = function(event) {
|
|
$rootScope.$apply(function() {
|
|
element.unbind(endEventName, transitionEndHandler);
|
|
deferred.resolve(element);
|
|
});
|
|
};
|
|
|
|
if (endEventName) {
|
|
element.bind(endEventName, transitionEndHandler);
|
|
}
|
|
|
|
// Wrap in a timeout to allow the browser time to update the DOM before the transition is to occur
|
|
$timeout(function() {
|
|
if ( angular.isString(trigger) ) {
|
|
element.addClass(trigger);
|
|
} else if ( angular.isFunction(trigger) ) {
|
|
trigger(element);
|
|
} else if ( angular.isObject(trigger) ) {
|
|
element.css(trigger);
|
|
}
|
|
//If browser does not support transitions, instantly resolve
|
|
if ( !endEventName ) {
|
|
deferred.resolve(element);
|
|
}
|
|
});
|
|
|
|
// Add our custom cancel function to the promise that is returned
|
|
// We can call this if we are about to run a new transition, which we know will prevent this transition from ending,
|
|
// i.e. it will therefore never raise a transitionEnd event for that transition
|
|
deferred.promise.cancel = function() {
|
|
if ( endEventName ) {
|
|
element.unbind(endEventName, transitionEndHandler);
|
|
}
|
|
deferred.reject('Transition cancelled');
|
|
};
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
// Work out the name of the transitionEnd event
|
|
var transElement = document.createElement('trans');
|
|
var transitionEndEventNames = {
|
|
'WebkitTransition': 'webkitTransitionEnd',
|
|
'MozTransition': 'transitionend',
|
|
'OTransition': 'oTransitionEnd',
|
|
'transition': 'transitionend'
|
|
};
|
|
var animationEndEventNames = {
|
|
'WebkitTransition': 'webkitAnimationEnd',
|
|
'MozTransition': 'animationend',
|
|
'OTransition': 'oAnimationEnd',
|
|
'transition': 'animationend'
|
|
};
|
|
function findEndEventName(endEventNames) {
|
|
for (var name in endEventNames){
|
|
if (transElement.style[name] !== undefined) {
|
|
return endEventNames[name];
|
|
}
|
|
}
|
|
}
|
|
$transition.transitionEndEventName = findEndEventName(transitionEndEventNames);
|
|
$transition.animationEndEventName = findEndEventName(animationEndEventNames);
|
|
return $transition;
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.collapse', ['ui.bootstrap.transition'])
|
|
|
|
.directive('collapse', ['$transition', function ($transition, $timeout) {
|
|
|
|
return {
|
|
link: function (scope, element, attrs) {
|
|
|
|
var initialAnimSkip = true;
|
|
var currentTransition;
|
|
|
|
function doTransition(change) {
|
|
var newTransition = $transition(element, change);
|
|
if (currentTransition) {
|
|
currentTransition.cancel();
|
|
}
|
|
currentTransition = newTransition;
|
|
newTransition.then(newTransitionDone, newTransitionDone);
|
|
return newTransition;
|
|
|
|
function newTransitionDone() {
|
|
// Make sure it's this transition, otherwise, leave it alone.
|
|
if (currentTransition === newTransition) {
|
|
currentTransition = undefined;
|
|
}
|
|
}
|
|
}
|
|
|
|
function expand() {
|
|
if (initialAnimSkip) {
|
|
initialAnimSkip = false;
|
|
expandDone();
|
|
} else {
|
|
element.removeClass('collapse').addClass('collapsing');
|
|
doTransition({ height: element[0].scrollHeight + 'px' }).then(expandDone);
|
|
}
|
|
}
|
|
|
|
function expandDone() {
|
|
element.removeClass('collapsing');
|
|
element.addClass('collapse in');
|
|
element.css({height: 'auto'});
|
|
}
|
|
|
|
function collapse() {
|
|
if (initialAnimSkip) {
|
|
initialAnimSkip = false;
|
|
collapseDone();
|
|
element.css({height: 0});
|
|
} else {
|
|
// CSS transitions don't work with height: auto, so we have to manually change the height to a specific value
|
|
element.css({ height: element[0].scrollHeight + 'px' });
|
|
//trigger reflow so a browser realizes that height was updated from auto to a specific value
|
|
var x = element[0].offsetWidth;
|
|
|
|
element.removeClass('collapse in').addClass('collapsing');
|
|
|
|
doTransition({ height: 0 }).then(collapseDone);
|
|
}
|
|
}
|
|
|
|
function collapseDone() {
|
|
element.removeClass('collapsing');
|
|
element.addClass('collapse');
|
|
}
|
|
|
|
scope.$watch(attrs.collapse, function (shouldCollapse) {
|
|
if (shouldCollapse) {
|
|
collapse();
|
|
} else {
|
|
expand();
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
|
|
|
|
.constant('accordionConfig', {
|
|
closeOthers: true
|
|
})
|
|
|
|
.controller('AccordionController', ['$scope', '$attrs', 'accordionConfig', function ($scope, $attrs, accordionConfig) {
|
|
|
|
// This array keeps track of the accordion groups
|
|
this.groups = [];
|
|
|
|
// Ensure that all the groups in this accordion are closed, unless close-others explicitly says not to
|
|
this.closeOthers = function(openGroup) {
|
|
var closeOthers = angular.isDefined($attrs.closeOthers) ? $scope.$eval($attrs.closeOthers) : accordionConfig.closeOthers;
|
|
if ( closeOthers ) {
|
|
angular.forEach(this.groups, function (group) {
|
|
if ( group !== openGroup ) {
|
|
group.isOpen = false;
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
// This is called from the accordion-group directive to add itself to the accordion
|
|
this.addGroup = function(groupScope) {
|
|
var that = this;
|
|
this.groups.push(groupScope);
|
|
|
|
groupScope.$on('$destroy', function (event) {
|
|
that.removeGroup(groupScope);
|
|
});
|
|
};
|
|
|
|
// This is called from the accordion-group directive when to remove itself
|
|
this.removeGroup = function(group) {
|
|
var index = this.groups.indexOf(group);
|
|
if ( index !== -1 ) {
|
|
this.groups.splice(this.groups.indexOf(group), 1);
|
|
}
|
|
};
|
|
|
|
}])
|
|
|
|
// The accordion directive simply sets up the directive controller
|
|
// and adds an accordion CSS class to itself element.
|
|
.directive('accordion', function () {
|
|
return {
|
|
restrict:'EA',
|
|
controller:'AccordionController',
|
|
transclude: true,
|
|
replace: false,
|
|
templateUrl: 'template/accordion/accordion.html'
|
|
};
|
|
})
|
|
|
|
// The accordion-group directive indicates a block of html that will expand and collapse in an accordion
|
|
.directive('accordionGroup', ['$parse', function($parse) {
|
|
return {
|
|
require:'^accordion', // We need this directive to be inside an accordion
|
|
restrict:'EA',
|
|
transclude:true, // It transcludes the contents of the directive into the template
|
|
replace: true, // The element containing the directive will be replaced with the template
|
|
templateUrl:'template/accordion/accordion-group.html',
|
|
scope:{ heading:'@' }, // Create an isolated scope and interpolate the heading attribute onto this scope
|
|
controller: function() {
|
|
this.setHeading = function(element) {
|
|
this.heading = element;
|
|
};
|
|
},
|
|
link: function(scope, element, attrs, accordionCtrl) {
|
|
var getIsOpen, setIsOpen;
|
|
|
|
accordionCtrl.addGroup(scope);
|
|
|
|
scope.isOpen = false;
|
|
|
|
if ( attrs.isOpen ) {
|
|
getIsOpen = $parse(attrs.isOpen);
|
|
setIsOpen = getIsOpen.assign;
|
|
|
|
scope.$parent.$watch(getIsOpen, function(value) {
|
|
scope.isOpen = !!value;
|
|
});
|
|
}
|
|
|
|
scope.$watch('isOpen', function(value) {
|
|
if ( value ) {
|
|
accordionCtrl.closeOthers(scope);
|
|
}
|
|
if ( setIsOpen ) {
|
|
setIsOpen(scope.$parent, value);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}])
|
|
|
|
// Use accordion-heading below an accordion-group to provide a heading containing HTML
|
|
// <accordion-group>
|
|
// <accordion-heading>Heading containing HTML - <img src="..."></accordion-heading>
|
|
// </accordion-group>
|
|
.directive('accordionHeading', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
transclude: true, // Grab the contents to be used as the heading
|
|
template: '', // In effect remove this element!
|
|
replace: true,
|
|
require: '^accordionGroup',
|
|
compile: function(element, attr, transclude) {
|
|
return function link(scope, element, attr, accordionGroupCtrl) {
|
|
// Pass the heading to the accordion-group controller
|
|
// so that it can be transcluded into the right place in the template
|
|
// [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
|
|
accordionGroupCtrl.setHeading(transclude(scope, function() {}));
|
|
};
|
|
}
|
|
};
|
|
})
|
|
|
|
// Use in the accordion-group template to indicate where you want the heading to be transcluded
|
|
// You must provide the property on the accordion-group controller that will hold the transcluded element
|
|
// <div class="accordion-group">
|
|
// <div class="accordion-heading" ><a ... accordion-transclude="heading">...</a></div>
|
|
// ...
|
|
// </div>
|
|
.directive('accordionTransclude', function() {
|
|
return {
|
|
require: '^accordionGroup',
|
|
link: function(scope, element, attr, controller) {
|
|
scope.$watch(function() { return controller[attr.accordionTransclude]; }, function(heading) {
|
|
if ( heading ) {
|
|
element.html('');
|
|
element.append(heading);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
});
|
|
|
|
angular.module("ui.bootstrap.alert", [])
|
|
|
|
.controller('AlertController', ['$scope', '$attrs', function ($scope, $attrs) {
|
|
$scope.closeable = 'close' in $attrs;
|
|
}])
|
|
|
|
.directive('alert', function () {
|
|
return {
|
|
restrict:'EA',
|
|
controller:'AlertController',
|
|
templateUrl:'template/alert/alert.html',
|
|
transclude:true,
|
|
replace:true,
|
|
scope: {
|
|
type: '=',
|
|
close: '&'
|
|
}
|
|
};
|
|
});
|
|
|
|
angular.module('ui.bootstrap.bindHtml', [])
|
|
|
|
.directive('bindHtmlUnsafe', function () {
|
|
return function (scope, element, attr) {
|
|
element.addClass('ng-binding').data('$binding', attr.bindHtmlUnsafe);
|
|
scope.$watch(attr.bindHtmlUnsafe, function bindHtmlUnsafeWatchAction(value) {
|
|
element.html(value || '');
|
|
});
|
|
};
|
|
});
|
|
angular.module('ui.bootstrap.buttons', [])
|
|
|
|
.constant('buttonConfig', {
|
|
activeClass: 'active',
|
|
toggleEvent: 'click'
|
|
})
|
|
|
|
.controller('ButtonsController', ['buttonConfig', function(buttonConfig) {
|
|
this.activeClass = buttonConfig.activeClass || 'active';
|
|
this.toggleEvent = buttonConfig.toggleEvent || 'click';
|
|
}])
|
|
|
|
.directive('btnRadio', function () {
|
|
return {
|
|
require: ['btnRadio', 'ngModel'],
|
|
controller: 'ButtonsController',
|
|
link: function (scope, element, attrs, ctrls) {
|
|
var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
|
|
|
//model -> UI
|
|
ngModelCtrl.$render = function () {
|
|
element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, scope.$eval(attrs.btnRadio)));
|
|
};
|
|
|
|
//ui->model
|
|
element.bind(buttonsCtrl.toggleEvent, function () {
|
|
if (!element.hasClass(buttonsCtrl.activeClass)) {
|
|
scope.$apply(function () {
|
|
ngModelCtrl.$setViewValue(scope.$eval(attrs.btnRadio));
|
|
ngModelCtrl.$render();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
};
|
|
})
|
|
|
|
.directive('btnCheckbox', function () {
|
|
return {
|
|
require: ['btnCheckbox', 'ngModel'],
|
|
controller: 'ButtonsController',
|
|
link: function (scope, element, attrs, ctrls) {
|
|
var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1];
|
|
|
|
function getTrueValue() {
|
|
return getCheckboxValue(attrs.btnCheckboxTrue, true);
|
|
}
|
|
|
|
function getFalseValue() {
|
|
return getCheckboxValue(attrs.btnCheckboxFalse, false);
|
|
}
|
|
|
|
function getCheckboxValue(attributeValue, defaultValue) {
|
|
var val = scope.$eval(attributeValue);
|
|
return angular.isDefined(val) ? val : defaultValue;
|
|
}
|
|
|
|
//model -> UI
|
|
ngModelCtrl.$render = function () {
|
|
element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, getTrueValue()));
|
|
};
|
|
|
|
//ui->model
|
|
element.bind(buttonsCtrl.toggleEvent, function () {
|
|
scope.$apply(function () {
|
|
ngModelCtrl.$setViewValue(element.hasClass(buttonsCtrl.activeClass) ? getFalseValue() : getTrueValue());
|
|
ngModelCtrl.$render();
|
|
});
|
|
});
|
|
}
|
|
};
|
|
});
|
|
|
|
/**
|
|
* @ngdoc overview
|
|
* @name ui.bootstrap.carousel
|
|
*
|
|
* @description
|
|
* AngularJS version of an image carousel.
|
|
*
|
|
*/
|
|
angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
|
|
.controller('CarouselController', ['$scope', '$timeout', '$transition', '$q', function ($scope, $timeout, $transition, $q) {
|
|
var self = this,
|
|
slides = self.slides = [],
|
|
currentIndex = -1,
|
|
currentTimeout, isPlaying;
|
|
self.currentSlide = null;
|
|
|
|
var destroyed = false;
|
|
/* direction: "prev" or "next" */
|
|
self.select = function(nextSlide, direction) {
|
|
var nextIndex = slides.indexOf(nextSlide);
|
|
//Decide direction if it's not given
|
|
if (direction === undefined) {
|
|
direction = nextIndex > currentIndex ? "next" : "prev";
|
|
}
|
|
if (nextSlide && nextSlide !== self.currentSlide) {
|
|
if ($scope.$currentTransition) {
|
|
$scope.$currentTransition.cancel();
|
|
//Timeout so ng-class in template has time to fix classes for finished slide
|
|
$timeout(goNext);
|
|
} else {
|
|
goNext();
|
|
}
|
|
}
|
|
function goNext() {
|
|
// Scope has been destroyed, stop here.
|
|
if (destroyed) { return; }
|
|
//If we have a slide to transition from and we have a transition type and we're allowed, go
|
|
if (self.currentSlide && angular.isString(direction) && !$scope.noTransition && nextSlide.$element) {
|
|
//We shouldn't do class manip in here, but it's the same weird thing bootstrap does. need to fix sometime
|
|
nextSlide.$element.addClass(direction);
|
|
var reflow = nextSlide.$element[0].offsetWidth; //force reflow
|
|
|
|
//Set all other slides to stop doing their stuff for the new transition
|
|
angular.forEach(slides, function(slide) {
|
|
angular.extend(slide, {direction: '', entering: false, leaving: false, active: false});
|
|
});
|
|
angular.extend(nextSlide, {direction: direction, active: true, entering: true});
|
|
angular.extend(self.currentSlide||{}, {direction: direction, leaving: true});
|
|
|
|
$scope.$currentTransition = $transition(nextSlide.$element, {});
|
|
//We have to create new pointers inside a closure since next & current will change
|
|
(function(next,current) {
|
|
$scope.$currentTransition.then(
|
|
function(){ transitionDone(next, current); },
|
|
function(){ transitionDone(next, current); }
|
|
);
|
|
}(nextSlide, self.currentSlide));
|
|
} else {
|
|
transitionDone(nextSlide, self.currentSlide);
|
|
}
|
|
self.currentSlide = nextSlide;
|
|
currentIndex = nextIndex;
|
|
//every time you change slides, reset the timer
|
|
restartTimer();
|
|
}
|
|
function transitionDone(next, current) {
|
|
angular.extend(next, {direction: '', active: true, leaving: false, entering: false});
|
|
angular.extend(current||{}, {direction: '', active: false, leaving: false, entering: false});
|
|
$scope.$currentTransition = null;
|
|
}
|
|
};
|
|
$scope.$on('$destroy', function () {
|
|
destroyed = true;
|
|
});
|
|
|
|
/* Allow outside people to call indexOf on slides array */
|
|
self.indexOfSlide = function(slide) {
|
|
return slides.indexOf(slide);
|
|
};
|
|
|
|
$scope.next = function() {
|
|
var newIndex = (currentIndex + 1) % slides.length;
|
|
|
|
//Prevent this user-triggered transition from occurring if there is already one in progress
|
|
if (!$scope.$currentTransition) {
|
|
return self.select(slides[newIndex], 'next');
|
|
}
|
|
};
|
|
|
|
$scope.prev = function() {
|
|
var newIndex = currentIndex - 1 < 0 ? slides.length - 1 : currentIndex - 1;
|
|
|
|
//Prevent this user-triggered transition from occurring if there is already one in progress
|
|
if (!$scope.$currentTransition) {
|
|
return self.select(slides[newIndex], 'prev');
|
|
}
|
|
};
|
|
|
|
$scope.select = function(slide) {
|
|
self.select(slide);
|
|
};
|
|
|
|
$scope.isActive = function(slide) {
|
|
return self.currentSlide === slide;
|
|
};
|
|
|
|
$scope.slides = function() {
|
|
return slides;
|
|
};
|
|
|
|
$scope.$watch('interval', restartTimer);
|
|
$scope.$on('$destroy', resetTimer);
|
|
|
|
function restartTimer() {
|
|
resetTimer();
|
|
var interval = +$scope.interval;
|
|
if (!isNaN(interval) && interval>=0) {
|
|
currentTimeout = $timeout(timerFn, interval);
|
|
}
|
|
}
|
|
|
|
function resetTimer() {
|
|
if (currentTimeout) {
|
|
$timeout.cancel(currentTimeout);
|
|
currentTimeout = null;
|
|
}
|
|
}
|
|
|
|
function timerFn() {
|
|
if (isPlaying) {
|
|
$scope.next();
|
|
restartTimer();
|
|
} else {
|
|
$scope.pause();
|
|
}
|
|
}
|
|
|
|
$scope.play = function() {
|
|
if (!isPlaying) {
|
|
isPlaying = true;
|
|
restartTimer();
|
|
}
|
|
};
|
|
$scope.pause = function() {
|
|
if (!$scope.noPause) {
|
|
isPlaying = false;
|
|
resetTimer();
|
|
}
|
|
};
|
|
|
|
self.addSlide = function(slide, element) {
|
|
slide.$element = element;
|
|
slides.push(slide);
|
|
//if this is the first slide or the slide is set to active, select it
|
|
if(slides.length === 1 || slide.active) {
|
|
self.select(slides[slides.length-1]);
|
|
if (slides.length == 1) {
|
|
$scope.play();
|
|
}
|
|
} else {
|
|
slide.active = false;
|
|
}
|
|
};
|
|
|
|
self.removeSlide = function(slide) {
|
|
//get the index of the slide inside the carousel
|
|
var index = slides.indexOf(slide);
|
|
slides.splice(index, 1);
|
|
if (slides.length > 0 && slide.active) {
|
|
if (index >= slides.length) {
|
|
self.select(slides[index-1]);
|
|
} else {
|
|
self.select(slides[index]);
|
|
}
|
|
} else if (currentIndex > index) {
|
|
currentIndex--;
|
|
}
|
|
};
|
|
|
|
}])
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name ui.bootstrap.carousel.directive:carousel
|
|
* @restrict EA
|
|
*
|
|
* @description
|
|
* Carousel is the outer container for a set of image 'slides' to showcase.
|
|
*
|
|
* @param {number=} interval The time, in milliseconds, that it will take the carousel to go to the next slide.
|
|
* @param {boolean=} noTransition Whether to disable transitions on the carousel.
|
|
* @param {boolean=} noPause Whether to disable pausing on the carousel (by default, the carousel interval pauses on hover).
|
|
*
|
|
* @example
|
|
<example module="ui.bootstrap">
|
|
<file name="index.html">
|
|
<carousel>
|
|
<slide>
|
|
<img src="http://placekitten.com/150/150" style="margin:auto;">
|
|
<div class="carousel-caption">
|
|
<p>Beautiful!</p>
|
|
</div>
|
|
</slide>
|
|
<slide>
|
|
<img src="http://placekitten.com/100/150" style="margin:auto;">
|
|
<div class="carousel-caption">
|
|
<p>D'aww!</p>
|
|
</div>
|
|
</slide>
|
|
</carousel>
|
|
</file>
|
|
<file name="demo.css">
|
|
.carousel-indicators {
|
|
top: auto;
|
|
bottom: 15px;
|
|
}
|
|
</file>
|
|
</example>
|
|
*/
|
|
.directive('carousel', [function() {
|
|
return {
|
|
restrict: 'EA',
|
|
transclude: true,
|
|
replace: true,
|
|
controller: 'CarouselController',
|
|
require: 'carousel',
|
|
templateUrl: 'template/carousel/carousel.html',
|
|
scope: {
|
|
interval: '=',
|
|
noTransition: '=',
|
|
noPause: '='
|
|
}
|
|
};
|
|
}])
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name ui.bootstrap.carousel.directive:slide
|
|
* @restrict EA
|
|
*
|
|
* @description
|
|
* Creates a slide inside a {@link ui.bootstrap.carousel.directive:carousel carousel}. Must be placed as a child of a carousel element.
|
|
*
|
|
* @param {boolean=} active Model binding, whether or not this slide is currently active.
|
|
*
|
|
* @example
|
|
<example module="ui.bootstrap">
|
|
<file name="index.html">
|
|
<div ng-controller="CarouselDemoCtrl">
|
|
<carousel>
|
|
<slide ng-repeat="slide in slides" active="slide.active">
|
|
<img ng-src="{{slide.image}}" style="margin:auto;">
|
|
<div class="carousel-caption">
|
|
<h4>Slide {{$index}}</h4>
|
|
<p>{{slide.text}}</p>
|
|
</div>
|
|
</slide>
|
|
</carousel>
|
|
<div class="row-fluid">
|
|
<div class="span6">
|
|
<ul>
|
|
<li ng-repeat="slide in slides">
|
|
<button class="btn btn-mini" ng-class="{'btn-info': !slide.active, 'btn-success': slide.active}" ng-disabled="slide.active" ng-click="slide.active = true">select</button>
|
|
{{$index}}: {{slide.text}}
|
|
</li>
|
|
</ul>
|
|
<a class="btn" ng-click="addSlide()">Add Slide</a>
|
|
</div>
|
|
<div class="span6">
|
|
Interval, in milliseconds: <input type="number" ng-model="myInterval">
|
|
<br />Enter a negative number to stop the interval.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</file>
|
|
<file name="script.js">
|
|
function CarouselDemoCtrl($scope) {
|
|
$scope.myInterval = 5000;
|
|
var slides = $scope.slides = [];
|
|
$scope.addSlide = function() {
|
|
var newWidth = 200 + ((slides.length + (25 * slides.length)) % 150);
|
|
slides.push({
|
|
image: 'http://placekitten.com/' + newWidth + '/200',
|
|
text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' '
|
|
['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
|
|
});
|
|
};
|
|
for (var i=0; i<4; i++) $scope.addSlide();
|
|
}
|
|
</file>
|
|
<file name="demo.css">
|
|
.carousel-indicators {
|
|
top: auto;
|
|
bottom: 15px;
|
|
}
|
|
</file>
|
|
</example>
|
|
*/
|
|
|
|
.directive('slide', ['$parse', function($parse) {
|
|
return {
|
|
require: '^carousel',
|
|
restrict: 'EA',
|
|
transclude: true,
|
|
replace: true,
|
|
templateUrl: 'template/carousel/slide.html',
|
|
scope: {
|
|
},
|
|
link: function (scope, element, attrs, carouselCtrl) {
|
|
//Set up optional 'active' = binding
|
|
if (attrs.active) {
|
|
var getActive = $parse(attrs.active);
|
|
var setActive = getActive.assign;
|
|
var lastValue = scope.active = getActive(scope.$parent);
|
|
scope.$watch(function parentActiveWatch() {
|
|
var parentActive = getActive(scope.$parent);
|
|
|
|
if (parentActive !== scope.active) {
|
|
// we are out of sync and need to copy
|
|
if (parentActive !== lastValue) {
|
|
// parent changed and it has precedence
|
|
lastValue = scope.active = parentActive;
|
|
} else {
|
|
// if the parent can be assigned then do so
|
|
setActive(scope.$parent, parentActive = lastValue = scope.active);
|
|
}
|
|
}
|
|
return parentActive;
|
|
});
|
|
}
|
|
|
|
carouselCtrl.addSlide(scope, element);
|
|
//when the scope is destroyed then remove the slide from the current slides array
|
|
scope.$on('$destroy', function() {
|
|
carouselCtrl.removeSlide(scope);
|
|
});
|
|
|
|
scope.$watch('active', function(active) {
|
|
if (active) {
|
|
carouselCtrl.select(scope);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.position', [])
|
|
|
|
/**
|
|
* A set of utility methods that can be use to retrieve position of DOM elements.
|
|
* It is meant to be used where we need to absolute-position DOM elements in
|
|
* relation to other, existing elements (this is the case for tooltips, popovers,
|
|
* typeahead suggestions etc.).
|
|
*/
|
|
.factory('$position', ['$document', '$window', function ($document, $window) {
|
|
|
|
function getStyle(el, cssprop) {
|
|
if (el.currentStyle) { //IE
|
|
return el.currentStyle[cssprop];
|
|
} else if ($window.getComputedStyle) {
|
|
return $window.getComputedStyle(el)[cssprop];
|
|
}
|
|
// finally try and get inline style
|
|
return el.style[cssprop];
|
|
}
|
|
|
|
/**
|
|
* Checks if a given element is statically positioned
|
|
* @param element - raw DOM element
|
|
*/
|
|
function isStaticPositioned(element) {
|
|
return (getStyle(element, "position") || 'static' ) === 'static';
|
|
}
|
|
|
|
/**
|
|
* returns the closest, non-statically positioned parentOffset of a given element
|
|
* @param element
|
|
*/
|
|
var parentOffsetEl = function (element) {
|
|
var docDomEl = $document[0];
|
|
var offsetParent = element.offsetParent || docDomEl;
|
|
while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent) ) {
|
|
offsetParent = offsetParent.offsetParent;
|
|
}
|
|
return offsetParent || docDomEl;
|
|
};
|
|
|
|
return {
|
|
/**
|
|
* Provides read-only equivalent of jQuery's position function:
|
|
* http://api.jquery.com/position/
|
|
*/
|
|
position: function (element) {
|
|
var elBCR = this.offset(element);
|
|
var offsetParentBCR = { top: 0, left: 0 };
|
|
var offsetParentEl = parentOffsetEl(element[0]);
|
|
if (offsetParentEl != $document[0]) {
|
|
offsetParentBCR = this.offset(angular.element(offsetParentEl));
|
|
offsetParentBCR.top += offsetParentEl.clientTop - offsetParentEl.scrollTop;
|
|
offsetParentBCR.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft;
|
|
}
|
|
|
|
var boundingClientRect = element[0].getBoundingClientRect();
|
|
return {
|
|
width: boundingClientRect.width || element.prop('offsetWidth'),
|
|
height: boundingClientRect.height || element.prop('offsetHeight'),
|
|
top: elBCR.top - offsetParentBCR.top,
|
|
left: elBCR.left - offsetParentBCR.left
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Provides read-only equivalent of jQuery's offset function:
|
|
* http://api.jquery.com/offset/
|
|
*/
|
|
offset: function (element) {
|
|
var boundingClientRect = element[0].getBoundingClientRect();
|
|
return {
|
|
width: boundingClientRect.width || element.prop('offsetWidth'),
|
|
height: boundingClientRect.height || element.prop('offsetHeight'),
|
|
top: boundingClientRect.top + ($window.pageYOffset || $document[0].body.scrollTop || $document[0].documentElement.scrollTop),
|
|
left: boundingClientRect.left + ($window.pageXOffset || $document[0].body.scrollLeft || $document[0].documentElement.scrollLeft)
|
|
};
|
|
}
|
|
};
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.position'])
|
|
|
|
.constant('datepickerConfig', {
|
|
dayFormat: 'dd',
|
|
monthFormat: 'MMMM',
|
|
yearFormat: 'yyyy',
|
|
dayHeaderFormat: 'EEE',
|
|
dayTitleFormat: 'MMMM yyyy',
|
|
monthTitleFormat: 'yyyy',
|
|
showWeeks: true,
|
|
startingDay: 0,
|
|
yearRange: 20,
|
|
minDate: null,
|
|
maxDate: null
|
|
})
|
|
|
|
.controller('DatepickerController', ['$scope', '$attrs', 'dateFilter', 'datepickerConfig', function($scope, $attrs, dateFilter, dtConfig) {
|
|
var format = {
|
|
day: getValue($attrs.dayFormat, dtConfig.dayFormat),
|
|
month: getValue($attrs.monthFormat, dtConfig.monthFormat),
|
|
year: getValue($attrs.yearFormat, dtConfig.yearFormat),
|
|
dayHeader: getValue($attrs.dayHeaderFormat, dtConfig.dayHeaderFormat),
|
|
dayTitle: getValue($attrs.dayTitleFormat, dtConfig.dayTitleFormat),
|
|
monthTitle: getValue($attrs.monthTitleFormat, dtConfig.monthTitleFormat)
|
|
},
|
|
startingDay = getValue($attrs.startingDay, dtConfig.startingDay),
|
|
yearRange = getValue($attrs.yearRange, dtConfig.yearRange);
|
|
|
|
this.minDate = dtConfig.minDate ? new Date(dtConfig.minDate) : null;
|
|
this.maxDate = dtConfig.maxDate ? new Date(dtConfig.maxDate) : null;
|
|
|
|
function getValue(value, defaultValue) {
|
|
return angular.isDefined(value) ? $scope.$parent.$eval(value) : defaultValue;
|
|
}
|
|
|
|
function getDaysInMonth( year, month ) {
|
|
return new Date(year, month, 0).getDate();
|
|
}
|
|
|
|
function getDates(startDate, n) {
|
|
var dates = new Array(n);
|
|
var current = startDate, i = 0;
|
|
while (i < n) {
|
|
dates[i++] = new Date(current);
|
|
current.setDate( current.getDate() + 1 );
|
|
}
|
|
return dates;
|
|
}
|
|
|
|
function makeDate(date, format, isSelected, isSecondary) {
|
|
return { date: date, label: dateFilter(date, format), selected: !!isSelected, secondary: !!isSecondary };
|
|
}
|
|
|
|
this.modes = [
|
|
{
|
|
name: 'day',
|
|
getVisibleDates: function(date, selected) {
|
|
var year = date.getFullYear(), month = date.getMonth(), firstDayOfMonth = new Date(year, month, 1);
|
|
var difference = startingDay - firstDayOfMonth.getDay(),
|
|
numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : - difference,
|
|
firstDate = new Date(firstDayOfMonth), numDates = 0;
|
|
|
|
if ( numDisplayedFromPreviousMonth > 0 ) {
|
|
firstDate.setDate( - numDisplayedFromPreviousMonth + 1 );
|
|
numDates += numDisplayedFromPreviousMonth; // Previous
|
|
}
|
|
numDates += getDaysInMonth(year, month + 1); // Current
|
|
numDates += (7 - numDates % 7) % 7; // Next
|
|
|
|
var days = getDates(firstDate, numDates), labels = new Array(7);
|
|
for (var i = 0; i < numDates; i ++) {
|
|
var dt = new Date(days[i]);
|
|
days[i] = makeDate(dt, format.day, (selected && selected.getDate() === dt.getDate() && selected.getMonth() === dt.getMonth() && selected.getFullYear() === dt.getFullYear()), dt.getMonth() !== month);
|
|
}
|
|
for (var j = 0; j < 7; j++) {
|
|
labels[j] = dateFilter(days[j].date, format.dayHeader);
|
|
}
|
|
return { objects: days, title: dateFilter(date, format.dayTitle), labels: labels };
|
|
},
|
|
compare: function(date1, date2) {
|
|
return (new Date( date1.getFullYear(), date1.getMonth(), date1.getDate() ) - new Date( date2.getFullYear(), date2.getMonth(), date2.getDate() ) );
|
|
},
|
|
split: 7,
|
|
step: { months: 1 }
|
|
},
|
|
{
|
|
name: 'month',
|
|
getVisibleDates: function(date, selected) {
|
|
var months = new Array(12), year = date.getFullYear();
|
|
for ( var i = 0; i < 12; i++ ) {
|
|
var dt = new Date(year, i, 1);
|
|
months[i] = makeDate(dt, format.month, (selected && selected.getMonth() === i && selected.getFullYear() === year));
|
|
}
|
|
return { objects: months, title: dateFilter(date, format.monthTitle) };
|
|
},
|
|
compare: function(date1, date2) {
|
|
return new Date( date1.getFullYear(), date1.getMonth() ) - new Date( date2.getFullYear(), date2.getMonth() );
|
|
},
|
|
split: 3,
|
|
step: { years: 1 }
|
|
},
|
|
{
|
|
name: 'year',
|
|
getVisibleDates: function(date, selected) {
|
|
var years = new Array(yearRange), year = date.getFullYear(), startYear = parseInt((year - 1) / yearRange, 10) * yearRange + 1;
|
|
for ( var i = 0; i < yearRange; i++ ) {
|
|
var dt = new Date(startYear + i, 0, 1);
|
|
years[i] = makeDate(dt, format.year, (selected && selected.getFullYear() === dt.getFullYear()));
|
|
}
|
|
return { objects: years, title: [years[0].label, years[yearRange - 1].label].join(' - ') };
|
|
},
|
|
compare: function(date1, date2) {
|
|
return date1.getFullYear() - date2.getFullYear();
|
|
},
|
|
split: 5,
|
|
step: { years: yearRange }
|
|
}
|
|
];
|
|
|
|
this.isDisabled = function(date, mode) {
|
|
var currentMode = this.modes[mode || 0];
|
|
return ((this.minDate && currentMode.compare(date, this.minDate) < 0) || (this.maxDate && currentMode.compare(date, this.maxDate) > 0) || ($scope.dateDisabled && $scope.dateDisabled({date: date, mode: currentMode.name})));
|
|
};
|
|
}])
|
|
|
|
.directive( 'datepicker', ['dateFilter', '$parse', 'datepickerConfig', '$log', function (dateFilter, $parse, datepickerConfig, $log) {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
templateUrl: 'template/datepicker/datepicker.html',
|
|
scope: {
|
|
dateDisabled: '&'
|
|
},
|
|
require: ['datepicker', '?^ngModel'],
|
|
controller: 'DatepickerController',
|
|
link: function(scope, element, attrs, ctrls) {
|
|
var datepickerCtrl = ctrls[0], ngModel = ctrls[1];
|
|
|
|
if (!ngModel) {
|
|
return; // do nothing if no ng-model
|
|
}
|
|
|
|
// Configuration parameters
|
|
var mode = 0, selected = new Date(), showWeeks = datepickerConfig.showWeeks;
|
|
|
|
if (attrs.showWeeks) {
|
|
scope.$parent.$watch($parse(attrs.showWeeks), function(value) {
|
|
showWeeks = !! value;
|
|
updateShowWeekNumbers();
|
|
});
|
|
} else {
|
|
updateShowWeekNumbers();
|
|
}
|
|
|
|
if (attrs.min) {
|
|
scope.$parent.$watch($parse(attrs.min), function(value) {
|
|
datepickerCtrl.minDate = value ? new Date(value) : null;
|
|
refill();
|
|
});
|
|
}
|
|
if (attrs.max) {
|
|
scope.$parent.$watch($parse(attrs.max), function(value) {
|
|
datepickerCtrl.maxDate = value ? new Date(value) : null;
|
|
refill();
|
|
});
|
|
}
|
|
|
|
function updateShowWeekNumbers() {
|
|
scope.showWeekNumbers = mode === 0 && showWeeks;
|
|
}
|
|
|
|
// Split array into smaller arrays
|
|
function split(arr, size) {
|
|
var arrays = [];
|
|
while (arr.length > 0) {
|
|
arrays.push(arr.splice(0, size));
|
|
}
|
|
return arrays;
|
|
}
|
|
|
|
function refill( updateSelected ) {
|
|
var date = null, valid = true;
|
|
|
|
if ( ngModel.$modelValue ) {
|
|
date = new Date( ngModel.$modelValue );
|
|
|
|
if ( isNaN(date) ) {
|
|
valid = false;
|
|
$log.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
|
|
} else if ( updateSelected ) {
|
|
selected = date;
|
|
}
|
|
}
|
|
ngModel.$setValidity('date', valid);
|
|
|
|
var currentMode = datepickerCtrl.modes[mode], data = currentMode.getVisibleDates(selected, date);
|
|
angular.forEach(data.objects, function(obj) {
|
|
obj.disabled = datepickerCtrl.isDisabled(obj.date, mode);
|
|
});
|
|
|
|
ngModel.$setValidity('date-disabled', (!date || !datepickerCtrl.isDisabled(date)));
|
|
|
|
scope.rows = split(data.objects, currentMode.split);
|
|
scope.labels = data.labels || [];
|
|
scope.title = data.title;
|
|
}
|
|
|
|
function setMode(value) {
|
|
mode = value;
|
|
updateShowWeekNumbers();
|
|
refill();
|
|
}
|
|
|
|
ngModel.$render = function() {
|
|
refill( true );
|
|
};
|
|
|
|
scope.select = function( date ) {
|
|
if ( mode === 0 ) {
|
|
var dt = ngModel.$modelValue ? new Date( ngModel.$modelValue ) : new Date(0, 0, 0, 0, 0, 0, 0);
|
|
dt.setFullYear( date.getFullYear(), date.getMonth(), date.getDate() );
|
|
ngModel.$setViewValue( dt );
|
|
refill( true );
|
|
} else {
|
|
selected = date;
|
|
setMode( mode - 1 );
|
|
}
|
|
};
|
|
scope.move = function(direction) {
|
|
var step = datepickerCtrl.modes[mode].step;
|
|
selected.setMonth( selected.getMonth() + direction * (step.months || 0) );
|
|
selected.setFullYear( selected.getFullYear() + direction * (step.years || 0) );
|
|
refill();
|
|
};
|
|
scope.toggleMode = function() {
|
|
setMode( (mode + 1) % datepickerCtrl.modes.length );
|
|
};
|
|
scope.getWeekNumber = function(row) {
|
|
return ( mode === 0 && scope.showWeekNumbers && row.length === 7 ) ? getISO8601WeekNumber(row[0].date) : null;
|
|
};
|
|
|
|
function getISO8601WeekNumber(date) {
|
|
var checkDate = new Date(date);
|
|
checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); // Thursday
|
|
var time = checkDate.getTime();
|
|
checkDate.setMonth(0); // Compare with Jan 1
|
|
checkDate.setDate(1);
|
|
return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
|
|
}
|
|
}
|
|
};
|
|
}])
|
|
|
|
.constant('datepickerPopupConfig', {
|
|
dateFormat: 'yyyy-MM-dd',
|
|
currentText: 'Today',
|
|
toggleWeeksText: 'Weeks',
|
|
clearText: 'Clear',
|
|
closeText: 'Done',
|
|
closeOnDateSelection: true,
|
|
appendToBody: false,
|
|
showButtonBar: true
|
|
})
|
|
|
|
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'datepickerPopupConfig', 'datepickerConfig',
|
|
function ($compile, $parse, $document, $position, dateFilter, datepickerPopupConfig, datepickerConfig) {
|
|
return {
|
|
restrict: 'EA',
|
|
require: 'ngModel',
|
|
link: function(originalScope, element, attrs, ngModel) {
|
|
var scope = originalScope.$new(), // create a child scope so we are not polluting original one
|
|
dateFormat,
|
|
closeOnDateSelection = angular.isDefined(attrs.closeOnDateSelection) ? originalScope.$eval(attrs.closeOnDateSelection) : datepickerPopupConfig.closeOnDateSelection,
|
|
appendToBody = angular.isDefined(attrs.datepickerAppendToBody) ? originalScope.$eval(attrs.datepickerAppendToBody) : datepickerPopupConfig.appendToBody;
|
|
|
|
attrs.$observe('datepickerPopup', function(value) {
|
|
dateFormat = value || datepickerPopupConfig.dateFormat;
|
|
ngModel.$render();
|
|
});
|
|
|
|
scope.showButtonBar = angular.isDefined(attrs.showButtonBar) ? originalScope.$eval(attrs.showButtonBar) : datepickerPopupConfig.showButtonBar;
|
|
|
|
originalScope.$on('$destroy', function() {
|
|
$popup.remove();
|
|
scope.$destroy();
|
|
});
|
|
|
|
attrs.$observe('currentText', function(text) {
|
|
scope.currentText = angular.isDefined(text) ? text : datepickerPopupConfig.currentText;
|
|
});
|
|
attrs.$observe('toggleWeeksText', function(text) {
|
|
scope.toggleWeeksText = angular.isDefined(text) ? text : datepickerPopupConfig.toggleWeeksText;
|
|
});
|
|
attrs.$observe('clearText', function(text) {
|
|
scope.clearText = angular.isDefined(text) ? text : datepickerPopupConfig.clearText;
|
|
});
|
|
attrs.$observe('closeText', function(text) {
|
|
scope.closeText = angular.isDefined(text) ? text : datepickerPopupConfig.closeText;
|
|
});
|
|
|
|
var getIsOpen, setIsOpen;
|
|
if ( attrs.isOpen ) {
|
|
getIsOpen = $parse(attrs.isOpen);
|
|
setIsOpen = getIsOpen.assign;
|
|
|
|
originalScope.$watch(getIsOpen, function updateOpen(value) {
|
|
scope.isOpen = !! value;
|
|
});
|
|
}
|
|
scope.isOpen = getIsOpen ? getIsOpen(originalScope) : false; // Initial state
|
|
|
|
function setOpen( value ) {
|
|
if (setIsOpen) {
|
|
setIsOpen(originalScope, !!value);
|
|
} else {
|
|
scope.isOpen = !!value;
|
|
}
|
|
}
|
|
|
|
var documentClickBind = function(event) {
|
|
if (scope.isOpen && event.target !== element[0]) {
|
|
scope.$apply(function() {
|
|
setOpen(false);
|
|
});
|
|
}
|
|
};
|
|
|
|
var elementFocusBind = function() {
|
|
scope.$apply(function() {
|
|
setOpen( true );
|
|
});
|
|
};
|
|
|
|
// popup element used to display calendar
|
|
var popupEl = angular.element('<div datepicker-popup-wrap><div datepicker></div></div>');
|
|
popupEl.attr({
|
|
'ng-model': 'date',
|
|
'ng-change': 'dateSelection()'
|
|
});
|
|
var datepickerEl = angular.element(popupEl.children()[0]),
|
|
datepickerOptions = {};
|
|
if (attrs.datepickerOptions) {
|
|
datepickerOptions = originalScope.$eval(attrs.datepickerOptions);
|
|
datepickerEl.attr(angular.extend({}, datepickerOptions));
|
|
}
|
|
|
|
// TODO: reverse from dateFilter string to Date object
|
|
function parseDate(viewValue) {
|
|
if (!viewValue) {
|
|
ngModel.$setValidity('date', true);
|
|
return null;
|
|
} else if (angular.isDate(viewValue)) {
|
|
ngModel.$setValidity('date', true);
|
|
return viewValue;
|
|
} else if (angular.isString(viewValue)) {
|
|
var date = new Date(viewValue);
|
|
if (isNaN(date)) {
|
|
ngModel.$setValidity('date', false);
|
|
return undefined;
|
|
} else {
|
|
ngModel.$setValidity('date', true);
|
|
return date;
|
|
}
|
|
} else {
|
|
ngModel.$setValidity('date', false);
|
|
return undefined;
|
|
}
|
|
}
|
|
ngModel.$parsers.unshift(parseDate);
|
|
|
|
// Inner change
|
|
scope.dateSelection = function(dt) {
|
|
if (angular.isDefined(dt)) {
|
|
scope.date = dt;
|
|
}
|
|
ngModel.$setViewValue(scope.date);
|
|
ngModel.$render();
|
|
|
|
if (closeOnDateSelection) {
|
|
setOpen( false );
|
|
}
|
|
};
|
|
|
|
element.bind('input change keyup', function() {
|
|
scope.$apply(function() {
|
|
scope.date = ngModel.$modelValue;
|
|
});
|
|
});
|
|
|
|
// Outter change
|
|
ngModel.$render = function() {
|
|
var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
|
|
element.val(date);
|
|
scope.date = ngModel.$modelValue;
|
|
};
|
|
|
|
function addWatchableAttribute(attribute, scopeProperty, datepickerAttribute) {
|
|
if (attribute) {
|
|
originalScope.$watch($parse(attribute), function(value){
|
|
scope[scopeProperty] = value;
|
|
});
|
|
datepickerEl.attr(datepickerAttribute || scopeProperty, scopeProperty);
|
|
}
|
|
}
|
|
addWatchableAttribute(attrs.min, 'min');
|
|
addWatchableAttribute(attrs.max, 'max');
|
|
if (attrs.showWeeks) {
|
|
addWatchableAttribute(attrs.showWeeks, 'showWeeks', 'show-weeks');
|
|
} else {
|
|
scope.showWeeks = 'show-weeks' in datepickerOptions ? datepickerOptions['show-weeks'] : datepickerConfig.showWeeks;
|
|
datepickerEl.attr('show-weeks', 'showWeeks');
|
|
}
|
|
if (attrs.dateDisabled) {
|
|
datepickerEl.attr('date-disabled', attrs.dateDisabled);
|
|
}
|
|
|
|
function updatePosition() {
|
|
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
|
|
scope.position.top = scope.position.top + element.prop('offsetHeight');
|
|
}
|
|
|
|
var documentBindingInitialized = false, elementFocusInitialized = false;
|
|
scope.$watch('isOpen', function(value) {
|
|
if (value) {
|
|
updatePosition();
|
|
$document.bind('click', documentClickBind);
|
|
if(elementFocusInitialized) {
|
|
element.unbind('focus', elementFocusBind);
|
|
}
|
|
element[0].focus();
|
|
documentBindingInitialized = true;
|
|
} else {
|
|
if(documentBindingInitialized) {
|
|
$document.unbind('click', documentClickBind);
|
|
}
|
|
element.bind('focus', elementFocusBind);
|
|
elementFocusInitialized = true;
|
|
}
|
|
|
|
if ( setIsOpen ) {
|
|
setIsOpen(originalScope, value);
|
|
}
|
|
});
|
|
|
|
scope.today = function() {
|
|
scope.dateSelection(new Date());
|
|
};
|
|
scope.clear = function() {
|
|
scope.dateSelection(null);
|
|
};
|
|
|
|
var $popup = $compile(popupEl)(scope);
|
|
if ( appendToBody ) {
|
|
$document.find('body').append($popup);
|
|
} else {
|
|
element.after($popup);
|
|
}
|
|
}
|
|
};
|
|
}])
|
|
|
|
.directive('datepickerPopupWrap', function() {
|
|
return {
|
|
restrict:'EA',
|
|
replace: true,
|
|
transclude: true,
|
|
templateUrl: 'template/datepicker/popup.html',
|
|
link:function (scope, element, attrs) {
|
|
element.bind('click', function(event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
});
|
|
}
|
|
};
|
|
});
|
|
|
|
/*
|
|
* dropdownToggle - Provides dropdown menu functionality in place of bootstrap js
|
|
* @restrict class or attribute
|
|
* @example:
|
|
<li class="dropdown">
|
|
<a class="dropdown-toggle">My Dropdown Menu</a>
|
|
<ul class="dropdown-menu">
|
|
<li ng-repeat="choice in dropChoices">
|
|
<a ng-href="{{choice.href}}">{{choice.text}}</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
*/
|
|
|
|
angular.module('ui.bootstrap.dropdownToggle', []).directive('dropdownToggle', ['$document', '$location', function ($document, $location) {
|
|
var openElement = null,
|
|
closeMenu = angular.noop;
|
|
return {
|
|
restrict: 'CA',
|
|
link: function(scope, element, attrs) {
|
|
scope.$watch('$location.path', function() { closeMenu(); });
|
|
element.parent().bind('click', function() { closeMenu(); });
|
|
element.bind('click', function (event) {
|
|
|
|
var elementWasOpen = (element === openElement);
|
|
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
if (!!openElement) {
|
|
closeMenu();
|
|
}
|
|
|
|
if (!elementWasOpen && !element.hasClass('disabled') && !element.prop('disabled')) {
|
|
element.parent().addClass('open');
|
|
openElement = element;
|
|
closeMenu = function (event) {
|
|
if (event) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
}
|
|
$document.unbind('click', closeMenu);
|
|
element.parent().removeClass('open');
|
|
closeMenu = angular.noop;
|
|
openElement = null;
|
|
};
|
|
$document.bind('click', closeMenu);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
|
|
|
/**
|
|
* A helper, internal data structure that acts as a map but also allows getting / removing
|
|
* elements in the LIFO order
|
|
*/
|
|
.factory('$$stackedMap', function () {
|
|
return {
|
|
createNew: function () {
|
|
var stack = [];
|
|
|
|
return {
|
|
add: function (key, value) {
|
|
stack.push({
|
|
key: key,
|
|
value: value
|
|
});
|
|
},
|
|
get: function (key) {
|
|
for (var i = 0; i < stack.length; i++) {
|
|
if (key == stack[i].key) {
|
|
return stack[i];
|
|
}
|
|
}
|
|
},
|
|
keys: function() {
|
|
var keys = [];
|
|
for (var i = 0; i < stack.length; i++) {
|
|
keys.push(stack[i].key);
|
|
}
|
|
return keys;
|
|
},
|
|
top: function () {
|
|
return stack[stack.length - 1];
|
|
},
|
|
remove: function (key) {
|
|
var idx = -1;
|
|
for (var i = 0; i < stack.length; i++) {
|
|
if (key == stack[i].key) {
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
return stack.splice(idx, 1)[0];
|
|
},
|
|
removeTop: function () {
|
|
return stack.splice(stack.length - 1, 1)[0];
|
|
},
|
|
length: function () {
|
|
return stack.length;
|
|
}
|
|
};
|
|
}
|
|
};
|
|
})
|
|
|
|
/**
|
|
* A helper directive for the $modal service. It creates a backdrop element.
|
|
*/
|
|
.directive('modalBackdrop', ['$timeout', function ($timeout) {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
templateUrl: 'template/modal/backdrop.html',
|
|
link: function (scope) {
|
|
|
|
scope.animate = false;
|
|
|
|
//trigger CSS transitions
|
|
$timeout(function () {
|
|
scope.animate = true;
|
|
});
|
|
}
|
|
};
|
|
}])
|
|
|
|
.directive('modalWindow', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
|
|
return {
|
|
restrict: 'EA',
|
|
scope: {
|
|
index: '@',
|
|
animate: '='
|
|
},
|
|
replace: true,
|
|
transclude: true,
|
|
templateUrl: 'template/modal/window.html',
|
|
link: function (scope, element, attrs) {
|
|
scope.windowClass = attrs.windowClass || '';
|
|
|
|
$timeout(function () {
|
|
// trigger CSS transitions
|
|
scope.animate = true;
|
|
// focus a freshly-opened modal
|
|
element[0].focus();
|
|
});
|
|
|
|
scope.close = function (evt) {
|
|
var modal = $modalStack.getTop();
|
|
if (modal && modal.value.backdrop && modal.value.backdrop != 'static' && (evt.target === evt.currentTarget)) {
|
|
evt.preventDefault();
|
|
evt.stopPropagation();
|
|
$modalStack.dismiss(modal.key, 'backdrop click');
|
|
}
|
|
};
|
|
}
|
|
};
|
|
}])
|
|
|
|
.factory('$modalStack', ['$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap',
|
|
function ($transition, $timeout, $document, $compile, $rootScope, $$stackedMap) {
|
|
|
|
var OPENED_MODAL_CLASS = 'modal-open';
|
|
|
|
var backdropDomEl, backdropScope;
|
|
var openedWindows = $$stackedMap.createNew();
|
|
var $modalStack = {};
|
|
|
|
function backdropIndex() {
|
|
var topBackdropIndex = -1;
|
|
var opened = openedWindows.keys();
|
|
for (var i = 0; i < opened.length; i++) {
|
|
if (openedWindows.get(opened[i]).value.backdrop) {
|
|
topBackdropIndex = i;
|
|
}
|
|
}
|
|
return topBackdropIndex;
|
|
}
|
|
|
|
$rootScope.$watch(backdropIndex, function(newBackdropIndex){
|
|
if (backdropScope) {
|
|
backdropScope.index = newBackdropIndex;
|
|
}
|
|
});
|
|
|
|
function removeModalWindow(modalInstance) {
|
|
|
|
var body = $document.find('body').eq(0);
|
|
var modalWindow = openedWindows.get(modalInstance).value;
|
|
|
|
//clean up the stack
|
|
openedWindows.remove(modalInstance);
|
|
|
|
//remove window DOM element
|
|
removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, 300, checkRemoveBackdrop);
|
|
body.toggleClass(OPENED_MODAL_CLASS, openedWindows.length() > 0);
|
|
}
|
|
|
|
function checkRemoveBackdrop() {
|
|
//remove backdrop if no longer needed
|
|
if (backdropDomEl && backdropIndex() == -1) {
|
|
var backdropScopeRef = backdropScope;
|
|
removeAfterAnimate(backdropDomEl, backdropScope, 150, function () {
|
|
backdropScopeRef.$destroy();
|
|
backdropScopeRef = null;
|
|
});
|
|
backdropDomEl = undefined;
|
|
backdropScope = undefined;
|
|
}
|
|
}
|
|
|
|
function removeAfterAnimate(domEl, scope, emulateTime, done) {
|
|
// Closing animation
|
|
scope.animate = false;
|
|
|
|
var transitionEndEventName = $transition.transitionEndEventName;
|
|
if (transitionEndEventName) {
|
|
// transition out
|
|
var timeout = $timeout(afterAnimating, emulateTime);
|
|
|
|
domEl.bind(transitionEndEventName, function () {
|
|
$timeout.cancel(timeout);
|
|
afterAnimating();
|
|
scope.$apply();
|
|
});
|
|
} else {
|
|
// Ensure this call is async
|
|
$timeout(afterAnimating, 0);
|
|
}
|
|
|
|
function afterAnimating() {
|
|
if (afterAnimating.done) {
|
|
return;
|
|
}
|
|
afterAnimating.done = true;
|
|
|
|
domEl.remove();
|
|
if (done) {
|
|
done();
|
|
}
|
|
}
|
|
}
|
|
|
|
$document.bind('keydown', function (evt) {
|
|
var modal;
|
|
|
|
if (evt.which === 27) {
|
|
modal = openedWindows.top();
|
|
if (modal && modal.value.keyboard) {
|
|
$rootScope.$apply(function () {
|
|
$modalStack.dismiss(modal.key);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
$modalStack.open = function (modalInstance, modal) {
|
|
|
|
openedWindows.add(modalInstance, {
|
|
deferred: modal.deferred,
|
|
modalScope: modal.scope,
|
|
backdrop: modal.backdrop,
|
|
keyboard: modal.keyboard
|
|
});
|
|
|
|
var body = $document.find('body').eq(0),
|
|
currBackdropIndex = backdropIndex();
|
|
|
|
if (currBackdropIndex >= 0 && !backdropDomEl) {
|
|
backdropScope = $rootScope.$new(true);
|
|
backdropScope.index = currBackdropIndex;
|
|
backdropDomEl = $compile('<div modal-backdrop></div>')(backdropScope);
|
|
body.append(backdropDomEl);
|
|
}
|
|
|
|
var angularDomEl = angular.element('<div modal-window></div>');
|
|
angularDomEl.attr('window-class', modal.windowClass);
|
|
angularDomEl.attr('index', openedWindows.length() - 1);
|
|
angularDomEl.attr('animate', 'animate');
|
|
angularDomEl.html(modal.content);
|
|
|
|
var modalDomEl = $compile(angularDomEl)(modal.scope);
|
|
openedWindows.top().value.modalDomEl = modalDomEl;
|
|
body.append(modalDomEl);
|
|
body.addClass(OPENED_MODAL_CLASS);
|
|
};
|
|
|
|
$modalStack.close = function (modalInstance, result) {
|
|
var modalWindow = openedWindows.get(modalInstance).value;
|
|
if (modalWindow) {
|
|
modalWindow.deferred.resolve(result);
|
|
removeModalWindow(modalInstance);
|
|
}
|
|
};
|
|
|
|
$modalStack.dismiss = function (modalInstance, reason) {
|
|
var modalWindow = openedWindows.get(modalInstance).value;
|
|
if (modalWindow) {
|
|
modalWindow.deferred.reject(reason);
|
|
removeModalWindow(modalInstance);
|
|
}
|
|
};
|
|
|
|
$modalStack.dismissAll = function (reason) {
|
|
var topModal = this.getTop();
|
|
while (topModal) {
|
|
this.dismiss(topModal.key, reason);
|
|
topModal = this.getTop();
|
|
}
|
|
};
|
|
|
|
$modalStack.getTop = function () {
|
|
return openedWindows.top();
|
|
};
|
|
|
|
return $modalStack;
|
|
}])
|
|
|
|
.provider('$modal', function () {
|
|
|
|
var $modalProvider = {
|
|
options: {
|
|
backdrop: true, //can be also false or 'static'
|
|
keyboard: true
|
|
},
|
|
$get: ['$injector', '$rootScope', '$q', '$http', '$templateCache', '$controller', '$modalStack',
|
|
function ($injector, $rootScope, $q, $http, $templateCache, $controller, $modalStack) {
|
|
|
|
var $modal = {};
|
|
|
|
function getTemplatePromise(options) {
|
|
return options.template ? $q.when(options.template) :
|
|
$http.get(options.templateUrl, {cache: $templateCache}).then(function (result) {
|
|
return result.data;
|
|
});
|
|
}
|
|
|
|
function getResolvePromises(resolves) {
|
|
var promisesArr = [];
|
|
angular.forEach(resolves, function (value, key) {
|
|
if (angular.isFunction(value) || angular.isArray(value)) {
|
|
promisesArr.push($q.when($injector.invoke(value)));
|
|
}
|
|
});
|
|
return promisesArr;
|
|
}
|
|
|
|
$modal.open = function (modalOptions) {
|
|
|
|
var modalResultDeferred = $q.defer();
|
|
var modalOpenedDeferred = $q.defer();
|
|
|
|
//prepare an instance of a modal to be injected into controllers and returned to a caller
|
|
var modalInstance = {
|
|
result: modalResultDeferred.promise,
|
|
opened: modalOpenedDeferred.promise,
|
|
close: function (result) {
|
|
$modalStack.close(modalInstance, result);
|
|
},
|
|
dismiss: function (reason) {
|
|
$modalStack.dismiss(modalInstance, reason);
|
|
}
|
|
};
|
|
|
|
//merge and clean up options
|
|
modalOptions = angular.extend({}, $modalProvider.options, modalOptions);
|
|
modalOptions.resolve = modalOptions.resolve || {};
|
|
|
|
//verify options
|
|
if (!modalOptions.template && !modalOptions.templateUrl) {
|
|
throw new Error('One of template or templateUrl options is required.');
|
|
}
|
|
|
|
var templateAndResolvePromise =
|
|
$q.all([getTemplatePromise(modalOptions)].concat(getResolvePromises(modalOptions.resolve)));
|
|
|
|
|
|
templateAndResolvePromise.then(function resolveSuccess(tplAndVars) {
|
|
|
|
var modalScope = (modalOptions.scope || $rootScope).$new();
|
|
modalScope.$close = modalInstance.close;
|
|
modalScope.$dismiss = modalInstance.dismiss;
|
|
|
|
var ctrlInstance, ctrlLocals = {};
|
|
var resolveIter = 1;
|
|
|
|
//controllers
|
|
if (modalOptions.controller) {
|
|
ctrlLocals.$scope = modalScope;
|
|
ctrlLocals.$modalInstance = modalInstance;
|
|
angular.forEach(modalOptions.resolve, function (value, key) {
|
|
ctrlLocals[key] = tplAndVars[resolveIter++];
|
|
});
|
|
|
|
ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
|
|
}
|
|
|
|
$modalStack.open(modalInstance, {
|
|
scope: modalScope,
|
|
deferred: modalResultDeferred,
|
|
content: tplAndVars[0],
|
|
backdrop: modalOptions.backdrop,
|
|
keyboard: modalOptions.keyboard,
|
|
windowClass: modalOptions.windowClass
|
|
});
|
|
|
|
}, function resolveError(reason) {
|
|
modalResultDeferred.reject(reason);
|
|
});
|
|
|
|
templateAndResolvePromise.then(function () {
|
|
modalOpenedDeferred.resolve(true);
|
|
}, function () {
|
|
modalOpenedDeferred.reject(false);
|
|
});
|
|
|
|
return modalInstance;
|
|
};
|
|
|
|
return $modal;
|
|
}]
|
|
};
|
|
|
|
return $modalProvider;
|
|
});
|
|
|
|
angular.module('ui.bootstrap.pagination', [])
|
|
|
|
.controller('PaginationController', ['$scope', '$attrs', '$parse', '$interpolate', function ($scope, $attrs, $parse, $interpolate) {
|
|
var self = this,
|
|
setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop;
|
|
|
|
this.init = function(defaultItemsPerPage) {
|
|
if ($attrs.itemsPerPage) {
|
|
$scope.$parent.$watch($parse($attrs.itemsPerPage), function(value) {
|
|
self.itemsPerPage = parseInt(value, 10);
|
|
$scope.totalPages = self.calculateTotalPages();
|
|
});
|
|
} else {
|
|
this.itemsPerPage = defaultItemsPerPage;
|
|
}
|
|
};
|
|
|
|
this.noPrevious = function() {
|
|
return this.page === 1;
|
|
};
|
|
this.noNext = function() {
|
|
return this.page === $scope.totalPages;
|
|
};
|
|
|
|
this.isActive = function(page) {
|
|
return this.page === page;
|
|
};
|
|
|
|
this.calculateTotalPages = function() {
|
|
var totalPages = this.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / this.itemsPerPage);
|
|
return Math.max(totalPages || 0, 1);
|
|
};
|
|
|
|
this.getAttributeValue = function(attribute, defaultValue, interpolate) {
|
|
return angular.isDefined(attribute) ? (interpolate ? $interpolate(attribute)($scope.$parent) : $scope.$parent.$eval(attribute)) : defaultValue;
|
|
};
|
|
|
|
this.render = function() {
|
|
this.page = parseInt($scope.page, 10) || 1;
|
|
if (this.page > 0 && this.page <= $scope.totalPages) {
|
|
$scope.pages = this.getPages(this.page, $scope.totalPages);
|
|
}
|
|
};
|
|
|
|
$scope.selectPage = function(page) {
|
|
if ( ! self.isActive(page) && page > 0 && page <= $scope.totalPages) {
|
|
$scope.page = page;
|
|
$scope.onSelectPage({ page: page });
|
|
}
|
|
};
|
|
|
|
$scope.$watch('page', function() {
|
|
self.render();
|
|
});
|
|
|
|
$scope.$watch('totalItems', function() {
|
|
$scope.totalPages = self.calculateTotalPages();
|
|
});
|
|
|
|
$scope.$watch('totalPages', function(value) {
|
|
setNumPages($scope.$parent, value); // Readonly variable
|
|
|
|
if ( self.page > value ) {
|
|
$scope.selectPage(value);
|
|
} else {
|
|
self.render();
|
|
}
|
|
});
|
|
}])
|
|
|
|
.constant('paginationConfig', {
|
|
itemsPerPage: 10,
|
|
boundaryLinks: false,
|
|
directionLinks: true,
|
|
firstText: 'First',
|
|
previousText: 'Previous',
|
|
nextText: 'Next',
|
|
lastText: 'Last',
|
|
rotate: true
|
|
})
|
|
|
|
.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) {
|
|
return {
|
|
restrict: 'EA',
|
|
scope: {
|
|
page: '=',
|
|
totalItems: '=',
|
|
onSelectPage:' &'
|
|
},
|
|
controller: 'PaginationController',
|
|
templateUrl: 'template/pagination/pagination.html',
|
|
replace: true,
|
|
link: function(scope, element, attrs, paginationCtrl) {
|
|
|
|
// Setup configuration parameters
|
|
var maxSize,
|
|
boundaryLinks = paginationCtrl.getAttributeValue(attrs.boundaryLinks, config.boundaryLinks ),
|
|
directionLinks = paginationCtrl.getAttributeValue(attrs.directionLinks, config.directionLinks ),
|
|
firstText = paginationCtrl.getAttributeValue(attrs.firstText, config.firstText, true),
|
|
previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
|
|
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
|
|
lastText = paginationCtrl.getAttributeValue(attrs.lastText, config.lastText, true),
|
|
rotate = paginationCtrl.getAttributeValue(attrs.rotate, config.rotate);
|
|
|
|
paginationCtrl.init(config.itemsPerPage);
|
|
|
|
if (attrs.maxSize) {
|
|
scope.$parent.$watch($parse(attrs.maxSize), function(value) {
|
|
maxSize = parseInt(value, 10);
|
|
paginationCtrl.render();
|
|
});
|
|
}
|
|
|
|
// Create page object used in template
|
|
function makePage(number, text, isActive, isDisabled) {
|
|
return {
|
|
number: number,
|
|
text: text,
|
|
active: isActive,
|
|
disabled: isDisabled
|
|
};
|
|
}
|
|
|
|
paginationCtrl.getPages = function(currentPage, totalPages) {
|
|
var pages = [];
|
|
|
|
// Default page limits
|
|
var startPage = 1, endPage = totalPages;
|
|
var isMaxSized = ( angular.isDefined(maxSize) && maxSize < totalPages );
|
|
|
|
// recompute if maxSize
|
|
if ( isMaxSized ) {
|
|
if ( rotate ) {
|
|
// Current page is displayed in the middle of the visible ones
|
|
startPage = Math.max(currentPage - Math.floor(maxSize/2), 1);
|
|
endPage = startPage + maxSize - 1;
|
|
|
|
// Adjust if limit is exceeded
|
|
if (endPage > totalPages) {
|
|
endPage = totalPages;
|
|
startPage = endPage - maxSize + 1;
|
|
}
|
|
} else {
|
|
// Visible pages are paginated with maxSize
|
|
startPage = ((Math.ceil(currentPage / maxSize) - 1) * maxSize) + 1;
|
|
|
|
// Adjust last page if limit is exceeded
|
|
endPage = Math.min(startPage + maxSize - 1, totalPages);
|
|
}
|
|
}
|
|
|
|
// Add page number links
|
|
for (var number = startPage; number <= endPage; number++) {
|
|
var page = makePage(number, number, paginationCtrl.isActive(number), false);
|
|
pages.push(page);
|
|
}
|
|
|
|
// Add links to move between page sets
|
|
if ( isMaxSized && ! rotate ) {
|
|
if ( startPage > 1 ) {
|
|
var previousPageSet = makePage(startPage - 1, '...', false, false);
|
|
pages.unshift(previousPageSet);
|
|
}
|
|
|
|
if ( endPage < totalPages ) {
|
|
var nextPageSet = makePage(endPage + 1, '...', false, false);
|
|
pages.push(nextPageSet);
|
|
}
|
|
}
|
|
|
|
// Add previous & next links
|
|
if (directionLinks) {
|
|
var previousPage = makePage(currentPage - 1, previousText, false, paginationCtrl.noPrevious());
|
|
pages.unshift(previousPage);
|
|
|
|
var nextPage = makePage(currentPage + 1, nextText, false, paginationCtrl.noNext());
|
|
pages.push(nextPage);
|
|
}
|
|
|
|
// Add first & last links
|
|
if (boundaryLinks) {
|
|
var firstPage = makePage(1, firstText, false, paginationCtrl.noPrevious());
|
|
pages.unshift(firstPage);
|
|
|
|
var lastPage = makePage(totalPages, lastText, false, paginationCtrl.noNext());
|
|
pages.push(lastPage);
|
|
}
|
|
|
|
return pages;
|
|
};
|
|
}
|
|
};
|
|
}])
|
|
|
|
.constant('pagerConfig', {
|
|
itemsPerPage: 10,
|
|
previousText: '« Previous',
|
|
nextText: 'Next »',
|
|
align: true
|
|
})
|
|
|
|
.directive('pager', ['pagerConfig', function(config) {
|
|
return {
|
|
restrict: 'EA',
|
|
scope: {
|
|
page: '=',
|
|
totalItems: '=',
|
|
onSelectPage:' &'
|
|
},
|
|
controller: 'PaginationController',
|
|
templateUrl: 'template/pagination/pager.html',
|
|
replace: true,
|
|
link: function(scope, element, attrs, paginationCtrl) {
|
|
|
|
// Setup configuration parameters
|
|
var previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
|
|
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
|
|
align = paginationCtrl.getAttributeValue(attrs.align, config.align);
|
|
|
|
paginationCtrl.init(config.itemsPerPage);
|
|
|
|
// Create page object used in template
|
|
function makePage(number, text, isDisabled, isPrevious, isNext) {
|
|
return {
|
|
number: number,
|
|
text: text,
|
|
disabled: isDisabled,
|
|
previous: ( align && isPrevious ),
|
|
next: ( align && isNext )
|
|
};
|
|
}
|
|
|
|
paginationCtrl.getPages = function(currentPage) {
|
|
return [
|
|
makePage(currentPage - 1, previousText, paginationCtrl.noPrevious(), true, false),
|
|
makePage(currentPage + 1, nextText, paginationCtrl.noNext(), false, true)
|
|
];
|
|
};
|
|
}
|
|
};
|
|
}]);
|
|
|
|
/**
|
|
* The following features are still outstanding: animation as a
|
|
* function, placement as a function, inside, support for more triggers than
|
|
* just mouse enter/leave, html tooltips, and selector delegation.
|
|
*/
|
|
angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap.bindHtml' ] )
|
|
|
|
/**
|
|
* The $tooltip service creates tooltip- and popover-like directives as well as
|
|
* houses global options for them.
|
|
*/
|
|
.provider( '$tooltip', function () {
|
|
// The default options tooltip and popover.
|
|
var defaultOptions = {
|
|
placement: 'top',
|
|
animation: true,
|
|
popupDelay: 0
|
|
};
|
|
|
|
// Default hide triggers for each show trigger
|
|
var triggerMap = {
|
|
'mouseenter': 'mouseleave',
|
|
'click': 'click',
|
|
'focus': 'blur'
|
|
};
|
|
|
|
// The options specified to the provider globally.
|
|
var globalOptions = {};
|
|
|
|
/**
|
|
* `options({})` allows global configuration of all tooltips in the
|
|
* application.
|
|
*
|
|
* var app = angular.module( 'App', ['ui.bootstrap.tooltip'], function( $tooltipProvider ) {
|
|
* // place tooltips left instead of top by default
|
|
* $tooltipProvider.options( { placement: 'left' } );
|
|
* });
|
|
*/
|
|
this.options = function( value ) {
|
|
angular.extend( globalOptions, value );
|
|
};
|
|
|
|
/**
|
|
* This allows you to extend the set of trigger mappings available. E.g.:
|
|
*
|
|
* $tooltipProvider.setTriggers( 'openTrigger': 'closeTrigger' );
|
|
*/
|
|
this.setTriggers = function setTriggers ( triggers ) {
|
|
angular.extend( triggerMap, triggers );
|
|
};
|
|
|
|
/**
|
|
* This is a helper function for translating camel-case to snake-case.
|
|
*/
|
|
function snake_case(name){
|
|
var regexp = /[A-Z]/g;
|
|
var separator = '-';
|
|
return name.replace(regexp, function(letter, pos) {
|
|
return (pos ? separator : '') + letter.toLowerCase();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns the actual instance of the $tooltip service.
|
|
* TODO support multiple triggers
|
|
*/
|
|
this.$get = [ '$window', '$compile', '$timeout', '$parse', '$document', '$position', '$interpolate', function ( $window, $compile, $timeout, $parse, $document, $position, $interpolate ) {
|
|
return function $tooltip ( type, prefix, defaultTriggerShow ) {
|
|
var options = angular.extend( {}, defaultOptions, globalOptions );
|
|
|
|
/**
|
|
* Returns an object of show and hide triggers.
|
|
*
|
|
* If a trigger is supplied,
|
|
* it is used to show the tooltip; otherwise, it will use the `trigger`
|
|
* option passed to the `$tooltipProvider.options` method; else it will
|
|
* default to the trigger supplied to this directive factory.
|
|
*
|
|
* The hide trigger is based on the show trigger. If the `trigger` option
|
|
* was passed to the `$tooltipProvider.options` method, it will use the
|
|
* mapped trigger from `triggerMap` or the passed trigger if the map is
|
|
* undefined; otherwise, it uses the `triggerMap` value of the show
|
|
* trigger; else it will just use the show trigger.
|
|
*/
|
|
function getTriggers ( trigger ) {
|
|
var show = trigger || options.trigger || defaultTriggerShow;
|
|
var hide = triggerMap[show] || show;
|
|
return {
|
|
show: show,
|
|
hide: hide
|
|
};
|
|
}
|
|
|
|
var directiveName = snake_case( type );
|
|
|
|
var startSym = $interpolate.startSymbol();
|
|
var endSym = $interpolate.endSymbol();
|
|
var template =
|
|
'<div '+ directiveName +'-popup '+
|
|
'title="'+startSym+'tt_title'+endSym+'" '+
|
|
'content="'+startSym+'tt_content'+endSym+'" '+
|
|
'placement="'+startSym+'tt_placement'+endSym+'" '+
|
|
'animation="tt_animation" '+
|
|
'is-open="tt_isOpen"'+
|
|
'>'+
|
|
'</div>';
|
|
|
|
return {
|
|
restrict: 'EA',
|
|
scope: true,
|
|
compile: function (tElem, tAttrs) {
|
|
var tooltipLinker = $compile( template );
|
|
|
|
return function link ( scope, element, attrs ) {
|
|
var tooltip;
|
|
var transitionTimeout;
|
|
var popupTimeout;
|
|
var appendToBody = angular.isDefined( options.appendToBody ) ? options.appendToBody : false;
|
|
var triggers = getTriggers( undefined );
|
|
var hasRegisteredTriggers = false;
|
|
var hasEnableExp = angular.isDefined(attrs[prefix+'Enable']);
|
|
|
|
var positionTooltip = function (){
|
|
var position,
|
|
ttWidth,
|
|
ttHeight,
|
|
ttPosition;
|
|
// Get the position of the directive element.
|
|
position = appendToBody ? $position.offset( element ) : $position.position( element );
|
|
|
|
// Get the height and width of the tooltip so we can center it.
|
|
ttWidth = tooltip.prop( 'offsetWidth' );
|
|
ttHeight = tooltip.prop( 'offsetHeight' );
|
|
|
|
// Calculate the tooltip's top and left coordinates to center it with
|
|
// this directive.
|
|
switch ( scope.tt_placement ) {
|
|
case 'right':
|
|
ttPosition = {
|
|
top: position.top + position.height / 2 - ttHeight / 2,
|
|
left: position.left + position.width
|
|
};
|
|
break;
|
|
case 'bottom':
|
|
ttPosition = {
|
|
top: position.top + position.height,
|
|
left: position.left + position.width / 2 - ttWidth / 2
|
|
};
|
|
break;
|
|
case 'left':
|
|
ttPosition = {
|
|
top: position.top + position.height / 2 - ttHeight / 2,
|
|
left: position.left - ttWidth
|
|
};
|
|
break;
|
|
default:
|
|
ttPosition = {
|
|
top: position.top - ttHeight,
|
|
left: position.left + position.width / 2 - ttWidth / 2
|
|
};
|
|
break;
|
|
}
|
|
|
|
ttPosition.top += 'px';
|
|
ttPosition.left += 'px';
|
|
|
|
// Now set the calculated positioning.
|
|
tooltip.css( ttPosition );
|
|
|
|
};
|
|
|
|
// By default, the tooltip is not open.
|
|
// TODO add ability to start tooltip opened
|
|
scope.tt_isOpen = false;
|
|
|
|
function toggleTooltipBind () {
|
|
if ( ! scope.tt_isOpen ) {
|
|
showTooltipBind();
|
|
} else {
|
|
hideTooltipBind();
|
|
}
|
|
}
|
|
|
|
// Show the tooltip with delay if specified, otherwise show it immediately
|
|
function showTooltipBind() {
|
|
if(hasEnableExp && !scope.$eval(attrs[prefix+'Enable'])) {
|
|
return;
|
|
}
|
|
if ( scope.tt_popupDelay ) {
|
|
popupTimeout = $timeout( show, scope.tt_popupDelay, false );
|
|
popupTimeout.then(function(reposition){reposition();});
|
|
} else {
|
|
show()();
|
|
}
|
|
}
|
|
|
|
function hideTooltipBind () {
|
|
scope.$apply(function () {
|
|
hide();
|
|
});
|
|
}
|
|
|
|
// Show the tooltip popup element.
|
|
function show() {
|
|
|
|
|
|
// Don't show empty tooltips.
|
|
if ( ! scope.tt_content ) {
|
|
return angular.noop;
|
|
}
|
|
|
|
createTooltip();
|
|
|
|
// If there is a pending remove transition, we must cancel it, lest the
|
|
// tooltip be mysteriously removed.
|
|
if ( transitionTimeout ) {
|
|
$timeout.cancel( transitionTimeout );
|
|
}
|
|
|
|
// Set the initial positioning.
|
|
tooltip.css({ top: 0, left: 0, display: 'block' });
|
|
|
|
// Now we add it to the DOM because need some info about it. But it's not
|
|
// visible yet anyway.
|
|
if ( appendToBody ) {
|
|
$document.find( 'body' ).append( tooltip );
|
|
} else {
|
|
element.after( tooltip );
|
|
}
|
|
|
|
positionTooltip();
|
|
|
|
// And show the tooltip.
|
|
scope.tt_isOpen = true;
|
|
scope.$digest(); // digest required as $apply is not called
|
|
|
|
// Return positioning function as promise callback for correct
|
|
// positioning after draw.
|
|
return positionTooltip;
|
|
}
|
|
|
|
// Hide the tooltip popup element.
|
|
function hide() {
|
|
// First things first: we don't show it anymore.
|
|
scope.tt_isOpen = false;
|
|
|
|
//if tooltip is going to be shown after delay, we must cancel this
|
|
$timeout.cancel( popupTimeout );
|
|
|
|
// And now we remove it from the DOM. However, if we have animation, we
|
|
// need to wait for it to expire beforehand.
|
|
// FIXME: this is a placeholder for a port of the transitions library.
|
|
if ( scope.tt_animation ) {
|
|
transitionTimeout = $timeout(removeTooltip, 500);
|
|
} else {
|
|
removeTooltip();
|
|
}
|
|
}
|
|
|
|
function createTooltip() {
|
|
// There can only be one tooltip element per directive shown at once.
|
|
if (tooltip) {
|
|
removeTooltip();
|
|
}
|
|
tooltip = tooltipLinker(scope, function () {});
|
|
|
|
// Get contents rendered into the tooltip
|
|
scope.$digest();
|
|
}
|
|
|
|
function removeTooltip() {
|
|
if (tooltip) {
|
|
tooltip.remove();
|
|
tooltip = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Observe the relevant attributes.
|
|
*/
|
|
attrs.$observe( type, function ( val ) {
|
|
scope.tt_content = val;
|
|
|
|
if (!val && scope.tt_isOpen ) {
|
|
hide();
|
|
}
|
|
});
|
|
|
|
attrs.$observe( prefix+'Title', function ( val ) {
|
|
scope.tt_title = val;
|
|
});
|
|
|
|
attrs.$observe( prefix+'Placement', function ( val ) {
|
|
scope.tt_placement = angular.isDefined( val ) ? val : options.placement;
|
|
});
|
|
|
|
attrs.$observe( prefix+'PopupDelay', function ( val ) {
|
|
var delay = parseInt( val, 10 );
|
|
scope.tt_popupDelay = ! isNaN(delay) ? delay : options.popupDelay;
|
|
});
|
|
|
|
var unregisterTriggers = function() {
|
|
if (hasRegisteredTriggers) {
|
|
element.unbind( triggers.show, showTooltipBind );
|
|
element.unbind( triggers.hide, hideTooltipBind );
|
|
}
|
|
};
|
|
|
|
attrs.$observe( prefix+'Trigger', function ( val ) {
|
|
unregisterTriggers();
|
|
|
|
triggers = getTriggers( val );
|
|
|
|
if ( triggers.show === triggers.hide ) {
|
|
element.bind( triggers.show, toggleTooltipBind );
|
|
} else {
|
|
element.bind( triggers.show, showTooltipBind );
|
|
element.bind( triggers.hide, hideTooltipBind );
|
|
}
|
|
|
|
hasRegisteredTriggers = true;
|
|
});
|
|
|
|
var animation = scope.$eval(attrs[prefix + 'Animation']);
|
|
scope.tt_animation = angular.isDefined(animation) ? !!animation : options.animation;
|
|
|
|
attrs.$observe( prefix+'AppendToBody', function ( val ) {
|
|
appendToBody = angular.isDefined( val ) ? $parse( val )( scope ) : appendToBody;
|
|
});
|
|
|
|
// if a tooltip is attached to <body> we need to remove it on
|
|
// location change as its parent scope will probably not be destroyed
|
|
// by the change.
|
|
if ( appendToBody ) {
|
|
scope.$on('$locationChangeSuccess', function closeTooltipOnLocationChangeSuccess () {
|
|
if ( scope.tt_isOpen ) {
|
|
hide();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Make sure tooltip is destroyed and removed.
|
|
scope.$on('$destroy', function onDestroyTooltip() {
|
|
$timeout.cancel( transitionTimeout );
|
|
$timeout.cancel( popupTimeout );
|
|
unregisterTriggers();
|
|
removeTooltip();
|
|
});
|
|
};
|
|
}
|
|
};
|
|
};
|
|
}];
|
|
})
|
|
|
|
.directive( 'tooltipPopup', function () {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
|
|
templateUrl: 'template/tooltip/tooltip-popup.html'
|
|
};
|
|
})
|
|
|
|
.directive( 'tooltip', [ '$tooltip', function ( $tooltip ) {
|
|
return $tooltip( 'tooltip', 'tooltip', 'mouseenter' );
|
|
}])
|
|
|
|
.directive( 'tooltipHtmlUnsafePopup', function () {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
|
|
templateUrl: 'template/tooltip/tooltip-html-unsafe-popup.html'
|
|
};
|
|
})
|
|
|
|
.directive( 'tooltipHtmlUnsafe', [ '$tooltip', function ( $tooltip ) {
|
|
return $tooltip( 'tooltipHtmlUnsafe', 'tooltip', 'mouseenter' );
|
|
}]);
|
|
|
|
/**
|
|
* The following features are still outstanding: popup delay, animation as a
|
|
* function, placement as a function, inside, support for more triggers than
|
|
* just mouse enter/leave, html popovers, and selector delegatation.
|
|
*/
|
|
angular.module( 'ui.bootstrap.popover', [ 'ui.bootstrap.tooltip' ] )
|
|
|
|
.directive( 'popoverPopup', function () {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' },
|
|
templateUrl: 'template/popover/popover.html'
|
|
};
|
|
})
|
|
|
|
.directive( 'popover', [ '$tooltip', function ( $tooltip ) {
|
|
return $tooltip( 'popover', 'popover', 'click' );
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.progressbar', ['ui.bootstrap.transition'])
|
|
|
|
.constant('progressConfig', {
|
|
animate: true,
|
|
max: 100
|
|
})
|
|
|
|
.controller('ProgressController', ['$scope', '$attrs', 'progressConfig', '$transition', function($scope, $attrs, progressConfig, $transition) {
|
|
var self = this,
|
|
bars = [],
|
|
max = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : progressConfig.max,
|
|
animate = angular.isDefined($attrs.animate) ? $scope.$parent.$eval($attrs.animate) : progressConfig.animate;
|
|
|
|
this.addBar = function(bar, element) {
|
|
var oldValue = 0, index = bar.$parent.$index;
|
|
if ( angular.isDefined(index) && bars[index] ) {
|
|
oldValue = bars[index].value;
|
|
}
|
|
bars.push(bar);
|
|
|
|
this.update(element, bar.value, oldValue);
|
|
|
|
bar.$watch('value', function(value, oldValue) {
|
|
if (value !== oldValue) {
|
|
self.update(element, value, oldValue);
|
|
}
|
|
});
|
|
|
|
bar.$on('$destroy', function() {
|
|
self.removeBar(bar);
|
|
});
|
|
};
|
|
|
|
// Update bar element width
|
|
this.update = function(element, newValue, oldValue) {
|
|
var percent = this.getPercentage(newValue);
|
|
|
|
if (animate) {
|
|
element.css('width', this.getPercentage(oldValue) + '%');
|
|
$transition(element, {width: percent + '%'});
|
|
} else {
|
|
element.css({'transition': 'none', 'width': percent + '%'});
|
|
}
|
|
};
|
|
|
|
this.removeBar = function(bar) {
|
|
bars.splice(bars.indexOf(bar), 1);
|
|
};
|
|
|
|
this.getPercentage = function(value) {
|
|
return Math.round(100 * value / max);
|
|
};
|
|
}])
|
|
|
|
.directive('progress', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
transclude: true,
|
|
controller: 'ProgressController',
|
|
require: 'progress',
|
|
scope: {},
|
|
template: '<div class="progress" ng-transclude></div>'
|
|
//templateUrl: 'template/progressbar/progress.html' // Works in AngularJS 1.2
|
|
};
|
|
})
|
|
|
|
.directive('bar', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
transclude: true,
|
|
require: '^progress',
|
|
scope: {
|
|
value: '=',
|
|
type: '@'
|
|
},
|
|
templateUrl: 'template/progressbar/bar.html',
|
|
link: function(scope, element, attrs, progressCtrl) {
|
|
progressCtrl.addBar(scope, element);
|
|
}
|
|
};
|
|
})
|
|
|
|
.directive('progressbar', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
replace: true,
|
|
transclude: true,
|
|
controller: 'ProgressController',
|
|
scope: {
|
|
value: '=',
|
|
type: '@'
|
|
},
|
|
templateUrl: 'template/progressbar/progressbar.html',
|
|
link: function(scope, element, attrs, progressCtrl) {
|
|
progressCtrl.addBar(scope, angular.element(element.children()[0]));
|
|
}
|
|
};
|
|
});
|
|
angular.module('ui.bootstrap.rating', [])
|
|
|
|
.constant('ratingConfig', {
|
|
max: 5,
|
|
stateOn: null,
|
|
stateOff: null
|
|
})
|
|
|
|
.controller('RatingController', ['$scope', '$attrs', '$parse', 'ratingConfig', function($scope, $attrs, $parse, ratingConfig) {
|
|
|
|
this.maxRange = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max;
|
|
this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
|
|
this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;
|
|
|
|
this.createRateObjects = function(states) {
|
|
var defaultOptions = {
|
|
stateOn: this.stateOn,
|
|
stateOff: this.stateOff
|
|
};
|
|
|
|
for (var i = 0, n = states.length; i < n; i++) {
|
|
states[i] = angular.extend({ index: i }, defaultOptions, states[i]);
|
|
}
|
|
return states;
|
|
};
|
|
|
|
// Get objects used in template
|
|
$scope.range = angular.isDefined($attrs.ratingStates) ? this.createRateObjects(angular.copy($scope.$parent.$eval($attrs.ratingStates))): this.createRateObjects(new Array(this.maxRange));
|
|
|
|
$scope.rate = function(value) {
|
|
if ( $scope.value !== value && !$scope.readonly ) {
|
|
$scope.value = value;
|
|
}
|
|
};
|
|
|
|
$scope.enter = function(value) {
|
|
if ( ! $scope.readonly ) {
|
|
$scope.val = value;
|
|
}
|
|
$scope.onHover({value: value});
|
|
};
|
|
|
|
$scope.reset = function() {
|
|
$scope.val = angular.copy($scope.value);
|
|
$scope.onLeave();
|
|
};
|
|
|
|
$scope.$watch('value', function(value) {
|
|
$scope.val = value;
|
|
});
|
|
|
|
$scope.readonly = false;
|
|
if ($attrs.readonly) {
|
|
$scope.$parent.$watch($parse($attrs.readonly), function(value) {
|
|
$scope.readonly = !!value;
|
|
});
|
|
}
|
|
}])
|
|
|
|
.directive('rating', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
scope: {
|
|
value: '=',
|
|
onHover: '&',
|
|
onLeave: '&'
|
|
},
|
|
controller: 'RatingController',
|
|
templateUrl: 'template/rating/rating.html',
|
|
replace: true
|
|
};
|
|
});
|
|
|
|
/**
|
|
* @ngdoc overview
|
|
* @name ui.bootstrap.tabs
|
|
*
|
|
* @description
|
|
* AngularJS version of the tabs directive.
|
|
*/
|
|
|
|
angular.module('ui.bootstrap.tabs', [])
|
|
|
|
.controller('TabsetController', ['$scope', function TabsetCtrl($scope) {
|
|
var ctrl = this,
|
|
tabs = ctrl.tabs = $scope.tabs = [];
|
|
|
|
ctrl.select = function(tab) {
|
|
angular.forEach(tabs, function(tab) {
|
|
tab.active = false;
|
|
});
|
|
tab.active = true;
|
|
};
|
|
|
|
ctrl.addTab = function addTab(tab) {
|
|
tabs.push(tab);
|
|
if (tabs.length === 1 || tab.active) {
|
|
ctrl.select(tab);
|
|
}
|
|
};
|
|
|
|
ctrl.removeTab = function removeTab(tab) {
|
|
var index = tabs.indexOf(tab);
|
|
//Select a new tab if the tab to be removed is selected
|
|
if (tab.active && tabs.length > 1) {
|
|
//If this is the last tab, select the previous tab. else, the next tab.
|
|
var newActiveIndex = index == tabs.length - 1 ? index - 1 : index + 1;
|
|
ctrl.select(tabs[newActiveIndex]);
|
|
}
|
|
tabs.splice(index, 1);
|
|
};
|
|
}])
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name ui.bootstrap.tabs.directive:tabset
|
|
* @restrict EA
|
|
*
|
|
* @description
|
|
* Tabset is the outer container for the tabs directive
|
|
*
|
|
* @param {boolean=} vertical Whether or not to use vertical styling for the tabs.
|
|
* @param {boolean=} justified Whether or not to use justified styling for the tabs.
|
|
*
|
|
* @example
|
|
<example module="ui.bootstrap">
|
|
<file name="index.html">
|
|
<tabset>
|
|
<tab heading="Tab 1"><b>First</b> Content!</tab>
|
|
<tab heading="Tab 2"><i>Second</i> Content!</tab>
|
|
</tabset>
|
|
<hr />
|
|
<tabset vertical="true">
|
|
<tab heading="Vertical Tab 1"><b>First</b> Vertical Content!</tab>
|
|
<tab heading="Vertical Tab 2"><i>Second</i> Vertical Content!</tab>
|
|
</tabset>
|
|
<tabset justified="true">
|
|
<tab heading="Justified Tab 1"><b>First</b> Justified Content!</tab>
|
|
<tab heading="Justified Tab 2"><i>Second</i> Justified Content!</tab>
|
|
</tabset>
|
|
</file>
|
|
</example>
|
|
*/
|
|
.directive('tabset', function() {
|
|
return {
|
|
restrict: 'EA',
|
|
transclude: true,
|
|
replace: true,
|
|
scope: {},
|
|
controller: 'TabsetController',
|
|
templateUrl: 'template/tabs/tabset.html',
|
|
link: function(scope, element, attrs) {
|
|
scope.vertical = angular.isDefined(attrs.vertical) ? scope.$parent.$eval(attrs.vertical) : false;
|
|
scope.justified = angular.isDefined(attrs.justified) ? scope.$parent.$eval(attrs.justified) : false;
|
|
scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs';
|
|
}
|
|
};
|
|
})
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name ui.bootstrap.tabs.directive:tab
|
|
* @restrict EA
|
|
*
|
|
* @param {string=} heading The visible heading, or title, of the tab. Set HTML headings with {@link ui.bootstrap.tabs.directive:tabHeading tabHeading}.
|
|
* @param {string=} select An expression to evaluate when the tab is selected.
|
|
* @param {boolean=} active A binding, telling whether or not this tab is selected.
|
|
* @param {boolean=} disabled A binding, telling whether or not this tab is disabled.
|
|
*
|
|
* @description
|
|
* Creates a tab with a heading and content. Must be placed within a {@link ui.bootstrap.tabs.directive:tabset tabset}.
|
|
*
|
|
* @example
|
|
<example module="ui.bootstrap">
|
|
<file name="index.html">
|
|
<div ng-controller="TabsDemoCtrl">
|
|
<button class="btn btn-small" ng-click="items[0].active = true">
|
|
Select item 1, using active binding
|
|
</button>
|
|
<button class="btn btn-small" ng-click="items[1].disabled = !items[1].disabled">
|
|
Enable/disable item 2, using disabled binding
|
|
</button>
|
|
<br />
|
|
<tabset>
|
|
<tab heading="Tab 1">First Tab</tab>
|
|
<tab select="alertMe()">
|
|
<tab-heading><i class="icon-bell"></i> Alert me!</tab-heading>
|
|
Second Tab, with alert callback and html heading!
|
|
</tab>
|
|
<tab ng-repeat="item in items"
|
|
heading="{{item.title}}"
|
|
disabled="item.disabled"
|
|
active="item.active">
|
|
{{item.content}}
|
|
</tab>
|
|
</tabset>
|
|
</div>
|
|
</file>
|
|
<file name="script.js">
|
|
function TabsDemoCtrl($scope) {
|
|
$scope.items = [
|
|
{ title:"Dynamic Title 1", content:"Dynamic Item 0" },
|
|
{ title:"Dynamic Title 2", content:"Dynamic Item 1", disabled: true }
|
|
];
|
|
|
|
$scope.alertMe = function() {
|
|
setTimeout(function() {
|
|
alert("You've selected the alert tab!");
|
|
});
|
|
};
|
|
};
|
|
</file>
|
|
</example>
|
|
*/
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name ui.bootstrap.tabs.directive:tabHeading
|
|
* @restrict EA
|
|
*
|
|
* @description
|
|
* Creates an HTML heading for a {@link ui.bootstrap.tabs.directive:tab tab}. Must be placed as a child of a tab element.
|
|
*
|
|
* @example
|
|
<example module="ui.bootstrap">
|
|
<file name="index.html">
|
|
<tabset>
|
|
<tab>
|
|
<tab-heading><b>HTML</b> in my titles?!</tab-heading>
|
|
And some content, too!
|
|
</tab>
|
|
<tab>
|
|
<tab-heading><i class="icon-heart"></i> Icon heading?!?</tab-heading>
|
|
That's right.
|
|
</tab>
|
|
</tabset>
|
|
</file>
|
|
</example>
|
|
*/
|
|
.directive('tab', ['$parse', function($parse) {
|
|
return {
|
|
require: '^tabset',
|
|
restrict: 'EA',
|
|
replace: true,
|
|
templateUrl: 'template/tabs/tab.html',
|
|
transclude: true,
|
|
scope: {
|
|
heading: '@',
|
|
onSelect: '&select', //This callback is called in contentHeadingTransclude
|
|
//once it inserts the tab's content into the dom
|
|
onDeselect: '&deselect'
|
|
},
|
|
controller: function() {
|
|
//Empty controller so other directives can require being 'under' a tab
|
|
},
|
|
compile: function(elm, attrs, transclude) {
|
|
return function postLink(scope, elm, attrs, tabsetCtrl) {
|
|
var getActive, setActive;
|
|
if (attrs.active) {
|
|
getActive = $parse(attrs.active);
|
|
setActive = getActive.assign;
|
|
scope.$parent.$watch(getActive, function updateActive(value, oldVal) {
|
|
// Avoid re-initializing scope.active as it is already initialized
|
|
// below. (watcher is called async during init with value ===
|
|
// oldVal)
|
|
if (value !== oldVal) {
|
|
scope.active = !!value;
|
|
}
|
|
});
|
|
scope.active = getActive(scope.$parent);
|
|
} else {
|
|
setActive = getActive = angular.noop;
|
|
}
|
|
|
|
scope.$watch('active', function(active) {
|
|
// Note this watcher also initializes and assigns scope.active to the
|
|
// attrs.active expression.
|
|
setActive(scope.$parent, active);
|
|
if (active) {
|
|
tabsetCtrl.select(scope);
|
|
scope.onSelect();
|
|
} else {
|
|
scope.onDeselect();
|
|
}
|
|
});
|
|
|
|
scope.disabled = false;
|
|
if ( attrs.disabled ) {
|
|
scope.$parent.$watch($parse(attrs.disabled), function(value) {
|
|
scope.disabled = !! value;
|
|
});
|
|
}
|
|
|
|
scope.select = function() {
|
|
if ( ! scope.disabled ) {
|
|
scope.active = true;
|
|
}
|
|
};
|
|
|
|
tabsetCtrl.addTab(scope);
|
|
scope.$on('$destroy', function() {
|
|
tabsetCtrl.removeTab(scope);
|
|
});
|
|
|
|
|
|
//We need to transclude later, once the content container is ready.
|
|
//when this link happens, we're inside a tab heading.
|
|
scope.$transcludeFn = transclude;
|
|
};
|
|
}
|
|
};
|
|
}])
|
|
|
|
.directive('tabHeadingTransclude', [function() {
|
|
return {
|
|
restrict: 'A',
|
|
require: '^tab',
|
|
link: function(scope, elm, attrs, tabCtrl) {
|
|
scope.$watch('headingElement', function updateHeadingElement(heading) {
|
|
if (heading) {
|
|
elm.html('');
|
|
elm.append(heading);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}])
|
|
|
|
.directive('tabContentTransclude', function() {
|
|
return {
|
|
restrict: 'A',
|
|
require: '^tabset',
|
|
link: function(scope, elm, attrs) {
|
|
var tab = scope.$eval(attrs.tabContentTransclude);
|
|
|
|
//Now our tab is ready to be transcluded: both the tab heading area
|
|
//and the tab content area are loaded. Transclude 'em both.
|
|
tab.$transcludeFn(tab.$parent, function(contents) {
|
|
angular.forEach(contents, function(node) {
|
|
if (isTabHeading(node)) {
|
|
//Let tabHeadingTransclude know.
|
|
tab.headingElement = node;
|
|
} else {
|
|
elm.append(node);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
};
|
|
function isTabHeading(node) {
|
|
return node.tagName && (
|
|
node.hasAttribute('tab-heading') ||
|
|
node.hasAttribute('data-tab-heading') ||
|
|
node.tagName.toLowerCase() === 'tab-heading' ||
|
|
node.tagName.toLowerCase() === 'data-tab-heading'
|
|
);
|
|
}
|
|
})
|
|
|
|
;
|
|
|
|
angular.module('ui.bootstrap.timepicker', [])
|
|
|
|
.constant('timepickerConfig', {
|
|
hourStep: 1,
|
|
minuteStep: 1,
|
|
showMeridian: true,
|
|
meridians: null,
|
|
readonlyInput: false,
|
|
mousewheel: true
|
|
})
|
|
|
|
.directive('timepicker', ['$parse', '$log', 'timepickerConfig', '$locale', function ($parse, $log, timepickerConfig, $locale) {
|
|
return {
|
|
restrict: 'EA',
|
|
require:'?^ngModel',
|
|
replace: true,
|
|
scope: {},
|
|
templateUrl: 'template/timepicker/timepicker.html',
|
|
link: function(scope, element, attrs, ngModel) {
|
|
if ( !ngModel ) {
|
|
return; // do nothing if no ng-model
|
|
}
|
|
|
|
var selected = new Date(),
|
|
meridians = angular.isDefined(attrs.meridians) ? scope.$parent.$eval(attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS;
|
|
|
|
var hourStep = timepickerConfig.hourStep;
|
|
if (attrs.hourStep) {
|
|
scope.$parent.$watch($parse(attrs.hourStep), function(value) {
|
|
hourStep = parseInt(value, 10);
|
|
});
|
|
}
|
|
|
|
var minuteStep = timepickerConfig.minuteStep;
|
|
if (attrs.minuteStep) {
|
|
scope.$parent.$watch($parse(attrs.minuteStep), function(value) {
|
|
minuteStep = parseInt(value, 10);
|
|
});
|
|
}
|
|
|
|
// 12H / 24H mode
|
|
scope.showMeridian = timepickerConfig.showMeridian;
|
|
if (attrs.showMeridian) {
|
|
scope.$parent.$watch($parse(attrs.showMeridian), function(value) {
|
|
scope.showMeridian = !!value;
|
|
|
|
if ( ngModel.$error.time ) {
|
|
// Evaluate from template
|
|
var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate();
|
|
if (angular.isDefined( hours ) && angular.isDefined( minutes )) {
|
|
selected.setHours( hours );
|
|
refresh();
|
|
}
|
|
} else {
|
|
updateTemplate();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Get scope.hours in 24H mode if valid
|
|
function getHoursFromTemplate ( ) {
|
|
var hours = parseInt( scope.hours, 10 );
|
|
var valid = ( scope.showMeridian ) ? (hours > 0 && hours < 13) : (hours >= 0 && hours < 24);
|
|
if ( !valid ) {
|
|
return undefined;
|
|
}
|
|
|
|
if ( scope.showMeridian ) {
|
|
if ( hours === 12 ) {
|
|
hours = 0;
|
|
}
|
|
if ( scope.meridian === meridians[1] ) {
|
|
hours = hours + 12;
|
|
}
|
|
}
|
|
return hours;
|
|
}
|
|
|
|
function getMinutesFromTemplate() {
|
|
var minutes = parseInt(scope.minutes, 10);
|
|
return ( minutes >= 0 && minutes < 60 ) ? minutes : undefined;
|
|
}
|
|
|
|
function pad( value ) {
|
|
return ( angular.isDefined(value) && value.toString().length < 2 ) ? '0' + value : value;
|
|
}
|
|
|
|
// Input elements
|
|
var inputs = element.find('input'), hoursInputEl = inputs.eq(0), minutesInputEl = inputs.eq(1);
|
|
|
|
// Respond on mousewheel spin
|
|
var mousewheel = (angular.isDefined(attrs.mousewheel)) ? scope.$eval(attrs.mousewheel) : timepickerConfig.mousewheel;
|
|
if ( mousewheel ) {
|
|
|
|
var isScrollingUp = function(e) {
|
|
if (e.originalEvent) {
|
|
e = e.originalEvent;
|
|
}
|
|
//pick correct delta variable depending on event
|
|
var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY;
|
|
return (e.detail || delta > 0);
|
|
};
|
|
|
|
hoursInputEl.bind('mousewheel wheel', function(e) {
|
|
scope.$apply( (isScrollingUp(e)) ? scope.incrementHours() : scope.decrementHours() );
|
|
e.preventDefault();
|
|
});
|
|
|
|
minutesInputEl.bind('mousewheel wheel', function(e) {
|
|
scope.$apply( (isScrollingUp(e)) ? scope.incrementMinutes() : scope.decrementMinutes() );
|
|
e.preventDefault();
|
|
});
|
|
}
|
|
|
|
scope.readonlyInput = (angular.isDefined(attrs.readonlyInput)) ? scope.$eval(attrs.readonlyInput) : timepickerConfig.readonlyInput;
|
|
if ( ! scope.readonlyInput ) {
|
|
|
|
var invalidate = function(invalidHours, invalidMinutes) {
|
|
ngModel.$setViewValue( null );
|
|
ngModel.$setValidity('time', false);
|
|
if (angular.isDefined(invalidHours)) {
|
|
scope.invalidHours = invalidHours;
|
|
}
|
|
if (angular.isDefined(invalidMinutes)) {
|
|
scope.invalidMinutes = invalidMinutes;
|
|
}
|
|
};
|
|
|
|
scope.updateHours = function() {
|
|
var hours = getHoursFromTemplate();
|
|
|
|
if ( angular.isDefined(hours) ) {
|
|
selected.setHours( hours );
|
|
refresh( 'h' );
|
|
} else {
|
|
invalidate(true);
|
|
}
|
|
};
|
|
|
|
hoursInputEl.bind('blur', function(e) {
|
|
if ( !scope.validHours && scope.hours < 10) {
|
|
scope.$apply( function() {
|
|
scope.hours = pad( scope.hours );
|
|
});
|
|
}
|
|
});
|
|
|
|
scope.updateMinutes = function() {
|
|
var minutes = getMinutesFromTemplate();
|
|
|
|
if ( angular.isDefined(minutes) ) {
|
|
selected.setMinutes( minutes );
|
|
refresh( 'm' );
|
|
} else {
|
|
invalidate(undefined, true);
|
|
}
|
|
};
|
|
|
|
minutesInputEl.bind('blur', function(e) {
|
|
if ( !scope.invalidMinutes && scope.minutes < 10 ) {
|
|
scope.$apply( function() {
|
|
scope.minutes = pad( scope.minutes );
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
scope.updateHours = angular.noop;
|
|
scope.updateMinutes = angular.noop;
|
|
}
|
|
|
|
ngModel.$render = function() {
|
|
var date = ngModel.$modelValue ? new Date( ngModel.$modelValue ) : null;
|
|
|
|
if ( isNaN(date) ) {
|
|
ngModel.$setValidity('time', false);
|
|
$log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
|
|
} else {
|
|
if ( date ) {
|
|
selected = date;
|
|
}
|
|
makeValid();
|
|
updateTemplate();
|
|
}
|
|
};
|
|
|
|
// Call internally when we know that model is valid.
|
|
function refresh( keyboardChange ) {
|
|
makeValid();
|
|
ngModel.$setViewValue( new Date(selected) );
|
|
updateTemplate( keyboardChange );
|
|
}
|
|
|
|
function makeValid() {
|
|
ngModel.$setValidity('time', true);
|
|
scope.invalidHours = false;
|
|
scope.invalidMinutes = false;
|
|
}
|
|
|
|
function updateTemplate( keyboardChange ) {
|
|
var hours = selected.getHours(), minutes = selected.getMinutes();
|
|
|
|
if ( scope.showMeridian ) {
|
|
hours = ( hours === 0 || hours === 12 ) ? 12 : hours % 12; // Convert 24 to 12 hour system
|
|
}
|
|
scope.hours = keyboardChange === 'h' ? hours : pad(hours);
|
|
scope.minutes = keyboardChange === 'm' ? minutes : pad(minutes);
|
|
scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
|
|
}
|
|
|
|
function addMinutes( minutes ) {
|
|
var dt = new Date( selected.getTime() + minutes * 60000 );
|
|
selected.setHours( dt.getHours(), dt.getMinutes() );
|
|
refresh();
|
|
}
|
|
|
|
scope.incrementHours = function() {
|
|
addMinutes( hourStep * 60 );
|
|
};
|
|
scope.decrementHours = function() {
|
|
addMinutes( - hourStep * 60 );
|
|
};
|
|
scope.incrementMinutes = function() {
|
|
addMinutes( minuteStep );
|
|
};
|
|
scope.decrementMinutes = function() {
|
|
addMinutes( - minuteStep );
|
|
};
|
|
scope.toggleMeridian = function() {
|
|
addMinutes( 12 * 60 * (( selected.getHours() < 12 ) ? 1 : -1) );
|
|
};
|
|
}
|
|
};
|
|
}]);
|
|
|
|
angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap.bindHtml'])
|
|
|
|
/**
|
|
* A helper service that can parse typeahead's syntax (string provided by users)
|
|
* Extracted to a separate service for ease of unit testing
|
|
*/
|
|
.factory('typeaheadParser', ['$parse', function ($parse) {
|
|
|
|
// 00000111000000000000022200000000000000003333333333333330000000000044000
|
|
var TYPEAHEAD_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;
|
|
|
|
return {
|
|
parse:function (input) {
|
|
|
|
var match = input.match(TYPEAHEAD_REGEXP), modelMapper, viewMapper, source;
|
|
if (!match) {
|
|
throw new Error(
|
|
"Expected typeahead specification in form of '_modelValue_ (as _label_)? for _item_ in _collection_'" +
|
|
" but got '" + input + "'.");
|
|
}
|
|
|
|
return {
|
|
itemName:match[3],
|
|
source:$parse(match[4]),
|
|
viewMapper:$parse(match[2] || match[1]),
|
|
modelMapper:$parse(match[1])
|
|
};
|
|
}
|
|
};
|
|
}])
|
|
|
|
.directive('typeahead', ['$compile', '$parse', '$q', '$timeout', '$document', '$position', 'typeaheadParser',
|
|
function ($compile, $parse, $q, $timeout, $document, $position, typeaheadParser) {
|
|
|
|
var HOT_KEYS = [9, 13, 27, 38, 40];
|
|
|
|
return {
|
|
require:'ngModel',
|
|
link:function (originalScope, element, attrs, modelCtrl) {
|
|
|
|
//SUPPORTED ATTRIBUTES (OPTIONS)
|
|
|
|
//minimal no of characters that needs to be entered before typeahead kicks-in
|
|
var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 1;
|
|
|
|
//minimal wait time after last character typed before typehead kicks-in
|
|
var waitTime = originalScope.$eval(attrs.typeaheadWaitMs) || 0;
|
|
|
|
//should it restrict model values to the ones selected from the popup only?
|
|
var isEditable = originalScope.$eval(attrs.typeaheadEditable) !== false;
|
|
|
|
//binding to a variable that indicates if matches are being retrieved asynchronously
|
|
var isLoadingSetter = $parse(attrs.typeaheadLoading).assign || angular.noop;
|
|
|
|
//a callback executed when a match is selected
|
|
var onSelectCallback = $parse(attrs.typeaheadOnSelect);
|
|
|
|
var inputFormatter = attrs.typeaheadInputFormatter ? $parse(attrs.typeaheadInputFormatter) : undefined;
|
|
|
|
var appendToBody = attrs.typeaheadAppendToBody ? $parse(attrs.typeaheadAppendToBody) : false;
|
|
|
|
//INTERNAL VARIABLES
|
|
|
|
//model setter executed upon match selection
|
|
var $setModelValue = $parse(attrs.ngModel).assign;
|
|
|
|
//expressions used by typeahead
|
|
var parserResult = typeaheadParser.parse(attrs.typeahead);
|
|
|
|
var hasFocus;
|
|
|
|
//pop-up element used to display matches
|
|
var popUpEl = angular.element('<div typeahead-popup></div>');
|
|
popUpEl.attr({
|
|
matches: 'matches',
|
|
active: 'activeIdx',
|
|
select: 'select(activeIdx)',
|
|
query: 'query',
|
|
position: 'position'
|
|
});
|
|
//custom item template
|
|
if (angular.isDefined(attrs.typeaheadTemplateUrl)) {
|
|
popUpEl.attr('template-url', attrs.typeaheadTemplateUrl);
|
|
}
|
|
|
|
//create a child scope for the typeahead directive so we are not polluting original scope
|
|
//with typeahead-specific data (matches, query etc.)
|
|
var scope = originalScope.$new();
|
|
originalScope.$on('$destroy', function(){
|
|
scope.$destroy();
|
|
});
|
|
|
|
var resetMatches = function() {
|
|
scope.matches = [];
|
|
scope.activeIdx = -1;
|
|
};
|
|
|
|
var getMatchesAsync = function(inputValue) {
|
|
|
|
var locals = {$viewValue: inputValue};
|
|
isLoadingSetter(originalScope, true);
|
|
$q.when(parserResult.source(originalScope, locals)).then(function(matches) {
|
|
|
|
//it might happen that several async queries were in progress if a user were typing fast
|
|
//but we are interested only in responses that correspond to the current view value
|
|
if (inputValue === modelCtrl.$viewValue && hasFocus) {
|
|
if (matches.length > 0) {
|
|
|
|
scope.activeIdx = 0;
|
|
scope.matches.length = 0;
|
|
|
|
//transform labels
|
|
for(var i=0; i<matches.length; i++) {
|
|
locals[parserResult.itemName] = matches[i];
|
|
scope.matches.push({
|
|
label: parserResult.viewMapper(scope, locals),
|
|
model: matches[i]
|
|
});
|
|
}
|
|
|
|
scope.query = inputValue;
|
|
//position pop-up with matches - we need to re-calculate its position each time we are opening a window
|
|
//with matches as a pop-up might be absolute-positioned and position of an input might have changed on a page
|
|
//due to other elements being rendered
|
|
scope.position = appendToBody ? $position.offset(element) : $position.position(element);
|
|
scope.position.top = scope.position.top + element.prop('offsetHeight');
|
|
|
|
} else {
|
|
resetMatches();
|
|
}
|
|
isLoadingSetter(originalScope, false);
|
|
}
|
|
}, function(){
|
|
resetMatches();
|
|
isLoadingSetter(originalScope, false);
|
|
});
|
|
};
|
|
|
|
resetMatches();
|
|
|
|
//we need to propagate user's query so we can higlight matches
|
|
scope.query = undefined;
|
|
|
|
//Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later
|
|
var timeoutPromise;
|
|
|
|
//plug into $parsers pipeline to open a typeahead on view changes initiated from DOM
|
|
//$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue
|
|
modelCtrl.$parsers.unshift(function (inputValue) {
|
|
|
|
hasFocus = true;
|
|
|
|
if (inputValue && inputValue.length >= minSearch) {
|
|
if (waitTime > 0) {
|
|
if (timeoutPromise) {
|
|
$timeout.cancel(timeoutPromise);//cancel previous timeout
|
|
}
|
|
timeoutPromise = $timeout(function () {
|
|
getMatchesAsync(inputValue);
|
|
}, waitTime);
|
|
} else {
|
|
getMatchesAsync(inputValue);
|
|
}
|
|
} else {
|
|
isLoadingSetter(originalScope, false);
|
|
resetMatches();
|
|
}
|
|
|
|
if (isEditable) {
|
|
return inputValue;
|
|
} else {
|
|
if (!inputValue) {
|
|
// Reset in case user had typed something previously.
|
|
modelCtrl.$setValidity('editable', true);
|
|
return inputValue;
|
|
} else {
|
|
modelCtrl.$setValidity('editable', false);
|
|
return undefined;
|
|
}
|
|
}
|
|
});
|
|
|
|
modelCtrl.$formatters.push(function (modelValue) {
|
|
|
|
var candidateViewValue, emptyViewValue;
|
|
var locals = {};
|
|
|
|
if (inputFormatter) {
|
|
|
|
locals['$model'] = modelValue;
|
|
return inputFormatter(originalScope, locals);
|
|
|
|
} else {
|
|
|
|
//it might happen that we don't have enough info to properly render input value
|
|
//we need to check for this situation and simply return model value if we can't apply custom formatting
|
|
locals[parserResult.itemName] = modelValue;
|
|
candidateViewValue = parserResult.viewMapper(originalScope, locals);
|
|
locals[parserResult.itemName] = undefined;
|
|
emptyViewValue = parserResult.viewMapper(originalScope, locals);
|
|
|
|
return candidateViewValue!== emptyViewValue ? candidateViewValue : modelValue;
|
|
}
|
|
});
|
|
|
|
scope.select = function (activeIdx) {
|
|
//called from within the $digest() cycle
|
|
var locals = {};
|
|
var model, item;
|
|
|
|
locals[parserResult.itemName] = item = scope.matches[activeIdx].model;
|
|
model = parserResult.modelMapper(originalScope, locals);
|
|
$setModelValue(originalScope, model);
|
|
modelCtrl.$setValidity('editable', true);
|
|
|
|
onSelectCallback(originalScope, {
|
|
$item: item,
|
|
$model: model,
|
|
$label: parserResult.viewMapper(originalScope, locals)
|
|
});
|
|
|
|
resetMatches();
|
|
|
|
//return focus to the input element if a mach was selected via a mouse click event
|
|
element[0].focus();
|
|
};
|
|
|
|
//bind keyboard events: arrows up(38) / down(40), enter(13) and tab(9), esc(27)
|
|
element.bind('keydown', function (evt) {
|
|
|
|
//typeahead is open and an "interesting" key was pressed
|
|
if (scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1) {
|
|
return;
|
|
}
|
|
|
|
evt.preventDefault();
|
|
|
|
if (evt.which === 40) {
|
|
scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length;
|
|
scope.$digest();
|
|
|
|
} else if (evt.which === 38) {
|
|
scope.activeIdx = (scope.activeIdx ? scope.activeIdx : scope.matches.length) - 1;
|
|
scope.$digest();
|
|
|
|
} else if (evt.which === 13 || evt.which === 9) {
|
|
scope.$apply(function () {
|
|
scope.select(scope.activeIdx);
|
|
});
|
|
|
|
} else if (evt.which === 27) {
|
|
evt.stopPropagation();
|
|
|
|
resetMatches();
|
|
scope.$digest();
|
|
}
|
|
});
|
|
|
|
element.bind('blur', function (evt) {
|
|
hasFocus = false;
|
|
});
|
|
|
|
// Keep reference to click handler to unbind it.
|
|
var dismissClickHandler = function (evt) {
|
|
if (element[0] !== evt.target) {
|
|
resetMatches();
|
|
scope.$digest();
|
|
}
|
|
};
|
|
|
|
$document.bind('click', dismissClickHandler);
|
|
|
|
originalScope.$on('$destroy', function(){
|
|
$document.unbind('click', dismissClickHandler);
|
|
});
|
|
|
|
var $popup = $compile(popUpEl)(scope);
|
|
if ( appendToBody ) {
|
|
$document.find('body').append($popup);
|
|
} else {
|
|
element.after($popup);
|
|
}
|
|
}
|
|
};
|
|
|
|
}])
|
|
|
|
.directive('typeaheadPopup', function () {
|
|
return {
|
|
restrict:'EA',
|
|
scope:{
|
|
matches:'=',
|
|
query:'=',
|
|
active:'=',
|
|
position:'=',
|
|
select:'&'
|
|
},
|
|
replace:true,
|
|
templateUrl:'template/typeahead/typeahead-popup.html',
|
|
link:function (scope, element, attrs) {
|
|
|
|
scope.templateUrl = attrs.templateUrl;
|
|
|
|
scope.isOpen = function () {
|
|
return scope.matches.length > 0;
|
|
};
|
|
|
|
scope.isActive = function (matchIdx) {
|
|
return scope.active == matchIdx;
|
|
};
|
|
|
|
scope.selectActive = function (matchIdx) {
|
|
scope.active = matchIdx;
|
|
};
|
|
|
|
scope.selectMatch = function (activeIdx) {
|
|
scope.select({activeIdx:activeIdx});
|
|
};
|
|
}
|
|
};
|
|
})
|
|
|
|
.directive('typeaheadMatch', ['$http', '$templateCache', '$compile', '$parse', function ($http, $templateCache, $compile, $parse) {
|
|
return {
|
|
restrict:'EA',
|
|
scope:{
|
|
index:'=',
|
|
match:'=',
|
|
query:'='
|
|
},
|
|
link:function (scope, element, attrs) {
|
|
var tplUrl = $parse(attrs.templateUrl)(scope.$parent) || 'template/typeahead/typeahead-match.html';
|
|
$http.get(tplUrl, {cache: $templateCache}).success(function(tplContent){
|
|
element.replaceWith($compile(tplContent.trim())(scope));
|
|
});
|
|
}
|
|
};
|
|
}])
|
|
|
|
.filter('typeaheadHighlight', function() {
|
|
|
|
function escapeRegexp(queryToEscape) {
|
|
return queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
|
|
}
|
|
|
|
return function(matchItem, query) {
|
|
return query ? matchItem.replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchItem;
|
|
};
|
|
});
|
|
angular.module("template/accordion/accordion-group.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/accordion/accordion-group.html",
|
|
"<div class=\"panel panel-default\">\n" +
|
|
" <div class=\"panel-heading\">\n" +
|
|
" <h4 class=\"panel-title\">\n" +
|
|
" <a class=\"accordion-toggle\" ng-click=\"isOpen = !isOpen\" accordion-transclude=\"heading\">{{heading}}</a>\n" +
|
|
" </h4>\n" +
|
|
" </div>\n" +
|
|
" <div class=\"panel-collapse\" collapse=\"!isOpen\">\n" +
|
|
" <div class=\"panel-body\" ng-transclude></div>\n" +
|
|
" </div>\n" +
|
|
"</div>");
|
|
}]);
|
|
|
|
angular.module("template/accordion/accordion.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/accordion/accordion.html",
|
|
"<div class=\"panel-group\" ng-transclude></div>");
|
|
}]);
|
|
|
|
angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/alert/alert.html",
|
|
"<div class='alert' ng-class='\"alert-\" + (type || \"warning\")'>\n" +
|
|
" <button ng-show='closeable' type='button' class='close' ng-click='close()'>×</button>\n" +
|
|
" <div ng-transclude></div>\n" +
|
|
"</div>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/carousel/carousel.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/carousel/carousel.html",
|
|
"<div ng-mouseenter=\"pause()\" ng-mouseleave=\"play()\" class=\"carousel\">\n" +
|
|
" <ol class=\"carousel-indicators\" ng-show=\"slides().length > 1\">\n" +
|
|
" <li ng-repeat=\"slide in slides()\" ng-class=\"{active: isActive(slide)}\" ng-click=\"select(slide)\"></li>\n" +
|
|
" </ol>\n" +
|
|
" <div class=\"carousel-inner\" ng-transclude></div>\n" +
|
|
" <a class=\"left carousel-control\" ng-click=\"prev()\" ng-show=\"slides().length > 1\"><span class=\"icon-prev\"></span></a>\n" +
|
|
" <a class=\"right carousel-control\" ng-click=\"next()\" ng-show=\"slides().length > 1\"><span class=\"icon-next\"></span></a>\n" +
|
|
"</div>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/carousel/slide.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/carousel/slide.html",
|
|
"<div ng-class=\"{\n" +
|
|
" 'active': leaving || (active && !entering),\n" +
|
|
" 'prev': (next || active) && direction=='prev',\n" +
|
|
" 'next': (next || active) && direction=='next',\n" +
|
|
" 'right': direction=='prev',\n" +
|
|
" 'left': direction=='next'\n" +
|
|
" }\" class=\"item text-center\" ng-transclude></div>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/datepicker/datepicker.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/datepicker/datepicker.html",
|
|
"<table>\n" +
|
|
" <thead>\n" +
|
|
" <tr>\n" +
|
|
" <th><button type=\"button\" class=\"btn btn-default btn-sm pull-left\" ng-click=\"move(-1)\"><i class=\"glyphicon glyphicon-chevron-left\"></i></button></th>\n" +
|
|
" <th colspan=\"{{rows[0].length - 2 + showWeekNumbers}}\"><button type=\"button\" class=\"btn btn-default btn-sm btn-block\" ng-click=\"toggleMode()\"><strong>{{title}}</strong></button></th>\n" +
|
|
" <th><button type=\"button\" class=\"btn btn-default btn-sm pull-right\" ng-click=\"move(1)\"><i class=\"glyphicon glyphicon-chevron-right\"></i></button></th>\n" +
|
|
" </tr>\n" +
|
|
" <tr ng-show=\"labels.length > 0\" class=\"h6\">\n" +
|
|
" <th ng-show=\"showWeekNumbers\" class=\"text-center\">#</th>\n" +
|
|
" <th ng-repeat=\"label in labels\" class=\"text-center\">{{label}}</th>\n" +
|
|
" </tr>\n" +
|
|
" </thead>\n" +
|
|
" <tbody>\n" +
|
|
" <tr ng-repeat=\"row in rows\">\n" +
|
|
" <td ng-show=\"showWeekNumbers\" class=\"text-center\"><em>{{ getWeekNumber(row) }}</em></td>\n" +
|
|
" <td ng-repeat=\"dt in row\" class=\"text-center\">\n" +
|
|
" <button type=\"button\" style=\"width:100%;\" class=\"btn btn-default btn-sm\" ng-class=\"{'btn-info': dt.selected}\" ng-click=\"select(dt.date)\" ng-disabled=\"dt.disabled\"><span ng-class=\"{'text-muted': dt.secondary}\">{{dt.label}}</span></button>\n" +
|
|
" </td>\n" +
|
|
" </tr>\n" +
|
|
" </tbody>\n" +
|
|
"</table>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/datepicker/popup.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/datepicker/popup.html",
|
|
"<ul class=\"dropdown-menu\" ng-style=\"{display: (isOpen && 'block') || 'none', top: position.top+'px', left: position.left+'px'}\">\n" +
|
|
" <li ng-transclude></li>\n" +
|
|
" <li ng-show=\"showButtonBar\" style=\"padding:10px 9px 2px\">\n" +
|
|
" <span class=\"btn-group\">\n" +
|
|
" <button type=\"button\" class=\"btn btn-sm btn-info\" ng-click=\"today()\">{{currentText}}</button>\n" +
|
|
" <button type=\"button\" class=\"btn btn-sm btn-default\" ng-click=\"showWeeks = ! showWeeks\" ng-class=\"{active: showWeeks}\">{{toggleWeeksText}}</button>\n" +
|
|
" <button type=\"button\" class=\"btn btn-sm btn-danger\" ng-click=\"clear()\">{{clearText}}</button>\n" +
|
|
" </span>\n" +
|
|
" <button type=\"button\" class=\"btn btn-sm btn-success pull-right\" ng-click=\"isOpen = false\">{{closeText}}</button>\n" +
|
|
" </li>\n" +
|
|
"</ul>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/modal/backdrop.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/modal/backdrop.html",
|
|
"<div class=\"modal-backdrop fade\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1040 + index*10}\"></div>");
|
|
}]);
|
|
|
|
angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/modal/window.html",
|
|
"<div tabindex=\"-1\" class=\"modal fade {{ windowClass }}\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\" ng-click=\"close($event)\">\n" +
|
|
" <div class=\"modal-dialog\"><div class=\"modal-content\" ng-transclude></div></div>\n" +
|
|
"</div>");
|
|
}]);
|
|
|
|
angular.module("template/pagination/pager.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/pagination/pager.html",
|
|
"<ul class=\"pager\">\n" +
|
|
" <li ng-repeat=\"page in pages\" ng-class=\"{disabled: page.disabled, previous: page.previous, next: page.next}\"><a ng-click=\"selectPage(page.number)\">{{page.text}}</a></li>\n" +
|
|
"</ul>");
|
|
}]);
|
|
|
|
angular.module("template/pagination/pagination.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/pagination/pagination.html",
|
|
"<ul class=\"pagination\">\n" +
|
|
" <li ng-repeat=\"page in pages\" ng-class=\"{active: page.active, disabled: page.disabled}\"><a ng-click=\"selectPage(page.number)\">{{page.text}}</a></li>\n" +
|
|
"</ul>");
|
|
}]);
|
|
|
|
angular.module("template/tooltip/tooltip-html-unsafe-popup.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/tooltip/tooltip-html-unsafe-popup.html",
|
|
"<div class=\"tooltip {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
|
|
" <div class=\"tooltip-arrow\"></div>\n" +
|
|
" <div class=\"tooltip-inner\" bind-html-unsafe=\"content\"></div>\n" +
|
|
"</div>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/tooltip/tooltip-popup.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/tooltip/tooltip-popup.html",
|
|
"<div class=\"tooltip {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
|
|
" <div class=\"tooltip-arrow\"></div>\n" +
|
|
" <div class=\"tooltip-inner\" ng-bind=\"content\"></div>\n" +
|
|
"</div>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/popover/popover.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/popover/popover.html",
|
|
"<div class=\"popover {{placement}}\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
|
|
" <div class=\"arrow\"></div>\n" +
|
|
"\n" +
|
|
" <div class=\"popover-inner\">\n" +
|
|
" <h3 class=\"popover-title\" ng-bind=\"title\" ng-show=\"title\"></h3>\n" +
|
|
" <div class=\"popover-content\" ng-bind=\"content\"></div>\n" +
|
|
" </div>\n" +
|
|
"</div>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/progressbar/bar.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/progressbar/bar.html",
|
|
"<div class=\"progress-bar\" ng-class=\"type && 'progress-bar-' + type\" ng-transclude></div>");
|
|
}]);
|
|
|
|
angular.module("template/progressbar/progress.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/progressbar/progress.html",
|
|
"<div class=\"progress\" ng-transclude></div>");
|
|
}]);
|
|
|
|
angular.module("template/progressbar/progressbar.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/progressbar/progressbar.html",
|
|
"<div class=\"progress\"><div class=\"progress-bar\" ng-class=\"type && 'progress-bar-' + type\" ng-transclude></div></div>");
|
|
}]);
|
|
|
|
angular.module("template/rating/rating.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/rating/rating.html",
|
|
"<span ng-mouseleave=\"reset()\">\n" +
|
|
" <i ng-repeat=\"r in range\" ng-mouseenter=\"enter($index + 1)\" ng-click=\"rate($index + 1)\" class=\"glyphicon\" ng-class=\"$index < val && (r.stateOn || 'glyphicon-star') || (r.stateOff || 'glyphicon-star-empty')\"></i>\n" +
|
|
"</span>");
|
|
}]);
|
|
|
|
angular.module("template/tabs/tab.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/tabs/tab.html",
|
|
"<li ng-class=\"{active: active, disabled: disabled}\">\n" +
|
|
" <a ng-click=\"select()\" tab-heading-transclude>{{heading}}</a>\n" +
|
|
"</li>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/tabs/tabset-titles.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/tabs/tabset-titles.html",
|
|
"<ul class=\"nav {{type && 'nav-' + type}}\" ng-class=\"{'nav-stacked': vertical}\">\n" +
|
|
"</ul>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/tabs/tabset.html",
|
|
"\n" +
|
|
"<div class=\"tabbable\">\n" +
|
|
" <ul class=\"nav {{type && 'nav-' + type}}\" ng-class=\"{'nav-stacked': vertical, 'nav-justified': justified}\" ng-transclude></ul>\n" +
|
|
" <div class=\"tab-content\">\n" +
|
|
" <div class=\"tab-pane\" \n" +
|
|
" ng-repeat=\"tab in tabs\" \n" +
|
|
" ng-class=\"{active: tab.active}\"\n" +
|
|
" tab-content-transclude=\"tab\">\n" +
|
|
" </div>\n" +
|
|
" </div>\n" +
|
|
"</div>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/timepicker/timepicker.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/timepicker/timepicker.html",
|
|
"<table>\n" +
|
|
" <tbody>\n" +
|
|
" <tr class=\"text-center\">\n" +
|
|
" <td><a ng-click=\"incrementHours()\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-up\"></span></a></td>\n" +
|
|
" <td> </td>\n" +
|
|
" <td><a ng-click=\"incrementMinutes()\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-up\"></span></a></td>\n" +
|
|
" <td ng-show=\"showMeridian\"></td>\n" +
|
|
" </tr>\n" +
|
|
" <tr>\n" +
|
|
" <td style=\"width:50px;\" class=\"form-group\" ng-class=\"{'has-error': invalidHours}\">\n" +
|
|
" <input type=\"text\" ng-model=\"hours\" ng-change=\"updateHours()\" class=\"form-control text-center\" ng-mousewheel=\"incrementHours()\" ng-readonly=\"readonlyInput\" maxlength=\"2\">\n" +
|
|
" </td>\n" +
|
|
" <td>:</td>\n" +
|
|
" <td style=\"width:50px;\" class=\"form-group\" ng-class=\"{'has-error': invalidMinutes}\">\n" +
|
|
" <input type=\"text\" ng-model=\"minutes\" ng-change=\"updateMinutes()\" class=\"form-control text-center\" ng-readonly=\"readonlyInput\" maxlength=\"2\">\n" +
|
|
" </td>\n" +
|
|
" <td ng-show=\"showMeridian\"><button type=\"button\" class=\"btn btn-default text-center\" ng-click=\"toggleMeridian()\">{{meridian}}</button></td>\n" +
|
|
" </tr>\n" +
|
|
" <tr class=\"text-center\">\n" +
|
|
" <td><a ng-click=\"decrementHours()\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-down\"></span></a></td>\n" +
|
|
" <td> </td>\n" +
|
|
" <td><a ng-click=\"decrementMinutes()\" class=\"btn btn-link\"><span class=\"glyphicon glyphicon-chevron-down\"></span></a></td>\n" +
|
|
" <td ng-show=\"showMeridian\"></td>\n" +
|
|
" </tr>\n" +
|
|
" </tbody>\n" +
|
|
"</table>\n" +
|
|
"");
|
|
}]);
|
|
|
|
angular.module("template/typeahead/typeahead-match.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/typeahead/typeahead-match.html",
|
|
"<a tabindex=\"-1\" bind-html-unsafe=\"match.label | typeaheadHighlight:query\"></a>");
|
|
}]);
|
|
|
|
angular.module("template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) {
|
|
$templateCache.put("template/typeahead/typeahead-popup.html",
|
|
"<ul class=\"dropdown-menu\" ng-style=\"{display: isOpen()&&'block' || 'none', top: position.top+'px', left: position.left+'px'}\">\n" +
|
|
" <li ng-repeat=\"match in matches\" ng-class=\"{active: isActive($index) }\" ng-mouseenter=\"selectActive($index)\" ng-click=\"selectMatch($index)\">\n" +
|
|
" <div typeahead-match index=\"$index\" match=\"match\" query=\"query\" template-url=\"templateUrl\"></div>\n" +
|
|
" </li>\n" +
|
|
"</ul>");
|
|
}]);
|
|
|
|
// Source: public/lib/angular-ui-utils/ui-utils.min.js
|
|
/**
|
|
* angular-ui-utils - Swiss-Army-Knife of AngularJS tools (with no external dependencies!)
|
|
* @version v0.1.1 - 2014-02-05
|
|
* @link http://angular-ui.github.com
|
|
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
*/
|
|
angular.module("ui.alias",[]).config(["$compileProvider","uiAliasConfig",function(a,b){b=b||{},angular.forEach(b,function(b,c){angular.isString(b)&&(b={replace:!0,template:b}),a.directive(c,function(){return b})})}]),angular.module("ui.event",[]).directive("uiEvent",["$parse",function(a){return function(b,c,d){var e=b.$eval(d.uiEvent);angular.forEach(e,function(d,e){var f=a(d);c.bind(e,function(a){var c=Array.prototype.slice.call(arguments);c=c.splice(1),f(b,{$event:a,$params:c}),b.$$phase||b.$apply()})})}}]),angular.module("ui.format",[]).filter("format",function(){return function(a,b){var c=a;if(angular.isString(c)&&void 0!==b)if(angular.isArray(b)||angular.isObject(b)||(b=[b]),angular.isArray(b)){var d=b.length,e=function(a,c){return c=parseInt(c,10),c>=0&&d>c?b[c]:a};c=c.replace(/\$([0-9]+)/g,e)}else angular.forEach(b,function(a,b){c=c.split(":"+b).join(a)});return c}}),angular.module("ui.highlight",[]).filter("highlight",function(){return function(a,b,c){return b||angular.isNumber(b)?(a=a.toString(),b=b.toString(),c?a.split(b).join('<span class="ui-match">'+b+"</span>"):a.replace(new RegExp(b,"gi"),'<span class="ui-match">$&</span>')):a}}),angular.module("ui.include",[]).directive("uiInclude",["$http","$templateCache","$anchorScroll","$compile",function(a,b,c,d){return{restrict:"ECA",terminal:!0,compile:function(e,f){var g=f.uiInclude||f.src,h=f.fragment||"",i=f.onload||"",j=f.autoscroll;return function(e,f){function k(){var k=++m,o=e.$eval(g),p=e.$eval(h);o?a.get(o,{cache:b}).success(function(a){if(k===m){l&&l.$destroy(),l=e.$new();var b;b=p?angular.element("<div/>").html(a).find(p):angular.element("<div/>").html(a).contents(),f.html(b),d(b)(l),!angular.isDefined(j)||j&&!e.$eval(j)||c(),l.$emit("$includeContentLoaded"),e.$eval(i)}}).error(function(){k===m&&n()}):n()}var l,m=0,n=function(){l&&(l.$destroy(),l=null),f.html("")};e.$watch(h,k),e.$watch(g,k)}}}}]),angular.module("ui.indeterminate",[]).directive("uiIndeterminate",[function(){return{compile:function(a,b){return b.type&&"checkbox"===b.type.toLowerCase()?function(a,b,c){a.$watch(c.uiIndeterminate,function(a){b[0].indeterminate=!!a})}:angular.noop}}}]),angular.module("ui.inflector",[]).filter("inflector",function(){function a(a){return a.replace(/^([a-z])|\s+([a-z])/g,function(a){return a.toUpperCase()})}function b(a,b){return a.replace(/[A-Z]/g,function(a){return b+a})}var c={humanize:function(c){return a(b(c," ").split("_").join(" "))},underscore:function(a){return a.substr(0,1).toLowerCase()+b(a.substr(1),"_").toLowerCase().split(" ").join("_")},variable:function(b){return b=b.substr(0,1).toLowerCase()+a(b.split("_").join(" ")).substr(1).split(" ").join("")}};return function(a,b){return b!==!1&&angular.isString(a)?(b=b||"humanize",c[b](a)):a}}),angular.module("ui.jq",[]).value("uiJqConfig",{}).directive("uiJq",["uiJqConfig","$timeout",function(a,b){return{restrict:"A",compile:function(c,d){if(!angular.isFunction(c[d.uiJq]))throw new Error('ui-jq: The "'+d.uiJq+'" function does not exist');var e=a&&a[d.uiJq];return function(a,c,d){function f(){b(function(){c[d.uiJq].apply(c,g)},0,!1)}var g=[];d.uiOptions?(g=a.$eval("["+d.uiOptions+"]"),angular.isObject(e)&&angular.isObject(g[0])&&(g[0]=angular.extend({},e,g[0]))):e&&(g=[e]),d.ngModel&&c.is("select,input,textarea")&&c.bind("change",function(){c.trigger("input")}),d.uiRefresh&&a.$watch(d.uiRefresh,function(){f()}),f()}}}}]),angular.module("ui.keypress",[]).factory("keypressHelper",["$parse",function(a){var b={8:"backspace",9:"tab",13:"enter",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"delete"},c=function(a){return a.charAt(0).toUpperCase()+a.slice(1)};return function(d,e,f,g){var h,i=[];h=e.$eval(g["ui"+c(d)]),angular.forEach(h,function(b,c){var d,e;e=a(b),angular.forEach(c.split(" "),function(a){d={expression:e,keys:{}},angular.forEach(a.split("-"),function(a){d.keys[a]=!0}),i.push(d)})}),f.bind(d,function(a){var c=!(!a.metaKey||a.ctrlKey),f=!!a.altKey,g=!!a.ctrlKey,h=!!a.shiftKey,j=a.keyCode;"keypress"===d&&!h&&j>=97&&122>=j&&(j-=32),angular.forEach(i,function(d){var i=d.keys[b[j]]||d.keys[j.toString()],k=!!d.keys.meta,l=!!d.keys.alt,m=!!d.keys.ctrl,n=!!d.keys.shift;i&&k===c&&l===f&&m===g&&n===h&&e.$apply(function(){d.expression(e,{$event:a})})})})}}]),angular.module("ui.keypress").directive("uiKeydown",["keypressHelper",function(a){return{link:function(b,c,d){a("keydown",b,c,d)}}}]),angular.module("ui.keypress").directive("uiKeypress",["keypressHelper",function(a){return{link:function(b,c,d){a("keypress",b,c,d)}}}]),angular.module("ui.keypress").directive("uiKeyup",["keypressHelper",function(a){return{link:function(b,c,d){a("keyup",b,c,d)}}}]),angular.module("ui.mask",[]).value("uiMaskConfig",{maskDefinitions:{9:/\d/,A:/[a-zA-Z]/,"*":/[a-zA-Z0-9]/}}).directive("uiMask",["uiMaskConfig",function(a){return{priority:100,require:"ngModel",restrict:"A",compile:function(){var b=a;return function(a,c,d,e){function f(a){return angular.isDefined(a)?(s(a),N?(k(),l(),!0):j()):j()}function g(a){angular.isDefined(a)&&(D=a,N&&w())}function h(a){return N?(G=o(a||""),I=n(G),e.$setValidity("mask",I),I&&G.length?p(G):void 0):a}function i(a){return N?(G=o(a||""),I=n(G),e.$viewValue=G.length?p(G):"",e.$setValidity("mask",I),""===G&&void 0!==e.$error.required&&e.$setValidity("required",!1),I?G:void 0):a}function j(){return N=!1,m(),angular.isDefined(P)?c.attr("placeholder",P):c.removeAttr("placeholder"),angular.isDefined(Q)?c.attr("maxlength",Q):c.removeAttr("maxlength"),c.val(e.$modelValue),e.$viewValue=e.$modelValue,!1}function k(){G=K=o(e.$modelValue||""),H=J=p(G),I=n(G);var a=I&&G.length?H:"";d.maxlength&&c.attr("maxlength",2*B[B.length-1]),c.attr("placeholder",D),c.val(a),e.$viewValue=a}function l(){O||(c.bind("blur",t),c.bind("mousedown mouseup",u),c.bind("input keyup click focus",w),O=!0)}function m(){O&&(c.unbind("blur",t),c.unbind("mousedown",u),c.unbind("mouseup",u),c.unbind("input",w),c.unbind("keyup",w),c.unbind("click",w),c.unbind("focus",w),O=!1)}function n(a){return a.length?a.length>=F:!0}function o(a){var b="",c=C.slice();return a=a.toString(),angular.forEach(E,function(b){a=a.replace(b,"")}),angular.forEach(a.split(""),function(a){c.length&&c[0].test(a)&&(b+=a,c.shift())}),b}function p(a){var b="",c=B.slice();return angular.forEach(D.split(""),function(d,e){a.length&&e===c[0]?(b+=a.charAt(0)||"_",a=a.substr(1),c.shift()):b+=d}),b}function q(a){var b=d.placeholder;return"undefined"!=typeof b&&b[a]?b[a]:"_"}function r(){return D.replace(/[_]+/g,"_").replace(/([^_]+)([a-zA-Z0-9])([^_])/g,"$1$2_$3").split("_")}function s(a){var b=0;if(B=[],C=[],D="","string"==typeof a){F=0;var c=!1,d=a.split("");angular.forEach(d,function(a,d){R.maskDefinitions[a]?(B.push(b),D+=q(d),C.push(R.maskDefinitions[a]),b++,c||F++):"?"===a?c=!0:(D+=a,b++)})}B.push(B.slice().pop()+1),E=r(),N=B.length>1?!0:!1}function t(){L=0,M=0,I&&0!==G.length||(H="",c.val(""),a.$apply(function(){e.$setViewValue("")}))}function u(a){"mousedown"===a.type?c.bind("mouseout",v):c.unbind("mouseout",v)}function v(){M=A(this),c.unbind("mouseout",v)}function w(b){b=b||{};var d=b.which,f=b.type;if(16!==d&&91!==d){var g,h=c.val(),i=J,j=o(h),k=K,l=!1,m=y(this)||0,n=L||0,q=m-n,r=B[0],s=B[j.length]||B.slice().shift(),t=M||0,u=A(this)>0,v=t>0,w=h.length>i.length||t&&h.length>i.length-t,C=h.length<i.length||t&&h.length===i.length-t,D=d>=37&&40>=d&&b.shiftKey,E=37===d,F=8===d||"keyup"!==f&&C&&-1===q,G=46===d||"keyup"!==f&&C&&0===q&&!v,H=(E||F||"click"===f)&&m>r;if(M=A(this),!D&&(!u||"click"!==f&&"keyup"!==f)){if("input"===f&&C&&!v&&j===k){for(;F&&m>r&&!x(m);)m--;for(;G&&s>m&&-1===B.indexOf(m);)m++;var I=B.indexOf(m);j=j.substring(0,I)+j.substring(I+1),l=!0}for(g=p(j),J=g,K=j,c.val(g),l&&a.$apply(function(){e.$setViewValue(j)}),w&&r>=m&&(m=r+1),H&&m--,m=m>s?s:r>m?r:m;!x(m)&&m>r&&s>m;)m+=H?-1:1;(H&&s>m||w&&!x(n))&&m++,L=m,z(this,m)}}}function x(a){return B.indexOf(a)>-1}function y(a){if(!a)return 0;if(void 0!==a.selectionStart)return a.selectionStart;if(document.selection){a.focus();var b=document.selection.createRange();return b.moveStart("character",-a.value.length),b.text.length}return 0}function z(a,b){if(!a)return 0;if(0!==a.offsetWidth&&0!==a.offsetHeight)if(a.setSelectionRange)a.focus(),a.setSelectionRange(b,b);else if(a.createTextRange){var c=a.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",b),c.select()}}function A(a){return a?void 0!==a.selectionStart?a.selectionEnd-a.selectionStart:document.selection?document.selection.createRange().text.length:0:0}var B,C,D,E,F,G,H,I,J,K,L,M,N=!1,O=!1,P=d.placeholder,Q=d.maxlength,R={};d.uiOptions?(R=a.$eval("["+d.uiOptions+"]"),angular.isObject(R[0])&&(R=function(a,b){for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]?angular.extend(b[c],a[c]):b[c]=angular.copy(a[c]));return b}(b,R[0]))):R=b,d.$observe("uiMask",f),d.$observe("placeholder",g),e.$formatters.push(h),e.$parsers.push(i),c.bind("mousedown mouseup",u),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){if(null===this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>1&&(d=Number(arguments[1]),d!==d?d=0:0!==d&&1/0!==d&&d!==-1/0&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);c>e;e++)if(e in b&&b[e]===a)return e;return-1})}}}}]),angular.module("ui.reset",[]).value("uiResetConfig",null).directive("uiReset",["uiResetConfig",function(a){var b=null;return void 0!==a&&(b=a),{require:"ngModel",link:function(a,c,d,e){var f;f=angular.element('<a class="ui-reset" />'),c.wrap('<span class="ui-resetwrap" />').after(f),f.bind("click",function(c){c.preventDefault(),a.$apply(function(){e.$setViewValue(d.uiReset?a.$eval(d.uiReset):b),e.$render()})})}}}]),angular.module("ui.route",[]).directive("uiRoute",["$location","$parse",function(a,b){return{restrict:"AC",scope:!0,compile:function(c,d){var e;if(d.uiRoute)e="uiRoute";else if(d.ngHref)e="ngHref";else{if(!d.href)throw new Error("uiRoute missing a route or href property on "+c[0]);e="href"}return function(c,d,f){function g(b){var d=b.indexOf("#");d>-1&&(b=b.substr(d+1)),(j=function(){i(c,a.path().indexOf(b)>-1)})()}function h(b){var d=b.indexOf("#");d>-1&&(b=b.substr(d+1)),(j=function(){var d=new RegExp("^"+b+"$",["i"]);i(c,d.test(a.path()))})()}var i=b(f.ngModel||f.routeModel||"$uiRoute").assign,j=angular.noop;switch(e){case"uiRoute":f.uiRoute?h(f.uiRoute):f.$observe("uiRoute",h);break;case"ngHref":f.ngHref?g(f.ngHref):f.$observe("ngHref",g);break;case"href":g(f.href)}c.$on("$routeChangeSuccess",function(){j()}),c.$on("$stateChangeSuccess",function(){j()})}}}}]),angular.module("ui.scroll.jqlite",["ui.scroll"]).service("jqLiteExtras",["$log","$window",function(a,b){return{registerFor:function(a){var c,d,e,f,g,h,i;return d=angular.element.prototype.css,a.prototype.css=function(a,b){var c,e;return e=this,c=e[0],c&&3!==c.nodeType&&8!==c.nodeType&&c.style?d.call(e,a,b):void 0},h=function(a){return a&&a.document&&a.location&&a.alert&&a.setInterval},i=function(a,b,c){var d,e,f,g,i;return d=a[0],i={top:["scrollTop","pageYOffset","scrollLeft"],left:["scrollLeft","pageXOffset","scrollTop"]}[b],e=i[0],g=i[1],f=i[2],h(d)?angular.isDefined(c)?d.scrollTo(a[f].call(a),c):g in d?d[g]:d.document.documentElement[e]:angular.isDefined(c)?d[e]=c:d[e]},b.getComputedStyle?(f=function(a){return b.getComputedStyle(a,null)},c=function(a,b){return parseFloat(b)}):(f=function(a){return a.currentStyle},c=function(a,b){var c,d,e,f,g,h,i;return c=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,f=new RegExp("^("+c+")(?!px)[a-z%]+$","i"),f.test(b)?(i=a.style,d=i.left,g=a.runtimeStyle,h=g&&g.left,g&&(g.left=i.left),i.left=b,e=i.pixelLeft,i.left=d,h&&(g.left=h),e):parseFloat(b)}),e=function(a,b){var d,e,g,i,j,k,l,m,n,o,p,q,r;return h(a)?(d=document.documentElement[{height:"clientHeight",width:"clientWidth"}[b]],{base:d,padding:0,border:0,margin:0}):(r={width:[a.offsetWidth,"Left","Right"],height:[a.offsetHeight,"Top","Bottom"]}[b],d=r[0],l=r[1],m=r[2],k=f(a),p=c(a,k["padding"+l])||0,q=c(a,k["padding"+m])||0,e=c(a,k["border"+l+"Width"])||0,g=c(a,k["border"+m+"Width"])||0,i=k["margin"+l],j=k["margin"+m],n=c(a,i)||0,o=c(a,j)||0,{base:d,padding:p+q,border:e+g,margin:n+o})},g=function(a,b,c){var d,g,h;return g=e(a,b),g.base>0?{base:g.base-g.padding-g.border,outer:g.base,outerfull:g.base+g.margin}[c]:(d=f(a),h=d[b],(0>h||null===h)&&(h=a.style[b]||0),h=parseFloat(h)||0,{base:h-g.padding-g.border,outer:h,outerfull:h+g.padding+g.border+g.margin}[c])},angular.forEach({before:function(a){var b,c,d,e,f,g,h;if(f=this,c=f[0],e=f.parent(),b=e.contents(),b[0]===c)return e.prepend(a);for(d=g=1,h=b.length-1;h>=1?h>=g:g>=h;d=h>=1?++g:--g)if(b[d]===c)return void angular.element(b[d-1]).after(a);throw new Error("invalid DOM structure "+c.outerHTML)},height:function(a){var b;return b=this,angular.isDefined(a)?(angular.isNumber(a)&&(a+="px"),d.call(b,"height",a)):g(this[0],"height","base")},outerHeight:function(a){return g(this[0],"height",a?"outerfull":"outer")},offset:function(a){var b,c,d,e,f,g;return f=this,arguments.length?void 0===a?f:a:(b={top:0,left:0},e=f[0],(c=e&&e.ownerDocument)?(d=c.documentElement,e.getBoundingClientRect&&(b=e.getBoundingClientRect()),g=c.defaultView||c.parentWindow,{top:b.top+(g.pageYOffset||d.scrollTop)-(d.clientTop||0),left:b.left+(g.pageXOffset||d.scrollLeft)-(d.clientLeft||0)}):void 0)},scrollTop:function(a){return i(this,"top",a)},scrollLeft:function(a){return i(this,"left",a)}},function(b,c){return a.prototype[c]?void 0:a.prototype[c]=b})}}}]).run(["$log","$window","jqLiteExtras",function(a,b,c){return b.jQuery?void 0:c.registerFor(angular.element)}]),angular.module("ui.scroll",[]).directive("ngScrollViewport",["$log",function(){return{controller:["$scope","$element",function(a,b){return b}]}}]).directive("ngScroll",["$log","$injector","$rootScope","$timeout",function(a,b,c,d){return{require:["?^ngScrollViewport"],transclude:"element",priority:1e3,terminal:!0,compile:function(e,f,g){return function(f,h,i,j){var k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T;if(H=i.ngScroll.match(/^\s*(\w+)\s+in\s+(\w+)\s*$/),!H)throw new Error('Expected ngScroll in form of "item_ in _datasource_" but got "'+i.ngScroll+'"');if(F=H[1],v=H[2],D=function(a){return angular.isObject(a)&&a.get&&angular.isFunction(a.get)},u=f[v],!D(u)&&(u=b.get(v),!D(u)))throw new Error(v+" is not a valid datasource");return r=Math.max(3,+i.bufferSize||10),q=function(){return T.height()*Math.max(.1,+i.padding||.1)},O=function(a){return a[0].scrollHeight||a[0].document.documentElement.scrollHeight},k=null,g(R=f.$new(),function(a){var b,c,d,f,g,h;if(f=a[0].localName,"dl"===f)throw new Error("ng-scroll directive does not support <"+a[0].localName+"> as a repeating tag: "+a[0].outerHTML);return"li"!==f&&"tr"!==f&&(f="div"),h=j[0]||angular.element(window),h.css({"overflow-y":"auto",display:"block"}),d=function(a){var b,c,d;switch(a){case"tr":return d=angular.element("<table><tr><td><div></div></td></tr></table>"),b=d.find("div"),c=d.find("tr"),c.paddingHeight=function(){return b.height.apply(b,arguments)},c;default:return c=angular.element("<"+a+"></"+a+">"),c.paddingHeight=c.height,c}},c=function(a,b,c){return b[{top:"before",bottom:"after"}[c]](a),{paddingHeight:function(){return a.paddingHeight.apply(a,arguments)},insert:function(b){return a[{top:"after",bottom:"before"}[c]](b)}}},g=c(d(f),e,"top"),b=c(d(f),e,"bottom"),R.$destroy(),k={viewport:h,topPadding:g.paddingHeight,bottomPadding:b.paddingHeight,append:b.insert,prepend:g.insert,bottomDataPos:function(){return O(h)-b.paddingHeight()},topDataPos:function(){return g.paddingHeight()}}}),T=k.viewport,B=1,I=1,p=[],J=[],x=!1,n=!1,G=u.loading||function(){},E=!1,L=function(a,b){var c,d;for(c=d=a;b>=a?b>d:d>b;c=b>=a?++d:--d)p[c].scope.$destroy(),p[c].element.remove();return p.splice(a,b-a)},K=function(){return B=1,I=1,L(0,p.length),k.topPadding(0),k.bottomPadding(0),J=[],x=!1,n=!1,l(!1)},o=function(){return T.scrollTop()+T.height()},S=function(){return T.scrollTop()},P=function(){return!x&&k.bottomDataPos()<o()+q()},s=function(){var b,c,d,e,f,g;for(b=0,e=0,c=f=g=p.length-1;(0>=g?0>=f:f>=0)&&(d=p[c].element.outerHeight(!0),k.bottomDataPos()-b-d>o()+q());c=0>=g?++f:--f)b+=d,e++,x=!1;return e>0?(k.bottomPadding(k.bottomPadding()+b),L(p.length-e,p.length),I-=e,a.log("clipped off bottom "+e+" bottom padding "+k.bottomPadding())):void 0},Q=function(){return!n&&k.topDataPos()>S()-q()},t=function(){var b,c,d,e,f,g;for(e=0,d=0,f=0,g=p.length;g>f&&(b=p[f],c=b.element.outerHeight(!0),k.topDataPos()+e+c<S()-q());f++)e+=c,d++,n=!1;return d>0?(k.topPadding(k.topPadding()+e),L(0,d),B+=d,a.log("clipped off top "+d+" top padding "+k.topPadding())):void 0},w=function(a,b){return E||(E=!0,G(!0)),1===J.push(a)?z(b):void 0},C=function(a,b){var c,d,e;return c=f.$new(),c[F]=b,d=a>B,c.$index=a,d&&c.$index--,e={scope:c},g(c,function(b){return e.element=b,d?a===I?(k.append(b),p.push(e)):(p[a-B].element.after(b),p.splice(a-B+1,0,e)):(k.prepend(b),p.unshift(e))}),{appended:d,wrapper:e}},m=function(a,b){var c;return a?k.bottomPadding(Math.max(0,k.bottomPadding()-b.element.outerHeight(!0))):(c=k.topPadding()-b.element.outerHeight(!0),c>=0?k.topPadding(c):T.scrollTop(T.scrollTop()+b.element.outerHeight(!0)))},l=function(b,c,e){var f;return f=function(){return a.log("top {actual="+k.topDataPos()+" visible from="+S()+" bottom {visible through="+o()+" actual="+k.bottomDataPos()+"}"),P()?w(!0,b):Q()&&w(!1,b),e?e():void 0},c?d(function(){var a,b,d;for(b=0,d=c.length;d>b;b++)a=c[b],m(a.appended,a.wrapper);return f()}):f()},A=function(a,b){return l(a,b,function(){return J.shift(),0===J.length?(E=!1,G(!1)):z(a)})},z=function(b){var c;return c=J[0],c?p.length&&!P()?A(b):u.get(I,r,function(c){var d,e,f,g;if(e=[],0===c.length)x=!0,k.bottomPadding(0),a.log("appended: requested "+r+" records starting from "+I+" recieved: eof");else{for(t(),f=0,g=c.length;g>f;f++)d=c[f],e.push(C(++I,d));a.log("appended: requested "+r+" received "+c.length+" buffer size "+p.length+" first "+B+" next "+I)}return A(b,e)}):p.length&&!Q()?A(b):u.get(B-r,r,function(c){var d,e,f,g;if(e=[],0===c.length)n=!0,k.topPadding(0),a.log("prepended: requested "+r+" records starting from "+(B-r)+" recieved: bof");else{for(s(),d=f=g=c.length-1;0>=g?0>=f:f>=0;d=0>=g?++f:--f)e.unshift(C(--B,c[d]));a.log("prepended: requested "+r+" received "+c.length+" buffer size "+p.length+" first "+B+" next "+I)}return A(b,e)})},M=function(){return c.$$phase||E?void 0:(l(!1),f.$apply())},T.bind("resize",M),N=function(){return c.$$phase||E?void 0:(l(!0),f.$apply())},T.bind("scroll",N),f.$watch(u.revision,function(){return K()}),y=u.scope?u.scope.$new():f.$new(),f.$on("$destroy",function(){return y.$destroy(),T.unbind("resize",M),T.unbind("scroll",N)}),y.$on("update.items",function(a,b,c){var d,e,f,g,h;if(angular.isFunction(b))for(e=function(a){return b(a.scope)},f=0,g=p.length;g>f;f++)d=p[f],e(d);else 0<=(h=b-B-1)&&h<p.length&&(p[b-B-1].scope[F]=c);return null}),y.$on("delete.items",function(a,b){var c,d,e,f,g,h,i,j,k,m,n,o;if(angular.isFunction(b)){for(e=[],h=0,k=p.length;k>h;h++)d=p[h],e.unshift(d);for(g=function(a){return b(a.scope)?(L(e.length-1-c,e.length-c),I--):void 0},c=i=0,m=e.length;m>i;c=++i)f=e[c],g(f)}else 0<=(o=b-B-1)&&o<p.length&&(L(b-B-1,b-B),I--);for(c=j=0,n=p.length;n>j;c=++j)d=p[c],d.scope.$index=B+c;return l(!1)}),y.$on("insert.item",function(a,b,c){var d,e,f,g,h,i,j,k,m,n,o,q;if(e=[],angular.isFunction(b)){for(f=[],i=0,m=p.length;m>i;i++)c=p[i],f.unshift(c);for(h=function(a){var f,g,h,i,j;if(g=b(a.scope)){if(C=function(a,b){return C(a,b),I++},angular.isArray(g)){for(j=[],f=h=0,i=g.length;i>h;f=++h)c=g[f],j.push(e.push(C(d+f,c)));return j}return e.push(C(d,g))}},d=j=0,n=f.length;n>j;d=++j)g=f[d],h(g)}else 0<=(q=b-B-1)&&q<p.length&&(e.push(C(b,c)),I++);for(d=k=0,o=p.length;o>k;d=++k)c=p[d],c.scope.$index=B+d;return l(!1,e)})}}}}]),angular.module("ui.scrollfix",[]).directive("uiScrollfix",["$window",function(a){return{require:"^?uiScrollfixTarget",link:function(b,c,d,e){function f(){var b;if(angular.isDefined(a.pageYOffset))b=a.pageYOffset;else{var e=document.compatMode&&"BackCompat"!==document.compatMode?document.documentElement:document.body;b=e.scrollTop}!c.hasClass("ui-scrollfix")&&b>d.uiScrollfix?c.addClass("ui-scrollfix"):c.hasClass("ui-scrollfix")&&b<d.uiScrollfix&&c.removeClass("ui-scrollfix")}var g=c[0].offsetTop,h=e&&e.$element||angular.element(a);d.uiScrollfix?"string"==typeof d.uiScrollfix&&("-"===d.uiScrollfix.charAt(0)?d.uiScrollfix=g-parseFloat(d.uiScrollfix.substr(1)):"+"===d.uiScrollfix.charAt(0)&&(d.uiScrollfix=g+parseFloat(d.uiScrollfix.substr(1)))):d.uiScrollfix=g,h.on("scroll",f),b.$on("$destroy",function(){h.off("scroll",f)})}}}]).directive("uiScrollfixTarget",[function(){return{controller:["$element",function(a){this.$element=a}]}}]),angular.module("ui.showhide",[]).directive("uiShow",[function(){return function(a,b,c){a.$watch(c.uiShow,function(a){a?b.addClass("ui-show"):b.removeClass("ui-show")})}}]).directive("uiHide",[function(){return function(a,b,c){a.$watch(c.uiHide,function(a){a?b.addClass("ui-hide"):b.removeClass("ui-hide")})}}]).directive("uiToggle",[function(){return function(a,b,c){a.$watch(c.uiToggle,function(a){a?b.removeClass("ui-hide").addClass("ui-show"):b.removeClass("ui-show").addClass("ui-hide")})}}]),angular.module("ui.unique",[]).filter("unique",["$parse",function(a){return function(b,c){if(c===!1)return b;if((c||angular.isUndefined(c))&&angular.isArray(b)){var d=[],e=angular.isString(c)?a(c):function(a){return a},f=function(a){return angular.isObject(a)?e(a):a};angular.forEach(b,function(a){for(var b=!1,c=0;c<d.length;c++)if(angular.equals(f(d[c]),f(a))){b=!0;break}b||d.push(a)}),b=d}return b}}]),angular.module("ui.validate",[]).directive("uiValidate",function(){return{restrict:"A",require:"ngModel",link:function(a,b,c,d){function e(b){return angular.isString(b)?void a.$watch(b,function(){angular.forEach(g,function(a){a(d.$modelValue)})}):angular.isArray(b)?void angular.forEach(b,function(b){a.$watch(b,function(){angular.forEach(g,function(a){a(d.$modelValue)})})}):void(angular.isObject(b)&&angular.forEach(b,function(b,c){angular.isString(b)&&a.$watch(b,function(){g[c](d.$modelValue)}),angular.isArray(b)&&angular.forEach(b,function(b){a.$watch(b,function(){g[c](d.$modelValue)})})}))}var f,g={},h=a.$eval(c.uiValidate);h&&(angular.isString(h)&&(h={validator:h}),angular.forEach(h,function(b,c){f=function(e){var f=a.$eval(b,{$value:e});return angular.isObject(f)&&angular.isFunction(f.then)?(f.then(function(){d.$setValidity(c,!0)},function(){d.$setValidity(c,!1)}),e):f?(d.$setValidity(c,!0),e):(d.$setValidity(c,!1),e)},g[c]=f,d.$formatters.push(f),d.$parsers.push(f)}),c.uiValidateWatch&&e(a.$eval(c.uiValidateWatch)))}}}),angular.module("ui.utils",["ui.event","ui.format","ui.highlight","ui.include","ui.indeterminate","ui.inflector","ui.jq","ui.keypress","ui.mask","ui.reset","ui.route","ui.scrollfix","ui.scroll","ui.scroll.jqlite","ui.showhide","ui.unique","ui.validate"]);
|
|
// Source: public/lib/ngprogress/build/ngProgress.min.js
|
|
/*
|
|
ngProgress 1.0.7 - slim, site-wide progressbar for AngularJS
|
|
(C) 2013 - Victor Bjelkholm
|
|
License: MIT
|
|
Source: https://github.com/VictorBjelkholm/ngProgress
|
|
Date Compiled: 2014-09-26
|
|
*/
|
|
angular.module("ngProgress.provider",["ngProgress.directive"]).provider("ngProgress",function(){"use strict";this.autoStyle=!0,this.count=0,this.height="2px",this.color="firebrick",this.$get=["$document","$window","$compile","$rootScope","$timeout",function(a,b,c,d,e){var f=this.count,g=this.height,h=this.color,i=d,j=a.find("body")[0],k=c("<ng-progress></ng-progress>")(i);j.appendChild(k[0]),i.count=f,void 0!==g&&k.eq(0).children().css("height",g),void 0!==h&&(k.eq(0).children().css("background-color",h),k.eq(0).children().css("color",h));var l,m=0;return{start:function(){this.show();var a=this;clearInterval(m),m=setInterval(function(){if(isNaN(f))clearInterval(m),f=0,a.hide();else{var b=100-f;f+=.15*Math.pow(1-Math.sqrt(b),2),a.updateCount(f)}},200)},updateCount:function(a){i.count=a,i.$$phase||i.$apply()},height:function(a){return void 0!==a&&(g=a,i.height=g,i.$$phase||i.$apply()),g},color:function(a){return void 0!==a&&(h=a,i.color=h,i.$$phase||i.$apply()),h},hide:function(){k.children().css("opacity","0");var a=this;a.animate(function(){k.children().css("width","0%"),a.animate(function(){a.show()},500)},500)},show:function(){var a=this;a.animate(function(){k.children().css("opacity","1")},100)},animate:function(a,b){l&&e.cancel(l),l=e(a,b)},status:function(){return f},stop:function(){clearInterval(m)},set:function(a){return this.show(),this.updateCount(a),f=a,clearInterval(m),f},css:function(a){return k.children().css(a)},reset:function(){return clearInterval(m),f=0,this.updateCount(f),0},complete:function(){f=100,this.updateCount(f);var a=this;return clearInterval(m),e(function(){a.hide(),e(function(){f=0,a.updateCount(f)},500)},1e3),f},setParent:function(a){if(null===a||void 0===a)throw new Error("Provide a valid parent of type HTMLElement");null!==j&&void 0!==j&&j.removeChild(k[0]),j=a,j.appendChild(k[0])},getDomElement:function(){return k}}}],this.setColor=function(a){return void 0!==a&&(this.color=a),this.color},this.setHeight=function(a){return void 0!==a&&(this.height=a),this.height}}),angular.module("ngProgress.directive",[]).directive("ngProgress",["$window","$rootScope",function(a,b){var c={replace:!0,restrict:"E",link:function(a,c){b.$watch("count",function(b){(void 0!==b||null!==b)&&(a.counter=b,c.eq(0).children().css("width",b+"%"))}),b.$watch("color",function(b){(void 0!==b||null!==b)&&(a.color=b,c.eq(0).children().css("background-color",b),c.eq(0).children().css("color",b))}),b.$watch("height",function(b){(void 0!==b||null!==b)&&(a.height=b,c.eq(0).children().css("height",b))})},template:'<div id="ngProgress-container"><div id="ngProgress"></div></div>'};return c}]),angular.module("ngProgress",["ngProgress.directive","ngProgress.provider"]);
|
|
// Source: public/lib/angular-gettext/dist/angular-gettext.min.js
|
|
angular.module("gettext",[]),angular.module("gettext").constant("gettext",function(a){return a}),angular.module("gettext").factory("gettextCatalog",["gettextPlurals","$http","$cacheFactory","$interpolate","$rootScope",function(a,b,c,d,e){function f(){e.$broadcast("gettextLanguageChanged")}var g,h=function(a){return g.debug&&g.currentLanguage!==g.baseLanguage?g.debugPrefix+a:a},i=function(a){return g.showTranslatedMarkers?g.translatedMarkerPrefix+a+g.translatedMarkerSuffix:a};return g={debug:!1,debugPrefix:"[MISSING]: ",showTranslatedMarkers:!1,translatedMarkerPrefix:"[",translatedMarkerSuffix:"]",strings:{},baseLanguage:"en",currentLanguage:"en",cache:c("strings"),setCurrentLanguage:function(a){this.currentLanguage=a,f()},setStrings:function(a,b){this.strings[a]||(this.strings[a]={});for(var c in b){var d=b[c];this.strings[a][c]="string"==typeof d?[d]:d}f()},getStringForm:function(a,b){var c=this.strings[this.currentLanguage]||{},d=c[a]||[];return d[b]},getString:function(a,b){return a=this.getStringForm(a,0)||h(a),a=b?d(a)(b):a,i(a)},getPlural:function(b,c,e,f){var g=a(this.currentLanguage,b);return c=this.getStringForm(c,g)||h(1===b?c:e),c=f?d(c)(f):c,i(c)},loadRemote:function(a){return b({method:"GET",url:a,cache:g.cache}).success(function(a){for(var b in a)g.setStrings(b,a[b])})}}}]),angular.module("gettext").directive("translate",["gettextCatalog","$parse","$animate","$compile",function(a,b,c,d){function e(a,b,c){if(!a)throw new Error("You should add a "+b+" attribute whenever you add a "+c+" attribute.")}var f=function(){return String.prototype.trim?function(a){return"string"==typeof a?a.trim():a}:function(a){return"string"==typeof a?a.replace(/^\s*/,"").replace(/\s*$/,""):a}}();return{restrict:"A",terminal:!0,compile:function(g,h){e(!h.translatePlural||h.translateN,"translate-n","translate-plural"),e(!h.translateN||h.translatePlural,"translate-plural","translate-n");var i=f(g.html()),j=h.translatePlural;return{post:function(e,f,g){function h(){var b;j?(e=l||(l=e.$new()),e.$count=k(e),b=a.getPlural(e.$count,i,j)):b=a.getString(i);var g=angular.element("<span>"+b+"</span>");d(g.contents())(e);var h=f.contents(),m=g.contents();c.enter(m,f),c.leave(h)}var k=b(g.translateN),l=null;g.translateN&&e.$watch(g.translateN,h),e.$on("gettextLanguageChanged",h),h()}}}}}]),angular.module("gettext").filter("translate",["gettextCatalog",function(a){function b(b){return a.getString(b)}return b.$stateful=!0,b}]),angular.module("gettext").factory("gettextPlurals",function(){return function(a,b){switch(a){case"ay":case"bo":case"cgg":case"dz":case"fa":case"id":case"ja":case"jbo":case"ka":case"kk":case"km":case"ko":case"ky":case"lo":case"ms":case"my":case"sah":case"su":case"th":case"tt":case"ug":case"vi":case"wo":case"zh":return 0;case"is":return b%10!=1||b%100==11?1:0;case"jv":return 0!=b?1:0;case"mk":return 1==b||b%10==1?0:1;case"ach":case"ak":case"am":case"arn":case"br":case"fil":case"fr":case"gun":case"ln":case"mfe":case"mg":case"mi":case"oc":case"pt_BR":case"tg":case"ti":case"tr":case"uz":case"wa":case"zh":return b>1?1:0;case"lv":return b%10==1&&b%100!=11?0:0!=b?1:2;case"lt":return b%10==1&&b%100!=11?0:b%10>=2&&(10>b%100||b%100>=20)?1:2;case"be":case"bs":case"hr":case"ru":case"sr":case"uk":return b%10==1&&b%100!=11?0:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?1:2;case"mnk":return 0==b?0:1==b?1:2;case"ro":return 1==b?0:0==b||b%100>0&&20>b%100?1:2;case"pl":return 1==b?0:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?1:2;case"cs":case"sk":return 1==b?0:b>=2&&4>=b?1:2;case"sl":return b%100==1?1:b%100==2?2:b%100==3||b%100==4?3:0;case"mt":return 1==b?0:0==b||b%100>1&&11>b%100?1:b%100>10&&20>b%100?2:3;case"gd":return 1==b||11==b?0:2==b||12==b?1:b>2&&20>b?2:3;case"cy":return 1==b?0:2==b?1:8!=b&&11!=b?2:3;case"kw":return 1==b?0:2==b?1:3==b?2:3;case"ga":return 1==b?0:2==b?1:7>b?2:11>b?3:4;case"ar":return 0==b?0:1==b?1:2==b?2:b%100>=3&&10>=b%100?3:b%100>=11?4:5;default:return 1!=b?1:0}}});
|
|
// Source: public/lib/angular-moment/angular-moment.min.js
|
|
"format global";"deps angular";"deps moment";!function(){"use strict";function a(a,b){return a.module("angularMoment",[]).constant("angularMomentConfig",{preprocess:null,timezone:"",format:null}).constant("moment",b).constant("amTimeAgoConfig",{withoutSuffix:!1,serverTime:null,titleFormat:null}).directive("amTimeAgo",["$window","moment","amMoment","amTimeAgoConfig","angularMomentConfig",function(b,c,d,e,f){return function(g,h,i){function j(){var a;if(e.serverTime){var b=(new Date).getTime(),d=b-u+e.serverTime;a=c(d)}else a=c();return a}function k(){q&&(b.clearTimeout(q),q=null)}function l(a){if(h.text(a.from(j(),s)),t&&!h.attr("title")&&h.attr("title",a.local().format(t)),!x){var c=Math.abs(j().diff(a,"minute")),d=3600;1>c?d=1:60>c?d=30:180>c&&(d=300),q=b.setTimeout(function(){l(a)},1e3*d)}}function m(a){y&&h.attr("datetime",a)}function n(){if(k(),o){var a=d.preprocessDate(o,v,r);l(a),m(a.toISOString())}}var o,p,q=null,r=f.format,s=e.withoutSuffix,t=e.titleFormat,u=(new Date).getTime(),v=f.preprocess,w=i.amTimeAgo.replace(/^::/,""),x=0===i.amTimeAgo.indexOf("::"),y="TIME"===h[0].nodeName.toUpperCase();p=g.$watch(w,function(a){return"undefined"==typeof a||null===a||""===a?(k(),void(o&&(h.text(""),m(""),o=null))):(o=a,n(),void(void 0!==a&&x&&p()))}),a.isDefined(i.amWithoutSuffix)&&g.$watch(i.amWithoutSuffix,function(a){"boolean"==typeof a?(s=a,n()):s=e.withoutSuffix}),i.$observe("amFormat",function(a){"undefined"!=typeof a&&(r=a,n())}),i.$observe("amPreprocess",function(a){v=a,n()}),g.$on("$destroy",function(){k()}),g.$on("amMoment:localeChanged",function(){n()})}}]).service("amMoment",["moment","$rootScope","$log","angularMomentConfig",function(b,c,d,e){var f=this;this.preprocessors={utc:b.utc,unix:b.unix},this.changeLocale=function(d){var e=(b.locale||b.lang)(d);return a.isDefined(d)&&(c.$broadcast("amMoment:localeChanged"),c.$broadcast("amMoment:languageChange")),e},this.changeLanguage=function(a){return d.warn("angular-moment: Usage of amMoment.changeLanguage() is deprecated. Please use changeLocale()"),f.changeLocale(a)},this.preprocessDate=function(c,f,g){return a.isUndefined(f)&&(f=e.preprocess),this.preprocessors[f]?this.preprocessors[f](c,g):(f&&d.warn("angular-moment: Ignoring unsupported value for preprocess: "+f),!isNaN(parseFloat(c))&&isFinite(c)?b(parseInt(c,10)):b(c,g))},this.applyTimezone=function(a){var b=e.timezone;return a&&b&&(a.tz?a=a.tz(b):d.warn("angular-moment: timezone specified but moment.tz() is undefined. Did you forget to include moment-timezone.js?")),a}}]).filter("amCalendar",["moment","amMoment",function(a,b){return function(c,d){if("undefined"==typeof c||null===c)return"";c=b.preprocessDate(c,d);var e=a(c);return e.isValid()?b.applyTimezone(e).calendar():""}}]).filter("amDateFormat",["moment","amMoment",function(a,b){return function(c,d,e){if("undefined"==typeof c||null===c)return"";c=b.preprocessDate(c,e);var f=a(c);return f.isValid()?b.applyTimezone(f).format(d):""}}]).filter("amDurationFormat",["moment",function(a){return function(b,c,d){return"undefined"==typeof b||null===b?"":a.duration(b,c).humanize(d)}}]).filter("amTimeAgo",["moment","amMoment",function(a,b){return function(c,d,e){if("undefined"==typeof c||null===c)return"";c=b.preprocessDate(c,d);var f=a(c);return f.isValid()?b.applyTimezone(f).fromNow(e):""}}])}"function"==typeof define&&define.amd?define("angular-moment",["angular","moment"],a):"undefined"!=typeof module&&module&&module.exports?a(angular,require("moment")):a(angular,window.moment)}();
|
|
//# sourceMappingURL=angular-moment.min.js.map
|