js-beautify all the controllers, services and directives (and jshint)

This commit is contained in:
Emory P 2014-02-12 01:18:36 -05:00
parent 95f7ef53f2
commit bb7d018de4
23 changed files with 2533 additions and 3446 deletions

View file

@ -1,173 +0,0 @@
/*
AngularJS v1.1.4
(c) 2010-2012 Google, Inc. http://angularjs.org
License: MIT
*/
(function(M,V,s){'use strict';function gc(){var b=M.angular;M.angular=hc;return b}function o(b,a,c){var d;if(b)if(I(b))for(d in b)d!="prototype"&&d!="length"&&d!="name"&&b.hasOwnProperty(d)&&a.call(c,b[d],d);else if(b.forEach&&b.forEach!==o)b.forEach(a,c);else if(!b||typeof b.length!=="number"?0:typeof b.hasOwnProperty!="function"&&typeof b.constructor!="function"||b instanceof P||ca&&b instanceof ca||Da.call(b)!=="[object Object]"||typeof b.callee==="function")for(d=0;d<b.length;d++)a.call(c,b[d],
d);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],d);return b}function rb(b){var a=[],c;for(c in b)b.hasOwnProperty(c)&&a.push(c);return a.sort()}function ic(b,a,c){for(var d=rb(b),e=0;e<d.length;e++)a.call(c,b[d[e]],d[e]);return d}function sb(b){return function(a,c){b(c,a)}}function Ea(){for(var b=Z.length,a;b;){b--;a=Z[b].charCodeAt(0);if(a==57)return Z[b]="A",Z.join("");if(a==90)Z[b]="0";else return Z[b]=String.fromCharCode(a+1),Z.join("")}Z.unshift("0");return Z.join("")}function y(b){o(arguments,
function(a){a!==b&&o(a,function(a,d){b[d]=a})});return b}function K(b){return parseInt(b,10)}function Fa(b,a){return y(new (y(function(){},{prototype:b})),a)}function t(){}function pa(b){return b}function Q(b){return function(){return b}}function u(b){return typeof b=="undefined"}function w(b){return typeof b!="undefined"}function L(b){return b!=null&&typeof b=="object"}function x(b){return typeof b=="string"}function Za(b){return typeof b=="number"}function qa(b){return Da.apply(b)=="[object Date]"}
function C(b){return Da.apply(b)=="[object Array]"}function I(b){return typeof b=="function"}function ra(b){return b&&b.document&&b.location&&b.alert&&b.setInterval}function S(b){return x(b)?b.replace(/^\s*/,"").replace(/\s*$/,""):b}function jc(b){return b&&(b.nodeName||b.bind&&b.find)}function $a(b,a,c){var d=[];o(b,function(b,f,i){d.push(a.call(c,b,f,i))});return d}function Ga(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 sa(b,a){var c=Ga(b,
a);c>=0&&b.splice(c,1);return a}function W(b,a){if(ra(b)||b&&b.$evalAsync&&b.$watch)throw Error("Can't copy Window or Scope");if(a){if(b===a)throw Error("Can't copy equivalent objects or arrays");if(C(b))for(var c=a.length=0;c<b.length;c++)a.push(W(b[c]));else for(c in o(a,function(b,c){delete a[c]}),b)a[c]=W(b[c])}else(a=b)&&(C(b)?a=W(b,[]):qa(b)?a=new Date(b.getTime()):L(b)&&(a=W(b,{})));return a}function kc(b,a){var a=a||{},c;for(c in b)b.hasOwnProperty(c)&&c.substr(0,2)!=="$$"&&(a[c]=b[c]);return a}
function ja(b,a){if(b===a)return!0;if(b===null||a===null)return!1;if(b!==b&&a!==a)return!0;var c=typeof b,d;if(c==typeof a&&c=="object")if(C(b)){if((c=b.length)==a.length){for(d=0;d<c;d++)if(!ja(b[d],a[d]))return!1;return!0}}else if(qa(b))return qa(a)&&b.getTime()==a.getTime();else{if(b&&b.$evalAsync&&b.$watch||a&&a.$evalAsync&&a.$watch||ra(b)||ra(a))return!1;c={};for(d in b)if(!(d.charAt(0)==="$"||I(b[d]))){if(!ja(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c[d]&&d.charAt(0)!=="$"&&a[d]!==s&&!I(a[d]))return!1;
return!0}return!1}function ab(b,a){var c=arguments.length>2?ka.call(arguments,2):[];return I(a)&&!(a instanceof RegExp)?c.length?function(){return arguments.length?a.apply(b,c.concat(ka.call(arguments,0))):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}:a}function lc(b,a){var c=a;/^\$+/.test(b)?c=s:ra(a)?c="$WINDOW":a&&V===a?c="$DOCUMENT":a&&a.$evalAsync&&a.$watch&&(c="$SCOPE");return c}function da(b,a){return JSON.stringify(b,lc,a?" ":null)}function tb(b){return x(b)?
JSON.parse(b):b}function Ha(b){b&&b.length!==0?(b=J(""+b),b=!(b=="f"||b=="0"||b=="false"||b=="no"||b=="n"||b=="[]")):b=!1;return b}function ta(b){b=v(b).clone();try{b.html("")}catch(a){}var c=v("<div>").append(b).html();try{return b[0].nodeType===3?J(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+J(b)})}catch(d){return J(c)}}function bb(b){var a={},c,d;o((b||"").split("&"),function(b){b&&(c=b.split("="),d=decodeURIComponent(c[0]),a[d]=w(c[1])?decodeURIComponent(c[1]):!0)});
return a}function ub(b){var a=[];o(b,function(b,d){a.push(ua(d,!0)+(b===!0?"":"="+ua(b,!0)))});return a.length?a.join("&"):""}function cb(b){return ua(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function ua(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function mc(b,a){function c(a){a&&d.push(a)}var d=[b],e,f,i=["ng:app","ng-app","x-ng-app","data-ng-app"],h=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
o(i,function(a){i[a]=!0;c(V.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(o(b.querySelectorAll("."+a),c),o(b.querySelectorAll("."+a+"\\:"),c),o(b.querySelectorAll("["+a+"]"),c))});o(d,function(a){if(!e){var b=h.exec(" "+a.className+" ");b?(e=a,f=(b[2]||"").replace(/\s+/g,",")):o(a.attributes,function(b){if(!e&&i[b.name])e=a,f=b.value})}});e&&a(e,f?[f]:[])}function vb(b,a){var c=function(){b=v(b);a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");
var c=wb(a);c.invoke(["$rootScope","$rootElement","$compile","$injector",function(a,b,c,d){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(M&&!d.test(M.name))return c();M.name=M.name.replace(d,"");Ia.resumeBootstrap=function(b){o(b,function(b){a.push(b)});c()}}function db(b,a){a=a||"_";return b.replace(nc,function(b,d){return(d?a:"")+b.toLowerCase()})}function eb(b,a,c){if(!b)throw Error("Argument '"+(a||"?")+"' is "+(c||"required"));return b}function va(b,
a,c){c&&C(b)&&(b=b[b.length-1]);eb(I(b),a,"not a function, got "+(b&&typeof b=="object"?b.constructor.name||"Object":typeof b));return b}function oc(b){function a(a,b,e){return a[b]||(a[b]=e())}return a(a(b,"angular",Object),"module",function(){var b={};return function(d,e,f){e&&b.hasOwnProperty(d)&&(b[d]=null);return a(b,d,function(){function a(c,d,e){return function(){b[e||"push"]([c,d,arguments]);return m}}if(!e)throw Error("No module: "+d);var b=[],c=[],g=a("$injector","invoke"),m={_invokeQueue:b,
_runBlocks:c,requires:e,name:d,provider:a("$provide","provider"),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$provide","value"),constant:a("$provide","constant","unshift"),animation:a("$animationProvider","register"),filter:a("$filterProvider","register"),controller:a("$controllerProvider","register"),directive:a("$compileProvider","directive"),config:g,run:function(a){c.push(a);return this}};f&&g(f);return m})}})}function Ja(b){return b.replace(pc,function(a,b,d,e){return e?
d.toUpperCase():d}).replace(qc,"Moz$1")}function fb(b,a){function c(){var e;for(var b=[this],c=a,i,h,j,g,m,k;b.length;){i=b.shift();h=0;for(j=i.length;h<j;h++){g=v(i[h]);c?g.triggerHandler("$destroy"):c=!c;m=0;for(e=(k=g.children()).length,g=e;m<g;m++)b.push(ca(k[m]))}}return d.apply(this,arguments)}var d=ca.fn[b],d=d.$original||d;c.$original=d;ca.fn[b]=c}function P(b){if(b instanceof P)return b;if(!(this instanceof P)){if(x(b)&&b.charAt(0)!="<")throw Error("selectors not implemented");return new P(b)}if(x(b)){var a=
V.createElement("div");a.innerHTML="<div>&#160;</div>"+b;a.removeChild(a.firstChild);gb(this,a.childNodes);this.remove()}else gb(this,b)}function hb(b){return b.cloneNode(!0)}function wa(b){xb(b);for(var a=0,b=b.childNodes||[];a<b.length;a++)wa(b[a])}function yb(b,a,c){var d=$(b,"events");$(b,"handle")&&(u(a)?o(d,function(a,c){ib(b,c,a);delete d[c]}):u(c)?(ib(b,a,d[a]),delete d[a]):sa(d[a],c))}function xb(b){var a=b[Ka],c=La[a];c&&(c.handle&&(c.events.$destroy&&c.handle({},"$destroy"),yb(b)),delete La[a],
b[Ka]=s)}function $(b,a,c){var d=b[Ka],d=La[d||-1];if(w(c))d||(b[Ka]=d=++rc,d=La[d]={}),d[a]=c;else return d&&d[a]}function zb(b,a,c){var d=$(b,"data"),e=w(c),f=!e&&w(a),i=f&&!L(a);!d&&!i&&$(b,"data",d={});if(e)d[a]=c;else if(f)if(i)return d&&d[a];else y(d,a);else return d}function Ma(b,a){return(" "+b.className+" ").replace(/[\n\t]/g," ").indexOf(" "+a+" ")>-1}function Ab(b,a){a&&o(a.split(" "),function(a){b.className=S((" "+b.className+" ").replace(/[\n\t]/g," ").replace(" "+S(a)+" "," "))})}function Bb(b,
a){a&&o(a.split(" "),function(a){if(!Ma(b,a))b.className=S(b.className+" "+S(a))})}function gb(b,a){if(a)for(var a=!a.nodeName&&w(a.length)&&!ra(a)?a:[a],c=0;c<a.length;c++)b.push(a[c])}function Cb(b,a){return Na(b,"$"+(a||"ngController")+"Controller")}function Na(b,a,c){b=v(b);for(b[0].nodeType==9&&(b=b.find("html"));b.length;){if(c=b.data(a))return c;b=b.parent()}}function Db(b,a){var c=Oa[a.toLowerCase()];return c&&Eb[b.nodeName]&&c}function sc(b,a){var c=function(c,e){if(!c.preventDefault)c.preventDefault=
function(){c.returnValue=!1};if(!c.stopPropagation)c.stopPropagation=function(){c.cancelBubble=!0};if(!c.target)c.target=c.srcElement||V;if(u(c.defaultPrevented)){var f=c.preventDefault;c.preventDefault=function(){c.defaultPrevented=!0;f.call(c)};c.defaultPrevented=!1}c.isDefaultPrevented=function(){return c.defaultPrevented};o(a[e||c.type],function(a){a.call(b,c)});X<=8?(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){var a=typeof b,c;if(a=="object"&&b!==null)if(typeof(c=b.$$hashKey)=="function")c=b.$$hashKey();else{if(c===s)c=b.$$hashKey=Ea()}else c=b;return a+":"+c}function Pa(b){o(b,this.put,this)}function Fb(b){var a,c;if(typeof b=="function"){if(!(a=b.$inject))a=[],c=b.toString().replace(tc,""),c=c.match(uc),o(c[1].split(vc),function(b){b.replace(wc,function(b,c,d){a.push(d)})}),b.$inject=a}else C(b)?(c=b.length-1,va(b[c],"fn"),a=b.slice(0,c)):va(b,"fn",!0);return a}function wb(b){function a(a){return function(b,
c){if(L(b))o(b,sb(a));else return a(b,c)}}function c(a,b){if(I(b)||C(b))b=k.instantiate(b);if(!b.$get)throw Error("Provider "+a+" must define $get factory method.");return m[a+h]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[];o(a,function(a){if(!g.get(a))if(g.put(a,!0),x(a)){var c=xa(a);b=b.concat(e(c.requires)).concat(c._runBlocks);try{for(var d=c._invokeQueue,c=0,h=d.length;c<h;c++){var f=d[c],n=k.get(f[0]);n[f[1]].apply(n,f[2])}}catch(j){throw j.message&&(j.message+=" from "+a),
j;}}else if(I(a))try{b.push(k.invoke(a))}catch(i){throw i.message&&(i.message+=" from "+a),i;}else if(C(a))try{b.push(k.invoke(a))}catch(l){throw l.message&&(l.message+=" from "+String(a[a.length-1])),l;}else va(a,"module")});return b}function f(a,b){function c(d){if(typeof d!=="string")throw Error("Service name expected");if(a.hasOwnProperty(d)){if(a[d]===i)throw Error("Circular dependency: "+j.join(" <- "));return a[d]}else try{return j.unshift(d),a[d]=i,a[d]=b(d)}finally{j.shift()}}function d(a,
b,e){var g=[],h=Fb(a),f,j,n;j=0;for(f=h.length;j<f;j++)n=h[j],g.push(e&&e.hasOwnProperty(n)?e[n]:c(n));a.$inject||(a=a[f]);switch(b?-1:g.length){case 0:return a();case 1:return a(g[0]);case 2:return a(g[0],g[1]);case 3:return a(g[0],g[1],g[2]);case 4:return a(g[0],g[1],g[2],g[3]);case 5:return a(g[0],g[1],g[2],g[3],g[4]);case 6:return a(g[0],g[1],g[2],g[3],g[4],g[5]);case 7:return a(g[0],g[1],g[2],g[3],g[4],g[5],g[6]);case 8:return a(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7]);case 9:return a(g[0],g[1],
g[2],g[3],g[4],g[5],g[6],g[7],g[8]);case 10:return a(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9]);default:return a.apply(b,g)}}return{invoke:d,instantiate:function(a,b){var c=function(){},e;c.prototype=(C(a)?a[a.length-1]:a).prototype;c=new c;e=d(a,c,b);return L(e)?e:c},get:c,annotate:Fb}}var i={},h="Provider",j=[],g=new Pa,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,Q(b))}),
constant:a(function(a,b){m[a]=b;l[a]=b}),decorator:function(a,b){var c=k.get(a+h),d=c.$get;c.$get=function(){var a=q.invoke(d,c);return q.invoke(b,null,{$delegate:a})}}}},k=m.$injector=f(m,function(){throw Error("Unknown provider: "+j.join(" <- "));}),l={},q=l.$injector=f(l,function(a){a=k.get(a+h);return q.invoke(a.$get,a)});o(e(b),function(a){q.invoke(a||t)});return q}function xc(){var b=!0;this.disableAutoScrolling=function(){b=!1};this.$get=["$window","$location","$rootScope",function(a,c,d){function e(a){var b=
null;o(a,function(a){!b&&J(a.nodeName)==="a"&&(b=a)});return b}function f(){var b=c.hash(),d;b?(d=i.getElementById(b))?d.scrollIntoView():(d=e(i.getElementsByName(b)))?d.scrollIntoView():b==="top"&&a.scrollTo(0,0):a.scrollTo(0,0)}var i=a.document;b&&d.$watch(function(){return c.hash()},function(){d.$evalAsync(f)});return f}]}function Gb(b){this.register=function(a,c){b.factory(Ja(a)+"Animation",c)};this.$get=["$injector",function(a){return function(b){if(b)try{return a.get(Ja(b)+"Animation")}catch(d){}}}]}
function yc(b,a,c,d){function e(a){try{a.apply(null,ka.call(arguments,1))}finally{if(n--,n===0)for(;B.length;)try{B.pop()()}catch(b){c.error(b)}}}function f(a,b){(function z(){o(r,function(a){a()});p=b(z,a)})()}function i(){E!=h.url()&&(E=h.url(),o(G,function(a){a(h.url())}))}var h=this,j=a[0],g=b.location,m=b.history,k=b.setTimeout,l=b.clearTimeout,q={};h.isMock=!1;var n=0,B=[];h.$$completeOutstandingRequest=e;h.$$incOutstandingRequestCount=function(){n++};h.notifyWhenNoOutstandingRequests=function(a){o(r,
function(a){a()});n===0?a():B.push(a)};var r=[],p;h.addPollFn=function(a){u(p)&&f(100,k);r.push(a);return a};var E=g.href,D=a.find("base");h.url=function(a,b){if(a){if(E!=a)return E=a,d.history?b?m.replaceState(null,"",a):(m.pushState(null,"",a),D.attr("href",D.attr("href"))):b?g.replace(a):g.href=a,h}else return g.href.replace(/%27/g,"'")};var G=[],R=!1;h.onUrlChange=function(a){R||(d.history&&v(b).bind("popstate",i),d.hashchange?v(b).bind("hashchange",i):h.addPollFn(i),R=!0);G.push(a);return a};
h.baseHref=function(){var a=D.attr("href");return a?a.replace(/^https?\:\/\/[^\/]*/,""):""};var A={},H="",F=h.baseHref();h.cookies=function(a,b){var d,e,g,h;if(a)if(b===s)j.cookie=escape(a)+"=;path="+F+";expires=Thu, 01 Jan 1970 00:00:00 GMT";else{if(x(b))d=(j.cookie=escape(a)+"="+escape(b)+";path="+F).length+1,d>4096&&c.warn("Cookie '"+a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!")}else{if(j.cookie!==H){H=j.cookie;d=H.split("; ");A={};for(g=0;g<d.length;g++)e=
d[g],h=e.indexOf("="),h>0&&(A[unescape(e.substring(0,h))]=unescape(e.substring(h+1)))}return A}};h.defer=function(a,b){var c;n++;c=k(function(){delete q[c];e(a)},b||0);q[c]=!0;return c};h.defer.cancel=function(a){return q[a]?(delete q[a],l(a),e(t),!0):!1}}function zc(){this.$get=["$window","$log","$sniffer","$document",function(b,a,c,d){return new yc(b,d,a,c)}]}function Ac(){this.$get=function(){function b(b,d){function e(a){if(a!=k){if(l){if(l==a)l=a.n}else l=a;f(a.n,a.p);f(a,k);k=a;k.n=null}}function f(a,
b){if(a!=b){if(a)a.p=b;if(b)b.n=a}}if(b in a)throw Error("cacheId "+b+" taken");var i=0,h=y({},d,{id:b}),j={},g=d&&d.capacity||Number.MAX_VALUE,m={},k=null,l=null;return a[b]={put:function(a,b){var c=m[a]||(m[a]={key:a});e(c);if(!u(b))return a in j||i++,j[a]=b,i>g&&this.remove(l.key),b},get:function(a){var b=m[a];if(b)return e(b),j[a]},remove:function(a){var b=m[a];if(b){if(b==k)k=b.p;if(b==l)l=b.n;f(b.n,b.p);delete m[a];delete j[a];i--}},removeAll:function(){j={};i=0;m={};k=l=null},destroy:function(){m=
h=j=null;delete a[b]},info:function(){return y({},h,{size:i})}}}var a={};b.info=function(){var b={};o(a,function(a,e){b[e]=a.info()});return b};b.get=function(b){return a[b]};return b}}function Bc(){this.$get=["$cacheFactory",function(b){return b("templates")}]}function Hb(b){var a={},c="Directive",d=/^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,e=/(([\d\w\-_]+)(?:\:([^;]+))?;?)/,f="Template must have exactly one root element. was: ",i=/^\s*(https?|ftp|mailto|file):/;this.directive=function j(d,e){x(d)?
(eb(e,"directive"),a.hasOwnProperty(d)||(a[d]=[],b.factory(d+c,["$injector","$exceptionHandler",function(b,c){var e=[];o(a[d],function(a){try{var f=b.invoke(a);if(I(f))f={compile:Q(f)};else if(!f.compile&&f.link)f.compile=Q(f.link);f.priority=f.priority||0;f.name=f.name||d;f.require=f.require||f.controller&&f.name;f.restrict=f.restrict||"A";e.push(f)}catch(j){c(j)}});return e}])),a[d].push(e)):o(d,sb(j));return this};this.urlSanitizationWhitelist=function(a){return w(a)?(i=a,this):i};this.$get=["$injector",
"$interpolate","$exceptionHandler","$http","$templateCache","$parse","$controller","$rootScope","$document",function(b,g,m,k,l,q,n,B,r){function p(a,b,c){a instanceof v||(a=v(a));o(a,function(b,c){b.nodeType==3&&b.nodeValue.match(/\S+/)&&(a[c]=v(b).wrap("<span></span>").parent()[0])});var d=D(a,b,a,c);return function(b,c){eb(b,"scope");for(var e=c?za.clone.call(a):a,g=0,f=e.length;g<f;g++){var j=e[g];(j.nodeType==1||j.nodeType==9)&&e.eq(g).data("$scope",b)}E(e,"ng-scope");c&&c(e,b);d&&d(b,e,e);return e}}
function E(a,b){try{a.addClass(b)}catch(c){}}function D(a,b,c,d){function e(a,c,d,f){var j,i,l,m,n,k,q,p=[];n=0;for(k=c.length;n<k;n++)p.push(c[n]);q=n=0;for(k=g.length;n<k;q++)i=p[q],c=g[n++],j=g[n++],c?(c.scope?(l=a.$new(L(c.scope)),v(i).data("$scope",l)):l=a,(m=c.transclude)||!f&&b?c(j,l,i,d,function(b){return function(c){var d=a.$new();d.$$transcluded=!0;return b(d,c).bind("$destroy",ab(d,d.$destroy))}}(m||b)):c(j,l,i,s,f)):j&&j(a,i.childNodes,s,f)}for(var g=[],f,j,i,l=0;l<a.length;l++)j=new ya,
f=G(a[l],[],j,d),j=(f=f.length?R(f,a[l],j,b,c):null)&&f.terminal||!a[l].childNodes||!a[l].childNodes.length?null:D(a[l].childNodes,f?f.transclude:b),g.push(f),g.push(j),i=i||f||j;return i?e:null}function G(a,b,c,g){var f=c.$attr,j;switch(a.nodeType){case 1:A(b,aa(jb(a).toLowerCase()),"E",g);var i,l,n;j=a.attributes;for(var m=0,k=j&&j.length;m<k;m++)if(i=j[m],i.specified)l=i.name,n=aa(l),ha.test(n)&&(l=n.substr(6).toLowerCase()),n=aa(l.toLowerCase()),f[n]=l,c[n]=i=S(X&&l=="href"?decodeURIComponent(a.getAttribute(l,
2)):i.value),Db(a,n)&&(c[n]=!0),z(a,b,i,n),A(b,n,"A",g);a=a.className;if(x(a)&&a!=="")for(;j=e.exec(a);)n=aa(j[2]),A(b,n,"C",g)&&(c[n]=S(j[3])),a=a.substr(j.index+j[0].length);break;case 3:ga(b,a.nodeValue);break;case 8:try{if(j=d.exec(a.nodeValue))n=aa(j[1]),A(b,n,"M",g)&&(c[n]=S(j[2]))}catch(q){}}b.sort(N);return b}function R(a,b,c,d,e){function j(a,b){if(a)a.require=z.require,B.push(a);if(b)b.require=z.require,r.push(b)}function i(a,b){var c,d="data",e=!1;if(x(a)){for(;(c=a.charAt(0))=="^"||c==
"?";)a=a.substr(1),c=="^"&&(d="inheritedData"),e=e||c=="?";c=b[d]("$"+a+"Controller");if(!c&&!e)throw Error("No controller: "+a);}else C(a)&&(c=[],o(a,function(a){c.push(i(a,b))}));return c}function l(a,d,e,f,j){var k,p,D,G,H;k=b===e?c:kc(c,new ya(v(e),c.$attr));p=k.$$element;if(ba){var z=/^\s*([@=&])(\??)\s*(\w*)\s*$/,F=d.$parent||d;o(ba.scope,function(a,b){var c=a.match(z)||[],e=c[3]||b,f=c[2]=="?",c=c[1],j,l,i;d.$$isolateBindings[b]=c+e;switch(c){case "@":k.$observe(e,function(a){d[b]=a});k.$$observers[e].$$scope=
F;k[e]&&(d[b]=g(k[e])(F));break;case "=":if(f&&!k[e])break;l=q(k[e]);i=l.assign||function(){j=d[b]=l(F);throw Error(Ib+k[e]+" (directive: "+ba.name+")");};j=d[b]=l(F);d.$watch(function(){var a=l(F);a!==d[b]&&(a!==j?j=d[b]=a:i(F,a=j=d[b]));return a});break;case "&":l=q(k[e]);d[b]=function(a){return l(F,a)};break;default:throw Error("Invalid isolate scope definition for directive "+ba.name+": "+a);}})}ha&&o(ha,function(a){var b={$scope:d,$element:p,$attrs:k,$transclude:j};H=a.controller;H=="@"&&(H=
k[a.name]);p.data("$"+a.name+"Controller",n(H,b))});f=0;for(D=B.length;f<D;f++)try{G=B[f],G(d,p,k,G.require&&i(G.require,p))}catch(E){m(E,ta(p))}a&&a(d,e.childNodes,s,j);f=0;for(D=r.length;f<D;f++)try{G=r[f],G(d,p,k,G.require&&i(G.require,p))}catch(N){m(N,ta(p))}}for(var k=-Number.MAX_VALUE,B=[],r=[],D=null,ba=null,N=null,A=c.$$element=v(b),z,T,R,ga,ia=d,ha,t,y,w=0,u=a.length;w<u;w++){z=a[w];R=s;if(k>z.priority)break;if(y=z.scope)ea("isolated scope",ba,z,A),L(y)&&(E(A,"ng-isolate-scope"),ba=z),E(A,
"ng-scope"),D=D||z;T=z.name;if(y=z.controller)ha=ha||{},ea("'"+T+"' controller",ha[T],z,A),ha[T]=z;if(y=z.transclude)ea("transclusion",ga,z,A),ga=z,k=z.priority,y=="element"?(R=v(b),A=c.$$element=v(V.createComment(" "+T+": "+c[T]+" ")),b=A[0],fa(e,v(R[0]),b),ia=p(R,d,k)):(R=v(hb(b)).contents(),A.html(""),ia=p(R,d));if(z.template)if(ea("template",N,z,A),N=z,y=I(z.template)?z.template(A,c):z.template,y=Jb(y),z.replace){R=v("<div>"+S(y)+"</div>").contents();b=R[0];if(R.length!=1||b.nodeType!==1)throw Error(f+
y);fa(e,A,b);T={$attr:{}};a=a.concat(G(b,a.splice(w+1,a.length-(w+1)),T));H(c,T);u=a.length}else A.html(y);if(z.templateUrl)ea("template",N,z,A),N=z,l=F(a.splice(w,a.length-w),l,A,c,e,z.replace,ia),u=a.length;else if(z.compile)try{t=z.compile(A,c,ia),I(t)?j(null,t):t&&j(t.pre,t.post)}catch(J){m(J,ta(A))}if(z.terminal)l.terminal=!0,k=Math.max(k,z.priority)}l.scope=D&&D.scope;l.transclude=ga&&ia;return l}function A(d,e,g,f){var l=!1;if(a.hasOwnProperty(e))for(var i,e=b.get(e+c),n=0,k=e.length;n<k;n++)try{if(i=
e[n],(f===s||f>i.priority)&&i.restrict.indexOf(g)!=-1)d.push(i),l=!0}catch(q){m(q)}return l}function H(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;o(a,function(d,e){e.charAt(0)!="$"&&(b[e]&&(d+=(e==="style"?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});o(b,function(b,g){g=="class"?(E(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):g=="style"?e.attr("style",e.attr("style")+";"+b):g.charAt(0)!="$"&&!a.hasOwnProperty(g)&&(a[g]=b,d[g]=c[g])})}function F(a,b,c,d,e,g,j){var i=[],n,m,q=c[0],p=a.shift(),ya=y({},
p,{controller:null,templateUrl:null,transclude:null,scope:null}),p=I(p.templateUrl)?p.templateUrl(c,d):p.templateUrl;c.html("");k.get(p,{cache:l}).success(function(l){var k,p,l=Jb(l);if(g){p=v("<div>"+S(l)+"</div>").contents();k=p[0];if(p.length!=1||k.nodeType!==1)throw Error(f+l);l={$attr:{}};fa(e,c,k);G(k,a,l);H(d,l)}else k=q,c.html(l);a.unshift(ya);n=R(a,k,d,j);for(m=D(c[0].childNodes,j);i.length;){var B=i.shift(),l=i.shift();p=i.shift();var r=i.shift(),F=k;l!==q&&(F=hb(k),fa(p,v(l),F));n(function(){b(m,
B,F,e,r)},B,F,e,r)}i=null}).error(function(a,b,c,d){throw Error("Failed to load template: "+d.url);});return function(a,c,d,e,g){i?(i.push(c),i.push(d),i.push(e),i.push(g)):n(function(){b(m,c,d,e,g)},c,d,e,g)}}function N(a,b){return b.priority-a.priority}function ea(a,b,c,d){if(b)throw Error("Multiple directives ["+b.name+", "+c.name+"] asking for "+a+" on: "+ta(d));}function ga(a,b){var c=g(b,!0);c&&a.push({priority:0,compile:Q(function(a,b){var d=b.parent(),e=d.data("$binding")||[];e.push(c);E(d.data("$binding",
e),"ng-binding");a.$watch(c,function(a){b[0].nodeValue=a})})})}function z(a,b,c,d){var e=g(c,!0);e&&b.push({priority:100,compile:Q(function(a,b,c){b=c.$$observers||(c.$$observers={});if(e=g(c[d],!0))c[d]=e(a),(b[d]||(b[d]=[])).$$inter=!0,(c.$$observers&&c.$$observers[d].$$scope||a).$watch(e,function(a){c.$set(d,a)})})})}function fa(a,b,c){var d=b[0],e=d.parentNode,g,f;if(a){g=0;for(f=a.length;g<f;g++)if(a[g]==d){a[g]=c;break}}e&&e.replaceChild(c,d);c[v.expando]=d[v.expando];b[0]=c}var ya=function(a,
b){this.$$element=a;this.$attr=b||{}};ya.prototype={$normalize:aa,$set:function(a,b,c,d){var e=Db(this.$$element[0],a),g=this.$$observers;e&&(this.$$element.prop(a,b),d=e);this[a]=b;d?this.$attr[a]=d:(d=this.$attr[a])||(this.$attr[a]=d=db(a,"-"));if(jb(this.$$element[0])==="A"&&a==="href")ba.setAttribute("href",b),e=ba.href,e.match(i)||(this[a]=b="unsafe:"+e);c!==!1&&(b===null||b===s?this.$$element.removeAttr(d):this.$$element.attr(d,b));g&&o(g[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);B.$evalAsync(function(){e.$$inter||b(c[a])});return b}};var ba=r[0].createElement("a"),T=g.startSymbol(),ia=g.endSymbol(),Jb=T=="{{"||ia=="}}"?pa:function(a){return a.replace(/\{\{/g,T).replace(/}}/g,ia)},ha=/^ngAttr[A-Z]/;return p}]}function aa(b){return Ja(b.replace(Cc,""))}function Dc(){var b={};this.register=function(a,c){L(a)?y(b,a):b[a]=c};this.$get=["$injector","$window",function(a,c){return function(d,e){if(x(d)){var f=
d,d=b.hasOwnProperty(f)?b[f]:kb(e.$scope,f,!0)||kb(c,f,!0);va(d,f,!0)}return a.instantiate(d,e)}}]}function Ec(){this.$get=["$window",function(b){return v(b.document)}]}function Fc(){this.$get=["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function Gc(){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",function(c,d){function e(e,j){for(var g,m,k=0,l=[],q=e.length,n=
!1,B=[];k<q;)(g=e.indexOf(b,k))!=-1&&(m=e.indexOf(a,g+f))!=-1?(k!=g&&l.push(e.substring(k,g)),l.push(k=c(n=e.substring(g+f,m))),k.exp=n,k=m+i,n=!0):(k!=q&&l.push(e.substring(k)),k=q);if(!(q=l.length))l.push(""),q=1;if(!j||n)return B.length=q,k=function(a){try{for(var b=0,c=q,g;b<c;b++){if(typeof(g=l[b])=="function")g=g(a),g==null||g==s?g="":typeof g!="string"&&(g=da(g));B[b]=g}return B.join("")}catch(f){d(Error("Error while interpolating: "+e+"\n"+f.toString()))}},k.exp=e,k.parts=l,k}var f=b.length,
i=a.length;e.startSymbol=function(){return b};e.endSymbol=function(){return a};return e}]}function Kb(b){for(var b=b.split("/"),a=b.length;a--;)b[a]=cb(b[a]);return b.join("/")}function Aa(b,a){var c=lb.exec(b),c={protocol:c[1],host:c[3],port:K(c[5])||Ba[c[1]]||null,path:c[6]||"/",search:c[8],hash:c[10]};if(a)a.$$protocol=c.protocol,a.$$host=c.host,a.$$port=c.port;return c}function ma(b,a,c){return b+"://"+a+(c==Ba[b]?"":":"+c)}function Hc(b,a,c){var d=Aa(b);return decodeURIComponent(d.path)!=a||
u(d.hash)||d.hash.indexOf(c)!==0?b:ma(d.protocol,d.host,d.port)+a.substr(0,a.lastIndexOf("/"))+d.hash.substr(c.length)}function Ic(b,a,c){var d=Aa(b);if(decodeURIComponent(d.path)==a&&!u(d.hash)&&d.hash.indexOf(c)===0)return b;else{var e=d.search&&"?"+d.search||"",f=d.hash&&"#"+d.hash||"",i=a.substr(0,a.lastIndexOf("/")),h=d.path.substr(i.length);if(d.path.indexOf(i)!==0)throw Error('Invalid url "'+b+'", missing path prefix "'+i+'" !');return ma(d.protocol,d.host,d.port)+a+"#"+c+h+e+f}}function mb(b,
a,c){a=a||"";this.$$parse=function(b){var c=Aa(b,this);if(c.path.indexOf(a)!==0)throw Error('Invalid url "'+b+'", missing path prefix "'+a+'" !');this.$$path=decodeURIComponent(c.path.substr(a.length));this.$$search=bb(c.search);this.$$hash=c.hash&&decodeURIComponent(c.hash)||"";this.$$compose()};this.$$compose=function(){var b=ub(this.$$search),c=this.$$hash?"#"+cb(this.$$hash):"";this.$$url=Kb(this.$$path)+(b?"?"+b:"")+c;this.$$absUrl=ma(this.$$protocol,this.$$host,this.$$port)+a+this.$$url};this.$$rewriteAppUrl=
function(a){if(a.indexOf(c)==0)return a};this.$$parse(b)}function Qa(b,a,c){var d;this.$$parse=function(b){var c=Aa(b,this);if(c.hash&&c.hash.indexOf(a)!==0)throw Error('Invalid url "'+b+'", missing hash prefix "'+a+'" !');d=c.path+(c.search?"?"+c.search:"");c=Jc.exec((c.hash||"").substr(a.length));this.$$path=c[1]?(c[1].charAt(0)=="/"?"":"/")+decodeURIComponent(c[1]):"";this.$$search=bb(c[3]);this.$$hash=c[5]&&decodeURIComponent(c[5])||"";this.$$compose()};this.$$compose=function(){var b=ub(this.$$search),
c=this.$$hash?"#"+cb(this.$$hash):"";this.$$url=Kb(this.$$path)+(b?"?"+b:"")+c;this.$$absUrl=ma(this.$$protocol,this.$$host,this.$$port)+d+(this.$$url?"#"+a+this.$$url:"")};this.$$rewriteAppUrl=function(a){if(a.indexOf(c)==0)return a};this.$$parse(b)}function Lb(b,a,c,d){Qa.apply(this,arguments);this.$$rewriteAppUrl=function(b){if(b.indexOf(c)==0)return c+d+"#"+a+b.substr(c.length)}}function Ra(b){return function(){return this[b]}}function Mb(b,a){return function(c){if(u(c))return this[b];this[b]=
a(c);this.$$compose();return this}}function Kc(){var b="",a=!1;this.hashPrefix=function(a){return w(a)?(b=a,this):b};this.html5Mode=function(b){return w(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,f){function i(a){c.$broadcast("$locationChangeSuccess",h.absUrl(),a)}var h,j,g,m=d.url(),k=Aa(m);a?(j=d.baseHref()||"/",g=j.substr(0,j.lastIndexOf("/")),k=ma(k.protocol,k.host,k.port)+g+"/",h=e.history?new mb(Hc(m,j,b),g,k):new Lb(Ic(m,j,b),b,k,j.substr(g.length+
1))):(k=ma(k.protocol,k.host,k.port)+(k.path||"")+(k.search?"?"+k.search:"")+"#"+b+"/",h=new Qa(m,b,k));f.bind("click",function(a){if(!a.ctrlKey&&!(a.metaKey||a.which==2)){for(var b=v(a.target);J(b[0].nodeName)!=="a";)if(b[0]===f[0]||!(b=b.parent())[0])return;var d=b.prop("href"),e=h.$$rewriteAppUrl(d);d&&!b.attr("target")&&e&&(h.$$parse(e),c.$apply(),a.preventDefault(),M.angular["ff-684208-preventDefault"]=!0)}});h.absUrl()!=m&&d.url(h.absUrl(),!0);d.onUrlChange(function(a){h.absUrl()!=a&&(c.$evalAsync(function(){var b=
h.absUrl();h.$$parse(a);i(b)}),c.$$phase||c.$digest())});var l=0;c.$watch(function(){var a=d.url(),b=h.$$replace;if(!l||a!=h.absUrl())l++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),i(a))});h.$$replace=!1;return l});return h}]}function Lc(){var b=!0,a=this;this.debugEnabled=function(a){return w(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&a.stack.indexOf(a.message)===
-1?"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||t;return e.apply?function(){var a=[];o(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,b)}}return{log:e("log"),warn:e("warn"),info:e("info"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function Mc(b,a){function c(a){return a.indexOf(r)!=-1}function d(a){a=a||
1;return n+a<b.length?b.charAt(n+a):!1}function e(a){return"0"<=a&&a<="9"}function f(a){return a==" "||a=="\r"||a=="\t"||a=="\n"||a=="\u000b"||a=="\u00a0"}function i(a){return"a"<=a&&a<="z"||"A"<=a&&a<="Z"||"_"==a||a=="$"}function h(a){return a=="-"||a=="+"||e(a)}function j(a,c,d){d=d||n;throw Error("Lexer Error: "+a+" at column"+(w(c)?"s "+c+"-"+n+" ["+b.substring(c,d)+"]":" "+d)+" in expression ["+b+"].");}function g(){for(var a="",c=n;n<b.length;){var g=J(b.charAt(n));if(g=="."||e(g))a+=g;else{var f=
d();if(g=="e"&&h(f))a+=g;else if(h(g)&&f&&e(f)&&a.charAt(a.length-1)=="e")a+=g;else if(h(g)&&(!f||!e(f))&&a.charAt(a.length-1)=="e")j("Invalid exponent");else break}n++}a*=1;l.push({index:c,text:a,json:!0,fn:function(){return a}})}function m(){for(var c="",d=n,g,h,j;n<b.length;){var k=b.charAt(n);if(k=="."||i(k)||e(k))k=="."&&(g=n),c+=k;else break;n++}if(g)for(h=n;h<b.length;){k=b.charAt(h);if(k=="("){j=c.substr(g-d+1);c=c.substr(0,g-d);n=h;break}if(f(k))h++;else break}d={index:d,text:c};if(Ca.hasOwnProperty(c))d.fn=
d.json=Ca[c];else{var m=Nb(c,a);d.fn=y(function(a,b){return m(a,b)},{assign:function(a,b){return Ob(a,c,b)}})}l.push(d);j&&(l.push({index:g,text:".",json:!1}),l.push({index:g+1,text:j,json:!1}))}function k(a){var c=n;n++;for(var d="",e=a,g=!1;n<b.length;){var h=b.charAt(n);e+=h;if(g)h=="u"?(h=b.substring(n+1,n+5),h.match(/[\da-f]{4}/i)||j("Invalid unicode escape [\\u"+h+"]"),n+=4,d+=String.fromCharCode(parseInt(h,16))):(g=Nc[h],d+=g?g:h),g=!1;else if(h=="\\")g=!0;else if(h==a){n++;l.push({index:c,
text:e,string:d,json:!0,fn:function(){return d}});return}else d+=h;n++}j("Unterminated quote",c)}for(var l=[],q,n=0,B=[],r,p=":";n<b.length;){r=b.charAt(n);if(c("\"'"))k(r);else if(e(r)||c(".")&&e(d()))g();else if(i(r)){if(m(),"{,".indexOf(p)!=-1&&B[0]=="{"&&(q=l[l.length-1]))q.json=q.text.indexOf(".")==-1}else if(c("(){}[].,;:"))l.push({index:n,text:r,json:":[,".indexOf(p)!=-1&&c("{[")||c("}]:,")}),c("{[")&&B.unshift(r),c("}]")&&B.shift(),n++;else if(f(r)){n++;continue}else{var E=r+d(),D=E+d(2),
G=Ca[r],o=Ca[E],A=Ca[D];A?(l.push({index:n,text:D,fn:A}),n+=3):o?(l.push({index:n,text:E,fn:o}),n+=2):G?(l.push({index:n,text:r,fn:G,json:"[,:".indexOf(p)!=-1&&c("+-")}),n+=1):j("Unexpected next character ",n,n+1)}p=r}return l}function Oc(b,a,c,d){function e(a,c){throw Error("Syntax Error: Token '"+c.text+"' "+a+" at column "+(c.index+1)+" of the expression ["+b+"] starting at ["+b.substring(c.index)+"].");}function f(){if(F.length===0)throw Error("Unexpected end of expression: "+b);return F[0]}function i(a,
b,c,d){if(F.length>0){var e=F[0],g=e.text;if(g==a||g==b||g==c||g==d||!a&&!b&&!c&&!d)return e}return!1}function h(b,c,d,g){return(b=i(b,c,d,g))?(a&&!b.json&&e("is not valid json",b),F.shift(),b):!1}function j(a){h(a)||e("is unexpected, expecting ["+a+"]",i())}function g(a,b){return y(function(c,d){return a(c,d,b)},{constant:b.constant})}function m(a,b,c){return y(function(d,e){return b(d,e,a,c)},{constant:a.constant&&c.constant})}function k(){for(var a=[];;)if(F.length>0&&!i("}",")",";","]")&&a.push(fa()),
!h(";"))return a.length==1?a[0]:function(b,c){for(var d,e=0;e<a.length;e++){var g=a[e];g&&(d=g(b,c))}return d}}function l(){for(var a=h(),b=c(a.text),d=[];;)if(a=h(":"))d.push(N());else{var e=function(a,c,e){for(var e=[e],g=0;g<d.length;g++)e.push(d[g](a,c));return b.apply(a,e)};return function(){return e}}}function q(){for(var a=n(),b;;)if(b=h("||"))a=m(a,b.fn,n());else return a}function n(){var a=B(),b;if(b=h("&&"))a=m(a,b.fn,n());return a}function B(){var a=r(),b;if(b=h("==","!=","===","!=="))a=
m(a,b.fn,B());return a}function r(){var a;a=p();for(var b;b=h("+","-");)a=m(a,b.fn,p());if(b=h("<",">","<=",">="))a=m(a,b.fn,r());return a}function p(){for(var a=E(),b;b=h("*","/","%");)a=m(a,b.fn,E());return a}function E(){var a;return h("+")?D():(a=h("-"))?m(A,a.fn,E()):(a=h("!"))?g(a.fn,E()):D()}function D(){var a;if(h("("))a=fa(),j(")");else if(h("["))a=G();else if(h("{"))a=o();else{var b=h();(a=b.fn)||e("not a primary expression",b);if(b.json)a.constant=a.literal=!0}for(var c;b=h("(","[",".");)b.text===
"("?(a=ea(a,c),c=null):b.text==="["?(c=a,a=z(a)):b.text==="."?(c=a,a=ga(a)):e("IMPOSSIBLE");return a}function G(){var a=[],b=!0;if(f().text!="]"){do{var c=N();a.push(c);c.constant||(b=!1)}while(h(","))}j("]");return y(function(b,c){for(var d=[],e=0;e<a.length;e++)d.push(a[e](b,c));return d},{literal:!0,constant:b})}function o(){var a=[],b=!0;if(f().text!="}"){do{var c=h(),c=c.string||c.text;j(":");var d=N();a.push({key:c,value:d});d.constant||(b=!1)}while(h(","))}j("}");return y(function(b,c){for(var d=
{},e=0;e<a.length;e++){var g=a[e],h=g.value(b,c);d[g.key]=h}return d},{literal:!0,constant:b})}var A=Q(0),H,F=Mc(b,d),N=function(){var a=q(),c,d;return(d=h("="))?(a.assign||e("implies assignment but ["+b.substring(0,d.index)+"] can not be assigned to",d),c=q(),function(b,d){return a.assign(b,c(b,d),d)}):a},ea=function(a,b){var c=[];if(f().text!=")"){do c.push(N());while(h(","))}j(")");return function(d,e){for(var g=[],h=b?b(d,e):d,f=0;f<c.length;f++)g.push(c[f](d,e));f=a(d,e)||t;return f.apply?f.apply(h,
g):f(g[0],g[1],g[2],g[3],g[4])}},ga=function(a){var b=h().text,c=Nb(b,d);return y(function(b,d){return c(a(b,d),d)},{assign:function(c,d,e){return Ob(a(c,e),b,d)}})},z=function(a){var b=N();j("]");return y(function(c,d){var e=a(c,d),g=b(c,d),h;if(!e)return s;if((e=e[g])&&e.then){h=e;if(!("$$v"in e))h.$$v=s,h.then(function(a){h.$$v=a});e=e.$$v}return e},{assign:function(c,d,e){return a(c,e)[b(c,e)]=d}})},fa=function(){for(var a=N(),b;;)if(b=h("|"))a=m(a,b.fn,l());else return a};a?(N=q,ea=ga=z=fa=function(){e("is not valid json",
{text:b,index:0})},H=D()):H=k();F.length!==0&&e("is an unexpected token",F[0]);H.literal=!!H.literal;H.constant=!!H.constant;return H}function Ob(b,a,c){for(var a=a.split("."),d=0;a.length>1;d++){var e=a.shift(),f=b[e];f||(f={},b[e]=f);b=f}return b[a.shift()]=c}function kb(b,a,c){if(!a)return b;for(var a=a.split("."),d,e=b,f=a.length,i=0;i<f;i++)d=a[i],b&&(b=(e=b)[d]);return!c&&I(b)?ab(e,b):b}function Pb(b,a,c,d,e){return function(f,i){var h=i&&i.hasOwnProperty(b)?i:f,j;if(h===null||h===s)return h;
if((h=h[b])&&h.then){if(!("$$v"in h))j=h,j.$$v=s,j.then(function(a){j.$$v=a});h=h.$$v}if(!a||h===null||h===s)return h;if((h=h[a])&&h.then){if(!("$$v"in h))j=h,j.$$v=s,j.then(function(a){j.$$v=a});h=h.$$v}if(!c||h===null||h===s)return h;if((h=h[c])&&h.then){if(!("$$v"in h))j=h,j.$$v=s,j.then(function(a){j.$$v=a});h=h.$$v}if(!d||h===null||h===s)return h;if((h=h[d])&&h.then){if(!("$$v"in h))j=h,j.$$v=s,j.then(function(a){j.$$v=a});h=h.$$v}if(!e||h===null||h===s)return h;if((h=h[e])&&h.then){if(!("$$v"in
h))j=h,j.$$v=s,j.then(function(a){j.$$v=a});h=h.$$v}return h}}function Nb(b,a){if(nb.hasOwnProperty(b))return nb[b];var c=b.split("."),d=c.length,e;if(a)e=d<6?Pb(c[0],c[1],c[2],c[3],c[4]):function(a,b){var e=0,g;do g=Pb(c[e++],c[e++],c[e++],c[e++],c[e++])(a,b),b=s,a=g;while(e<d);return g};else{var f="var l, fn, p;\n";o(c,function(a,b){f+="if(s === null || s === undefined) return s;\nl=s;\ns="+(b?"s":'((k&&k.hasOwnProperty("'+a+'"))?k:s)')+'["'+a+'"];\nif (s && s.then) {\n if (!("$$v" in s)) {\n p=s;\n p.$$v = undefined;\n p.then(function(v) {p.$$v=v;});\n}\n s=s.$$v\n}\n'});
f+="return s;";e=Function("s","k",f);e.toString=function(){return f}}return nb[b]=e}function Pc(){var b={};this.$get=["$filter","$sniffer",function(a,c){return function(d){switch(typeof d){case "string":return b.hasOwnProperty(d)?b[d]:b[d]=Oc(d,!1,a,c.csp);case "function":return d;default:return t}}}]}function Qc(){this.$get=["$rootScope","$exceptionHandler",function(b,a){return Rc(function(a){b.$evalAsync(a)},a)}]}function Rc(b,a){function c(a){return a}function d(a){return i(a)}var e=function(){var h=
[],j,g;return g={resolve:function(a){if(h){var c=h;h=s;j=f(a);c.length&&b(function(){for(var a,b=0,d=c.length;b<d;b++)a=c[b],j.then(a[0],a[1])})}},reject:function(a){g.resolve(i(a))},promise:{then:function(b,g){var f=e(),i=function(d){try{f.resolve((b||c)(d))}catch(e){a(e),f.reject(e)}},n=function(b){try{f.resolve((g||d)(b))}catch(c){a(c),f.reject(c)}};h?h.push([i,n]):j.then(i,n);return f.promise}}}},f=function(a){return a&&a.then?a:{then:function(c){var d=e();b(function(){d.resolve(c(a))});return d.promise}}},
i=function(a){return{then:function(c,g){var f=e();b(function(){f.resolve((g||d)(a))});return f.promise}}};return{defer:e,reject:i,when:function(h,j,g){var m=e(),k,l=function(b){try{return(j||c)(b)}catch(d){return a(d),i(d)}},q=function(b){try{return(g||d)(b)}catch(c){return a(c),i(c)}};b(function(){f(h).then(function(a){k||(k=!0,m.resolve(f(a).then(l,q)))},function(a){k||(k=!0,m.resolve(q(a)))})});return m.promise},all:function(a){var b=e(),c=0,d=C(a)?[]:{};o(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)})});c===0&&b.resolve(d);return b.promise}}}function Sc(){var b={};this.when=function(a,c){b[a]=y({reloadOnSearch:!0,caseInsensitiveMatch:!1},c);if(a){var d=a[a.length-1]=="/"?a.substr(0,a.length-1):a+"/";b[d]={redirectTo:a}}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache",function(a,c,d,e,f,i,h){function j(a,b,c){for(var b=
"^"+b.replace(/[-\/\\^$:*+?.()|[\]{}]/g,"\\$&")+"$",d="",e=[],g={},f=/\\([:*])(\w+)/g,h,j=0;(h=f.exec(b))!==null;){d+=b.slice(j,h.index);switch(h[1]){case ":":d+="([^\\/]*)";break;case "*":d+="(.*)"}e.push(h[2]);j=f.lastIndex}d+=b.substr(j);var i=a.match(RegExp(d,c.caseInsensitiveMatch?"i":""));i&&o(e,function(a,b){g[a]=i[b+1]});return i?g:null}function g(){var b=m(),g=q.current;if(b&&g&&b.$$route===g.$$route&&ja(b.pathParams,g.pathParams)&&!b.reloadOnSearch&&!l)g.params=b.params,W(g.params,d),a.$broadcast("$routeUpdate",
g);else if(b||g)l=!1,a.$broadcast("$routeChangeStart",b,g),(q.current=b)&&b.redirectTo&&(x(b.redirectTo)?c.path(k(b.redirectTo,b.params)).search(b.params).replace():c.url(b.redirectTo(b.pathParams,c.path(),c.search())).replace()),e.when(b).then(function(){if(b){var a=y({},b.resolve),c;o(a,function(b,c){a[c]=x(b)?f.get(b):f.invoke(b)});if(w(c=b.template))I(c)&&(c=c(b.params));else if(w(c=b.templateUrl))if(I(c)&&(c=c(b.params)),w(c))b.loadedTemplateUrl=c,c=i.get(c,{cache:h}).then(function(a){return a.data});
w(c)&&(a.$template=c);return e.all(a)}}).then(function(c){if(b==q.current){if(b)b.locals=c,W(b.params,d);a.$broadcast("$routeChangeSuccess",b,g)}},function(c){b==q.current&&a.$broadcast("$routeChangeError",b,g,c)})}function m(){var a,d;o(b,function(b,e){if(!d&&(a=j(c.path(),e,b)))d=Fa(b,{params:y({},c.search(),a),pathParams:a}),d.$$route=b});return d||b[null]&&Fa(b[null],{params:{},pathParams:{}})}function k(a,b){var c=[];o((a||"").split(":"),function(a,d){if(d==0)c.push(a);else{var e=a.match(/(\w+)(.*)/),
g=e[1];c.push(b[g]);c.push(e[2]||"");delete b[g]}});return c.join("")}var l=!1,q={routes:b,reload:function(){l=!0;a.$evalAsync(g)}};a.$on("$locationChangeSuccess",g);return q}]}function Tc(){this.$get=Q({})}function Uc(){var b=10;this.digestTtl=function(a){arguments.length&&(b=a);return b};this.$get=["$injector","$exceptionHandler","$parse",function(a,c,d){function e(){this.$id=Ea();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.$$listeners={};this.$$isolateBindings={}}function f(a){if(j.$$phase)throw Error(j.$$phase+" already in progress");j.$$phase=a}function i(a,b){var c=d(a);va(c,b);return c}function h(){}e.prototype={$new:function(a){if(I(a))throw Error("API-CHANGE: Use $controller to instantiate controllers.");a?(a=new e,a.$root=this.$root):(a=function(){},a.prototype=this,a=new a,a.$id=Ea());a["this"]=a;a.$$listeners={};a.$parent=this;a.$$watchers=
a.$$nextSibling=a.$$childHead=a.$$childTail=null;a.$$prevSibling=this.$$childTail;this.$$childHead?this.$$childTail=this.$$childTail.$$nextSibling=a:this.$$childHead=this.$$childTail=a;return a},$watch:function(a,b,c){var d=i(a,"watch"),e=this.$$watchers,f={fn:b,last:h,get:d,exp:a,eq:!!c};if(!I(b)){var j=i(b||t,"listener");f.fn=function(a,b,c){j(c)}}if(typeof a=="string"&&d.constant){var r=f.fn;f.fn=function(a,b,c){r.call(this,a,b,c);sa(e,f)}}if(!e)e=this.$$watchers=[];e.unshift(f);return function(){sa(e,
f)}},$watchCollection:function(a,b){var c=this,e,f,h=0,j=d(a),i=[],p={},o=0;return this.$watch(function(){f=j(c);var a,b;if(L(f))if(C(f)){if(e!==i)e=i,o=e.length=0,h++;a=f.length;if(o!==a)h++,e.length=o=a;for(b=0;b<a;b++)e[b]!==f[b]&&(h++,e[b]=f[b])}else{e!==p&&(e=p={},o=0,h++);a=0;for(b in f)f.hasOwnProperty(b)&&(a++,e.hasOwnProperty(b)?e[b]!==f[b]&&(h++,e[b]=f[b]):(o++,e[b]=f[b],h++));if(o>a)for(b in h++,e)e.hasOwnProperty(b)&&!f.hasOwnProperty(b)&&(o--,delete e[b])}else e!==f&&(e=f,h++);return h},
function(){b(f,e,c)})},$digest:function(){var a,d,e,i,q=this.$$asyncQueue,n,o,r=b,p,E=[],D,G;f("$digest");do{o=!1;for(p=this;q.length;)try{p.$eval(q.shift())}catch(s){c(s)}do{if(i=p.$$watchers)for(n=i.length;n--;)try{if(a=i[n],(d=a.get(p))!==(e=a.last)&&!(a.eq?ja(d,e):typeof d=="number"&&typeof e=="number"&&isNaN(d)&&isNaN(e)))o=!0,a.last=a.eq?W(d):d,a.fn(d,e===h?d:e,p),r<5&&(D=4-r,E[D]||(E[D]=[]),G=I(a.exp)?"fn: "+(a.exp.name||a.exp.toString()):a.exp,G+="; newVal: "+da(d)+"; oldVal: "+da(e),E[D].push(G))}catch(A){c(A)}if(!(i=
p.$$childHead||p!==this&&p.$$nextSibling))for(;p!==this&&!(i=p.$$nextSibling);)p=p.$parent}while(p=i);if(o&&!r--)throw j.$$phase=null,Error(b+" $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: "+da(E));}while(o||q.length);j.$$phase=null},$destroy:function(){if(!(j==this||this.$$destroyed)){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;if(a.$$childHead==this)a.$$childHead=this.$$nextSibling;if(a.$$childTail==this)a.$$childTail=this.$$prevSibling;
if(this.$$prevSibling)this.$$prevSibling.$$nextSibling=this.$$nextSibling;if(this.$$nextSibling)this.$$nextSibling.$$prevSibling=this.$$prevSibling;this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null}},$eval:function(a,b){return d(a)(this,b)},$evalAsync:function(a){this.$$asyncQueue.push(a)},$apply:function(a){try{return f("$apply"),this.$eval(a)}catch(b){c(b)}finally{j.$$phase=null;try{j.$digest()}catch(d){throw c(d),d;}}},$on:function(a,b){var c=this.$$listeners[a];
c||(this.$$listeners[a]=c=[]);c.push(b);return function(){c[Ga(c,b)]=null}},$emit:function(a,b){var d=[],e,f=this,h=!1,i={name:a,targetScope:f,stopPropagation:function(){h=!0},preventDefault:function(){i.defaultPrevented=!0},defaultPrevented:!1},j=[i].concat(ka.call(arguments,1)),p,o;do{e=f.$$listeners[a]||d;i.currentScope=f;p=0;for(o=e.length;p<o;p++)if(e[p])try{if(e[p].apply(null,j),h)return i}catch(D){c(D)}else e.splice(p,1),p--,o--;f=f.$parent}while(f);return i},$broadcast:function(a,b){var d=
this,e=this,f={name:a,targetScope:this,preventDefault:function(){f.defaultPrevented=!0},defaultPrevented:!1},h=[f].concat(ka.call(arguments,1)),i,j;do{d=e;f.currentScope=d;e=d.$$listeners[a]||[];i=0;for(j=e.length;i<j;i++)if(e[i])try{e[i].apply(null,h)}catch(p){c(p)}else e.splice(i,1),i--,j--;if(!(e=d.$$childHead||d!==this&&d.$$nextSibling))for(;d!==this&&!(e=d.$$nextSibling);)d=d.$parent}while(d=e);return f}};var j=new e;return j}]}function Vc(){this.$get=["$window","$document",function(b,a){var c=
{},d=K((/android (\d+)/.exec(J((b.navigator||{}).userAgent))||[])[1]),e=a[0]||{},f,i=/^(Moz|webkit|O|ms)(?=[A-Z])/,h=e.body&&e.body.style,j=!1;if(h){for(var g in h)if(j=i.exec(g)){f=j[0];f=f.substr(0,1).toUpperCase()+f.substr(1);break}j=!!(f+"Transition"in h)}return{history:!(!b.history||!b.history.pushState||d<4),hashchange:"onhashchange"in b&&(!e.documentMode||e.documentMode>7),hasEvent:function(a){if(a=="input"&&X==9)return!1;if(u(c[a])){var b=e.createElement("div");c[a]="on"+a in b}return c[a]},
csp:e.securityPolicy?e.securityPolicy.isActive:!1,vendorPrefix:f,supportsTransitions:j}}]}function Wc(){this.$get=Q(M)}function Qb(b){var a={},c,d,e;if(!b)return a;o(b.split("\n"),function(b){e=b.indexOf(":");c=J(S(b.substr(0,e)));d=S(b.substr(e+1));c&&(a[c]?a[c]+=", "+d:a[c]=d)});return a}function Xc(b,a){var c=Yc.exec(b);if(c==null)return!0;var d={protocol:c[2],host:c[4],port:K(c[6])||Ba[c[2]]||null,relativeProtocol:c[2]===s||c[2]===""},c=lb.exec(a),c={protocol:c[1],host:c[3],port:K(c[5])||Ba[c[1]]||
null};return(d.protocol==c.protocol||d.relativeProtocol)&&d.host==c.host&&(d.port==c.port||d.relativeProtocol&&c.port==Ba[c.protocol])}function Rb(b){var a=L(b)?b:s;return function(c){a||(a=Qb(b));return c?a[J(c)]||null:a}}function Sb(b,a,c){if(I(c))return c(b,a);o(c,function(c){b=c(b,a)});return b}function Zc(){var b=/^\s*(\[|\{[^\{])/,a=/[\}\]]\s*$/,c=/^\)\]\}',?\n/,d=this.defaults={transformResponse:[function(d){x(d)&&(d=d.replace(c,""),b.test(d)&&a.test(d)&&(d=tb(d,!0)));return d}],transformRequest:[function(a){return L(a)&&
Da.apply(a)!=="[object File]"?da(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"},post:{"Content-Type":"application/json;charset=utf-8"},put:{"Content-Type":"application/json;charset=utf-8"}},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN"},e=this.interceptors=[],f=this.responseInterceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope","$q","$injector",function(a,b,c,g,m,k){function l(a){function c(a){var b=y({},a,{data:Sb(a.data,a.headers,e.transformResponse)});
return 200<=a.status&&a.status<300?b:m.reject(b)}var e={transformRequest:d.transformRequest,transformResponse:d.transformResponse},g={};y(e,a);e.headers=g;e.method=na(e.method);y(g,d.headers.common,d.headers[J(e.method)],a.headers);(a=Xc(e.url,b.url())?b.cookies()[e.xsrfCookieName||d.xsrfCookieName]:s)&&(g[e.xsrfHeaderName||d.xsrfHeaderName]=a);var f=[function(a){var b=Sb(a.data,Rb(g),a.transformRequest);u(a.data)&&delete g["Content-Type"];if(u(a.withCredentials)&&!u(d.withCredentials))a.withCredentials=
d.withCredentials;return q(a,b,g).then(c,c)},s],j=m.when(e);for(o(r,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;)var a=f.shift(),i=f.shift(),j=j.then(a,i);j.success=function(a){j.then(function(b){a(b.data,b.status,b.headers,e)});return j};j.error=function(a){j.then(null,function(b){a(b.data,b.status,b.headers,e)});return j};return j}function q(b,c,e){function f(a,b,c){o&&(200<=a&&a<300?o.put(s,
[a,b,Qb(c)]):o.remove(s));h(b,a,c);g.$apply()}function h(a,c,d){c=Math.max(c,0);(200<=c&&c<300?k.resolve:k.reject)({data:a,status:c,headers:Rb(d),config:b})}function j(){var a=Ga(l.pendingRequests,b);a!==-1&&l.pendingRequests.splice(a,1)}var k=m.defer(),q=k.promise,o,r,s=n(b.url,b.params);l.pendingRequests.push(b);q.then(j,j);if((b.cache||d.cache)&&b.cache!==!1&&b.method=="GET")o=L(b.cache)?b.cache:L(d.cache)?d.cache:B;if(o)if(r=o.get(s))if(r.then)return r.then(j,j),r;else C(r)?h(r[1],r[0],W(r[2])):
h(r,200,{});else o.put(s,q);r||a(b.method,s,c,f,e,b.timeout,b.withCredentials,b.responseType);return q}function n(a,b){if(!b)return a;var c=[];ic(b,function(a,b){a==null||a==s||(C(a)||(a=[a]),o(a,function(a){L(a)&&(a=da(a));c.push(ua(b)+"="+ua(a))}))});return a+(a.indexOf("?")==-1?"?":"&")+c.join("&")}var B=c("$http"),r=[];o(e,function(a){r.unshift(x(a)?k.get(a):k.invoke(a))});o(f,function(a,b){var c=x(a)?k.get(a):k.invoke(a);r.splice(b,0,{response:function(a){return c(m.when(a))},responseError:function(a){return c(m.reject(a))}})});
l.pendingRequests=[];(function(a){o(arguments,function(a){l[a]=function(b,c){return l(y(c||{},{method:a,url:b}))}})})("get","delete","head","jsonp");(function(a){o(arguments,function(a){l[a]=function(b,c,d){return l(y(d||{},{method:a,url:b,data:c}))}})})("post","put");l.defaults=d;return l}]}function $c(){this.$get=["$browser","$window","$document",function(b,a,c){return ad(b,bd,b.defer,a.angular.callbacks,c[0],a.location.protocol.replace(":",""))}]}function ad(b,a,c,d,e,f){function i(a,b){var c=
e.createElement("script"),d=function(){e.body.removeChild(c);b&&b()};c.type="text/javascript";c.src=a;X?c.onreadystatechange=function(){/loaded|complete/.test(c.readyState)&&d()}:c.onload=c.onerror=d;e.body.appendChild(c)}return function(e,j,g,m,k,l,q,n){function B(a,c,d,e){c=(j.match(lb)||["",f])[1]=="file"?d?200:404:c;a(c==1223?204:c,d,e);b.$$completeOutstandingRequest(t)}b.$$incOutstandingRequestCount();j=j||b.url();if(J(e)=="jsonp"){var r="_"+(d.counter++).toString(36);d[r]=function(a){d[r].data=
a};i(j.replace("JSON_CALLBACK","angular.callbacks."+r),function(){d[r].data?B(m,200,d[r].data):B(m,-2);delete d[r]})}else{var p=new a;p.open(e,j,!0);o(k,function(a,b){a&&p.setRequestHeader(b,a)});var s;p.onreadystatechange=function(){if(p.readyState==4){var a=p.getAllResponseHeaders(),b=["Cache-Control","Content-Language","Content-Type","Expires","Last-Modified","Pragma"];a||(a="",o(b,function(b){var c=p.getResponseHeader(b);c&&(a+=b+": "+c+"\n")}));B(m,s||p.status,p.responseType?p.response:p.responseText,
a)}};if(q)p.withCredentials=!0;if(n)p.responseType=n;p.send(g||"");l>0&&c(function(){s=-1;p.abort()},l)}}}function cd(){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 b===1?"one":"other"}}}}function dd(){this.$get=["$rootScope","$browser","$q",
"$exceptionHandler",function(b,a,c,d){function e(e,h,j){var g=c.defer(),m=g.promise,k=w(j)&&!j,h=a.defer(function(){try{g.resolve(e())}catch(a){g.reject(a),d(a)}k||b.$apply()},h),j=function(){delete f[m.$$timeoutId]};m.$$timeoutId=h;f[h]=g;m.then(j,j);return m}var f={};e.cancel=function(b){return b&&b.$$timeoutId in f?(f[b.$$timeoutId].reject("canceled"),a.defer.cancel(b.$$timeoutId)):!1};return e}]}function Tb(b){function a(a,e){return b.factory(a+c,e)}var c="Filter";this.register=a;this.$get=["$injector",
function(a){return function(b){return a.get(b+c)}}];a("currency",Ub);a("date",Vb);a("filter",ed);a("json",fd);a("limitTo",gd);a("lowercase",hd);a("number",Wb);a("orderBy",Xb);a("uppercase",id)}function ed(){return function(b,a,c){if(!C(b))return b;var d=[];d.check=function(a){for(var b=0;b<d.length;b++)if(!d[b](a))return!1;return!0};switch(typeof c){case "function":break;case "boolean":if(c==!0){c=function(a,b){return Ia.equals(a,b)};break}default:c=function(a,b){b=(""+b).toLowerCase();return(""+
a).toLowerCase().indexOf(b)>-1}}var e=function(a,b){if(typeof b=="string"&&b.charAt(0)==="!")return!e(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)!=="$"&&e(a[d],b))return!0}return!1;case "array":for(d=0;d<a.length;d++)if(e(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 f in a)f==
"$"?function(){if(a[f]){var b=f;d.push(function(c){return e(c,a[b])})}}():function(){if(a[f]){var b=f;d.push(function(c){return e(kb(c,b),a[b])})}}();break;case "function":d.push(a);break;default:return b}for(var i=[],h=0;h<b.length;h++){var j=b[h];d.check(j)&&i.push(j)}return i}}function Ub(b){var a=b.NUMBER_FORMATS;return function(b,d){if(u(d))d=a.CURRENCY_SYM;return Yb(b,a.PATTERNS[1],a.GROUP_SEP,a.DECIMAL_SEP,2).replace(/\u00A4/g,d)}}function Wb(b){var a=b.NUMBER_FORMATS;return function(b,d){return Yb(b,
a.PATTERNS[0],a.GROUP_SEP,a.DECIMAL_SEP,d)}}function Yb(b,a,c,d,e){if(isNaN(b)||!isFinite(b))return"";var f=b<0,b=Math.abs(b),i=b+"",h="",j=[],g=!1;if(i.indexOf("e")!==-1){var m=i.match(/([\d\.]+)e(-?)(\d+)/);m&&m[2]=="-"&&m[3]>e+1?i="0":(h=i,g=!0)}if(!g){i=(i.split(Zb)[1]||"").length;u(e)&&(e=Math.min(Math.max(a.minFrac,i),a.maxFrac));var i=Math.pow(10,e),b=Math.round(b*i)/i,b=(""+b).split(Zb),i=b[0],b=b[1]||"",g=0,m=a.lgSize,k=a.gSize;if(i.length>=m+k)for(var g=i.length-m,l=0;l<g;l++)(g-l)%k===
0&&l!==0&&(h+=c),h+=i.charAt(l);for(l=g;l<i.length;l++)(i.length-l)%m===0&&l!==0&&(h+=c),h+=i.charAt(l);for(;b.length<e;)b+="0";e&&e!=="0"&&(h+=d+b.substr(0,e))}j.push(f?a.negPre:a.posPre);j.push(h);j.push(f?a.negSuf:a.posSuf);return j.join("")}function ob(b,a,c){var d="";b<0&&(d="-",b=-b);for(b=""+b;b.length<a;)b="0"+b;c&&(b=b.substr(b.length-a));return d+b}function O(b,a,c,d){return function(e){e=e["get"+b]();if(c>0||e>-c)e+=c;e===0&&c==-12&&(e=12);return ob(e,a,d)}}function Sa(b,a){return function(c,
d){var e=c["get"+b](),f=na(a?"SHORT"+b:b);return d[f][e]}}function Vb(b){function a(a){var b;if(b=a.match(c)){var a=new Date(0),f=0,i=0,h=b[8]?a.setUTCFullYear:a.setFullYear,j=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=K(b[9]+b[10]),i=K(b[9]+b[11]));h.call(a,K(b[1]),K(b[2])-1,K(b[3]));j.call(a,K(b[4]||0)-f,K(b[5]||0)-i,K(b[6]||0),K(b[7]||0))}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="",i=[],h,j,e=e||
"mediumDate",e=b.DATETIME_FORMATS[e]||e;x(c)&&(c=jd.test(c)?K(c):a(c));Za(c)&&(c=new Date(c));if(!qa(c))return c;for(;e;)(j=kd.exec(e))?(i=i.concat(ka.call(j,1)),e=i.pop()):(i.push(e),e=null);o(i,function(a){h=ld[a];f+=h?h(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return f}}function fd(){return function(b){return da(b,!0)}}function gd(){return function(b,a){if(!C(b)&&!x(b))return b;a=K(a);if(x(b))return a?a>=0?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=
b.length:a<-b.length&&(a=-b.length);a>0?(d=0,e=a):(d=b.length+a,e=b.length);for(;d<e;d++)c.push(b[d]);return c}}function Xb(b){return function(a,c,d){function e(a,b){return Ha(b)?function(b,c){return a(c,b)}:a}if(!C(a))return a;if(!c)return a;for(var c=C(c)?c:[c],c=$a(c,function(a){var c=!1,d=a||pa;if(x(a)){if(a.charAt(0)=="+"||a.charAt(0)=="-")c=a.charAt(0)=="-",a=a.substring(1);d=b(a)}return e(function(a,b){var c;c=d(a);var e=d(b),f=typeof c,h=typeof e;f==h?(f=="string"&&(c=c.toLowerCase()),f==
"string"&&(e=e.toLowerCase()),c=c===e?0:c<e?-1:1):c=f<h?-1:1;return c},c)}),f=[],i=0;i<a.length;i++)f.push(a[i]);return f.sort(e(function(a,b){for(var d=0;d<c.length;d++){var e=c[d](a,b);if(e!==0)return e}return 0},d))}}function Y(b){I(b)&&(b={link:b});b.restrict=b.restrict||"AC";return Q(b)}function $b(b,a){function c(a,c){c=c?"-"+db(c,"-"):"";b.removeClass((a?Ta:Ua)+c).addClass((a?Ua:Ta)+c)}var d=this,e=b.parent().controller("form")||Va,f=0,i=d.$error={},h=[];d.$name=a.name;d.$dirty=!1;d.$pristine=
!0;d.$valid=!0;d.$invalid=!1;e.$addControl(d);b.addClass(oa);c(!0);d.$addControl=function(a){h.push(a);a.$name&&!d.hasOwnProperty(a.$name)&&(d[a.$name]=a)};d.$removeControl=function(a){a.$name&&d[a.$name]===a&&delete d[a.$name];o(i,function(b,c){d.$setValidity(c,!0,a)});sa(h,a)};d.$setValidity=function(a,b,h){var k=i[a];if(b){if(k&&(sa(k,h),!k.length)){f--;if(!f)c(b),d.$valid=!0,d.$invalid=!1;i[a]=!1;c(!0,a);e.$setValidity(a,!0,d)}}else{f||c(b);if(k){if(Ga(k,h)!=-1)return}else i[a]=k=[],f++,c(!1,
a),e.$setValidity(a,!1,d);k.push(h);d.$valid=!1;d.$invalid=!0}};d.$setDirty=function(){b.removeClass(oa).addClass(Wa);d.$dirty=!0;d.$pristine=!1;e.$setDirty()};d.$setPristine=function(){b.removeClass(Wa).addClass(oa);d.$dirty=!1;d.$pristine=!0;o(h,function(a){a.$setPristine()})}}function U(b){return u(b)||b===""||b===null||b!==b}function Xa(b,a,c,d,e,f){var i=function(){var e=a.val();if(Ha(c.ngTrim||"T"))e=S(e);d.$viewValue!==e&&b.$apply(function(){d.$setViewValue(e)})};if(e.hasEvent("input"))a.bind("input",
i);else{var h;a.bind("keydown",function(a){a=a.keyCode;a===91||15<a&&a<19||37<=a&&a<=40||h||(h=f.defer(function(){i();h=null}))});a.bind("change",i)}d.$render=function(){a.val(U(d.$viewValue)?"":d.$viewValue)};var j=c.ngPattern,g=function(a,b){return U(b)||a.test(b)?(d.$setValidity("pattern",!0),b):(d.$setValidity("pattern",!1),s)};j&&(j.match(/^\/(.*)\/$/)?(j=RegExp(j.substr(1,j.length-2)),e=function(a){return g(j,a)}):e=function(a){var c=b.$eval(j);if(!c||!c.test)throw Error("Expected "+j+" to be a RegExp but was "+
c);return g(c,a)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var m=K(c.ngMinlength),e=function(a){return!U(a)&&a.length<m?(d.$setValidity("minlength",!1),s):(d.$setValidity("minlength",!0),a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var k=K(c.ngMaxlength),e=function(a){return!U(a)&&a.length>k?(d.$setValidity("maxlength",!1),s):(d.$setValidity("maxlength",!0),a)};d.$parsers.push(e);d.$formatters.push(e)}}function pb(b,a){b="ngClass"+b;return Y(function(c,d,e){function f(b){if(a===
!0||c.$index%2===a)j&&b!==j&&i(j),h(b);j=b}function i(a){L(a)&&!C(a)&&(a=$a(a,function(a,b){if(a)return b}));d.removeClass(C(a)?a.join(" "):a)}function h(a){L(a)&&!C(a)&&(a=$a(a,function(a,b){if(a)return b}));a&&d.addClass(C(a)?a.join(" "):a)}var j=s;c.$watch(e[b],f,!0);e.$observe("class",function(){var a=c.$eval(e[b]);f(a,a)});b!=="ngClass"&&c.$watch("$index",function(d,f){var j=d%2;j!==f%2&&(j==a?h(c.$eval(e[b])):i(c.$eval(e[b])))})})}var J=function(b){return x(b)?b.toLowerCase():b},na=function(b){return x(b)?
b.toUpperCase():b},X=K((/msie (\d+)/.exec(J(navigator.userAgent))||[])[1]),v,ca,ka=[].slice,Ya=[].push,Da=Object.prototype.toString,hc=M.angular,Ia=M.angular||(M.angular={}),xa,jb,Z=["0","0","0"];t.$inject=[];pa.$inject=[];jb=X<9?function(b){b=b.nodeName?b:b[0];return b.scopeName&&b.scopeName!="HTML"?na(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var nc=/[A-Z]/g,md={full:"1.1.4",major:1,minor:1,dot:4,codeName:"quantum-manipulation"},La=P.cache={},
Ka=P.expando="ng-"+(new Date).getTime(),rc=1,ac=M.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},ib=M.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)},pc=/([\:\-\_]+(.))/g,qc=/^moz([A-Z])/,za=P.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;V.readyState==="complete"?setTimeout(a):(this.bind("DOMContentLoaded",a),P(M).bind("load",a))},toString:function(){var b=
[];o(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return b>=0?v(this[b]):v(this[this.length+b])},length:0,push:Ya,sort:[].sort,splice:[].splice},Oa={};o("multiple,selected,checked,disabled,readOnly,required,open".split(","),function(b){Oa[J(b)]=b});var Eb={};o("input,select,option,textarea,button,form,details".split(","),function(b){Eb[na(b)]=!0});o({data:zb,inheritedData:Na,scope:function(b){return Na(b,"$scope")},controller:Cb,injector:function(b){return Na(b,"$injector")},
removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Ma,css:function(b,a,c){a=Ja(a);if(w(c))b.style[a]=c;else{var d;X<=8&&(d=b.currentStyle&&b.currentStyle[a],d===""&&(d="auto"));d=d||b.style[a];X<=8&&(d=d===""?s:d);return d}},attr:function(b,a,c){var d=J(a);if(Oa[d])if(w(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||t).specified?d:s;else if(w(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),b===null?
s:b},prop:function(b,a,c){if(w(c))b[a]=c;else return b[a]},text:y(X<9?function(b,a){if(b.nodeType==1){if(u(a))return b.innerText;b.innerText=a}else{if(u(a))return b.nodeValue;b.nodeValue=a}}:function(b,a){if(u(a))return b.textContent;b.textContent=a},{$dv:""}),val:function(b,a){if(u(a))return b.value;b.value=a},html:function(b,a){if(u(a))return b.innerHTML;for(var c=0,d=b.childNodes;c<d.length;c++)wa(d[c]);b.innerHTML=a}},function(b,a){P.prototype[a]=function(a,d){var e,f;if((b.length==2&&b!==Ma&&
b!==Cb?a:d)===s)if(L(a)){for(e=0;e<this.length;e++)if(b===zb)b(this[e],a);else for(f in a)b(this[e],f,a[f]);return this}else{if(this.length)return b(this[0],a,d)}else{for(e=0;e<this.length;e++)b(this[e],a,d);return this}return b.$dv}});o({removeData:xb,dealoc:wa,bind:function a(c,d,e){var f=$(c,"events"),i=$(c,"handle");f||$(c,"events",f={});i||$(c,"handle",i=sc(c,f));o(d.split(" "),function(d){var j=f[d];if(!j){if(d=="mouseenter"||d=="mouseleave"){var g=0;f.mouseenter=[];f.mouseleave=[];a(c,"mouseover",
function(a){g++;g==1&&i(a,"mouseenter")});a(c,"mouseout",function(a){g--;g==0&&i(a,"mouseleave")})}else ac(c,d,i),f[d]=[];j=f[d]}j.push(e)})},unbind:yb,replaceWith:function(a,c){var d,e=a.parentNode;wa(a);o(new P(c),function(c){d?e.insertBefore(c,d.nextSibling):e.replaceChild(c,a);d=c})},children:function(a){var c=[];o(a.childNodes,function(a){a.nodeType===1&&c.push(a)});return c},contents:function(a){return a.childNodes||[]},append:function(a,c){o(new P(c),function(c){(a.nodeType===1||a.nodeType===
11)&&a.appendChild(c)})},prepend:function(a,c){if(a.nodeType===1){var d=a.firstChild;o(new P(c),function(c){d?a.insertBefore(c,d):(a.appendChild(c),d=c)})}},wrap:function(a,c){var c=v(c)[0],d=a.parentNode;d&&d.replaceChild(c,a);c.appendChild(a)},remove:function(a){wa(a);var c=a.parentNode;c&&c.removeChild(a)},after:function(a,c){var d=a,e=a.parentNode;o(new P(c),function(a){e.insertBefore(a,d.nextSibling);d=a})},addClass:Bb,removeClass:Ab,toggleClass:function(a,c,d){u(d)&&(d=!Ma(a,c));(d?Bb:Ab)(a,
c)},parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},next:function(a){if(a.nextElementSibling)return a.nextElementSibling;for(a=a.nextSibling;a!=null&&a.nodeType!==1;)a=a.nextSibling;return a},find:function(a,c){return a.getElementsByTagName(c)},clone:hb,triggerHandler:function(a,c){var d=($(a,"events")||{})[c];o(d,function(c){c.call(a,null)})}},function(a,c){P.prototype[c]=function(c,e){for(var f,i=0;i<this.length;i++)f==s?(f=a(this[i],c,e),f!==s&&(f=v(f))):gb(f,a(this[i],c,e));
return f==s?this:f}});Pa.prototype={put:function(a,c){this[la(a)]=c},get:function(a){return this[la(a)]},remove:function(a){var c=this[a=la(a)];delete this[a];return c}};var uc=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,vc=/,/,wc=/^\s*(_?)(\S+?)\1\s*$/,tc=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;Gb.$inject=["$provide"];var nd=function(){this.$get=["$animation","$window","$sniffer",function(a,c,d){function e(a){a.css("display","")}function f(a){a.css("display","none")}function i(a,c,d){d?d.after(a):c.append(a)}
function h(a){a.remove()}function j(a,c,d){i(a,c,d)}return function(g,m){function k(e,f,h){var i=l&&g.$eval(l),e=l?L(i)?i[e]:i+"-"+e:"",j=(i=a(e))&&i.setup,k=i&&i.start;if(e){var m=e+"-setup",q=e+"-start";return function(a,e,g){function i(){h(a,e,g);a.removeClass(m);a.removeClass(q)}if(!d.supportsTransitions&&!j&&!k)f(a,e,g),h(a,e,g);else{a.addClass(m);f(a,e,g);if(a.length==0)return i();var l=(j||t)(a);c.setTimeout(function(){a.addClass(q);if(k)k(a,i,l);else if(I(c.getComputedStyle)){var e=d.vendorPrefix+
"Transition",f=0;o(a,function(a){a=c.getComputedStyle(a)||{};f=Math.max(parseFloat(a.transitionDuration)||parseFloat(a[e+"Duration"])||0,f)});c.setTimeout(i,f*1E3)}else i()},1)}}}else return function(a,c,d){f(a,c,d);h(a,c,d)}}var l=m.ngAnimate,q={};q.enter=k("enter",i,t);q.leave=k("leave",t,h);q.move=k("move",j,t);q.show=k("show",e,t);q.hide=k("hide",t,f);return q}}]},Ib="Non-assignable model expression: ";Hb.$inject=["$provide"];var Cc=/^(x[\:\-_]|data[\:\-_])/i,lb=/^([^:]+):\/\/(\w+:{0,1}\w*@)?(\{?[\w\.-]*\}?)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,
bc=/^([^\?#]*)?(\?([^#]*))?(#(.*))?$/,Jc=bc,Ba={http:80,https:443,ftp:21};mb.prototype={$$replace:!1,absUrl:Ra("$$absUrl"),url:function(a,c){if(u(a))return this.$$url;var d=bc.exec(a);d[1]&&this.path(decodeURIComponent(d[1]));if(d[2]||d[1])this.search(d[3]||"");this.hash(d[5]||"",c);return this},protocol:Ra("$$protocol"),host:Ra("$$host"),port:Ra("$$port"),path:Mb("$$path",function(a){return a.charAt(0)=="/"?a:"/"+a}),search:function(a,c){if(u(a))return this.$$search;w(c)?c===null?delete this.$$search[a]:
this.$$search[a]=c:this.$$search=x(a)?bb(a):a;this.$$compose();return this},hash:Mb("$$hash",pa),replace:function(){this.$$replace=!0;return this}};Qa.prototype=Fa(mb.prototype);Lb.prototype=Fa(Qa.prototype);var Ca={"null":function(){return null},"true":function(){return!0},"false":function(){return!1},undefined:t,"+":function(a,c,d,e){d=d(a,c);e=e(a,c);return w(d)?w(e)?d+e:d:w(e)?e:s},"-":function(a,c,d,e){d=d(a,c);e=e(a,c);return(w(d)?d:0)-(w(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)},"=":t,"===":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)}},Nc={n:"\n",f:"\u000c",r:"\r",t:"\t",v:"\u000b","'":"'",'"':'"'},nb={},Yc=/^(([^:]+):)?\/\/(\w+:{0,1}\w*@)?([\w\.-]*)?(:([0-9]+))?(.*)$/,bd=M.XMLHttpRequest||function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(c){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(d){}throw Error("This browser does not support XMLHttpRequest.");
};Tb.$inject=["$provide"];Ub.$inject=["$locale"];Wb.$inject=["$locale"];var Zb=".",ld={yyyy:O("FullYear",4),yy:O("FullYear",2,0,!0),y:O("FullYear",1),MMMM:Sa("Month"),MMM:Sa("Month",!0),MM:O("Month",2,1),M:O("Month",1,1),dd:O("Date",2),d:O("Date",1),HH:O("Hours",2),H:O("Hours",1),hh:O("Hours",2,-12),h:O("Hours",1,-12),mm:O("Minutes",2),m:O("Minutes",1),ss:O("Seconds",2),s:O("Seconds",1),sss:O("Milliseconds",3),EEEE:Sa("Day"),EEE:Sa("Day",!0),a:function(a,c){return a.getHours()<12?c.AMPMS[0]:c.AMPMS[1]},
Z:function(a){var a=-1*a.getTimezoneOffset(),c=a>=0?"+":"";c+=ob(Math[a>0?"floor":"ceil"](a/60),2)+ob(Math.abs(a%60),2);return c}},kd=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,jd=/^\d+$/;Vb.$inject=["$locale"];var hd=Q(J),id=Q(na);Xb.$inject=["$parse"];var od=Q({restrict:"E",compile:function(a,c){X<=8&&(!c.href&&!c.name&&c.$set("href",""),a.append(V.createComment("IE fix")));return function(a,c){c.bind("click",function(a){c.attr("href")||a.preventDefault()})}}}),
qb={};o(Oa,function(a,c){var d=aa("ng-"+c);qb[d]=function(){return{priority:100,compile:function(){return function(a,f,i){a.$watch(i[d],function(a){i.$set(c,!!a)})}}}}});o(["src","href"],function(a){var c=aa("ng-"+a);qb[c]=function(){return{priority:99,link:function(d,e,f){f.$observe(c,function(c){c&&(f.$set(a,c),X&&e.prop(a,f[a]))})}}}});var Va={$addControl:t,$removeControl:t,$setValidity:t,$setDirty:t,$setPristine:t};$b.$inject=["$element","$attrs","$scope"];var Ya=function(a){return["$timeout",
function(c){var d={name:"form",restrict:"E",controller:$b,compile:function(){return{pre:function(a,d,i,h){if(!i.action){var j=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};ac(d[0],"submit",j);d.bind("$destroy",function(){c(function(){ib(d[0],"submit",j)},0,!1)})}var g=d.parent().controller("form"),m=i.name||i.ngForm;m&&(a[m]=h);g&&d.bind("$destroy",function(){g.$removeControl(h);m&&(a[m]=s);y(h,Va)})}}}};return a?y(W(d),{restrict:"EAC"}):d}]},pd=Ya(),qd=Ya(!0),rd=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,
sd=/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/,td=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,cc={text:Xa,number:function(a,c,d,e,f,i){Xa(a,c,d,e,f,i);e.$parsers.push(function(a){var c=U(a);return c||td.test(a)?(e.$setValidity("number",!0),a===""?null:c?a:parseFloat(a)):(e.$setValidity("number",!1),s)});e.$formatters.push(function(a){return U(a)?"":""+a});if(d.min){var h=parseFloat(d.min),a=function(a){return!U(a)&&a<h?(e.$setValidity("min",!1),s):(e.$setValidity("min",!0),a)};e.$parsers.push(a);
e.$formatters.push(a)}if(d.max){var j=parseFloat(d.max),d=function(a){return!U(a)&&a>j?(e.$setValidity("max",!1),s):(e.$setValidity("max",!0),a)};e.$parsers.push(d);e.$formatters.push(d)}e.$formatters.push(function(a){return U(a)||Za(a)?(e.$setValidity("number",!0),a):(e.$setValidity("number",!1),s)})},url:function(a,c,d,e,f,i){Xa(a,c,d,e,f,i);a=function(a){return U(a)||rd.test(a)?(e.$setValidity("url",!0),a):(e.$setValidity("url",!1),s)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,
c,d,e,f,i){Xa(a,c,d,e,f,i);a=function(a){return U(a)||sd.test(a)?(e.$setValidity("email",!0),a):(e.$setValidity("email",!1),s)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){u(d.name)&&c.attr("name",Ea());c.bind("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,i=d.ngFalseValue;x(f)||(f=!0);x(i)||(i=!1);c.bind("click",
function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$formatters.push(function(a){return a===f});e.$parsers.push(function(a){return a?f:i})},hidden:t,button:t,submit:t,reset:t},dc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",link:function(d,e,f,i){i&&(cc[J(f.type)]||cc.text)(d,e,f,i,c,a)}}}],Ua="ng-valid",Ta="ng-invalid",oa="ng-pristine",Wa="ng-dirty",ud=["$scope","$exceptionHandler","$attrs","$element","$parse",
function(a,c,d,e,f){function i(a,c){c=c?"-"+db(c,"-"):"";e.removeClass((a?Ta:Ua)+c).addClass((a?Ua:Ta)+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 h=f(d.ngModel),j=h.assign;if(!j)throw Error(Ib+d.ngModel+" ("+ta(e)+")");this.$render=t;var g=e.inheritedData("$formController")||Va,m=0,k=this.$error={};e.addClass(oa);i(!0);this.$setValidity=function(a,
c){if(k[a]!==!c){if(c){if(k[a]&&m--,!m)i(!0),this.$valid=!0,this.$invalid=!1}else i(!1),this.$invalid=!0,this.$valid=!1,m++;k[a]=!c;i(c,a);g.$setValidity(a,c,this)}};this.$setPristine=function(){this.$dirty=!1;this.$pristine=!0;e.removeClass(Wa).addClass(oa)};this.$setViewValue=function(d){this.$viewValue=d;if(this.$pristine)this.$dirty=!0,this.$pristine=!1,e.removeClass(oa).addClass(Wa),g.$setDirty();o(this.$parsers,function(a){d=a(d)});if(this.$modelValue!==d)this.$modelValue=d,j(a,d),o(this.$viewChangeListeners,
function(a){try{a()}catch(d){c(d)}})};var l=this;a.$watch(function(){var c=h(a);if(l.$modelValue!==c){var d=l.$formatters,e=d.length;for(l.$modelValue=c;e--;)c=d[e](c);if(l.$viewValue!==c)l.$viewValue=c,l.$render()}})}],vd=function(){return{require:["ngModel","^?form"],controller:ud,link:function(a,c,d,e){var f=e[0],i=e[1]||Va;i.$addControl(f);c.bind("$destroy",function(){i.$removeControl(f)})}}},wd=Q({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),
ec=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var f=function(a){if(d.required&&(U(a)||a===!1))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)})}}}},xd=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){var c=[];a&&o(a.split(f),function(a){a&&c.push(S(a))});
return c});e.$formatters.push(function(a){return C(a)?a.join(", "):s})}}},yd=/^(true|false|\d+)$/,zd=function(){return{priority:100,compile:function(a,c){return yd.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,!1)})}}}},Ad=Y(function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBind);a.$watch(d.ngBind,function(a){c.text(a==s?"":a)})}),Bd=["$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)})}}],Cd=[function(){return function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBindHtmlUnsafe);a.$watch(d.ngBindHtmlUnsafe,function(a){c.html(a||"")})}}],Dd=pb("",!0),Ed=pb("Odd",0),Fd=pb("Even",1),Gd=Y({compile:function(a,c){c.$set("ngCloak",s);a.removeClass("ng-cloak")}}),Hd=[function(){return{scope:!0,controller:"@"}}],Id=["$sniffer",function(a){return{priority:1E3,compile:function(){a.csp=!0}}}],
fc={};o("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress".split(" "),function(a){var c=aa("ng-"+a);fc[c]=["$parse",function(d){return function(e,f,i){var h=d(i[c]);f.bind(J(a),function(a){e.$apply(function(){h(e,{$event:a})})})}}]});var Jd=Y(function(a,c,d){c.bind("submit",function(){a.$apply(d.ngSubmit)})}),Kd=["$http","$templateCache","$anchorScroll","$compile","$animator",function(a,c,d,e,f){return{restrict:"ECA",terminal:!0,compile:function(i,
h){var j=h.ngInclude||h.src,g=h.onload||"",m=h.autoscroll;return function(h,i,o){var n=f(h,o),s=0,r,p=function(){r&&(r.$destroy(),r=null);n.leave(i.contents(),i)};h.$watch(j,function(f){var j=++s;f?a.get(f,{cache:c}).success(function(a){j===s&&(r&&r.$destroy(),r=h.$new(),n.leave(i.contents(),i),a=v("<div/>").html(a).contents(),n.enter(a,i),e(a)(r),w(m)&&(!m||h.$eval(m))&&d(),r.$emit("$includeContentLoaded"),h.$eval(g))}).error(function(){j===s&&p()}):p()})}}}}],Ld=Y({compile:function(){return{pre:function(a,
c,d){a.$eval(d.ngInit)}}}}),Md=Y({terminal:!0,priority:1E3}),Nd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,f,i){var h=i.count,j=f.attr(i.$attr.when),g=i.offset||0,m=e.$eval(j),k={},l=c.startSymbol(),q=c.endSymbol();o(m,function(a,e){k[e]=c(a.replace(d,l+h+"-"+g+q))});e.$watch(function(){var c=parseFloat(e.$eval(h));return isNaN(c)?"":(m[c]||(c=a.pluralCat(c-g)),k[c](e,f,!0))},function(a){f.text(a)})}}}],Od=["$parse","$animator",function(a,c){return{transclude:"element",
priority:1E3,terminal:!0,compile:function(d,e,f){return function(d,e,j){var g=c(d,j),m=j.ngRepeat,k=m.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),l,q,n,s,r,p={$id:la};if(!k)throw Error("Expected ngRepeat in form of '_item_ in _collection_[ track by _id_]' but got '"+m+"'.");j=k[1];n=k[2];(k=k[4])?(l=a(k),q=function(a,c,e){r&&(p[r]=a);p[s]=c;p.$index=e;return l(d,p)}):q=function(a,c){return la(c)};k=j.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!k)throw Error("'item' in 'item in collection' should be identifier or (key, value) but got '"+
j+"'.");s=k[3]||k[1];r=k[2];var y={};d.$watchCollection(n,function(a){var c,j,k=e,l,n={},p,t,v,z,w,u,x=[];if(C(a))w=a;else{w=[];for(v in a)a.hasOwnProperty(v)&&v.charAt(0)!="$"&&w.push(v);w.sort()}p=w.length;j=x.length=w.length;for(c=0;c<j;c++)if(v=a===w?c:w[c],z=a[v],l=q(v,z,c),u=y[l])delete y[l],n[l]=u,x[c]=u;else if(n.hasOwnProperty(l))throw o(x,function(a){a&&a.element&&(y[a.id]=a)}),Error("Duplicates in a repeater are not allowed. Repeater: "+m);else x[c]={id:l};for(v in y)if(y.hasOwnProperty(v))u=
y[v],g.leave(u.element),u.element[0].$$NG_REMOVED=!0,u.scope.$destroy();c=0;for(j=w.length;c<j;c++){v=a===w?c:w[c];z=a[v];u=x[c];if(u.element){t=u.scope;l=k[0];do l=l.nextSibling;while(l&&l.$$NG_REMOVED);u.element[0]!=l&&g.move(u.element,null,k);k=u.element}else t=d.$new();t[s]=z;r&&(t[r]=v);t.$index=c;t.$first=c===0;t.$last=c===p-1;t.$middle=!(t.$first||t.$last);u.element||f(t,function(a){g.enter(a,null,k);k=a;u.scope=t;u.element=a;n[u.id]=u})}y=n})}}}}],Pd=["$animator",function(a){return function(c,
d,e){var f=a(c,e);c.$watch(e.ngShow,function(a){f[Ha(a)?"show":"hide"](d)})}}],Qd=["$animator",function(a){return function(c,d,e){var f=a(c,e);c.$watch(e.ngHide,function(a){f[Ha(a)?"hide":"show"](d)})}}],Rd=Y(function(a,c,d){a.$watch(d.ngStyle,function(a,d){d&&a!==d&&o(d,function(a,d){c.css(d,"")});a&&c.css(a)},!0)}),Sd=["$animator",function(a){return{restrict:"EA",require:"ngSwitch",controller:["$scope",function(){this.cases={}}],link:function(c,d,e,f){var i=a(c,e),h,j,g=[];c.$watch(e.ngSwitch||
e.on,function(a){for(var d=0,l=g.length;d<l;d++)g[d].$destroy(),i.leave(j[d]);j=[];g=[];if(h=f.cases["!"+a]||f.cases["?"])c.$eval(e.change),o(h,function(a){var d=c.$new();g.push(d);a.transclude(d,function(c){var d=a.element;j.push(c);i.enter(c,d.parent(),d)})})})}}}],Td=Y({transclude:"element",priority:500,require:"^ngSwitch",compile:function(a,c,d){return function(a,f,i,h){h.cases["!"+c.ngSwitchWhen]=h.cases["!"+c.ngSwitchWhen]||[];h.cases["!"+c.ngSwitchWhen].push({transclude:d,element:f})}}}),Ud=
Y({transclude:"element",priority:500,require:"^ngSwitch",compile:function(a,c,d){return function(a,c,i,h){h.cases["?"]=h.cases["?"]||[];h.cases["?"].push({transclude:d,element:c})}}}),Vd=Y({controller:["$transclude","$element",function(a,c){a(function(a){c.append(a)})}]}),Wd=["$http","$templateCache","$route","$anchorScroll","$compile","$controller","$animator",function(a,c,d,e,f,i,h){return{restrict:"ECA",terminal:!0,link:function(a,c,m){function k(){var h=d.current&&d.current.locals,k=h&&h.$template;
if(k){n.leave(c.contents(),c);l&&(l.$destroy(),l=null);n.enter(v("<div></div>").html(k).contents(),c);var k=f(c.contents()),m=d.current;l=m.scope=a.$new();if(m.controller)h.$scope=l,h=i(m.controller,h),c.children().data("$ngControllerController",h);k(l);l.$emit("$viewContentLoaded");l.$eval(o);e()}else n.leave(c.contents(),c),l&&(l.$destroy(),l=null)}var l,o=m.onload||"",n=h(a,m);a.$on("$routeChangeSuccess",k);k()}}}],Xd=["$templateCache",function(a){return{restrict:"E",terminal:!0,compile:function(c,
d){d.type=="text/ng-template"&&a.put(d.id,c[0].text)}}}],Yd=Q({terminal:!0}),Zd=["$compile","$parse",function(a,c){var d=/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w\d]*)|(?:\(\s*([\$\w][\$\w\d]*)\s*,\s*([\$\w][\$\w\d]*)\s*\)))\s+in\s+(.*)$/,e={$setViewValue:t};return{restrict:"E",require:["select","?ngModel"],controller:["$element","$scope","$attrs",function(a,c,d){var j=this,g={},m=e,k;j.databound=d.ngModel;j.init=function(a,c,d){m=a;k=d};j.addOption=function(c){g[c]=
!0;m.$viewValue==c&&(a.val(c),k.parent()&&k.remove())};j.removeOption=function(a){this.hasOption(a)&&(delete g[a],m.$viewValue==a&&this.renderUnknownOption(a))};j.renderUnknownOption=function(c){c="? "+la(c)+" ?";k.val(c);a.prepend(k);a.val(c);k.prop("selected",!0)};j.hasOption=function(a){return g.hasOwnProperty(a)};c.$on("$destroy",function(){j.renderUnknownOption=t})}],link:function(e,i,h,j){function g(a,c,d,e){d.$render=function(){var a=d.$viewValue;e.hasOption(a)?(x.parent()&&x.remove(),c.val(a),
a===""&&p.prop("selected",!0)):u(a)&&p?c.val(""):e.renderUnknownOption(a)};c.bind("change",function(){a.$apply(function(){x.parent()&&x.remove();d.$setViewValue(c.val())})})}function m(a,c,d){var e;d.$render=function(){var a=new Pa(d.$viewValue);o(c.find("option"),function(c){c.selected=w(a.get(c.value))})};a.$watch(function(){ja(e,d.$viewValue)||(e=W(d.$viewValue),d.$render())});c.bind("change",function(){a.$apply(function(){var a=[];o(c.find("option"),function(c){c.selected&&a.push(c.value)});d.$setViewValue(a)})})}
function k(e,f,h){function g(){var a={"":[]},c=[""],d,i,t,v,u;t=h.$modelValue;v=p(e)||[];var w=l?rb(v):v,z,x,A;x={};u=!1;var B,C;if(n)u=new Pa(t);else if(t===null||r)a[""].push({selected:t===null,id:"",label:""}),u=!0;for(A=0;z=w.length,A<z;A++){x[k]=v[l?x[l]=w[A]:A];d=m(e,x)||"";if(!(i=a[d]))i=a[d]=[],c.push(d);n?d=u.remove(o(e,x))!=s:(d=t===o(e,x),u=u||d);B=j(e,x);B=B===s?"":B;i.push({id:l?w[A]:A,label:B,selected:d})}!n&&!u&&a[""].unshift({id:"?",label:"",selected:!0});x=0;for(w=c.length;x<w;x++){d=
c[x];i=a[d];if(q.length<=x)t={element:D.clone().attr("label",d),label:i.label},v=[t],q.push(v),f.append(t.element);else if(v=q[x],t=v[0],t.label!=d)t.element.attr("label",t.label=d);B=null;A=0;for(z=i.length;A<z;A++)if(d=i[A],u=v[A+1]){B=u.element;if(u.label!==d.label)B.text(u.label=d.label);if(u.id!==d.id)B.val(u.id=d.id);if(u.element.selected!==d.selected)B.prop("selected",u.selected=d.selected)}else d.id===""&&r?C=r:(C=y.clone()).val(d.id).attr("selected",d.selected).text(d.label),v.push({element:C,
label:d.label,id:d.id,selected:d.selected}),B?B.after(C):t.element.append(C),B=C;for(A++;v.length>A;)v.pop().element.remove()}for(;q.length>x;)q.pop()[0].element.remove()}var i;if(!(i=t.match(d)))throw Error("Expected ngOptions in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '"+t+"'.");var j=c(i[2]||i[1]),k=i[4]||i[6],l=i[5],m=c(i[3]||""),o=c(i[2]?i[1]:k),p=c(i[7]),q=[[{element:f,label:""}]];r&&(a(r)(e),r.removeClass("ng-scope"),r.remove());f.html("");f.bind("change",
function(){e.$apply(function(){var a,c=p(e)||[],d={},g,i,j,m,r,t;if(n){i=[];m=0;for(t=q.length;m<t;m++){a=q[m];j=1;for(r=a.length;j<r;j++)if((g=a[j].element)[0].selected)g=g.val(),l&&(d[l]=g),d[k]=c[g],i.push(o(e,d))}}else g=f.val(),g=="?"?i=s:g==""?i=null:(d[k]=c[g],l&&(d[l]=g),i=o(e,d));h.$setViewValue(i)})});h.$render=g;e.$watch(g)}if(j[1]){for(var l=j[0],q=j[1],n=h.multiple,t=h.ngOptions,r=!1,p,y=v(V.createElement("option")),D=v(V.createElement("optgroup")),x=y.clone(),j=0,C=i.children(),A=C.length;j<
A;j++)if(C[j].value==""){p=r=C.eq(j);break}l.init(q,r,x);if(n&&(h.required||h.ngRequired)){var H=function(a){q.$setValidity("required",!h.required||a&&a.length);return a};q.$parsers.push(H);q.$formatters.unshift(H);h.$observe("required",function(){H(q.$viewValue)})}t?k(e,i,q):n?m(e,i,q):g(e,i,q,l)}}}}],$d=["$interpolate",function(a){var c={addOption:t,removeOption:t};return{restrict:"E",priority:100,compile:function(d,e){if(u(e.value)){var f=a(d.text(),!0);f||e.$set("value",d.text())}return function(a,
d,e){var g=d.parent(),m=g.data("$selectController")||g.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.bind("$destroy",function(){m.removeOption(e.value)})}}}}],ae=Q({restrict:"E",terminal:!0});(ca=M.jQuery)?(v=ca,y(ca.fn,{scope:za.scope,controller:za.controller,injector:za.injector,inheritedData:za.inheritedData}),fb("remove",!0),fb("empty"),fb("html")):v=P;Ia.element=
v;(function(a){y(a,{bootstrap:vb,copy:W,extend:y,equals:ja,element:v,forEach:o,injector:wb,noop:t,bind:ab,toJson:da,fromJson:tb,identity:pa,isUndefined:u,isDefined:w,isString:x,isFunction:I,isObject:L,isNumber:Za,isElement:jc,isArray:C,version:md,isDate:qa,lowercase:J,uppercase:na,callbacks:{counter:0},noConflict:gc});xa=oc(M);try{xa("ngLocale")}catch(c){xa("ngLocale",[]).provider("$locale",cd)}xa("ng",["ngLocale"],["$provide",function(a){a.provider("$compile",Hb).directive({a:od,input:dc,textarea:dc,
form:pd,script:Xd,select:Zd,style:ae,option:$d,ngBind:Ad,ngBindHtmlUnsafe:Cd,ngBindTemplate:Bd,ngClass:Dd,ngClassEven:Fd,ngClassOdd:Ed,ngCsp:Id,ngCloak:Gd,ngController:Hd,ngForm:qd,ngHide:Qd,ngInclude:Kd,ngInit:Ld,ngNonBindable:Md,ngPluralize:Nd,ngRepeat:Od,ngShow:Pd,ngSubmit:Jd,ngStyle:Rd,ngSwitch:Sd,ngSwitchWhen:Td,ngSwitchDefault:Ud,ngOptions:Yd,ngView:Wd,ngTransclude:Vd,ngModel:vd,ngList:xd,ngChange:wd,required:ec,ngRequired:ec,ngValue:zd}).directive(qb).directive(fc);a.provider({$anchorScroll:xc,
$animation:Gb,$animator:nd,$browser:zc,$cacheFactory:Ac,$controller:Dc,$document:Ec,$exceptionHandler:Fc,$filter:Tb,$interpolate:Gc,$http:Zc,$httpBackend:$c,$location:Kc,$log:Lc,$parse:Pc,$route:Sc,$routeParams:Tc,$rootScope:Uc,$q:Qc,$sniffer:Vc,$templateCache:Bc,$timeout:dd,$window:Wc})}])})(Ia);v(V).ready(function(){mc(V,vb)})})(window,document);angular.element(document).find("head").append('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none;}ng\\:form{display:block;}</style>');

View file

@ -1,184 +0,0 @@
/**
* @license AngularJS v1.1.4
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {
'use strict';
/**
* @ngdoc overview
* @name ngCookies
*/
angular.module('ngCookies', ['ng']).
/**
* @ngdoc object
* @name ngCookies.$cookies
* @requires $browser
*
* @description
* Provides read/write access to browser's cookies.
*
* Only a simple Object is exposed and by adding or removing properties to/from
* this object, new cookies are created/deleted at the end of current $eval.
*
* @example
<doc:example>
<doc:source>
<script>
function ExampleController($cookies) {
// Retrieving a cookie
var favoriteCookie = $cookies.myFavorite;
// Setting a cookie
$cookies.myFavorite = 'oatmeal';
}
</script>
</doc:source>
</doc:example>
*/
factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) {
var cookies = {},
lastCookies = {},
lastBrowserCookies,
runEval = false,
copy = angular.copy,
isUndefined = angular.isUndefined;
//creates a poller fn that copies all cookies from the $browser to service & inits the service
$browser.addPollFn(function() {
var currentCookies = $browser.cookies();
if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl
lastBrowserCookies = currentCookies;
copy(currentCookies, lastCookies);
copy(currentCookies, cookies);
if (runEval) $rootScope.$apply();
}
})();
runEval = true;
//at the end of each eval, push cookies
//TODO: this should happen before the "delayed" watches fire, because if some cookies are not
// strings or browser refuses to store some cookies, we update the model in the push fn.
$rootScope.$watch(push);
return cookies;
/**
* Pushes all the cookies from the service to the browser and verifies if all cookies were stored.
*/
function push() {
var name,
value,
browserCookies,
updated;
//delete any cookies deleted in $cookies
for (name in lastCookies) {
if (isUndefined(cookies[name])) {
$browser.cookies(name, undefined);
}
}
//update all cookies updated in $cookies
for(name in cookies) {
value = cookies[name];
if (!angular.isString(value)) {
if (angular.isDefined(lastCookies[name])) {
cookies[name] = lastCookies[name];
} else {
delete cookies[name];
}
} else if (value !== lastCookies[name]) {
$browser.cookies(name, value);
updated = true;
}
}
//verify what was actually stored
if (updated){
updated = false;
browserCookies = $browser.cookies();
for (name in cookies) {
if (cookies[name] !== browserCookies[name]) {
//delete or reset all cookies that the browser dropped from $cookies
if (isUndefined(browserCookies[name])) {
delete cookies[name];
} else {
cookies[name] = browserCookies[name];
}
updated = true;
}
}
}
}
}]).
/**
* @ngdoc object
* @name ngCookies.$cookieStore
* @requires $cookies
*
* @description
* Provides a key-value (string-object) storage, that is backed by session cookies.
* Objects put or retrieved from this storage are automatically serialized or
* deserialized by angular's toJson/fromJson.
* @example
*/
factory('$cookieStore', ['$cookies', function($cookies) {
return {
/**
* @ngdoc method
* @name ngCookies.$cookieStore#get
* @methodOf ngCookies.$cookieStore
*
* @description
* Returns the value of given cookie key
*
* @param {string} key Id to use for lookup.
* @returns {Object} Deserialized cookie value.
*/
get: function(key) {
return angular.fromJson($cookies[key]);
},
/**
* @ngdoc method
* @name ngCookies.$cookieStore#put
* @methodOf ngCookies.$cookieStore
*
* @description
* Sets a value for given cookie key
*
* @param {string} key Id for the `value`.
* @param {Object} value Value to be stored.
*/
put: function(key, value) {
$cookies[key] = angular.toJson(value);
},
/**
* @ngdoc method
* @name ngCookies.$cookieStore#remove
* @methodOf ngCookies.$cookieStore
*
* @description
* Remove given cookie
*
* @param {string} key Id of the key-value pair to delete.
*/
remove: function(key) {
delete $cookies[key];
}
};
}]);
})(window, window.angular);

View file

@ -1,7 +0,0 @@
/*
AngularJS v1.1.4
(c) 2010-2012 Google, Inc. http://angularjs.org
License: MIT
*/
(function(m,f,l){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(d,c){var b={},g={},h,i=!1,j=f.copy,k=f.isUndefined;c.addPollFn(function(){var a=c.cookies();h!=a&&(h=a,j(a,g),j(a,b),i&&d.$apply())})();i=!0;d.$watch(function(){var a,e,d;for(a in g)k(b[a])&&c.cookies(a,l);for(a in b)e=b[a],f.isString(e)?e!==g[a]&&(c.cookies(a,e),d=!0):f.isDefined(g[a])?b[a]=g[a]:delete b[a];if(d)for(a in e=c.cookies(),b)b[a]!==e[a]&&(k(e[a])?delete b[a]:b[a]=e[a])});return b}]).factory("$cookieStore",
["$cookies",function(d){return{get:function(c){return f.fromJson(d[c])},put:function(c,b){d[c]=f.toJson(b)},remove:function(c){delete d[c]}}}])})(window,window.angular);

View file

@ -1,11 +0,0 @@
/*
AngularJS v1.1.4
(c) 2010-2012 Google, Inc. http://angularjs.org
License: MIT
*/
(function(B,f,x){'use strict';f.module("ngResource",["ng"]).factory("$resource",["$http","$parse",function(y,z){function v(g,c){this.template=g+"#";this.defaults=c||{};this.urlParams={}}function w(g,c,d){function j(e,b){var p={},b=q({},c,b);k(b,function(a,b){l(a)&&(a=a());var h;a.charAt&&a.charAt(0)=="@"?(h=a.substr(1),h=z(h)(e)):h=a;p[b]=h});return p}function b(b){u(b||{},this)}var m=new v(g),d=q({},A,d);k(d,function(e,c){e.method=f.uppercase(e.method);var p=e.method=="POST"||e.method=="PUT"||e.method==
"PATCH";b[c]=function(a,c,h,g){function f(){i.$resolved=!0}var n={},d,o=r,s=null;switch(arguments.length){case 4:s=g,o=h;case 3:case 2:if(l(c)){if(l(a)){o=a;s=c;break}o=c;s=h}else{n=a;d=c;o=h;break}case 1:l(a)?o=a:p?d=a:n=a;break;case 0:break;default:throw"Expected between 0-4 arguments [params, data, success, error], got "+arguments.length+" arguments.";}var i=this instanceof b?this:e.isArray?[]:new b(d),t={};k(e,function(a,b){b!="params"&&b!="isArray"&&(t[b]=u(a))});t.data=d;m.setUrlParams(t,q({},
j(d,e.params||{}),n),e.url);n=y(t);i.$resolved=!1;n.then(f,f);i.$then=n.then(function(a){var c=a.data,h=i.$then,d=i.$resolved;if(c)e.isArray?(i.length=0,k(c,function(a){i.push(new b(a))})):(u(c,i),i.$then=h,i.$resolved=d);(o||r)(i,a.headers);a.resource=i;return a},s).then;return i};b.prototype["$"+c]=function(a,e,h){var d=j(this),f=r,g;switch(arguments.length){case 3:d=a;f=e;g=h;break;case 2:case 1:l(a)?(f=a,g=e):(d=a,f=e||r);case 0:break;default:throw"Expected between 1-3 arguments [params, success, error], got "+
arguments.length+" arguments.";}b[c].call(this,d,p?this:x,f,g)}});b.bind=function(b){return w(g,q({},c,b),d)};return b}var A={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},r=f.noop,k=f.forEach,q=f.extend,u=f.copy,l=f.isFunction;v.prototype={setUrlParams:function(g,c,d){var j=this,b=d||j.template,m,e,l=j.urlParams={};k(b.split(/\W/),function(c){c&&RegExp("(^|[^\\\\]):"+c+"(\\W|$)").test(b)&&(l[c]=!0)});b=b.replace(/\\:/g,
":");c=c||{};k(j.urlParams,function(d,a){m=c.hasOwnProperty(a)?c[a]:j.defaults[a];f.isDefined(m)&&m!==null?(e=encodeURIComponent(m).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,"+"),b=b.replace(RegExp(":"+a+"(\\W|$)","g"),e+"$1")):b=b.replace(RegExp("(/?):"+a+"(\\W|$)","g"),function(a,b,c){return c.charAt(0)=="/"?c:b+c})});g.url=b.replace(/\/?#$/,"").replace(/\/*$/,"");k(c,function(b,
a){if(!j.urlParams[a])g.params=g.params||{},g.params[a]=b})}};return w}])})(window,window.angular);

View file

@ -1,13 +0,0 @@
/*
AngularJS v1.1.4
(c) 2010-2012 Google, Inc. http://angularjs.org
License: MIT
*/
(function(I,h){'use strict';function i(a){var d={},a=a.split(","),c;for(c=0;c<a.length;c++)d[a[c]]=!0;return d}function z(a,d){function c(a,b,c,f){b=h.lowercase(b);if(m[b])for(;e.last()&&n[e.last()];)g("",e.last());o[b]&&e.last()==b&&g("",b);(f=p[b]||!!f)||e.push(b);var j={};c.replace(A,function(a,b,d,c,g){j[b]=k(d||c||g||"")});d.start&&d.start(b,j,f)}function g(a,b){var c=0,g;if(b=h.lowercase(b))for(c=e.length-1;c>=0;c--)if(e[c]==b)break;if(c>=0){for(g=e.length-1;g>=c;g--)d.end&&d.end(e[g]);e.length=
c}}var b,f,e=[],j=a;for(e.last=function(){return e[e.length-1]};a;){f=!0;if(!e.last()||!q[e.last()]){if(a.indexOf("<\!--")===0)b=a.indexOf("--\>"),b>=0&&(d.comment&&d.comment(a.substring(4,b)),a=a.substring(b+3),f=!1);else if(B.test(a)){if(b=a.match(r))a=a.substring(b[0].length),b[0].replace(r,g),f=!1}else if(C.test(a)&&(b=a.match(s)))a=a.substring(b[0].length),b[0].replace(s,c),f=!1;f&&(b=a.indexOf("<"),f=b<0?a:a.substring(0,b),a=b<0?"":a.substring(b),d.chars&&d.chars(k(f)))}else a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+
e.last()+"[^>]*>","i"),function(a,b){b=b.replace(D,"$1").replace(E,"$1");d.chars&&d.chars(k(b));return""}),g("",e.last());if(a==j)throw"Parse Error: "+a;j=a}g()}function k(a){l.innerHTML=a.replace(/</g,"&lt;");return l.innerText||l.textContent||""}function t(a){return a.replace(/&/g,"&amp;").replace(F,function(a){return"&#"+a.charCodeAt(0)+";"}).replace(/</g,"&lt;").replace(/>/g,"&gt;")}function u(a){var d=!1,c=h.bind(a,a.push);return{start:function(a,b,f){a=h.lowercase(a);!d&&q[a]&&(d=a);!d&&v[a]==
!0&&(c("<"),c(a),h.forEach(b,function(a,b){var d=h.lowercase(b);if(G[d]==!0&&(w[d]!==!0||a.match(H)))c(" "),c(b),c('="'),c(t(a)),c('"')}),c(f?"/>":">"))},end:function(a){a=h.lowercase(a);!d&&v[a]==!0&&(c("</"),c(a),c(">"));a==d&&(d=!1)},chars:function(a){d||c(t(a))}}}var s=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,r=/^<\s*\/\s*([\w:-]+)[^>]*>/,A=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,C=/^</,B=/^<\s*\//,D=/<\!--(.*?)--\>/g,
E=/<!\[CDATA\[(.*?)]]\>/g,H=/^((ftp|https?):\/\/|mailto:|tel:|#)/,F=/([^\#-~| |!])/g,p=i("area,br,col,hr,img,wbr"),x=i("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),y=i("rp,rt"),o=h.extend({},y,x),m=h.extend({},x,i("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")),n=h.extend({},y,i("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var")),
q=i("script,style"),v=h.extend({},p,m,n,o),w=i("background,cite,href,longdesc,src,usemap"),G=h.extend({},w,i("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,span,start,summary,target,title,type,valign,value,vspace,width")),l=document.createElement("pre");h.module("ngSanitize",[]).value("$sanitize",function(a){var d=[];
z(a,u(d));return d.join("")});h.module("ngSanitize").directive("ngBindHtml",["$sanitize",function(a){return function(d,c,g){c.addClass("ng-binding").data("$binding",g.ngBindHtml);d.$watch(g.ngBindHtml,function(b){b=a(b);c.html(b||"")})}}]);h.module("ngSanitize").filter("linky",function(){var a=/((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/,d=/^mailto:/;return function(c,g){if(!c)return c;var b,f=c,e=[],j=u(e),i,k,l={};if(h.isDefined(g))l.target=g;for(;b=f.match(a);)i=
b[0],b[2]==b[3]&&(i="mailto:"+i),k=b.index,j.chars(f.substr(0,k)),l.href=i,j.start("a",l),j.chars(b[0].replace(d,"")),j.end("a"),f=f.substring(k+b[0].length);j.chars(f);return e.join("")}})})(window,window.angular);

View file

@ -1,43 +0,0 @@
define(['knockout', 'postbox', 'mapping', 'global', 'utils', 'model', 'player', 'jquery.layout', 'jquery.dateFormat'], function (ko, postbox, mapping, global, utils, model, player) {
return function () {
self.selectSong = function (data, event) {
if (self.selectedSongs.indexOf(this) >= 0) {
self.selectedSongs.remove(this);
this.selected(false);
} else {
self.selectedSongs.push(this);
this.selected(true);
}
}
self.addSongsToQueue = function (data, event) {
ko.utils.arrayForEach(self.selectedSongs(), function (item) {
self.queue.push(item);
item.selected(false);
});
utils.updateMessage(self.selectedSongs().length + ' Song(s) Added to Queue', true);
}
self.openLink = function (data, event) {
return true;
}
self.selectAll = function (data, event) {
ko.utils.arrayForEach(self.song(), function (item) {
self.selectedSongs.push(item);
item.selected(true);
});
}
self.selectNone = function (data, event) {
ko.utils.arrayForEach(self.song(), function (item) {
self.selectedSongs([]);
item.selected(false);
});
}
}
});

View file

@ -1,15 +0,0 @@
<!doctype html>
<html lang="en" ng-app="JamStash">
<head>
<meta charset="utf-8">
<title>Contact Manager</title>
</head>
<body ng-controller="AppCtrl">
<h1>AngularJS Contact Manager</h1>
[<a href="#/">index</a>]
<div ng-view></div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<script src="app.js"></script>
<script src="controllers.js"></script>
</body>
</html>

View file

@ -1,592 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
<title>Jamstash</title>
<link href="images/favicon_32x32.ico" rel="shortcut icon" />
<link rel="icon" href="images/favicon_48x48.png" sizes="48x48"/>
<link rel="icon" href="images/favicon_32x32.png" sizes="32x32"/>
<link href="style/Style.css" rel="stylesheet" type="text/css" data-name="main" />
<link href="" rel="stylesheet" type="text/css" data-name="theme" />
<link href="js/plugins/jquery.layout-default.css" rel="stylesheet" type="text/css" />
<link href="js/plugins/fancybox/jquery.fancybox.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" data-main="js/main" src="js/plugins/require.js"></script>
</head>
<body data-bind="event: { keydown: $root.scrollToIndex }">
<div id="container">
<div id="header">
<div id="messages"></div>
<div id="loading"></div>
<div id="nav">
<ul class="tabs">
<li><a href="#tabQueue" title="Play Queue" data-bind="click: $root.changeTab.bind($data, 'tabQueue'), css: { active: $root.activeTab() === 'tabQueue' } "><img src="images/play_alt_gd_16x16.png" /></a></li>
<li><a href="#tabLibrary" class="first" title="Library" data-bind="click: $root.changeTab.bind($data, 'tabLibrary'), css: { active: $root.activeTab() === 'tabLibrary' } "><img src="images/headphones_gd_16x14.png" /></a></li>
<li><a href="#tabArchive" class="first" title="Archive.org" data-bind="click: $root.changeTab.bind($data, 'tabArchive'), css: { active: $root.activeTab() === 'tabArchive' } "><img src="images/archive_gd_16x16.png" /></a></li>
<!--<li><a href="#tabPlaylists" title="Playlists"><img src="images/list_gd_16x14.png" /></a></li>-->
<!--<li><a href="#tabVideos" id="action_tabVideos" title="Videos"><img src="images/movie_gd_16x16.png" /></a></li>-->
<li><a href="#tabSettings" class="last" title="Settings" data-bind="click: $root.changeTab.bind($data, 'tabSettings'), css: { active: $root.activeTab() == 'tabSettings' } "><img src="images/cog_16x16.png" /></a></li>
</ul>
</div>
</div>
<div id="content">
<!-- Start: Library Tab -->
<div id="tab1" class="tabcontent" data-bind="visible: activeTab() == 'tabLibrary', stopBinding: true">
<div id="tabLibrary">
<a id="logo" target="_blank" data-bind="attr: { href: settings.Server(), title: settings.Server() }"></a>
<div id="search">
<input type="text" id="Search" class="medium" title="Wildcards (*) supported" data-bind="returnKey: $root.search"/>
<select id="SearchType" name="SearchType">
<option value="album">Album</option>
<option value="song">Song</option>
</select>
<a href="#" class="button" id="action_Search" title="Search" data-bind="click: $root.search"><img class="pad" src="images/magnifying_glass_alt_12x12.png" /></a>
</div>
<div class="actions floatleft">
<a href="#" class="button" id="action_RefreshArtists" title="Refresh Artist List" data-bind="click: $root.getArtists"><img class="pad" src="images/reload_9x11.png" /></a>
<a href="#" class="button" id="action_RescanLibrary" title="Rescan Library" data-bind="click: $root.rescanLibrary"><img class="pad" src="images/loop_alt1_gd_12x9.png" /></a>
</div>
<div class="subactions floatleft">
<a href="#" class="button" id="action_SelectAll" title="Select All" data-bind="click: $root.selectAll">All</a>
<a href="#" class="button" id="action_SelectNone" title="Select None" data-bind="click: $root.selectNone">None</a>
<a href="#" class="button" id="action_AddToQueue" title="Add To Play Queue" data-bind="click: $root.addSongsToQueue">+ Queue</a>
<a href="#" class="button" id="action_AddToPlaylist" title="Add Selected To Playlist" data-bind="click: $root.addSongsToPlaylist">+ Playlist</a>
<div id="submenu_AddToPlaylist" class="submenu shadow" style="display: none;" data-bind="foreach: playlistMenu">
<a href="#" data-bind="attr: { id: id }, html: name, click: $root.addToPlaylist"></a><br />
</div>
</div>
<div class="clear"></div>
<div id="SubsonicAlbums" class="section lgsection">
<div id="SubsonicArtists" class="ui-layout-west noselect hide" tabindex="0">
<div class="accordion">
<div class="accordionItem">
<div class="accordionItemTitle" id="libraryAccordion" data-bind="click: $root.toggleAccordion.bind($data, 'libraryAccordion')"><img src="images/headphones_gd_16x14.png" /> Library</div>
<div class="accordionItemContents">
<select id="MusicFolders" class="folders" data-bind="options: MusicFolders, optionsText: 'text', optionsValue: 'value', value: $root.selectedMusicFolders, optionsCaption: 'All Folders'"></select>
<ul id="AutoAlbumContainer" class="simplelist mainlist noselect">
<li class="index" id="auto">Auto Albums</li>
<!-- ko foreach: AutoAlbums -->
<li class="item" data-bind="attr: { id: id }, click: $root.getAlbumListBy.bind($data, 0), css: { selected: $data === $root.selectedAutoAlbum() }"><span data-bind="text: name"></span>
<div class="floatright">
<a href="#" class="nextprev hover" id="random" title="Previous" data-bind="click: $root.getAlbumListBy.bind($data, $root.offset() - parseInt(settings.AutoAlbumSize())), clickBubble: false">&lsaquo;</a>
<a href="#" class="nextprev hover" id="random" title="Next" data-bind="click: $root.getAlbumListBy.bind($data, $root.offset() + parseInt(settings.AutoAlbumSize())), clickBubble: false">&rsaquo;</a>
</div>
</li>
<!-- /ko -->
</ul>
<ul class="simplelist mainlist noselect">
<li class="index" title="Scroll to Top" data-bind="click: $root.scrollToTop"><a>Shortcuts</a></li>
<ul class="simplelist mainlist noselect" data-bind="foreach: shortcut">
<li class="item" data-bind="attr: { id: id }, click: $root.getAlbums, css: { selected: $data === $root.selectedArtist() }"><span data-bind="html: name"></span></li>
</ul>
</ul>
<div id="AZContainer" class="subactionsfixed">
<a href="" data-bind="click: $root.toggleAZ, clickBubble: false">A-Z</a>
</div>
<div id="submenu_AZIndex" class="submenu shadow" style="display: none;"><ul data-bind="foreach: index"><li><a data-bind="text: name, click: $root.scrollToIndex, clickBubble: false"></a></li></ul></div>
<ul class="simplelist mainlist noselect" data-bind="foreach: index">
<li class="index" title="Scroll to Top" data-bind="attr: { id: name }, click: $root.scrollToTop"><a data-bind="text: name"></a><span class="floatright"></span></li>
<ul class="simplelist mainlist noselect" data-bind="foreach: artist">
<li class="item" data-bind="attr: { id: id }, click: $root.getAlbums, css: { selected: $data === $root.selectedArtist() }"><span data-bind="html: name"></span></li>
</ul>
</ul>
</div>
</div>
<div class="accordionItem">
<div class="accordionItemTitle" id="playlistsAccordion" data-bind="click: $root.toggleAccordion.bind($data, 'playlistsAccordion')"><img src="images/list_gd_16x14.png" /> Playlists</div>
</div>
<div class="accordionItem">
<div class="accordionItemTitle" id="podcastsAccordion" data-bind="click: $root.toggleAccordion.bind($data, 'podcastsAccordion')"><img src="images/rss_16x16.png" /> Podcasts</div>
</div>
<div class="accordionItem">
<div class="accordionItemTitle" id="archiveAccordion" data-bind="click: $root.toggleAccordion.bind($data, 'archiveAccordion')"><img src="images/archive_gd_16x16.png" /> Archive.org</div>
</div>
</div>
</div>
<div class="ui-layout-center">
<div data-bind="templateWithContext: { name: $root.templateToUse(), data: $root.album, context: { flag: 'subsonic' } }"></div>
</div>
<div class="ui-layout-east noselect hide">
<ul class="simplelist songlist" data-bind="template: { name: 'song-template', foreach: $root.song }"></ul>
</div>
</div>
</div>
<div class="clear"></div>
</div>
<!-- End: Library Tab -->
<!-- Start: Archive.org Tab -->
<div id="tab2" class="tabcontent" data-bind="visible: activeTab() === 'tabArchive', stopBinding: true">
<div id="tabArchive">
<div class="actions floatleft">
<a href="#" class="button" id="action_RefreshArtists" title="Refresh Artist List"><img class="pad" src="images/reload_9x11.png" /></a>
</div>
<div class="subactions floatleft">
<a href="#" class="button" id="action_SelectAll" title="Select All" data-bind="click: $root.selectAll">All</a>
<a href="#" class="button" id="action_SelectNone" title="Select None" data-bind="click: $root.selectNone">None</a>
<a href="#" class="button" id="action_AddToQueue" title="Add To Play Queue" data-bind="click: $root.addSongsToQueue">+ Queue</a>
</div>
<div class="clear"></div>
<div id="ArchiveAlbums" class="section lgsection">
<div class="ui-layout-west" tabindex="0">
<select class="large" id="Collections" data-bind="event: { change: $root.selectedCollectionChange }, options: AllCollections, optionsCaption: '[Select Collection]'"></select><br />
<ul class="simplelist mainlist noselect" data-bind="foreach: artist">
<li class="item" data-bind="attr: { id: id }, click: $root.getAlbums.bind($data, 'collection'), css: { selected: $data === $root.selectedArtist() }"><span data-bind="text: name"></span></li>
</ul>
</div>
<div class="ui-layout-center">
<ul class="actionlist">
<li>
<select data-bind="options: ArchiveAlbumSort, value: $root.selectedArchiveAlbumSort"></select>
<select id="Years" data-bind="options: Years, value: $root.selectedYear, optionsCaption: '[Year]'"></select>
<input type="text" id="Source" name="Source" class="m" data-bind="value: $root.selectedSource" placeholder="Source" title="Source"/>
<input type="text" id="Description" name="Source" class="mlg" data-bind="value: $root.selectedDescription" placeholder="Description" title="Description"/>
</li>
</ul>
<ul class="simplelist songlist noselect" data-bind="templateWithContext: { name: 'album-template', data: $root.album, context: { flag: 'archive' } }"></ul>
</div>
<div class="ui-layout-east noselect">
<ul class="simplelist songlist" data-bind="template: { name: 'song-template', foreach: $root.song }"></ul>
</div>
</div>
</div>
<div class="clear"></div>
</div>
<!-- End: Archive.org Tab -->
<!-- Templates -->
<script type="text/html" id="album-template">
<!-- ko if: flag != 'archive' -->
<ul class="actionlist">
<li><select data-bind="options: $root.SubsonicSort, value: $root.selectedSubsonicAlbumSort"></select></li>
</ul>
<!-- /ko -->
<ul class="simplelist songlist noselect">
<!-- ko foreach: $data -->
<li class="album" userrating="undefined" data-bind="attr: { id: id, parentid: parentid }, click: $root.getSongs.bind($data, id(), ''), css: { selected: $data === $root.selectedAlbum() }">
<div class="albumlink"><a href="" data-bind="attr: { href: url, title: url }, visible: ($parent.flag == 'archive'), click: $root.openLink, clickBubble: false" target="_blank">Source</a></div>
<div class="itemactions">
<a class="add" href="" title="Add To Play Queue" data-bind="click: $root.getSongs.bind($data, id(), 'add'), clickBubble: false"></a>
<a class="play" href="" title="Play" data-bind="click: $root.getSongs.bind($data, id(), 'play'), clickBubble: false"></a>
<a class="download" href="" title="Download"></a>
<a href="" title="Favorite" data-bind="css: { favorite: starred(), rate: !starred() }, click: $root.updateFavorite, clickBubble: false"></a>
</div>
<div class="albumart"><img data-bind="attr: { src: coverart }" src="images/albumdefault_50.jpg"></div>
<div class="title" data-bind="html: name"></div>
<div class="artist"><a href="#" data-bind="attr: { id: parentid }, html: artist, click: $root.getAlbums, clickBubble: false"></a></div>
<div class="details" data-bind="text: 'Created: ' + date()"></div>
<div class="description shadow" data-bind="html: description, visible: ($parent.flag == 'archive' && $data === $root.selectedAlbum())"></div>
<div class="clear"></div>
</li>
<!-- /ko -->
</ul>
</script>
<script type="text/html" id="podcast-template">
<ul class="simplelist songlist" >
<!-- ko foreach: $data -->
<li class="album" userrating="undefined" data-bind="attr: { id: id, parentid: parentid }, click: $root.getPodcast.bind($data, ''), css: { selected: $data === $root.selectedAlbum() }">
<div class="itemactions">
<a class="add" href="" title="Add To Play Queue" data-bind="click: $root.getPodcast.bind($data, 'add'), clickBubble: false"></a><a class="play" href="" title="Play" data-bind="click: $root.getPodcast.bind($data, 'play'), clickBubble: false"></a>
</div>
<div class="albumart"><img data-bind="attr: { src: coverart }" src="images/albumdefault_50.jpg"></div>
<div class="title" data-bind="html: name"></div>
<div class="clear"></div>
</li>
<!-- /ko -->
</ul>
</script>
<script type="text/html" id="playlist-template">
<ul class="actionlist">
<li>
<a href="#" class="button" id="action_NewPlaylist" title="New Playlist" data-bind="click: $root.newPlaylist">+ New</a>
<a href="#" class="button" id="action_DeletePlaylist" title="Delete Selected Playlist" data-bind="click: $root.deletePlaylist">Delete</a>
<a href="#" class="button" id="action_SavePlaylist" title="Save Playlist" data-bind="click: $root.savePlaylist">Save</a>
<a href="#" class="button" id="action_RemoveSongs" title="Remove selected song(s) from playlist" data-bind="click: $root.removeSelectedSongs">Remove Song(s)</a>
</li>
</ul>
<ul class="simplelist"><li class="index" id="auto">Auto Playlists</li></ul>
<ul class="simplelist songlist">
<li class="album">
<div class="itemactions">
<a class="add" href="" title="Add To Play Queue"></a><a class="play" href="" title="Play"></a>
</div>
<div class="albumart"><img src="images/albumdefault_50.jpg"></div>
<div class="title">Starred</div>
<div class="clear"></div>
</li>
<li class="album" data-bind="click: $root.getRandomSongs.bind($data, '', '', '')">
<div class="itemactions">
<a class="add" href="" title="Add To Play Queue" data-bind="click: $root.getRandomSongs.bind($data, 'add', '', ''), clickBubble: false"></a><a class="play" href="" title="Play" data-bind="click: $root.getRandomSongs.bind($data, 'play', '', ''), clickBubble: false"></a>
</div>
<div class="albumart"><img src="images/albumdefault_50.jpg"></div>
<div class="title">Random</div>
<div class="clear"></div>
</li>
</ul>
<ul class="simplelist"><li class="index" id="folder">Folder Playlists</li></ul>
<ul class="simplelist songlist" data-bind="foreach: $root.MusicFolders">
<li class="album" data-bind="click: $root.getRandomSongs.bind($data, '', '', value())">
<div class="itemactions">
<a class="add" href="" title="Add To Play Queue" data-bind="click: $root.getRandomSongs.bind($data, 'add', '', value()), clickBubble: false"></a><a class="play" href="" title="Play" data-bind="click: $root.getRandomSongs.bind($data, 'play', '', value()), clickBubble: false"></a>
</div>
<div class="albumart"><img src="images/albumdefault_50.jpg"></div>
<div class="title" data-bind="html: text"></div>
<div class="clear"></div>
</li>
</ul>
<ul class="simplelist"><li class="index" id="auto">Saved Playlists</li></ul>
<ul class="simplelist songlist" >
<!-- ko foreach: $data -->
<li class="album" userrating="undefined" data-bind="attr: { id: id, parentid: parentid }, click: $root.getPlaylist.bind($data, id(), ''), css: { selected: $data === $root.selectedPlaylist() }">
<div class="itemactions">
<a class="add" href="" title="Add To Play Queue" data-bind="click: $root.getPlaylist.bind($data, id(), 'add'), clickBubble: false"></a><a class="play" href="" title="Play" data-bind="click: $root.getPlaylist.bind($data, id(), 'play'), clickBubble: false"></a>
</div>
<div class="albumart"><img data-bind="attr: { src: coverart }" src="images/albumdefault_50.jpg"></div>
<div class="title" data-bind="html: name"></div>
<div class="clear"></div>
</li>
<!-- /ko -->
</ul>
</script>
<script type="text/html" id="song-template">
<li class="row song" data-bind="attr: { id: id, parentid: parentid, title: description }, css: { selected: selected, playing: playing }, event: { dblclick: playSong.bind($data, false), click: $root.selectSong } ">
<div class="itemactions">
<a class="add" href="" title="Add To Play Queue"></a>
<a class="remove" href="" title="Remove"></a>
<a class="play" href="" title="Play" data-bind="click: $root.addFromPlayedToQueue, clickBubble: false"></a><a class="download" href="" title="Download"></a>
<a href="" title="Favorite" data-bind="css: { favorite: starred(), rate: !starred() }, click: $root.updateFavorite, clickBubble: false"></a>
<div class="clear"></div>
</div>
<div class="track floatleft" data-bind="html: track"></div>
<div class="title floatleft" data-bind="html: name"></div>
<a href="#" class="albumblock floatleft" data-bind="attr: { id: parentid }, html: album, click: $root.getSongs.bind($data, parentid(), ''), clickBubble: false"></a>
<div class="time floatleft" data-bind="text: time"></div>
<div class="clear"></div>
</li>
</script>
<!-- Start: Queue Tab -->
<div id="tabQueue" class="tabcontent" data-bind="visible: activeTab() == 'tabQueue'">
<div class="actions floatleft">
<a href="" class="button" title="Shuffle" data-bind="click: $root.queueShuffle"><img src="images/fork_gd_11x12.png" /></a>
<a href="#" class="button" id="action_CurrentSelectAll" title="Select All" data-bind="click: $root.selectAll">All</a>
<a href="#" class="button" id="action_CurrentSelectNone" title="Select None" data-bind="click: $root.selectNone">None</a>
<a href="#" class="button" id="action_CurrentRemoveSongs" title="Remove selected song(s) from Play Queue" data-bind="click: $root.removeSelectedSongs">Remove Song(s)</a>
<a href="#" class="button" id="action_Empty" title="Remove All" data-bind="click: $root.emptyQueue">Empty</a>
<a href="#" class="button" id="action_AddCurrentToPlaylist" title="Add Selected To Playlist">+ Playlist</a>
<div id="submenu_AddCurrentToPlaylist" class="submenu shadow" style="display: none;"></div>
</div>
<div id="Queue" class="section fullsection floatleft noselect">
<ul class="simplelist songlist" data-bind="foreach: queue">
<li class="row song" artistid="204" duration="194" userrating="undefined" data-bind="attr: { id: id, parentid: parentid }, css: { selected: selected, playing: playing }, event: { dblclick: playSong.bind($data, false), click: $root.selectSong } ">
<div class="itemactions">
<a class="remove" href="" title="Remove"></a><a class="play" href="" title="Play"></a><a class="download" href="" title="Download"></a><a class="rate" href="" title="Add To Favorites"></a>
<div class="clear"></div>
</div>
<div class="track floatleft" data-bind="html: track"></div>
<div class="title floatleft" data-bind="html: name"></div>
<div class="albumblock floatleft">
<img class="floatleft" data-bind="attr: { src: coverartthumb }" src="images/albumdefault_25.jpg" />
<div class="albumtext floatleft" data-bind="html: album"></div>
<div class="artist floatleft" data-bind="html: '[' + artist() + ']'"></div>
</div>
<div class="time floatleft" data-bind="text: time"></div>
<div class="clear"></div>
</li>
</ul>
</div>
<div id="status_Current" class="status" data-bind="text: $root.queueTotal"></div>
<div class="clear"></div>
</div>
<!-- End: Queue Tab -->
<!-- Start: Playlist Tab -->
<div id="tabPlaylists" class="tabcontent" data-bind="visible: activeTab() == 'tabPlaylists', stopBinding: true">
<div class="actions floatleft">
<a href="#" class="button" id="action_RefreshPlaylists" title="Refresh Playlists"><img class="pad" src="images/reload_9x11.png" /></a>
<a href="#" class="button" id="action_NewPlaylist" title="New Playlist">+ New</a>
</div>
<div id="playlistActions" class="subactions floatleft">
<a href="#" class="button" id="action_DeletePlaylist" title="Delete Selected Playlist">Delete</a>
<a href="#" class="button" id="action_SavePlaylist" title="Save Playlist">Save</a>
<a href="#" class="button" id="action_RemoveSongs" title="Remove selected song(s) from playlist">Remove Song(s)</a>
</div>
<div class="clear"></div>
<div id="Tracks" class="section lgsection floatleft noselect">
<div id="Playlists" class="smsection floatleft noselect">
<div class="padder">
<ul class="simplelist"><li class="index">Auto Playlists</li></ul>
<ul id="AutoPlaylistContainer" class="simplelist mainlist"></ul>
<ul class="simplelist"><li class="index">Folder Playlists</li></ul>
<ul id="FolderContainer" class="simplelist mainlist"></ul>
<ul class="simplelist"><li class="index">Saved Playlists</li></ul>
<ul id="PlaylistContainer" class="simplelist mainlist"></ul>
</div>
</div>
<div class="tablecontainer">
<table id="TrackContainer" class="simplelist songlist">
<thead></thead>
<tbody></tbody>
</table>
</div>
</div>
<div id="status_Playlists" class="status">0 song(s), 00:00:00 total time</div>
</div>
<!-- End: Playlist Tab -->
<!-- Start: Video Tab -->
<div id="tabVideos" class="tabcontent" data-bind="visible: activeTab() == 'tabVideos', stopBinding: true">
<div class="actions floatleft">
<a href="#" class="button" id="action_RefreshVideos" title="Refresh Videos"><img class="pad" src="images/reload_9x11.png" /></a>
</div>
<div class="subactions floatleft"><span class="alert">***Opens new window to the video URL...</span>
</div>
<div id="Videos" class="section fullsection floatleft noselect">
<div class="tablecontainer">
<table id="VideosContainer" class="simplelist songlist" cellspacing="1">
<thead></thead>
<tbody></tbody>
</table>
</div>
<div id="videodeck"></div>
<div id="videooverlay" class="darkoverlay"></div>
</div>
</div>
<!-- End: Video Tab -->
<div class="clear"></div>
</div>
<div id="tabSettings" class="tabcontent" data-bind="visible: activeTab() === 'tabSettings'">
<div class="section fullsection floatleft">
<form class="form" id="Settings" action="#" method="post">
<div class="subsection floatleft">
<h3 class="title">Login</h3>
<label for="Username">Username <span class="red">*</span></label><br />
<input type="text" id="Username" name="Username" class="large" data-bind="value: settings.Username"/><br />
<label for="Password">Password <span class="red">*</span></label><br />
<input type="password" id="Password" name="Password" class="large" data-bind="value: settings.Password"/><br />
<label for="Server">Server <span class="red">*</span> (<a href="" title="Connect to Demo Subsonic Server" data-bind="click: $root.setupDemo">Demo</a>)</label><br />
<input type="text" id="Server" name="Server" class="xlarge" title="Subsonic Server URL Ex: http://host:port/subsonic" data-bind="value: settings.Server"/><br />
<!--<a href="#" class="button" id="action_RequestURL" title="Request Permission for Server URL">Enable URL</a><br />-->
<label for="SubsonicVersion">Subsonic API: <span class="apiversion" id="SubsonicVersion" data-bind="text: settings.ApiVersion"></span></label><br />
<label for="SMStats">Audio State: <span id="SMStats"></span></label><br /><br />
<h3 class="title">Archive.org Settings</h3>
<label for="Collections">Saved Collections (<a href="" title="Load Example Collections?" data-bind="click: $root.setupDemoCollections">Demo</a>)</label><br />
<input type="text" id="SavedCollections" name="SavedCollections" class="large" title="Comma separated list of Collections" data-bind="value: settings.SavedCollections"/><br />
<br />
<a id="action_Welcome" href="#welcome">Launch Welcome</a>
<div id="welcome"><h2>Welcome</h2></div>
</div>
<div class="subsection floatleft">
<h3 class="title">Options</h3>
<label for="Theme">Theme</label><br />
<select id="Theme" name="Theme" class="large" data-bind="options: settings.Themes, value: settings.Theme"></select><br />
<label for="AutoPlaylists">Genres</label><br />
<select id="Genres" name="Genres" class="large"></select><br />
<input type="text" id="AutoPlaylists" name="AutoPlaylists" class="large" title="Comma separated list of genres for Auto Playlists" data-bind="value: settings.AutoPlaylists"/><br />
<!--<label for="AutoFilter">Filter</label><br />
<input type="text" id="AutoFilter" name="AutoFilter" class="large" title="Comma separated list of albums for the AutoPilot Filter"/><br />-->
<label for="AutoAlbumSize">Auto Album Size</label><br />
<input type="text" id="AutoAlbumSize" name="AutoAlbumSize" class="large" title="Number of Albums to Get on the Music Library tab" data-bind="value: settings.AutoAlbumSize"/><br />
<label for="AutoPlaylistSize">Auto Playlist Size</label><br />
<input type="text" id="AutoPlaylistSize" name="AutoPlaylistSize" class="large" title="Number of Songs to Get on the Playlist tab" data-bind="value: settings.AutoPlaylistSize"/><br />
<label for="ApplicationName">Application Name</label><br />
<input type="text" id="ApplicationName" name="ApplicationName" class="large" title="Custom Player Name" data-bind="value: settings.ApplicationName"/><br />
</div>
<div class="subsection floatleft">
<div class="checkboxes">
<fieldset>
<legend class="aligncenter">General</legend>
<div class="inputwrap"><input type="checkbox" id="AutoPlay" name="AutoPlay" value="1" title="When the Queue has ended, load random songs" data-bind="checked: settings.AutoPlay"/></div>
<label for="AutoPlay">Auto Play</label>
<div class="clear"></div>
<div class="inputwrap"><input type="checkbox" id="LoopQueue" name="LoopQueue" value="1" title="When the Queue has ended, start from beginning" data-bind="checked: settings.LoopQueue"/></div>
<label for="LoopQueue">Loop Queue</label>
<div class="clear"></div>
<div class="inputwrap"><input type="checkbox" id="HideAZ" name="HideAZ" value="1" title="Hide A-Z at Bottom of Artists (Tablet/Touch friendly feature)" data-bind="checked: settings.HideAZ"/></div>
<label for="HideAZ">Hide A-Z</label>
<div class="clear"></div>
<div class="inputwrap"><input type="checkbox" id="ScrollTitle" name="ScrollTitle" value="1" title="Scroll the Title Once" data-bind="checked: settings.ScrollTitle"/></div>
<label for="ScrollTitle">Scroll Title</label>
</fieldset>
<div class="clear"></div>
<fieldset>
<legend class="aligncenter">Advanced</legend>
<div class="inputwrap"><input type="checkbox" id="Debug" name="Debug" value="1" title="Enable Debug Mode (Events will be logged to the Javascript Console)" data-bind="checked: settings.Debug"/></div>
<label for="Debug">Debug Mode</label>
<div class="clear"></div>
<div class="inputwrap"><input type="checkbox" id="ForceFlash" name="ForceFlash" value="1" title="Force Flash Plugin for Audio (Option doesn't work with Chrome App)" data-bind="checked: settings.ForceFlash"/></div>
<label for="ForceFlash">Force Flash </label>
<div class="clear"></div>
<label for="Protocol">Protocol</label><br />
<select id="Protocol" name="Protocol" class="" data-bind="options: settings.Protocols, value: settings.Protocol" title="Enable Cross-Domain AJAX Requests (Use if hosted in a different domain than Subsonic)"></select>
</fieldset>
<div class="clear"></div>
<fieldset>
<legend class="aligncenter">HTML5 [Beta]</legend>
<span>Notifications</span><br />
<div class="clear"></div>
<div class="inputwrap"><input type="checkbox" id="NotificationSong" name="NotificationSong" value="1" title="Enable Notifications When Tracks Change" data-bind="checked: settings.NotificationSong"/></div>
<label for="Notification_Song">Song Change</label>
<div class="clear"></div>
<div class="inputwrap"><input type="checkbox" id="NotificationNowPlaying" name="NotificationNowPlaying" value="1" title="Enable Notifications When Other Users Play Songs" data-bind="checked: settings.NotificationNowPlaying"/></div>
<label for="Notification_Song">Now Playing</label>
<div class="clear"></div>
<span>Local Storage</span><br />
<div class="clear"></div>
<div class="inputwrap"><input type="checkbox" id="SaveTrackPosition" name="SaveTrackPosition" value="1" title="Saves Play Queue & Track Position Periodically (Uses HTML5: localStorage)" data-bind="checked: settings.SaveTrackPosition"/></div>
<label for="SaveTrackPosition">Save Progress</label>
</fieldset>
</div>
<div class="clear"></div>
</div>
<div class="clear"></div>
<div class="subsection floatleft"><small><i>*All settings will be automatically saved</i></small></div>
</form>
<div class="subsection floatleft">
<h3 class="title">Tips</h3>
<ul class="preferences">
<li>Click the Notification to quickly Skip the Song</li>
<li>Click <img src="images/play_gl_6x8.png" /> on a song to play the rest of the album</li>
</ul>
<h3 class="title">Keyboard Shortcuts</h3>
<ul class="preferences">
<!--<li><em>[1-6]</em> Switch to corresponding tab</li>-->
<li><em>[a-z]</em> Use to Quickly Browse to an Artist</li>
<li><em>Home</em> Scroll to Top of Artist List</li>
<li><em>Spacebar</em> Play/Pause</li>
<li><em>&rarr;</em> Next Track</li>
<li><em>&larr;</em> Previous Track</li>
<li><em>-/_</em> Volume Down <em>=/+</em> Volume Up</li>
<li><em>Media Keys</em> via <a href="https://chrome.google.com/webstore/detail/swayfm-unified-music-medi/icckhjgjjompfgoiidainoapgjepncej" target="_blank">Sway.fm Unified Music Media Keys</a></li>
</ul>
<div id="donate" class="subsection floatleft">
<h3 class="title">Buy me a <span class="beer">beer</span>! I'd like that :)</h3>
<form id="paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="VMTENRSJWQ234">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
<small>*This is a donation to <a href="https://twitter.com/tsquillario" target="_blank">tsquillario</a>, the developer of <a href="https://github.com/tsquillario/Jamstash" target="_blank">Jamstash</a>.
<br />Not related to a Subsonic License!</small>
</div>
</div>
<div class="clear"></div>
<div class="subsection floatleft">
<h3 class="title">Change Log</h3>
<ul id="ChangeLog" class="preferences" data-bind="foreach: $root.changeLog">
<li class="log"><span class="version" data-bind="text: date + ' - ' + version"></span>
<!-- ko foreach: changes -->
<span class="changes" data-bind="html: text"></span>
<!-- /ko -->
</li>
</ul>
<a href="#" data-bind="click: changeLogShowMore">Show More</a>
</div>
<div class="clear"></div>
<div class="subsection floatleft">
<h3 class="title">Links</h3>
<ul class="preferences">
<li>GitHub Repo - <a href="https://github.com/tsquillario/Jamstash" target="_blank">https://github.com/tsquillario/Jamstash</a></li>
<li>Jamstash Chrome App - <a href="https://chrome.google.com/webstore/detail/jccdpflnecheidefpofmlblgebobbloc" target="_blank">Chrome Web Store</a></li>
<li><a href="https://twitter.com/tsquillario" target="_blank">Follow @tsquillario</a>
</ul>
<h3 class="title">Thanks</h3>
<ul class="preferences">
<li>Icons - <a href="http://somerandomdude.com/work/iconic" target="_blank">http://somerandomdude.com/work/iconic</a></li>
<li>Audio Library - <a href="http://jplayer.org" target="_blank">http://jplayer.org</a></li>
</ul>
</div>
</div>
<div class="clear"></div>
</div>
<div id="SideBar">
<div id="NowPlaying">
<div class="header"><img src="images/rss_12x12.png" /> Now Playing</div>
<div id="NowPlayingList"><span class="user">Loading...</span></div>
</div>
<div id="Chat">
<div class="header"><img src="images/chat_alt_stroke_12x12.png" /> Chat</div>
<div id="ChatMsgs"></div>
</div>
<div class="submit"><img src="images/comment_stroke_gl_12x11.png" /><input type="text" id="ChatMsg" class="chat" title="Hit [Enter] to Post" /></div>
</div>
<!-- Audio Player -->
<div class="clear"></div>
<div class="clear"></div>
<div id="player">
<div id="playerleft" class="floatleft">
<div class="playeractions floatleft">
<a class="button" id="PreviousTrack" title="Previous Track"><img src="images/first_24x24.png" /></a>
<a class="button" id="PlayTrack" title="Play/Pause" data-bind="click: defaultPlay"><img src="images/play_24x32.png" /></a>
<a class="button" id="PauseTrack" title="Play/Pause" style="display: none;"><img src="images/pause_24x32.png" /></a>
<a class="button" id="NextTrack" title="Next Track" data-bind="click: nextTrack"><img src="images/last_24x24.png" /></a>
</div>
<div id="songdetails" data-bind="with: $root.playingSong">
<!--<pre data-bind="text: JSON.stringify(ko.toJS($root.playingSong), null, 2)"></pre>-->
<div id="coverart"><a id="coverartimage" data-bind="attr: { href: coverartfull }" href="images/albumdefault_120.jpg"><img data-bind="attr: { src: coverartthumb }" src="images/albumdefault_60.jpg" alt=""/></a></div>
<ul>
<li class="song" data-bind="attr: { id: id }, html: name"></li>
<li class="album" data-bind="html: album"></li>
<li class="specs" data-bind="html: specs"></li>
<li id="songdetails_controls">
<a href="#" id="action_Mute" class="mute first" title="Mute"></a>
<a href="#" id="action_UnMute" class="unmute first" title="Unmute" style="display: none;"></a>
<div class="jp-volume-bar"><div class="jp-volume-bar-value"></div></div><a href="#" id="action_VolumeMax" class="volume" title="Max Volume"></a>
<a href="#" class="loop" title="Repeat" id="Repeat" data-bind="click: $root.toggleSetting, css: { hoverSelected: !settings.Repeat() }"></a>
<a href="#" class="lock" title="Progress Saved" data-bind="visible: settings.SaveTrackPosition()"></a>
</li>
</ul>
<div class="rate"><a href="" title="Favorite" data-bind="css: { favorite: starred(), rate: !starred() }, click: $root.updateFavorite, clickBubble: false"></a></div>
<div class="vertshade"></div>
</div>
<div id="playdeck_1"></div>
<div id="playdeck_2"></div>
<div id="submenu_CurrentPlaylist" class="submenu shadow" style="display: none;">
<table id="CurrentPlaylistPreviewContainer" class="simplelist songlist">
<thead></thead>
<tbody></tbody>
</table>
</div>
</div>
<div class="playeractionssmall"><a href="#" class="button" id="action_ToggleSideBar" title="Toggle Side Bar"><img src="images/arrow_right_gl_12x12.png" /></a></div>
<div id="playermiddle">
<div id="audiocontainer">
<div class="audiojs" id="audio_wrapper0">
<div class="scrubber"><div class="progress"></div><div class="loaded"></div></div>
<div class="time"><em id="played">00:00</em>/<strong id="duration">00:00</strong></div>
<div class="error-message"></div>
</div>
</div>
<div id="preview"></div>
</div>
<div class="clear"></div>
</div>
</div><!-- end #content -->
</div> <!-- End container -->
<div id="footer">
<div id="QueuePreview">
<ul id="QueuePreviewList" class="songlist" data-bind="foreach: queue">
<li class="row song" data-bind="attr: { id: id, parentid: parentid }, css: { playing: playing }, event: { dblclick: playSong.bind($data, false) } ">
<div class="albumart"><img class="" data-bind="attr: { src: coverartthumb }" src="images/albumdefault_25.jpg" /></div>
<div class="clear"></div>
<div class="title" data-bind="html: name, attr: { title: track() + ' - ' + name() + ' - ' + time() }"></div>
<div class="albumtext" data-bind="html: album, attr: { title: album }"></div>
<div class="albumtext" data-bind="html: '[' + artist() + ']', attr: { title: artist }"></div>
</li>
</ul>
</div>
</div>
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-40174100-1', 'jamstash.com');
ga('send', 'pageview');
</script>
</body>
</html>

View file

@ -1,190 +0,0 @@
define(['knockout', 'postbox', 'mapping', 'global', 'utils', 'model', 'player', 'subsonic', 'jquery.scrollTo', 'jquery.layout', 'jquery.dateFormat'], function (ko, postbox, mapping, global, utils, model, player, subsonic) {
return function () {
var self = this;
self.settings = global.settings;
self.queue = ko.observableArray([]).syncWith("queue", true);
//self.layoutSubsonic = ko.observable().syncWith("layoutSubsonic");
//self.layoutArchive = ko.observable().syncWith("layoutArchive");
self.addFromPlayedToQueue = function (data, event) {
var i = self.song.indexOf(this);
var count = 0;
ko.utils.arrayForEach(self.song.slice(i, self.song().length), function (item) {
self.queue.push(item);
//item.selected(true);
count++;
});
player.nextTrack();
//self.selectedSongs([]);
//self.selectNone();
utils.updateMessage(count + ' Song(s) Added to Queue', true);
}
self.albumMapping = {
create: function (options) {
var album = options.data;
var coverart, starred;
if (typeof album.coverArt != 'undefined') {
coverart = self.settings.BaseURL() + '/getCoverArt.view?' + self.settings.BaseParams() + '&size=50&id=' + album.coverArt;
}
if (typeof album.starred !== 'undefined') { starred = true; } else { starred = false; }
return new model.Album(album.id, album.parent, album.album, album.artist, coverart, $.format.date(new Date(album.created), "yyyy-MM-dd h:mm a"), starred, '', '');
}
}
// Referenced Functions
self.getRandomSongs = function (action, genre, folder) { return subsonic.getRandomSongs(action, genre, folder); }
self.updateFavorite = function (data, event) { return subsonic.updateFavorite(data, event); }
/* Start Archive.org */
self.getArchiveArtists = function (data) {
var map = {
create: function (options) {
//return new model.Artist('', options.data);
return new model.Album(options.data, null, options.data, null, '', null, false, '', '');
}
};
mapping.fromJS(self.settings.SavedCollections().split(","), map, self.album);
};
self.getArchiveAlbums = function (from) {
var id, name;
if (from == 'collection') {
self.selectedArtist(this);
id = this.id();
name = this.name();
} else {
id = self.selectedArtist().id();
name = self.selectedArtist().name();
}
var map = {
create: function (options) {
var song = options.data;
var coverart, starred;
var url = self.archiveUrl + 'details/' + song.identifier;
coverart = 'images/albumdefault_50.jpg';
if (parseInt(song.avg_rating) == 5) { starred = true; } else { starred = false; }
//var description = '<b>Details</b><br />';
var description = '<b>Source</b>: ' + song.source + '<br />';
description += '<b>Date</b>: ' + song.date + '<br />';
description += typeof song.publisher != 'undefined' ? '<b>Transferer</b>: ' + song.publisher + '<br />' : '';
description += typeof song.avg_rating != 'undefined' ? '<b>Rating</b>: ' + song.avg_rating + '<br />' : '';
description += '<b>Downloads</b>: ' + song.downloads + '<br />';
//description += typeof song.description == 'undefined' ? '' : song.description.replace("\n", "<br />");
return new model.Album(song.identifier, null, song.title, null, coverart, $.format.date(new Date(song.publicdate), "yyyy-MM-dd h:mm a"), starred, description, url);
}
}
//var url = self.settings.BaseURL() + 'advancedsearch.php?q=collection%3A%28GreenskyBluegrass%29%20AND%20format%3A%28mp3%29&fl%5B%5D=avg_rating&fl%5B%5D=collection&fl%5B%5D=date&fl%5B%5D=description&fl%5B%5D=downloads&fl%5B%5D=headerImage&fl%5B%5D=identifier&fl%5B%5D=publicdate&fl%5B%5D=source&fl%5B%5D=subject&fl%5B%5D=title&format=mp3&sort%5B%5D=addeddate+desc&rows=50&page=1&output=json';
var url = self.archiveUrl + 'advancedsearch.php?q=collection:(' + name + ') AND format:(MP3)';
if (self.selectedSource()) {
url += ' AND source:(' + self.selectedSource() + ')';
}
if (self.selectedYear()) {
if (parseInt(self.selectedYear())) {
url += ' AND year:(' + self.selectedYear() + ')';
}
}
if (self.selectedDescription()) {
url += ' AND description:(' + self.selectedDescription() + ')';
}
url += '&fl[]=avg_rating,collection,date,description,downloads,headerImage,identifier,publisher,publicdate,source,subject,title,year';
if (self.selectedArchiveAlbumSort()) {
url += '&sort[]=' + self.selectedArchiveAlbumSort()
}
url += '&rows=50&page=1&output=json';
$.ajax({
url: url,
method: 'GET',
dataType: self.protocol,
timeout: 10000,
success: function (data) {
var items = [];
if (data["response"].docs.length > 0) {
items = data["response"].docs;
//alert(JSON.stringify(data["response"]));
mapping.fromJS(items, map, self.album);
} else {
utils.updateMessage("0 records returned", true);
}
},
error: function () {
alert('Archive.org service down :(');
}
});
};
// Init for page load
if (utils.getValue('SubsonicAccordion')) {
var id = utils.getValue('SubsonicAccordion');
self.toggleAccordion(id);
}
if (settings.Server() != '' && settings.Username() != '' && settings.Password() != '') {
self.ping();
self.getMusicFolders();
self.getArtists();
}
return {
index: self.index,
shortcut: self.shortcut,
album: self.album,
song: self.song,
templateToUse: self.templateToUse,
selectedArtist: self.selectedArtist,
selectedAlbum: self.selectedAlbum,
selectedPlaylist: self.selectedPlaylist,
selectedSongs: self.selectedSongs,
selectSong: self.selectSong,
addSongsToQueue: self.addSongsToQueue,
addFromPlayedToQueue: self.addFromPlayedToQueue,
getArtists: self.getArtists,
AutoAlbums: self.AutoAlbums,
selectedAutoAlbum: self.selectedAutoAlbum,
getAlbums: self.getAlbums,
offset: self.offset,
getAlbumListBy: self.getAlbumListBy,
getSongs: self.getSongs,
getRandomSongs: self.getRandomSongs,
search: self.search,
updateFavorite: self.updateFavorite,
MusicFolders: self.MusicFolders,
selectedMusicFolders: self.selectedMusicFolders,
getMusicFolders: self.getMusicFolders,
scrollToTop: self.scrollToTop,
scrollToIndex: self.scrollToIndex,
selectAll: self.selectAll,
selectNone: self.selectNone,
rescanLibrary: self.rescanLibrary,
toggleAZ: self.toggleAZ,
selectedSubsonicAlbumSort: self.selectedSubsonicAlbumSort,
SubsonicSort: self.SubsonicSort,
getPodcasts: self.getPodcasts,
getPodcast: self.getPodcast,
getPlaylists: self.getPlaylists,
getPlaylist: self.getPlaylist,
addSongsToPlaylist: self.addSongsToPlaylist,
newPlaylist: self.newPlaylist,
savePlaylist: self.savePlaylist,
deletePlaylist: self.deletePlaylist,
addToPlaylist: self.addToPlaylist,
playlistMenu: self.playlistMenu,
removeSelectedSongs: self.removeSelectedSongs,
toggleAccordion: self.toggleAccordion
};
}
});

View file

@ -1,21 +0,0 @@
define(['knockout', 'postbox', 'mapping', 'global', 'utils', 'model'], function (ko, postbox, mapping, global, utils, model) {
var self = this;
self.album = new ko.observableArray([]);
self.song = new ko.observableArray([]).syncWith("song");
self.templateToUse = ko.observable();
self.settings = global.settings;
self.queue = new ko.observableArray([]).syncWith("queue", true);
self.selectedArtist = ko.observable();
self.selectedAlbum = ko.observable();
self.selectedSongs = new ko.observableArray([]);
return {
getRandomSongs: self.getRandomSongs,
updateFavorite: self.updateFavorite
};
});

View file

@ -1,6 +1,5 @@
/* Declare app level module */
var JamStash = angular.module('JamStash', ['ngCookies', 'ngRoute', 'ngSanitize']);
//var JamStash = angular.module('JamStash', ['ngCookies', 'ngRoute']);
/*
JamStash.config(function ($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist(['/^\s*(https?|file|ms-appx):/', 'self']);
@ -10,36 +9,73 @@ JamStash.config(function ($sceDelegateProvider) {
// URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
// Route: /Chapter/:chapterId/Section/:sectionId
//
// Then
$routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
// Then $routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
*/
JamStash.config(function ($routeProvider) {
JamStash.config(function($routeProvider) {
$routeProvider
.when('/index', { redirectTo: '/library' })
.when('/settings', { templateUrl: 'js/partials/settings.html', controller: 'SettingsCtrl' })
.when('/queue', { templateUrl: 'js/partials/queue.html', controller: 'QueueCtrl' })
.when('/library', { templateUrl: 'js/partials/library.html', controller: 'SubsonicCtrl' })
.when('/library/:artistId', { templateUrl: 'js/partials/library.html', controller: 'SubsonicCtrl', reloadOnSearch: false })
.when('/library/:artistId/:albumId', { templateUrl: 'js/partials/library.html', controller: 'SubsonicCtrl', reloadOnSearch: false })
.when('/playlists', { templateUrl: 'js/partials/playlists.html', controller: 'PlaylistCtrl' })
.when('/podcasts', { templateUrl: 'js/partials/podcasts.html', controller: 'PodcastCtrl' })
.when('/archive', { templateUrl: 'js/partials/archive.html', controller: 'ArchiveCtrl' })
.when('/archive/:artist', { templateUrl: 'js/partials/archive.html', controller: 'ArchiveCtrl' })
.when('/archive/:artist/:album', { templateUrl: 'js/partials/archive.html', controller: 'ArchiveCtrl' })
.otherwise({ redirectTo: '/index' });
.when('/index', {
redirectTo: '/library'
})
.when('/settings', {
templateUrl: 'js/partials/settings.html',
controller: 'SettingsCtrl'
})
.when('/queue', {
templateUrl: 'js/partials/queue.html',
controller: 'QueueCtrl'
})
.when('/library', {
templateUrl: 'js/partials/library.html',
controller: 'SubsonicCtrl'
})
.when('/library/:artistId', {
templateUrl: 'js/partials/library.html',
controller: 'SubsonicCtrl',
reloadOnSearch: false
})
.when('/library/:artistId/:albumId', {
templateUrl: 'js/partials/library.html',
controller: 'SubsonicCtrl',
reloadOnSearch: false
})
.when('/playlists', {
templateUrl: 'js/partials/playlists.html',
controller: 'PlaylistCtrl'
})
.when('/podcasts', {
templateUrl: 'js/partials/podcasts.html',
controller: 'PodcastCtrl'
})
.when('/archive', {
templateUrl: 'js/partials/archive.html',
controller: 'ArchiveCtrl'
})
.when('/archive/:artist', {
templateUrl: 'js/partials/archive.html',
controller: 'ArchiveCtrl'
})
.when('/archive/:artist/:album', {
templateUrl: 'js/partials/archive.html',
controller: 'ArchiveCtrl'
})
.otherwise({
redirectTo: '/index'
});
})
.run(['$rootScope', '$location', 'globals', function ($rootScope, $location, globals) {
$rootScope.$on("$locationChangeStart", function (event, next, current) {
.run(['$rootScope', '$location', 'globals',
function($rootScope, $location, globals) {
$rootScope.$on("$locationChangeStart", function(event, next, current) {
$rootScope.loggedIn = false;
var path = $location.path().replace(/^\/([^\/]*).*$/, '$1');
if (globals.settings.Username != "" && globals.settings.Password != "" && globals.settings.Server != "" && path != 'archive') {
if (globals.settings.Username !== "" && globals.settings.Password !== "" && globals.settings.Server !== "" && path !== 'archive') {
$rootScope.loggedIn = true;
}
if (!$rootScope.loggedIn && (path != 'settings' && path != 'archive')) {
$location.path('/settings');
}
});
}]);
}
]);
/*
JamStash.config(function ($httpProvider, globals) {
$httpProvider.defaults.timeout = globals.settings.Timeout;

View file

@ -1,5 +1,5 @@
JamStash.controller('ArchiveCtrl',
function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils, globals, model, notifications, player, json) {
function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils, globals, model, notifications, player, json) {
//$("#left-component").layout($scope.layoutThreeCol);
$scope.settings = globals.settings;
@ -8,52 +8,57 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
$scope.Protocol = 'jsonp';
$scope.artist = [];
$scope.album = [];
$scope.selectedArtist;
$scope.selectedAlbum;
$scope.selectedArtist = null;
$scope.selectedAlbum = null;
$scope.selectedSongs = [];
$scope.SavedCollections = globals.SavedCollections;
$scope.AllCollections = [];
$scope.loadedCollection = false;
json.getCollections(function (data) {
json.getCollections(function(data) {
$scope.AllCollections = data;
$scope.loadedCollection = true;
});
$scope.writeSavedCollection = function () {
$scope.writeSavedCollection = function() {
utils.setValue('SavedCollections', $scope.SavedCollections.join(), false);
/*
$scope.$apply(function () {
});
*/
globals.SavedCollections = $scope.SavedCollections;
}
$scope.addSavedCollection = function (newValue) {
};
$scope.addSavedCollection = function(newValue) {
if ($scope.SavedCollections.indexOf(newValue) == -1) {
$scope.SavedCollections.push(newValue);
$scope.writeSavedCollection();
}
}
$scope.deleteSavedCollection = function (index) {
};
$scope.deleteSavedCollection = function(index) {
$scope.SavedCollections.splice(index, 1);
$scope.writeSavedCollection();
}
$scope.selectedCollection;
$scope.$watch("selectedCollection", function (newValue, oldValue) {
};
$scope.selectedCollection = null;
$scope.$watch("selectedCollection", function(newValue, oldValue) {
if (newValue !== oldValue) {
$scope.addSavedCollection(newValue);
}
});
$scope.setupDemoCollections = function () {
$scope.setupDemoCollections = function() {
var demo = ["YonderMountainStringBand", "GreenskyBluegrass"];
angular.forEach(demo, function (item, key) {
angular.forEach(demo, function(item, key) {
if ($scope.SavedCollections.indexOf(item) == -1) {
$scope.SavedCollections.push(item);
}
});
}
};
$scope.archiveUrl = 'https://archive.org/';
/* Filter */
$scope.selectedArchiveAlbumSort = "date desc";
$scope.ArchiveAlbumSort = [
'addeddate desc',
'addeddate asc',
@ -71,8 +76,9 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
'publicdate asc',
'stars desc',
'stars asc'
],
$scope.$watch("selectedArchiveAlbumSort", function (newValue, oldValue) {
];
$scope.$watch("selectedArchiveAlbumSort", function(newValue, oldValue) {
if (utils.getValue('AlbumSort') != newValue) {
if (typeof newValue != 'undefined') {
utils.setValue('AlbumSort', newValue, true);
@ -83,40 +89,37 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
$scope.getAlbums('');
}
});
$scope.getYears = function (startYear) {
var currentYear = new Date().getFullYear(), years = [];
$scope.getYears = function(startYear) {
var currentYear = new Date().getFullYear(),
years = [];
startYear = startYear || 1950;
while (startYear <= currentYear) {
years.push(startYear++);
}
return years;
}
$scope.Years = $scope.getYears(),
};
$scope.Years = $scope.getYears();
$scope.filter = {
Year: "",
Source: "",
Description: ""
};
$scope.filterSave = function () {
$scope.filterSave = function() {
if ($scope.selectedArtist) {
$scope.getAlbums('', '');
}
}
};
/* End Filter */
/*
$scope.getArtists = function (data) {
var map = function (data) {
return new model.Artist('', data);
};
angular.forEach($scope.SavedCollections, function (item, key) {
$scope.artist.push(map(item));
});
};
*/
$scope.getAlbums = function (name, identifier) {
$scope.getAlbums = function(name, identifier) {
var url = $scope.archiveUrl + 'advancedsearch.php?q=';
if (name != '') {
if (name !== '') {
$scope.selectedArtist = name;
url += 'collection:(' + name + ') AND format:(MP3)';
} else if ($scope.selectedArtist) {
@ -124,13 +127,18 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
} else {
url += 'identifier:(' + identifier + ')';
}
var map = function (data) {
var map = function(data) {
var song = data;
var coverartthumb, coverartfull, starred;
var url = $scope.archiveUrl + 'details/' + song.identifier;
coverartthumb = 'images/albumdefault_50.jpg';
coverartfull = 'images/albumdefault_160.jpg';
if (parseInt(song.avg_rating) == 5) { starred = true; } else { starred = false; }
if (parseInt(song.avg_rating) == 5) {
starred = true;
} else {
starred = false;
}
//var description = '<b>Details</b><br />';
var description = '<b>Source</b>: ' + song.source + '<br />';
description += '<b>Date</b>: ' + song.date + '<br />';
@ -138,36 +146,41 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
description += typeof song.avg_rating != 'undefined' ? '<b>Rating</b>: ' + song.avg_rating + '<br />' : '';
description += typeof song.downloads != 'undefined' ? '<b>Downloads</b>: ' + song.downloads + '<br />' : '';
return new model.Album(song.identifier, null, song.title, song.collection[0], '', coverartthumb, coverartfull, $.format.date(new Date(song.publicdate), "yyyy-MM-dd h:mm a"), starred, description, url);
}
};
if ($scope.filter.Source) {
url += ' AND source:(' + $scope.filter.Source + ')';
}
if ($scope.filter.Year) {
if (parseInt($scope.filter.Year)) {
url += ' AND year:(' + $scope.filter.Year + ')';
}
}
if ($scope.filter.Description) {
url += ' AND description:(' + $scope.filter.Description + ')';
}
if ($scope.selectedArchiveAlbumSort) {
url += '&sort[]=' + $scope.selectedArchiveAlbumSort;
}
url += '&fl[]=avg_rating,collection,date,description,downloads,headerImage,identifier,publisher,publicdate,source,subject,title,year';
url += '&rows=50&page=1&output=json';
$.ajax({
url: url,
method: 'GET',
dataType: $scope.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
var items = [];
if (data["response"].docs.length > 0) {
items = data["response"].docs;
//alert(JSON.stringify(data["response"]));
if (data.response.docs.length > 0) {
items = data.response.docs;
$scope.album = [];
$rootScope.song = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$scope.album.push(map(item));
});
$scope.$apply();
@ -176,24 +189,42 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
notifications.updateMessage("Sorry :(", true);
}
},
error: function () {
error: function() {
alert('Archive.org service down :(');
}
});
};
utils.mapSong = function (key, song, server, dir, identifier, coverart) {
utils.mapSong = function(key, song, server, dir, identifier, coverart) {
var url, time, track, title, rating, starred, contenttype, suffix;
var specs = ''
var specs = '';
if (song.format == 'VBR MP3') {
url = 'http://' + server + dir + key;
if (typeof song.bitrate == 'undefined' || typeof song.format == 'undefined') { specs = '&nbsp;'; } else { specs = song.bitrate + 'kbps, ' + song.format.toLowerCase(); }
if (typeof song.track == 'undefined') { track = '&nbsp;'; } else { track = song.track; }
if (typeof song.title == 'undefined') { title = '&nbsp;'; } else { title = song.title; }
if (typeof song.length == 'undefined') { time = '&nbsp;'; } else { time = utils.timeToSeconds(song.length); }
if (typeof song.bitrate == 'undefined' || typeof song.format == 'undefined') {
specs = '&nbsp;';
} else {
specs = song.bitrate + 'kbps, ' + song.format.toLowerCase();
}
if (typeof song.track == 'undefined') {
track = '&nbsp;';
} else {
track = song.track;
}
if (typeof song.title == 'undefined') {
title = '&nbsp;';
} else {
title = song.title;
}
if (typeof song.length == 'undefined') {
time = '&nbsp;';
} else {
time = utils.timeToSeconds(song.length);
}
return new model.Song(song.md5, identifier, song.track, title, song.creator, '', song.album, '', coverart, coverart, time, '', '', 'mp3', specs, url, 0, '');
}
};
$scope.getSongs = function (id, action) {
$scope.getSongs = function(id, action) {
$scope.selectedAlbum = id;
var url = $scope.archiveUrl + 'details/' + id + '?output=json';
$.ajax({
@ -201,7 +232,7 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
method: 'GET',
dataType: $scope.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
var coverart = '';
var server = data.server;
var dir = data.dir;
@ -211,7 +242,7 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
}
var items = data.files;
if (action == 'add') {
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
var song = utils.mapSong(key, item, server, dir, identifier, coverart);
if (song) {
$rootScope.queue.push(song);
@ -222,14 +253,14 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
$scope.$apply();
} else if (action == 'play') {
$rootScope.queue = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
var song = utils.mapSong(key, item, server, dir, identifier, coverart);
if (song) {
$rootScope.queue.push(song);
}
});
var next = $rootScope.queue[0];
$scope.$apply(function () {
$scope.$apply(function() {
$rootScope.playSong(false, next);
});
$rootScope.showQueue();
@ -237,7 +268,7 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
} else {
$scope.album = [];
$rootScope.song = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
var song = utils.mapSong(key, item, server, dir, identifier, coverart);
if (song) {
$rootScope.song.push(song);
@ -248,31 +279,35 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
}
});
};
$scope.addSongsToQueue = function () {
$scope.addSongsToQueue = function() {
if ($scope.selectedSongs.length > 0) {
angular.forEach($scope.selectedSongs, function (item, key) {
angular.forEach($scope.selectedSongs, function(item, key) {
$scope.queue.push(item);
item.selected = false;
});
$rootScope.showQueue();
notifications.updateMessage($scope.selectedSongs.length + ' Song(s) Added to Queue', true);
}
}
$scope.scrollToTop = function () {
};
$scope.scrollToTop = function() {
$('#Artists').stop().scrollTo('#auto', 400);
}
$scope.selectAll = function () {
angular.forEach($rootScope.song, function (item, key) {
};
$scope.selectAll = function() {
angular.forEach($rootScope.song, function(item, key) {
$scope.selectedSongs.push(item);
item.selected = true;
});
}
$scope.selectNone = function () {
angular.forEach($rootScope.song, function (item, key) {
};
$scope.selectNone = function() {
angular.forEach($rootScope.song, function(item, key) {
$scope.selectedSongs = [];
item.selected = false;
});
}
};
/* Launch on Startup */
if ($routeParams.artist) {
@ -285,4 +320,4 @@ function ArchiveCtrl($scope, $rootScope, $location, $routeParams, $http, utils,
$scope.addSavedCollection($routeParams.artist);
}
/* End Startup */
});
});

View file

@ -1,6 +1,5 @@
JamStash.controller('SubsonicCtrl',
function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, utils, globals, model, notifications, player) {
//$("#SubsonicAlbums").layout($scope.layoutThreeCol);
function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, utils, globals, model, notifications, player) {
$rootScope.song = [];
//$scope.artistId = $routeParams.artistId;
@ -12,59 +11,79 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
$scope.album = [];
$scope.Server = globals.settings.Server;
$scope.playlistMenu = [];
$scope.AutoAlbums = [
{ id: "random", name: "Random" },
{ id: "newest", name: "Recently Added" },
{ id: "starred", name: "Starred" },
{ id: "highest", name: "Top Rated" },
{ id: "frequent", name: "Most Played" },
{ id: "recent", name: "Recently Played" }
];
$scope.selectedAutoAlbum;
$scope.selectedArtist;
$scope.selectedAlbum;
$scope.AutoAlbums = [{
id: "random",
name: "Random"
}, {
id: "newest",
name: "Recently Added"
}, {
id: "starred",
name: "Starred"
}, {
id: "highest",
name: "Top Rated"
}, {
id: "frequent",
name: "Most Played"
}, {
id: "recent",
name: "Recently Played"
}];
$scope.selectedAutoAlbum = null;
$scope.selectedArtist = null;
$scope.selectedAlbum = null;
$scope.SelectedAlbumSort = globals.settings.DefaultAlbumSort;
$scope.AlbumSort = globals.AlbumSorts;
$scope.BreadCrumbs = [];
$scope.$watch("SelectedAlbumSort.id", function (newValue, oldValue) {
$scope.$watch("SelectedAlbumSort.id", function(newValue, oldValue) {
if (newValue !== oldValue) {
if ($rootScope.song.length > 0) {
$scope.sortSubsonicSongs(newValue);
} else if ($scope.album.length > 0) {
$scope.sortSubsonicAlbums(newValue);
indexes = $.map(globals.AlbumSorts, function (obj, index) {
indexes = $.map(globals.AlbumSorts, function(obj, index) {
if (obj.id == newValue) {
return index;
}
})
});
globals.settings.DefaultAlbumSort = globals.AlbumSorts[indexes];
}
}
});
$rootScope.$watch("SelectedMusicFolder", function (newValue, oldValue) {
$rootScope.$watch("SelectedMusicFolder", function(newValue, oldValue) {
if (newValue !== oldValue) {
utils.setValue('MusicFolders', angular.toJson(newValue), true);
$scope.getArtists(newValue.id);
}
});
$scope.SearchType = globals.settings.DefaultSearchType;
$scope.SearchTypes = globals.SearchTypes;
$scope.rescanLibrary = function (data, event) {
$scope.rescanLibrary = function(data, event) {
$.ajax({
url: globals.BaseURL() + '/getUser.view?' + globals.BaseParams() + '&username=' + globals.settings.Username,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
if (data["subsonic-response"].user.adminRole == true) {
success: function(data) {
if (data["subsonic-response"].user.adminRole === true) {
$.get(globals.settings.Server + '/musicFolderSettings.view?scanNow');
} else {
alert('You are not logged in as an admin user!');
}
}
});
}
$scope.mapArtist = function (data) {
};
$scope.mapArtist = function(data) {
var name = '';
var artist = data.artist;
var artists = [];
@ -73,23 +92,34 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
} else {
artists[0] = artist;
}
angular.forEach(artists, function (item, key) {
if (typeof item.name !== 'undefined') { item.name = item.name.toString(); }
angular.forEach(artists, function(item, key) {
if (typeof item.name !== 'undefined') {
item.name = item.name.toString();
}
});
if (typeof data.name !== 'undefined') { name = data.name.toString(); }
if (typeof data.name !== 'undefined') {
name = data.name.toString();
}
return new model.Index(name, artists);
}
$scope.mapIndex = function (data) {
};
$scope.mapIndex = function(data) {
var name, id = '';
if (typeof data.id !== 'undefined') { id = data.id; }
if (typeof data.name !== 'undefined') { name = data.name.toString(); }
if (typeof data.id !== 'undefined') {
id = data.id;
}
if (typeof data.name !== 'undefined') {
name = data.name.toString();
}
return new model.Artist(id, name);
}
$scope.mapPlaylist = function (data) {
};
$scope.mapPlaylist = function(data) {
return new model.Artist(data.id, data.name);
}
$scope.getArtists = function (id) {
var url, id;
};
$scope.getArtists = function(id) {
var url;
if (utils.getValue('MusicFolders')) {
var folder = angular.fromJson(utils.getValue('MusicFolders'));
id = folder.id;
@ -104,9 +134,17 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
done: function () { if (globals.settings.Debug) { console.log("DONE!"); } },
error: function () { if (globals.settings.Debug) { console.log("ERROR!"); } },
success: function (data) {
done: function() {
if (globals.settings.Debug) {
console.log("DONE!");
}
},
error: function() {
if (globals.settings.Debug) {
console.log("ERROR!");
}
},
success: function(data) {
var indexes = [];
if (typeof data["subsonic-response"].indexes.index != 'undefined') {
if (data["subsonic-response"].indexes.index.length > 0) {
@ -127,32 +165,41 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
} else {
items[0] = data["subsonic-response"].indexes.shortcut;
}
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$scope.shortcut.push($scope.mapIndex(item));
});
}
$scope.index = [];
angular.forEach(indexes, function (item, key) {
angular.forEach(indexes, function(item, key) {
$scope.index.push($scope.mapArtist(item));
});
$scope.$apply();
}
});
};
$scope.refreshArtists = function (id) {
$scope.refreshArtists = function(id) {
utils.setValue('MusicFolders', null, true);
$scope.getArtists();
};
$scope.mapAlbum = function (data) {
$scope.mapAlbum = function(data) {
var album = data;
var title, coverartthumb, coverartfull, starred;
if (typeof album.coverArt != 'undefined') {
coverartthumb = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&size=160&id=' + album.coverArt;
coverartfull = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&id=' + album.coverArt;
}
if (typeof album.starred !== 'undefined') { starred = true; } else { starred = false; }
if (typeof album.title !== 'undefined') { title = album.title; } else { title = album.name; }
if (typeof album.starred !== 'undefined') {
starred = true;
} else {
starred = false;
}
if (typeof album.title !== 'undefined') {
title = album.title;
} else {
title = album.name;
}
var type;
if (album.isDir) {
type = 'byfolder';
@ -160,19 +207,24 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
type = 'bytag';
}
return new model.Album(album.id, album.parent, title, album.artist, album.artistId, coverartthumb, coverartfull, $.format.date(new Date(album.created), "yyyy-MM-dd h:mm a"), starred, '', '', type);
}
$scope.getAlbums = function (id, name) {
};
$scope.getAlbums = function(id, name) {
$scope.selectedAutoAlbum = null;
$scope.selectedArtist = id;
$scope.BreadCrumbs = [];
$scope.BreadCrumbs.push({ 'type': 'artist', 'id': id, 'name': name });
$scope.BreadCrumbs.push({
'type': 'artist',
'id': id,
'name': name
});
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
$.ajax({
url: url,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
var items = [];
if (typeof data["subsonic-response"].directory.child != 'undefined') {
if (data["subsonic-response"].directory.child.length > 0) {
@ -183,7 +235,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
$scope.album = [];
$rootScope.song = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
if (item.isDir) {
$scope.album.push($scope.mapAlbum(item));
} else {
@ -200,21 +252,8 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
}
});
};
$scope.getArtistByTag = function (id) { // Gets Artist by ID3 tag
/*
var map = {
create: function (options) {
var album = options.data;
var coverart, starred;
if (typeof album.coverArt != 'undefined') {
coverart = self.settings.BaseURL() + '/getCoverArt.view?' + self.settings.BaseParams() + '&size=50&id=' + album.coverArt;
}
if (typeof album.starred !== 'undefined') { starred = true; } else { starred = false; }
return new model.Album(album.id, album.parent, album.name, album.artist, coverart, album.created, starred, '', '');
}
}
*/
$scope.getArtistByTag = function(id) { // Gets Artist by ID3 tag
$scope.selectedAutoAlbum = null;
$scope.selectedArtist = id;
var url = globals.BaseURL() + '/getArtist.view?' + globals.BaseParams() + '&id=' + id;
@ -223,7 +262,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
var items = [];
if (typeof data["subsonic-response"].artist != 'undefined') {
if (data["subsonic-response"].artist.album.length > 0) {
@ -234,7 +273,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
$scope.album = [];
$rootScope.song = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$scope.album.push($scope.mapAlbum(item));
});
$scope.$apply();
@ -244,13 +283,14 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
}
});
};
$scope.getAlbumByTag = function (id) { // Gets Album by ID3 tag
$scope.getAlbumByTag = function(id) { // Gets Album by ID3 tag
$.ajax({
url: globals.BaseURL() + '/getAlbum.view?' + globals.BaseParams() + '&id=' + id,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (typeof data["subsonic-response"].album != 'undefined') {
$scope.album = [];
$rootScope.song = [];
@ -263,7 +303,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
} else {
items[0] = data["subsonic-response"].album.song;
}
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.song.push(utils.mapSong(item));
});
$scope.$apply();
@ -271,28 +311,32 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
}
});
};
$scope.offset = 0;
$scope.getAlbumListBy = function (id, offset) {
$scope.getAlbumListBy = function(id, offset) {
var size, url;
$scope.selectedArtist = null;
$scope.selectedAutoAlbum = id;
$scope.BreadCrumbs = [];
if (offset == 'next') {
$scope.offset = $scope.offset + globals.settings.AutoAlbumSize;
} else if (offset == 'prev') {
$scope.offset = $scope.offset - globals.settings.AutoAlbumSize;
}
if ($scope.offset > 0) {
url = globals.BaseURL() + '/getAlbumList.view?' + globals.BaseParams() + '&size=' + globals.settings.AutoAlbumSize.toString() + '&type=' + id + '&offset=' + $scope.offset;
} else {
url = globals.BaseURL() + '/getAlbumList.view?' + globals.BaseParams() + '&size=' + globals.settings.AutoAlbumSize.toString() + '&type=' + id;
}
$.ajax({
url: url,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
var items = [];
if (typeof data["subsonic-response"].albumList.album != 'undefined') {
if (data["subsonic-response"].albumList.album.length > 0) {
@ -302,7 +346,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
}
$scope.album = [];
$rootScope.song = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
if (item.isDir) {
$scope.album.push($scope.mapAlbum(item));
} else {
@ -319,7 +363,8 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
}
});
};
$scope.getSongs = function (id, action) {
$scope.getSongs = function(id, action) {
$scope.selectedAlbum = id;
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
$.ajax({
@ -327,7 +372,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
var items = [];
if (typeof data["subsonic-response"].directory.child != 'undefined') {
if (data["subsonic-response"].directory.child.length > 0) {
@ -336,7 +381,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
items[0] = data["subsonic-response"].directory.child;
}
if (action == 'add') {
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.queue.push(utils.mapSong(item));
});
$scope.$apply();
@ -344,18 +389,18 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else if (action == 'play') {
$rootScope.queue = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.queue.push(utils.mapSong(item));
});
var next = $rootScope.queue[0];
$scope.$apply(function () {
$scope.$apply(function() {
$rootScope.playSong(false, next);
});
$rootScope.showQueue();
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else if (action == 'preview') {
$scope.songpreview = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
if (!item.isDir) {
$rootScope.songpreview.push(utils.mapSong(item));
}
@ -365,13 +410,21 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
if (typeof data["subsonic-response"].directory.id != 'undefined') {
var albumId = data["subsonic-response"].directory.id;
var albumName = data["subsonic-response"].directory.name;
if ($scope.BreadCrumbs.length > 0) { $scope.BreadCrumbs.splice(1, ($scope.BreadCrumbs.length - 1)) };
$scope.BreadCrumbs.push({ 'type': 'album', 'id': albumId, 'name': albumName });
if ($scope.BreadCrumbs.length > 0) {
$scope.BreadCrumbs.splice(1, ($scope.BreadCrumbs.length - 1));
}
$scope.BreadCrumbs.push({
'type': 'album',
'id': albumId,
'name': albumName
});
}
$rootScope.song = [];
$scope.album = [];
var albums = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
if (item.isDir) {
albums.push($scope.mapAlbum(item));
} else {
@ -392,16 +445,17 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
}
});
};
$scope.search = function () {
$scope.search = function() {
var query = $('#Search').val();
if (query != '') {
if (query !== '') {
var type = $('#SearchType').val();
$.ajax({
url: globals.BaseURL() + '/search2.view?' + globals.BaseParams() + '&query=' + query,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (data["subsonic-response"].searchResult2 !== "") {
var header;
var items = [];
@ -413,7 +467,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
items[0] = data["subsonic-response"].searchResult2.song;
}
$rootScope.song = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.song.push(utils.mapSong(item));
});
$scope.$apply();
@ -427,7 +481,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
items[0] = data["subsonic-response"].searchResult2.album;
}
$scope.album = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
if (item.isDir) {
$scope.album.push($scope.mapAlbum(item));
} else {
@ -444,7 +498,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
} else {
items[0] = data["subsonic-response"].searchResult2.artist;
}
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$scope.shortcut.push(item);
});
$scope.$apply();
@ -453,19 +507,20 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
}
}
});
//$('#Search').val("");
}
}
$scope.toggleAZ = function (event) {
};
$scope.toggleAZ = function(event) {
$scope.toggleSubmenu('#submenu_AZIndex', '#AZIndex', 'right', 44);
}
$scope.loadPlaylistsForMenu = function (data, event) {
};
$scope.loadPlaylistsForMenu = function(data, event) {
$.ajax({
url: globals.BaseURL() + '/getPlaylists.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
var playlists = [];
$scope.playlistMenu = [];
if (typeof data["subsonic-response"].playlists.playlist != 'undefined') {
@ -474,7 +529,7 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
} else {
playlists[0] = data["subsonic-response"].playlists.playlist;
}
angular.forEach(playlists, function (item, key) {
angular.forEach(playlists, function(item, key) {
if (item.owner == globals.settings.Username) {
$scope.playlistMenu.push($scope.mapPlaylist(item));
}
@ -494,11 +549,12 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
*/
}
});
}
$scope.addToPlaylist = function (id) {
};
$scope.addToPlaylist = function(id) {
var songs = [];
if ($scope.selectedSongs.length !== 0) {
angular.forEach($scope.selectedSongs, function (item, key) {
angular.forEach($scope.selectedSongs, function(item, key) {
songs.push(item.id);
});
var runningVersion = utils.parseVersionString(globals.settings.ApiVersion);
@ -509,8 +565,11 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
url: globals.BaseURL() + '/updatePlaylist.view?' + globals.BaseParams(),
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
data: { playlistId: id, songIdToAdd: songs },
success: function (data) {
data: {
playlistId: id,
songIdToAdd: songs
},
success: function(data) {
$scope.selectedSongs.length = 0;
notifications.updateMessage('Playlist Updated!', true);
},
@ -518,20 +577,25 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
});
}
}
}
$scope.sortDateFunction = function (a, b) {
};
$scope.sortDateFunction = function(a, b) {
return a.date < b.date ? 1 : -1;
};
$scope.sortArtistFunction = function (a, b) {
$scope.sortArtistFunction = function(a, b) {
return a.artist.toLowerCase() < b.artist.toLowerCase() ? -1 : 1;
};
$scope.sortAlbumFunction = function (a, b) {
$scope.sortAlbumFunction = function(a, b) {
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
};
$scope.sortTrackFunction = function (a, b) {
$scope.sortTrackFunction = function(a, b) {
return parseInt(a.track) > parseInt(b.track) ? -1 : 1;
};
$scope.sortSubsonicAlbums = function (newValue) {
$scope.sortSubsonicAlbums = function(newValue) {
if (typeof newValue != 'undefined') {
//alert(newValue);
switch (newValue) {
@ -547,7 +611,8 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
}
}
};
$scope.sortSubsonicSongs = function (newValue) {
$scope.sortSubsonicSongs = function(newValue) {
if (typeof newValue != 'undefined') {
//alert(newValue);
switch (newValue) {
@ -575,4 +640,4 @@ function SubsonicCtrl($scope, $rootScope, $location, $window, $routeParams, util
$scope.getAlbums($routeParams.artistId);
}
/* End Startup */
});
});

View file

@ -1,53 +1,60 @@
JamStash.controller('AppCtrl',
function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils, globals, model, notifications, player) {
function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils, globals, model, notifications, player) {
$rootScope.settings = globals.settings;
$rootScope.song = [];
$rootScope.queue = [];
$rootScope.playingSong;
$rootScope.playingSong = null;
$rootScope.MusicFolders = [];
$rootScope.Genres = [];
$rootScope.selectedPlaylist = "";
$rootScope.selectedAutoPlaylist = "";
$rootScope.SelectedMusicFolder = "";
$rootScope.unity;
$rootScope.loggedIn = function () {
if (globals.settings.Server != '' && globals.settings.Username != '' && globals.settings.Password != '') {
$rootScope.unity = null;
$rootScope.loggedIn = function() {
if (globals.settings.Server !== '' && globals.settings.Username !== '' && globals.settings.Password !== '') {
return true;
} else {
return false;
}
}
};
$rootScope.totalDisplayed = 50;
$rootScope.loadMore = function () {
$rootScope.loadMore = function() {
$scope.totalDisplayed += 50;
};
/*
$scope.playSong = function (loadonly, data) {
$scope.$apply(function () {
$rootScope.playSong(loadonly, data);
});
}
*/
// Reads cookies and sets globals.settings values
$scope.loadSettings = function () {
$scope.loadSettings = function() {
// Temporary Code to Convert Cookies added 2/2/2014
if ($cookieStore.get('Settings')) {
utils.setValue('Settings', $cookieStore.get('Settings'), false);
$cookieStore.remove('Settings');
}
if (utils.getValue('Settings')) {
$.each(utils.getValue('Settings'), function (k, v) {
if (v == 'false') { v = false; }
if (v == 'true') { v = true; }
$.each(utils.getValue('Settings'), function(k, v) {
if (v == 'false') {
v = false;
}
if (v == 'true') {
v = true;
}
globals.settings[k] = v;
});
}
if (utils.getValue("SavedCollections")) { globals.SavedCollections = utils.getValue("SavedCollections").split(","); }
if (utils.getValue("SavedGenres")) { globals.SavedGenres = utils.getValue("SavedGenres").split(","); }
if (globals.settings.Debug) { console.log('Settings: ' + JSON.stringify(globals.settings, null, 2)); }
if (utils.getValue("SavedCollections")) {
globals.SavedCollections = utils.getValue("SavedCollections").split(",");
}
$scope.toggleSetting = function (setting) {
if (utils.getValue("SavedGenres")) {
globals.SavedGenres = utils.getValue("SavedGenres").split(",");
}
if (globals.settings.Debug) {
console.log('Settings: ' + JSON.stringify(globals.settings, null, 2));
}
};
$scope.toggleSetting = function(setting) {
var id = setting;
if (globals.settings[id]) {
globals.settings[id] = false;
@ -55,24 +62,23 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
globals.settings[id] = true;
}
notifications.updateMessage(setting + ' : ' + globals.settings[id], true);
}
};
$.ajaxSetup({
'beforeSend': function () {
'beforeSend': function() {
$("#loading").show();
},
'complete': function () {
'complete': function() {
$("#loading").hide();
}
});
$(".coverartfancy").on("click", "a", function () {
$(".coverartfancy").on("click", "a", function() {
$("a.coverartfancy").fancybox({
beforeShow: function () {
beforeShow: function() {
//this.title = $('#songdetails_artist').html();
},
afterLoad: function () {
afterLoad: function() {
//this.inner.prepend( '<h1>1. My custom title</h1>' );
//this.content = '<h1>2. My custom title</h1>';
},
@ -84,15 +90,17 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
});
var submenu_active = false;
$('div.submenu').mouseenter(function () {
$('div.submenu').mouseenter(function() {
submenu_active = true;
});
$('div.submenu').mouseleave(function () {
$('div.submenu').mouseleave(function() {
submenu_active = false;
$('div.submenu').hide();
//setTimeout(function () { if (submenu_active == false) $('div.submenu').stop().fadeOut(); }, 400);
});
$scope.toggleSubmenu = function (menu, pl, pos, margin) {
$scope.toggleSubmenu = function(menu, pl, pos, margin) {
var submenu = $(menu);
if (submenu.css('display') !== 'none') {
submenu.fadeOut();
@ -104,39 +112,53 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
switch (pos) {
case 'right':
//show the menu to the right of placeholder
submenu.css({ "left": (off.left + margin) + "px", "top": (off.top) + "px" }).fadeIn(400);
submenu.css({
"left": (off.left + margin) + "px",
"top": (off.top) + "px"
}).fadeIn(400);
break;
case 'left':
//show the menu to the right of placeholder
submenu.css({ "left": (off.left - margin) + "px", "top": (off.top) + "px" }).fadeIn(400);
submenu.css({
"left": (off.left - margin) + "px",
"top": (off.top) + "px"
}).fadeIn(400);
break;
}
setTimeout(function () { if (submenu_active == false) $('div.submenu').stop().fadeOut(); }, 10000);
setTimeout(function() {
if (submenu_active === false) $('div.submenu').stop().fadeOut();
}, 10000);
}
}
$rootScope.showQueue = function () {
};
$rootScope.showQueue = function() {
var submenu = $('#QueuePreview');
submenu.fadeIn(400);
var timeout = globals.settings.Timeout;
setTimeout(function () { submenu.fadeOut(); }, timeout);
}
$rootScope.hideQueue = function () {
setTimeout(function() {
submenu.fadeOut();
}, timeout);
};
$rootScope.hideQueue = function() {
var submenu = $('#QueuePreview');
submenu.fadeOut();
}
$scope.toggleQueue = function () {
};
$scope.toggleQueue = function() {
var submenu = $('#QueuePreview');
if (submenu.css('display') == 'none') {
$rootScope.showQueue();
} else {
$rootScope.hideQueue();
}
}
};
$("a.coverartfancy").fancybox({
beforeShow: function () {
beforeShow: function() {
//this.title = $('#songdetails_artist').html();
},
afterLoad: function () {
afterLoad: function() {
//this.inner.prepend( '<h1>1. My custom title</h1>' );
//this.content = '<h1>2. My custom title</h1>';
},
@ -151,14 +173,20 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
closeEffect: 'none'
});
$('#audiocontainer .scrubber').mouseover(function (e) {
$('.audiojs .scrubber').stop().animate({ height: '8px' });
$('#audiocontainer .scrubber').mouseover(function(e) {
$('.audiojs .scrubber').stop().animate({
height: '8px'
});
});
$('#audiocontainer .scrubber').mouseout(function(e) {
$('.audiojs .scrubber').stop().animate({
height: '4px'
});
$('#audiocontainer .scrubber').mouseout(function (e) {
$('.audiojs .scrubber').stop().animate({ height: '4px' });
});
$('.message').on('click', function () { $(this).remove(); });
$('.message').on('click', function() {
$(this).remove();
});
// Sway.fm Unity Plugin
$rootScope.unity = UnityMusicShim();
@ -167,68 +195,60 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
next: true,
previous: true
});
$rootScope.unity.setCallbackObject({
pause: function () {
if (globals.settings.Debug) { console.log("Unity: Recieved playpause command"); }
pause: function() {
if (globals.settings.Debug) {
console.log("Unity: Recieved playpause command");
}
player.playPauseSong();
},
next: function () {
if (globals.settings.Debug) { console.log("Unity: Recieved next command"); }
next: function() {
if (globals.settings.Debug) {
console.log("Unity: Recieved next command");
}
$rootScope.nextTrack();
},
previous: function () {
if (globals.settings.Debug) { console.log("Unity: Recieved previous command"); }
previous: function() {
if (globals.settings.Debug) {
console.log("Unity: Recieved previous command");
}
$rootScope.previousTrack();
}
});
// JQuery UI Sortable - Drag and drop sorting
/*
var fixHelper = function (e, ui) {
ui.children().each(function () {
$(this).width($(this).width());
});
return ui;
};
$("#QueuePreview ul.songlist").sortable({
helper: fixHelper
});
*/
/* JQuery Layout Plugin - I don't think this is used anywhere
function resizePageLayout() {
var pageLayout = $("body").data("layout");
if (pageLayout) pageLayout.resizeAll();
};
*/
// Global Functions
window.onbeforeunload = function () {
window.onbeforeunload = function() {
if (!globals.settings.Debug) {
if ($rootScope.queue.length > 0) {
return "You're about to end your session, are you sure?";
}
}
}
};
$scope.dragStart = function (e, ui) {
$scope.dragStart = function(e, ui) {
ui.item.data('start', ui.item.index());
}
$scope.dragEnd = function (e, ui) {
};
$scope.dragEnd = function(e, ui) {
var start = ui.item.data('start'),
end = ui.item.index();
$rootScope.queue.splice(end, 0,
$rootScope.queue.splice(start, 1)[0]);
$scope.$apply();
}
$document.keydown(function (e) {
};
$document.keydown(function(e) {
$scope.scrollToIndex(e);
});
$scope.scrollToIndex = function (e) {
$scope.scrollToIndex = function(e) {
var source = e.target.id;
if (source != 'Search' && source != 'Source' && source != 'Description' && source != 'ChatMsg' && source != 'AutoPlaylists') {
var unicode = e.charCode ? e.charCode : e.keyCode;
if (globals.settings.Debug) { console.log('Keycode Triggered: ' + unicode); }
if (globals.settings.Debug) {
console.log('Keycode Triggered: ' + unicode);
}
/*
if (unicode == 49) {
utils.changeTab('tabQueue');
@ -263,10 +283,13 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
} else if (unicode == 36 && $('#tabLibrary').is(':visible')) { // home
$('#left-component').stop().scrollTo('#MusicFolders', 400);
}
var volume;
if (unicode == 189) { // dash - volume down
var volume = utils.getValue('Volume') ? parseFloat(utils.getValue('Volume')) : 1;
if (volume <= 1 && volume > 0 && source == '') {
volume += -.1;
volume = utils.getValue('Volume') ? parseFloat(utils.getValue('Volume')) : 1;
if (volume <= 1 && volume > 0 && source === '') {
volume += -0.1;
$(player1).jPlayer({
volume: volume
});
@ -274,10 +297,11 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
//updateMessage('Volume: ' + Math.round(volume * 100) + '%');
}
}
if (unicode == 187) { // equals - volume up
var volume = utils.getValue('Volume') ? parseFloat(utils.getValue('Volume')) : 1;
if (volume < 1 && volume >= 0 && source == '') {
volume += .1;
volume = utils.getValue('Volume') ? parseFloat(utils.getValue('Volume')) : 1;
if (volume < 1 && volume >= 0 && source === '') {
volume += 0.1;
$(player1).jPlayer({
volume: volume
});
@ -288,37 +312,43 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
}
return true;
};
$scope.scrollToIndexName = function (index) {
$scope.scrollToIndexName = function(index) {
var el = '#' + index;
if ($(el).length > 0) {
$('#left-component').stop().scrollTo(el, 400);
}
};
$scope.scrollToTop = function () {
$scope.scrollToTop = function() {
$('#Artists').stop().scrollTo('#auto', 400);
}
$scope.selectAll = function () {
angular.forEach($rootScope.song, function (item, key) {
};
$scope.selectAll = function() {
angular.forEach($rootScope.song, function(item, key) {
$scope.selectedSongs.push(item);
item.selected = true;
});
}
$scope.playAll = function () {
};
$scope.playAll = function() {
$rootScope.queue = [];
$scope.selectAll();
$scope.addSongsToQueue();
var next = $rootScope.queue[0];
$rootScope.playSong(false, next);
}
$scope.selectNone = function () {
angular.forEach($rootScope.song, function (item, key) {
};
$scope.selectNone = function() {
angular.forEach($rootScope.song, function(item, key) {
$scope.selectedSongs = [];
item.selected = false;
});
}
$scope.addSongsToQueue = function () {
};
$scope.addSongsToQueue = function() {
if ($scope.selectedSongs.length !== 0) {
angular.forEach($scope.selectedSongs, function (item, key) {
angular.forEach($scope.selectedSongs, function(item, key) {
$scope.queue.push(item);
item.selected = false;
});
@ -326,17 +356,19 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
notifications.updateMessage($scope.selectedSongs.length + ' Song(s) Added to Queue', true);
$scope.selectedSongs.length = 0;
}
}
$scope.isActive = function (route) {
};
$scope.isActive = function(route) {
return route === $location.path();
};
$scope.getMusicFolders = function () {
$scope.getMusicFolders = function() {
$.ajax({
url: globals.BaseURL() + '/getMusicFolders.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (data["subsonic-response"].musicFolders.musicFolder !== undefined) {
var folders = [];
if (data["subsonic-response"].musicFolders.musicFolder.length > 0) {
@ -348,8 +380,9 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
$rootScope.MusicFolders = folders;
if (utils.getValue('MusicFolders')) {
var folder = angular.fromJson(utils.getValue('MusicFolders'));
var i = 0, index = "";
angular.forEach($rootScope.MusicFolders, function (item, key) {
var i = 0,
index = "";
angular.forEach($rootScope.MusicFolders, function(item, key) {
if (item.id == folder.id) {
index = i;
}
@ -361,43 +394,25 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
}
}
});
}
$scope.getGenres = function () {
};
$scope.getGenres = function() {
var genres = 'Acid Rock,Acoustic,Alt Country,Alt/Indie,Alternative & Punk,Alternative Metal,Alternative,AlternRock,Awesome,Bluegrass,Blues,Blues-Rock,Classic Hard Rock,Classic Rock,Comedy,Country,Country-Rock,Dance,Dance-Rock,Deep Funk,Easy Listening,Electronic,Electronica,Electronica/Dance,Folk,Folk/Rock,Funk,Grunge,Hard Rock,Heavy Metal,Holiday,House,Improg,Indie Rock,Indie,International,Irish,Jam Band,Jam,Jazz Fusion,Jazz,Latin,Live Albums,Metal,Music,Oldies,Other,Pop,Pop/Rock,Post Rock,Progressive Rock,Psychedelic Rock,Psychedelic,Punk,R&B,Rap & Hip-Hop,Reggae,Rock & Roll,Rock,Rock/Pop,Roots,Ska,Soft Rock,Soul,Southern Rock,Thrash Metal,Unknown,Vocal,World';
$rootScope.Genres = genres.split(',');
/* This is broken in version 4.8, unable to convert XML to JSON
$.ajax({
url: globals.BaseURL() + '/getGenres.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
if (typeof data["subsonic-response"].genres != 'undefined') {
var items = [];
if (data["subsonic-response"].genres.length > 0) {
items = data["subsonic-response"].genres;
} else {
items[0] = data["subsonic-response"].genres;
}
// TODO: fix this
};
$rootScope.Genres = items;
$scope.$apply();
}
}
});
*/
}
$scope.download = function (id) {
$scope.download = function(id) {
$.ajax({
url: globals.BaseURL() + '/getUser.view?' + globals.BaseParams() + '&username=' + globals.settings.Username,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (typeof data["subsonic-response"].error != 'undefined') {
notifications.updateMessage('Error: ' + data["subsonic-response"].error.message, true);
} else {
if (data["subsonic-response"].user.downloadRole == true) {
if (data["subsonic-response"].user.downloadRole === true) {
$window.location.href = globals.BaseURL() + '/download.view?' + globals.BaseParams() + '&id=' + id;
} else {
notifications.updateMessage('You do not have permission to Download', true);
@ -405,14 +420,15 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
}
}
});
}
$scope.ping = function () {
};
$scope.ping = function() {
$.ajax({
url: globals.BaseURL() + '/ping.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (data["subsonic-response"].status == 'ok') {
globals.settings.ApiVersion = data["subsonic-response"].version;
} else {
@ -421,29 +437,33 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
}
}
},
error: function () {
error: function() {
notifications.updateMessage('Unable to connect to Subsonic server');
}
});
}
$scope.addSongToQueue = function (data) {
};
$scope.addSongToQueue = function(data) {
$rootScope.queue.push(data);
}
$scope.queueRemoveSelected = function (data, event) {
angular.forEach($scope.selectedSongs, function (item, key) {
};
$scope.queueRemoveSelected = function(data, event) {
angular.forEach($scope.selectedSongs, function(item, key) {
var index = $rootScope.queue.indexOf(item);
if (index > -1) {
$rootScope.queue.splice(index, 1);
}
});
}
$scope.queueEmpty = function () {
};
$scope.queueEmpty = function() {
//self.selectedSongs([]);
$rootScope.queue = [];
}
$scope.queueTotal = function () {
};
$scope.queueTotal = function() {
var total = 0;
ko.utils.arrayForEach(self.queue(), function (item) {
ko.utils.arrayForEach(self.queue(), function(item) {
total += parseInt(item.duration());
});
if (self.queue().length > 0) {
@ -451,12 +471,16 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
} else {
return '0 song(s), 00:00:00 total time';
}
}
$scope.queueShuffle = function () {
$rootScope.queue.sort(function () { return 0.5 - Math.random() });
}
};
$scope.queueShuffle = function() {
$rootScope.queue.sort(function() {
return 0.5 - Math.random();
});
};
$scope.selectedSongs = [];
$scope.selectSong = function (data) {
$scope.selectSong = function(data) {
var i = $scope.selectedSongs.indexOf(data);
if (i >= 0) {
$scope.selectedSongs.splice(i, 1);
@ -466,36 +490,44 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
data.selected = true;
}
//$scope.$apply();
};
$rootScope.getRandomSongs = function(action, genre, folder) {
if (globals.settings.Debug) {
console.log('action:' + action + ', genre:' + genre + ', folder:' + folder);
}
$rootScope.getRandomSongs = function (action, genre, folder) {
if (globals.settings.Debug) { console.log('action:' + action + ', genre:' + genre + ', folder:' + folder); }
var size = globals.settings.AutoPlaylistSize;
$rootScope.selectedPlaylist = null;
if (typeof folder == 'number') {
$rootScope.selectedAutoPlaylist = folder;
} else if (genre != '') {
} else if (genre !== '') {
$rootScope.selectedAutoPlaylist = genre;
} else {
$rootScope.selectedAutoPlaylist = 'random';
}
var genreParams = '';
if (genre != '' && genre != 'Random') {
if (genre !== '' && genre != 'Random') {
genreParams = '&genre=' + genre;
}
folderParams = '';
if (typeof folder == 'number' && folder != '' && folder != 'all') {
if (typeof folder == 'number' && folder !== '' && folder != 'all') {
//alert(folder);
folderParams = '&musicFolderId=' + folder;
} else if (typeof $rootScope.SelectedMusicFolder.id != 'undefined') {
//alert($rootScope.SelectedMusicFolder.id);
folderParams = '&musicFolderId=' + $rootScope.SelectedMusicFolder.id;
}
$.ajax({
url: globals.BaseURL() + '/getRandomSongs.view?' + globals.BaseParams() + '&size=' + size + genreParams + folderParams,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (typeof data["subsonic-response"].randomSongs.song != 'undefined') {
var items = [];
if (data["subsonic-response"].randomSongs.song.length > 0) {
@ -504,7 +536,7 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
items[0] = data["subsonic-response"].randomSongs.song;
}
if (action == 'add') {
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.queue.push(utils.mapSong(item));
});
$scope.$apply();
@ -512,18 +544,18 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else if (action == 'play') {
$rootScope.queue = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.queue.push(utils.mapSong(item));
});
var next = $rootScope.queue[0];
$scope.$apply(function () {
$scope.$apply(function() {
$rootScope.playSong(false, next);
});
$rootScope.showQueue();
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else {
$rootScope.song = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.song.push(utils.mapSong(item));
});
$scope.$apply();
@ -531,8 +563,9 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
}
}
});
}
$scope.updateFavorite = function (item) {
};
$scope.updateFavorite = function(item) {
var id = item.id;
var starred = item.starred;
var url;
@ -548,14 +581,15 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function () {
success: function() {
notifications.updateMessage('Favorite Updated!', true);
}
});
}
$scope.toTrusted = function (html) {
};
$scope.toTrusted = function(html) {
return $sce.trustAsHtml(html);
}
};
/* Launch on Startup */
$scope.loadSettings();
@ -569,4 +603,4 @@ function AppCtrl($scope, $rootScope, $document, $location, $cookieStore, utils,
}
}
/* End Startup */
});
});

View file

@ -1,52 +0,0 @@
JamStash.controller('PartialCtrl',
function PartialCtrl($scope, $rootScope, $location, $window, $routeParams, utils, globals) {
//$("#SubsonicAlbums").layout($scope.layoutThreeCol);
$scope.song = [];
$scope.itemType = 'ss';
$scope.index = [];
$scope.shortcut = [];
$scope.album = [];
$scope.Server = globals.settings.Server;
$scope.getSongs = function (id) {
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
$.ajax({
url: url,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
var items = [];
if (typeof data["subsonic-response"].directory.child != 'undefined') {
if (data["subsonic-response"].directory.child.length > 0) {
items = data["subsonic-response"].directory.child;
} else {
items[0] = data["subsonic-response"].directory.child;
}
$scope.song = [];
var albums = [];
angular.forEach(items, function (item, key) {
if (item.isDir) {
//albums.push($scope.mapAlbum(item));
} else {
$rootScope.song.push(utils.mapSong(item));
}
});
//$location.path('/library/0/' + id);
$scope.$apply();
} else {
notifications.updateMessage('No Songs Returned :(', true);
}
}
});
};
/* Launch on Startup */
if ($routeParams.albumId) {
$scope.getSongs($routeParams.albumId);
}
/* End Startup */
});

View file

@ -1,28 +1,31 @@
JamStash.controller('PlaylistCtrl',
function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, notifications) {
//$("#left-component").layout($scope.layoutTwoCol);
function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, notifications) {
$rootScope.song = [];
$scope.itemType = 'pl';
$scope.playlists = [];
$scope.playlistsPublic = [];
$scope.playlistsGenre = globals.SavedGenres;
$scope.selectedGenre;
$scope.$watch("selectedGenre", function (newValue, oldValue) {
$scope.selectedGenre = null;
$scope.$watch("selectedGenre", function(newValue, oldValue) {
if (newValue !== oldValue) {
globals.SavedGenres.push(newValue);
//$scope.playlistsGenre.push();
utils.setValue('SavedGenres', globals.SavedGenres.join(), false);
}
});
$scope.getPlaylists = function (refresh) {
if (globals.settings.Debug) { console.log("LOAD PLAYLISTS"); }
$scope.getPlaylists = function(refresh) {
if (globals.settings.Debug) {
console.log("LOAD PLAYLISTS");
}
$.ajax({
url: globals.BaseURL() + '/getPlaylists.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (data["subsonic-response"].playlists.playlist !== undefined) {
var items = [];
if (data["subsonic-response"].playlists.playlist.length > 0) {
@ -30,7 +33,7 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
} else {
items[0] = data["subsonic-response"].playlists.playlist;
}
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
if (item.owner == globals.settings.Username) {
$scope.playlists.push(item);
} else if (item.public) {
@ -41,8 +44,9 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
}
}
});
}
$scope.getPlaylist = function (id, action) {
};
$scope.getPlaylist = function(id, action) {
$rootScope.selectedAutoPlaylist = null;
$rootScope.selectedPlaylist = id;
$.ajax({
@ -50,7 +54,7 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (typeof data["subsonic-response"].playlist.entry != 'undefined') {
var items = [];
var playlist = data["subsonic-response"].playlist;
@ -60,7 +64,7 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
items[0] = playlist.entry;
}
if (action == 'add') {
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.queue.push(utils.mapSong(item));
});
$scope.$apply();
@ -68,11 +72,11 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else if (action == 'play') {
$rootScope.queue = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.queue.push(utils.mapSong(item));
});
var next = $rootScope.queue[0];
$scope.$apply(function () {
$scope.$apply(function() {
$rootScope.playSong(false, next);
});
$rootScope.showQueue();
@ -80,7 +84,7 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
} else {
$scope.album = [];
$rootScope.song = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.song.push(utils.mapSong(item));
});
$scope.$apply();
@ -90,8 +94,9 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
}
}
});
}
$scope.getStarred = function (action, type) {
};
$scope.getStarred = function(action, type) {
var size = globals.settings.AutoPlaylistSize;
$rootScope.selectedPlaylist = null;
$rootScope.selectedAutoPlaylist = 'starred';
@ -100,7 +105,7 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (typeof data["subsonic-response"].starred !== 'undefined') {
var items = [];
switch (type) {
@ -130,7 +135,7 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
items[0] = data["subsonic-response"].starred.song;
}
if (action == 'add') {
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.queue.push(utils.mapSong(item));
});
$scope.$apply();
@ -138,18 +143,18 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else if (action == 'play') {
$rootScope.queue = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.queue.push(utils.mapSong(item));
});
var next = $rootScope.queue[0];
$scope.$apply(function () {
$scope.$apply(function() {
$rootScope.playSong(false, next);
});
$rootScope.showQueue();
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else {
$rootScope.song = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
$rootScope.song.push(utils.mapSong(item));
});
$scope.$apply();
@ -162,23 +167,25 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
}
}
});
}
$scope.newPlaylist = function (data, event) {
};
$scope.newPlaylist = function(data, event) {
var reply = prompt("Choose a name for your new playlist.", "");
if (reply != 'null' && reply != null && reply != '') {
if (reply !== 'null' && reply !== null && reply !== '') {
$.ajax({
url: globals.BaseURL() + '/createPlaylist.view?' + globals.BaseParams() + '&name=' + reply,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
loadPlaylists(true);
}
});
}
}
$scope.deletePlaylist = function () {
if ($rootScope.selectedPlaylist != null) {
};
$scope.deletePlaylist = function() {
if ($rootScope.selectedPlaylist !== null) {
var id = $rootScope.selectedPlaylist;
if (utils.confirmDelete('Are you sure you want to delete the selected playlist?')) {
$.ajax({
@ -186,18 +193,19 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
$scope.getPlaylists();
}
});
}
}
}
$scope.savePlaylist = function () {
if ($rootScope.selectedPlaylist() != null) {
};
$scope.savePlaylist = function() {
if ($rootScope.selectedPlaylist() !== null) {
var id = $rootScope.selectedPlaylist().id();
var songs = [];
ko.utils.arrayForEach($rootScope.song(), function (item) {
ko.utils.arrayForEach($rootScope.song(), function(item) {
songs.push(item.id);
});
if (songs.length > 0) {
@ -206,8 +214,11 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
url: globals.BaseURL() + '/createPlaylist.view?' + globals.BaseParams(),
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
data: { playlistId: id, songId: songs },
success: function () {
data: {
playlistId: id,
songId: songs
},
success: function() {
$scope.getPlaylist(id);
notifications.updateMessage('Playlist Updated!', true);
},
@ -215,12 +226,14 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
});
}
}
}
$scope.removeSelectedSongs = function (data, event) {
ko.utils.arrayForEach($scope.selectedSongs(), function (item) {
};
$scope.removeSelectedSongs = function(data, event) {
ko.utils.arrayForEach($scope.selectedSongs(), function(item) {
$rootScope.song.remove(item);
});
}
};
/* End Playlists */
/* Launch on Startup */
@ -228,4 +241,4 @@ function PlaylistCtrl($scope, $rootScope, $location, utils, globals, model, noti
//$scope.getMusicFolders();
$scope.getGenres();
/* End Startup */
});
});

View file

@ -1,18 +1,20 @@
JamStash.controller('PodcastCtrl',
function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notifications) {
//$("#left-component").layout($scope.layoutTwoCol);
function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notifications) {
$rootScope.song = [];
$scope.podcasts = [];
$scope.selectedPodcast;
$scope.getPodcasts = function (refresh) {
if (globals.settings.Debug) { console.log("LOAD PODCASTS"); }
$scope.selectedPodcast = null;
$scope.getPodcasts = function(refresh) {
if (globals.settings.Debug) {
console.log("LOAD PODCASTS");
}
$.ajax({
url: globals.BaseURL() + '/getPodcasts.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (data["subsonic-response"].podcasts.channel !== undefined) {
var items = [];
if (data["subsonic-response"].podcasts.channel.length > 0) {
@ -25,34 +27,62 @@ function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notif
}
}
});
}
$scope.getPodcast = function (id, action) {
};
$scope.getPodcast = function(id, action) {
$scope.selectedPodcast = id;
var map = function (data) {
var map = function(data) {
var song = data;
var url, track, rating, starred, contenttype, suffix, description;
var specs = '', coverartthumb = '', coverartfull = '';
var specs = '',
coverartthumb = '',
coverartfull = '';
if (typeof song.coverArt != 'undefined') {
coverartthumb = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&size=60&id=' + song.coverArt;
coverartfull = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&id=' + song.coverArt;
}
if (typeof song.description == 'undefined') { description = ''; } else { description = song.description; }
if (typeof song.track == 'undefined') { track = '&nbsp;'; } else { track = song.track; }
if (typeof song.starred !== 'undefined') { starred = true; } else { starred = false; }
if (song.bitRate !== undefined) { specs += song.bitRate + ' Kbps'; }
if (song.transcodedSuffix !== undefined) { specs += ', transcoding:' + song.suffix + ' > ' + song.transcodedSuffix; } else { specs += ', ' + song.suffix; }
if (song.transcodedSuffix !== undefined) { suffix = song.transcodedSuffix; } else { suffix = song.suffix; }
if (suffix == 'ogg') { suffix = 'oga'; }
if (typeof song.description == 'undefined') {
description = '';
} else {
description = song.description;
}
if (typeof song.track == 'undefined') {
track = '&nbsp;';
} else {
track = song.track;
}
if (typeof song.starred !== 'undefined') {
starred = true;
} else {
starred = false;
}
if (song.bitRate !== undefined) {
specs += song.bitRate + ' Kbps';
}
if (song.transcodedSuffix !== undefined) {
specs += ', transcoding:' + song.suffix + ' > ' + song.transcodedSuffix;
} else {
specs += ', ' + song.suffix;
}
if (song.transcodedSuffix !== undefined) {
suffix = song.transcodedSuffix;
} else {
suffix = song.suffix;
}
if (suffix == 'ogg') {
suffix = 'oga';
}
var salt = Math.floor(Math.random() * 100000);
url = globals.BaseURL() + '/stream.view?' + globals.BaseParams() + '&id=' + song.streamId + '&salt=' + salt;
return new model.Song(song.streamId, song.parent, track, song.title, song.artist, song.artistId, song.album, song.albumId, coverartthumb, coverartfull, song.duration, song.userRating, starred, suffix, specs, url, 0, description);
}
};
$.ajax({
url: globals.BaseURL() + '/getPodcasts.view?' + globals.BaseParams(),
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
success: function(data) {
if (data["subsonic-response"].podcasts.channel !== undefined) {
var podcasts = [];
if (data["subsonic-response"].podcasts.channel.length > 0) {
@ -61,7 +91,7 @@ function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notif
podcasts[0] = data["subsonic-response"].podcasts.channel;
}
var items = [];
$.each(podcasts, function (i, item) {
$.each(podcasts, function(i, item) {
if (item.id == id) {
items = item.episode;
}
@ -69,7 +99,7 @@ function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notif
if (typeof items != 'undefined') {
if (action == 'add') {
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
if (item.status != "skipped") {
$rootScope.queue.push(map(item));
}
@ -79,13 +109,13 @@ function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notif
notifications.updateMessage(items.length + ' Song(s) Added to Queue', true);
} else if (action == 'play') {
$rootScope.queue = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
if (item.status != "skipped") {
$rootScope.queue.push(map(item));
}
});
var next = $rootScope.queue[0];
$scope.$apply(function () {
$scope.$apply(function() {
$rootScope.playSong(false, next);
});
$rootScope.showQueue();
@ -93,7 +123,7 @@ function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notif
} else {
$scope.album = [];
$rootScope.song = [];
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
if (item.status != "skipped") {
$rootScope.song.push(map(item));
}
@ -104,9 +134,9 @@ function PodcastCtrl($scope, $rootScope, $location, utils, globals, model, notif
}
}
});
}
};
/* Launch on Startup */
$scope.getPodcasts();
/* End Startup */
});
});

View file

@ -1,8 +1,8 @@
JamStash.controller('QueueCtrl',
function QueueCtrl($scope, $rootScope, $routeParams, $location, utils, globals, json, notifications) {
function QueueCtrl($scope, $rootScope, $routeParams, $location, utils, globals, json, notifications) {
$scope.settings = globals.settings;
//$scope.song = $rootScope.queue;
//angular.copy($rootScope.queue, $scope.song);
$scope.song = $rootScope.queue;
});
});

View file

@ -1,34 +1,55 @@
JamStash.controller('SettingsCtrl',
function SettingsCtrl($scope, $routeParams, $location, utils, globals, json, notifications) {
function SettingsCtrl($scope, $routeParams, $location, utils, globals, json, notifications) {
$scope.settings = globals.settings;
$scope.Timeouts = [
{ id: 10000, name: 10 },
{ id: 20000, name: 20 },
{ id: 30000, name: 30 },
{ id: 40000, name: 40 },
{ id: 50000, name: 50 },
{ id: 60000, name: 60 },
{ id: 90000, name: 90 },
{ id: 120000, name: 120 }
];
$scope.Timeouts = [{
id: 10000,
name: 10
}, {
id: 20000,
name: 20
}, {
id: 30000,
name: 30
}, {
id: 40000,
name: 40
}, {
id: 50000,
name: 50
}, {
id: 60000,
name: 60
}, {
id: 90000,
name: 90
}, {
id: 120000,
name: 120
}];
$scope.Protocols = ["json", "jsonp"];
$scope.Themes = ["Default", "Dark"];
$scope.SearchTypes = globals.SearchTypes;
$scope.Layouts = globals.Layouts;
$scope.$watch('settings.HideAZ', function () {
$scope.$watch('settings.HideAZ', function() {
if (globals.settings.HideAZ) {
$('#AZIndex').hide();
} else {
$('#AZIndex').show();
}
});
$scope.reset = function () {
$scope.reset = function() {
utils.setValue('Settings', null, true);
$scope.loadSettings();
};
$scope.save = function() {
if ($scope.settings.Password !== '' && globals.settings.Password.substring(0, 4) != 'enc:') {
$scope.settings.Password = 'enc:' + utils.HexEncode($scope.settings.Password);
}
$scope.save = function () {
if ($scope.settings.Password != '' && globals.settings.Password.substring(0, 4) != 'enc:') { $scope.settings.Password = 'enc:' + utils.HexEncode($scope.settings.Password); }
if (globals.settings.NotificationSong) {
notifications.requestPermissionIfRequired();
if (!notifications.hasNotificationPermission()) {
@ -52,19 +73,22 @@ function SettingsCtrl($scope, $routeParams, $location, utils, globals, json, not
utils.setValue('Settings', $scope.settings, true);
notifications.updateMessage('Settings Updated!', true);
$scope.loadSettings();
if (globals.settings.Server != '' && globals.settings.Username != '' && globals.settings.Password != '') {
if (globals.settings.Server !== '' && globals.settings.Username !== '' && globals.settings.Password !== '') {
$scope.ping();
}
};
json.getChangeLog(function (data) {
json.getChangeLog(function(data) {
$scope.changeLog = data.slice(0, 10);
});
$scope.changeLogShowMore = function () {
json.getChangeLog(function (data) {
$scope.changeLogShowMore = function() {
json.getChangeLog(function(data) {
$scope.changeLog = data;
});
}
$scope.setupDemo = function () {
};
$scope.setupDemo = function() {
var Username = "android-guest";
var Password = "guest";
var Server = "http://subsonic.org/demo";
@ -76,8 +100,8 @@ function SettingsCtrl($scope, $routeParams, $location, utils, globals, json, not
//$scope.save();
$location.url('/library');
}
}
};
/* Load on Startup */
/* End Startup */
});
});

View file

@ -1,31 +1,36 @@
JamStash.service('player', function ($rootScope, $window, utils, globals, model, notifications) {
JamStash.service('player', function($rootScope, $window, utils, globals, model, notifications) {
var player1 = '#playdeck_1';
var player2 = '#playdeck_2';
var scrobbled = false;
var timerid = 0;
$rootScope.defaultPlay = function (data, event) {
$rootScope.defaultPlay = function(data, event) {
if (typeof $(player1).data("jPlayer") == 'undefined') {
$rootScope.nextTrack();
}
}
$rootScope.nextTrack = function () {
};
$rootScope.nextTrack = function() {
var next = getNextSong();
if (next) {
$rootScope.playSong(false, next);
}
//$(player1).jPlayer("stop");
//$(player2).jPlayer("play");
}
$rootScope.previousTrack = function () {
};
$rootScope.previousTrack = function() {
var next = getNextSong(true);
if (next) {
$rootScope.playSong(false, next);
}
}
getNextSong = function (previous) {
};
getNextSong = function(previous) {
var song;
if (globals.settings.Debug) { console.log('Getting Next Song > ' + 'Queue length: ' + $rootScope.queue.length); }
if (globals.settings.Debug) {
console.log('Getting Next Song > ' + 'Queue length: ' + $rootScope.queue.length);
}
if ($rootScope.queue.length > 0) {
angular.forEach($rootScope.queue, function(item, key) {
if (item.playing === true) {
@ -40,7 +45,9 @@
next = $rootScope.queue[index + 1];
}
if (typeof next != 'undefined') {
if (globals.settings.Debug) { console.log('Next Song: ' + next.id); }
if (globals.settings.Debug) {
console.log('Next Song: ' + next.id);
}
return next;
} else {
return false;
@ -48,24 +55,26 @@
} else {
return false;
}
}
this.startSaveTrackPosition = function () {
};
this.startSaveTrackPosition = function() {
if (globals.settings.SaveTrackPosition) {
if (timerid != 0) {
if (timerid !== 0) {
clearInterval(timerid);
}
timerid = $window.setInterval(function () {
timerid = $window.setInterval(function() {
if (globals.settings.SaveTrackPosition) {
saveTrackPosition();
}
}, 30000);
}
}
saveTrackPosition = function () {
};
saveTrackPosition = function() {
//var audio = typeof $(player1).data("jPlayer") != 'undefined' ? true : false;
var audio = $(player1).data("jPlayer");
if (typeof audio != 'undefined') {
if (audio.status.currentTime > 0 && audio.status.paused == false) {
if (audio.status.currentTime > 0 && audio.status.paused === false) {
var song;
angular.forEach($rootScope.queue, function(item, key) {
if (item.playing === true) {
@ -74,7 +83,7 @@
});
if (song) {
var position = audio.status.currentTime;
if (position != null) {
if (position !== null) {
$('#action_SaveProgress').fadeTo("slow", 0).delay(500).fadeTo("slow", 1).delay(500).fadeTo("slow", 0).delay(500).fadeTo("slow", 1);
song.position = position;
// Save Queue
@ -82,13 +91,17 @@
try {
var songStr = angular.toJson(song);
localStorage.setItem('CurrentSong', songStr);
if (globals.settings.Debug) { console.log('Saving Current Position: ' + songStr); }
if (globals.settings.Debug) {
console.log('Saving Current Position: ' + songStr);
}
var html = localStorage.getItem('CurrentQueue');
if ($rootScope.queue.length > 0) {
var current = $rootScope.queue;
if (current != html) {
localStorage.setItem('CurrentQueue', angular.toJson(current));
if (globals.settings.Debug) { console.log('Saving Queue: ' + current.length + ' characters'); }
if (globals.settings.Debug) {
console.log('Saving Queue: ' + current.length + ' characters');
}
}
}
} catch (e) {
@ -97,14 +110,17 @@
}
}
} else {
if (globals.settings.Debug) { console.log('HTML5::loadStorage not supported on your browser'); }
if (globals.settings.Debug) {
console.log('HTML5::loadStorage not supported on your browser');
}
}
}
}
}
}
this.loadTrackPosition = function () {
};
this.loadTrackPosition = function() {
if (utils.browserStorageCheck()) {
// Load Saved Song
var song = angular.fromJson(localStorage.getItem('CurrentSong'));
@ -118,24 +134,36 @@
if ($rootScope.queue.length > 0) {
notifications.updateMessage($rootScope.queue.length + ' Saved Song(s)', true);
}
if (globals.settings.Debug) { console.log('Play Queue Loaded From localStorage: ' + $rootScope.queue.length + ' song(s)'); }
if (globals.settings.Debug) {
console.log('Play Queue Loaded From localStorage: ' + $rootScope.queue.length + ' song(s)');
}
}
}
} else {
if (globals.settings.Debug) { console.log('HTML5::loadStorage not supported on your browser'); }
if (globals.settings.Debug) {
console.log('HTML5::loadStorage not supported on your browser');
}
}
deleteCurrentQueue = function (data) {
};
deleteCurrentQueue = function(data) {
if (utils.browserStorageCheck()) {
localStorage.removeItem('CurrentQueue');
utils.setValue('CurrentSong', null, false);
if (globals.settings.Debug) { console.log('Removing Play Queue'); }
if (globals.settings.Debug) {
console.log('Removing Play Queue');
}
} else {
if (globals.settings.Debug) { console.log('HTML5::loadStorage not supported on your browser, ' + html.length + ' characters'); }
if (globals.settings.Debug) {
console.log('HTML5::loadStorage not supported on your browser, ' + html.length + ' characters');
}
}
$rootScope.playSong = function (loadonly, data) {
if (globals.settings.Debug) { console.log('Play: ' + JSON.stringify(data, null, 2)); }
};
$rootScope.playSong = function(loadonly, data) {
if (globals.settings.Debug) {
console.log('Play: ' + JSON.stringify(data, null, 2));
}
angular.forEach($rootScope.queue, function(item, key) {
item.playing = false;
});
@ -166,7 +194,8 @@
artist: artist,
favorite: false,
albumArt: coverartfull
}
};
if ($rootScope.unity) {
$rootScope.unity.sendState(playerState);
}
@ -177,13 +206,13 @@
$rootScope.showQueue();
}
var spechtml = '';
var data = $(player1).data().jPlayer;
data = $(player1).data().jPlayer;
for (i = 0; i < data.solutions.length; i++) {
var solution = data.solutions[i];
if (data[solution].used) {
spechtml += "<strong class=\"codesyntax\">" + solution + "</strong> is";
spechtml += " currently being used with<strong>";
for (format in data[solution].support) {
for (var format in data[solution].support) {
if (data[solution].support[format]) {
spechtml += " <strong class=\"codesyntax\">" + format + "</strong>";
}
@ -198,17 +227,18 @@
notifications.showNotification(coverartthumb, utils.toHTML.un(title), utils.toHTML.un(artist + ' - ' + album), 'text', '#NextTrack');
}
if (globals.settings.ScrollTitle) {
var title = utils.toHTML.un(artist) + ' - ' + utils.toHTML.un(title);
title = utils.toHTML.un(artist) + ' - ' + utils.toHTML.un(title);
utils.scrollTitle(title);
} else {
utils.setTitle(utils.toHTML.un(artist) + ' - ' + utils.toHTML.un(title));
}
//utils.safeApply();
if(!$rootScope.$root.$$phase) {
if (!$rootScope.$root.$$phase) {
$rootScope.$apply();
}
};
$rootScope.loadjPlayer = function (el, url, suffix, loadonly, position) {
$rootScope.loadjPlayer = function(el, url, suffix, loadonly, position) {
// jPlayer Setup
var volume = 1;
if (utils.getValue('Volume')) {
@ -242,7 +272,7 @@
currentTime: "#played",
duration: "#duration"
},
ready: function () {
ready: function() {
console.log("File Suffix: " + suffix);
if (suffix == 'oga') {
$(this).jPlayer("setMedia", {
@ -274,7 +304,9 @@
// Scrobble song once percentage is reached
var p = event.jPlayer.status.currentPercentAbsolute;
if (!scrobbled && p > 30) {
if (globals.settings.Debug) { console.log('LAST.FM SCROBBLE - Percent Played: ' + p); }
if (globals.settings.Debug) {
console.log('LAST.FM SCROBBLE - Percent Played: ' + p);
}
scrobbleSong(true);
}
},
@ -310,8 +342,9 @@
}
});
return;
}
this.playPauseSong = function () {
};
this.playPauseSong = function() {
if (typeof $(player1).data("jPlayer") != 'undefined') {
if ($(player1).data("jPlayer").status.paused) {
$(player1).jPlayer("play");
@ -319,20 +352,24 @@
$(player1).jPlayer("pause");
}
}
}
playVideo = function (id, bitrate) {
};
playVideo = function(id, bitrate) {
var w, h;
bitrate = parseInt(bitrate);
if (bitrate <= 600) {
w = 320; h = 240;
w = 320;
h = 240;
} else if (bitrate <= 1000) {
w = 480; h = 360;
w = 480;
h = 360;
} else {
w = 640; h = 480;
w = 640;
h = 480;
}
//$("#jPlayerSelector").jPlayer("option", "fullScreen", true);
$("#videodeck").jPlayer({
ready: function () {
ready: function() {
/*
$.fancybox({
autoSize: false,
@ -350,32 +387,35 @@
solution: "html, flash",
supplied: "m4v"
});
}
};
scrobbleSong = function (submission) {
scrobbleSong = function(submission) {
if ($rootScope.loggedIn && submission) {
var id = $rootScope.playingSong.id;
if (globals.settings.Debug) { console.log('Scrobble Song: ' + id); }
if (globals.settings.Debug) {
console.log('Scrobble Song: ' + id);
}
$.ajax({
url: globals.BaseURL() + '/scrobble.view?' + globals.BaseParams() + '&id=' + id + "&submission=" + submission,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: 10000,
success: function () {
success: function() {
scrobbled = true;
}
});
}
}
rateSong = function (songid, rating) {
};
rateSong = function(songid, rating) {
$.ajax({
url: baseURL + '/setRating.view?' + baseParams + '&id=' + songid + "&rating=" + rating,
method: 'GET',
dataType: protocol,
timeout: 10000,
success: function () {
success: function() {
updateMessage('Rating Updated!', true);
}
});
}
};
});

View file

@ -1,6 +1,6 @@
JamStash.service('model', function () {
JamStash.service('model', function() {
// Figure out how to move this, circular dependency with utils
secondsToTime = function (secs) {
secondsToTime = function(secs) {
// secs = 4729
var times = new Array(3600, 60, 1);
var time = '';
@ -12,12 +12,10 @@
// 2: 49/1 = 49
if (tmp < 1) {
tmp = '00';
}
else if (tmp < 10) {
} else if (tmp < 10) {
tmp = '0' + tmp;
}
if (i == 0 && tmp == '00') {
} else {
if (i === 0 && tmp == '00') {} else {
time += tmp;
if (i < 2) {
time += ':';
@ -26,16 +24,19 @@
secs = secs % times[i];
}
return time;
}
this.Index = function (name, artist) {
};
this.Index = function(name, artist) {
this.name = name;
this.artist = artist;
}
this.Artist = function (id, name) {
};
this.Artist = function(id, name) {
this.id = id;
this.name = name;
}
this.Album = function (id, parentid, name, artist, artistId, coverartthumb, coverartfull, date, starred, description, url, type) {
};
this.Album = function(id, parentid, name, artist, artistId, coverartthumb, coverartfull, date, starred, description, url, type) {
this.id = id;
this.parentid = parentid;
this.name = name;
@ -48,8 +49,9 @@
this.description = description;
this.url = url;
this.type = type;
}
this.Song = function (id, parentid, track, name, artist, artistId, album, albumId, coverartthumb, coverartfull, duration, rating, starred, suffix, specs, url, position, description) {
};
this.Song = function(id, parentid, track, name, artist, artistId, album, albumId, coverartthumb, coverartfull, duration, rating, starred, suffix, specs, url, position, description) {
this.id = id;
this.parentid = parentid;
this.track = track;
@ -61,7 +63,7 @@
this.coverartthumb = coverartthumb;
this.coverartfull = coverartfull;
this.duration = duration;
this.time = duration == '' ? '00:00' : secondsToTime(duration);
this.time = duration === '' ? '00:00' : secondsToTime(duration);
this.rating = rating;
this.starred = starred;
this.suffix = suffix;
@ -72,33 +74,50 @@
this.playing = false;
this.description = description;
this.displayName = this.name + " - " + this.album + " - " + this.artist;
}
};
});
JamStash.service('globals', function () {
this.SearchTypes = [
{ id: "song", name: "Song" },
{ id: "album", name: "Album" },
{ id: "artist", name: "Artist" },
];
this.Layouts = [
{ id: "grid", name: "Grid" },
{ id: "list", name: "List" }
];
this.AlbumSorts = [
{ id: "default", name: "Default Sort" },
{ id: "artist", name: "Artist" },
{ id: "album", name: "Album" },
{ id: "track", name: "Track" },
{ id: "createdate desc", name: "Date Added" },
];
JamStash.service('globals', function() {
this.SearchTypes = [{
id: "song",
name: "Song"
}, {
id: "album",
name: "Album"
}, {
id: "artist",
name: "Artist"
}, ];
this.Layouts = [{
id: "grid",
name: "Grid"
}, {
id: "list",
name: "List"
}];
this.AlbumSorts = [{
id: "default",
name: "Default Sort"
}, {
id: "artist",
name: "Artist"
}, {
id: "album",
name: "Album"
}, {
id: "track",
name: "Track"
}, {
id: "createdate desc",
name: "Date Added"
}, ];
this.settings = {
// Subsonic
/* Demo Server
Username: "android-guest"),
Password: "guest"),
Server: "http://subsonic.org/demo"),
*/
Url: "http://Jamstash.com/beta/#/archive/",
Username: "",
Password: "",
@ -127,17 +146,24 @@ JamStash.service('globals', function () {
Repeat: false,
Debug: false
};
this.SavedCollections = [];
this.SavedGenres = [];
this.BaseURL = function () { return this.settings.Server + '/rest'; };
this.BaseParams = function () { return 'u=' + this.settings.Username + '&p=' + this.settings.Password + '&f=' + this.settings.Protocol + '&v=' + this.settings.ApiVersion + '&c=' + this.settings.ApplicationName; };
this.BaseURL = function() {
return this.settings.Server + '/rest';
};
this.BaseParams = function() {
return 'u=' + this.settings.Username + '&p=' + this.settings.Password + '&f=' + this.settings.Protocol + '&v=' + this.settings.ApiVersion + '&c=' + this.settings.ApplicationName;
};
});
// Directives
JamStash.directive('layout', function () {
JamStash.directive('layout', function() {
return {
link: function (scope, elm, attrs) {
link: function(scope, elm, attrs) {
var pageLayoutOptions = {
name: 'pageLayout', // only for debugging
@ -157,16 +183,16 @@ JamStash.directive('layout', function () {
};
var layoutThreeCol = {
east__size: .42,
east__size: 0.42,
east__minSize: 400,
east__maxSize: .5, // 50% of layout width
east__maxSize: 0.5, // 50% of layout width
east__initClosed: false,
east__initHidden: false,
//center__size: 'auto',
center__minWidth: .38,
center__minWidth: 0.38,
center__initClosed: false,
center__initHidden: false,
west__size: .2,
west__size: 0.2,
west__minSize: 200,
west__initClosed: false,
west__initHidden: false,
@ -176,12 +202,12 @@ JamStash.directive('layout', function () {
};
var layoutTwoCol = {
center__size: .8,
center__size: 0.8,
center__minSize: 400,
center__maxSize: .5, // 50% of layout width
center__maxSize: 0.5, // 50% of layout width
center__initClosed: false,
center__initHidden: false,
west__size: .2,
west__size: 0.2,
west__minSize: 200,
west__initClosed: false,
west__initHidden: false,
@ -190,17 +216,20 @@ JamStash.directive('layout', function () {
//applyDefaultStyles: true
};
scope.$watch(attrs.state, function (state) {
scope.$watch(attrs.state, function(state) {
var layout;
if (state == 1) {
var layout = elm.layout(pageLayoutOptions);
layout = elm.layout(pageLayoutOptions);
}
if (state == 2) {
var layout = elm.layout(layoutTwoCol);
layout = elm.layout(layoutTwoCol);
//scope.layout.sizePane('east', 120);
//scope.layout.show('west');
//scope.layout.show('south');
} else if (state == 3) {
var layout = elm.layout(layoutThreeCol);
layout = elm.layout(layoutThreeCol);
//scope.layout.sizePane('east', 60);
//scope.layout.hide('west');
//scope.layout.hide('south');
@ -210,9 +239,10 @@ JamStash.directive('layout', function () {
}
};
});
JamStash.directive('sortable', function () {
JamStash.directive('sortable', function() {
return {
link: function (scope, elm, attrs) {
link: function(scope, elm, attrs) {
elm.sortable({
start: scope.dragStart,
update: scope.dragEnd
@ -221,49 +251,17 @@ JamStash.directive('sortable', function () {
}
};
});
JamStash.directive('split', function () {
JamStash.directive('split', function() {
return {
link: function (scope, elm, attrs) {
link: function(scope, elm, attrs) {
elm.splitPane();
/*
//elm.first().resizable({
$('#SubsonicAlbums > div:first').resizable({
handles: 'e',
minWidth: '100',
maxWidth: '400',
resize: function () {
alert('foo');
var remainingSpace = $(this).parent().width() - $(this).outerWidth();
var divTwo = $(this).next();
var divTwoWidth = remainingSpace - (divTwo.outerWidth() - divTwo.width());
divTwo.css('width', divTwoWidth + 'px');
}
});
*/
/*
scope.$watch(attrs.state, function (state) {
if (state == 1) {
var layout = elm.layout(pageLayoutOptions);
}
if (state == 2) {
var layout = elm.layout(layoutTwoCol);
//scope.layout.sizePane('east', 120);
//scope.layout.show('west');
//scope.layout.show('south');
} else if (state == 3) {
var layout = elm.layout(layoutThreeCol);
//scope.layout.sizePane('east', 60);
//scope.layout.hide('west');
//scope.layout.hide('south');
}
scope.layout = layout;
});
*/
}
};
});
JamStash.directive('fancybox', function ($compile) {
JamStash.directive('fancybox', function($compile) {
return {
restrict: 'A',
replace: false,
@ -274,7 +272,7 @@ JamStash.directive('fancybox', function ($compile) {
$.fancybox.open(el);
compiled($scope);
};
$scope.fancyboxOpenUrl = function () {
$scope.fancyboxOpenUrl = function() {
var el = angular.element(element.html()),
compiled = $compile(el);
$.fancybox.open(el);
@ -283,7 +281,8 @@ JamStash.directive('fancybox', function ($compile) {
}
};
});
JamStash.directive('songpreview', function ($compile, subsonic) {
JamStash.directive('songpreview', function($compile, subsonic) {
return {
restrict: 'E',
templateUrl: 'js/partials/songs.html',
@ -292,8 +291,8 @@ JamStash.directive('songpreview', function ($compile, subsonic) {
scope: {
song: '@'
},
link: function (scope, element, attrs) {
subsonic.getSongTemplate(function (data) {
link: function(scope, element, attrs) {
subsonic.getSongTemplate(function(data) {
scope.song = data;
//var el = angular.element(element.html()),
//var el = element.html(),
@ -302,23 +301,25 @@ JamStash.directive('songpreview', function ($compile, subsonic) {
//compiled($scope);
});
}
}
})
JamStash.directive('stopEvent', function () {
};
});
JamStash.directive('stopEvent', function() {
return {
restrict: 'A',
link: function (scope, element, attr) {
element.bind(attr.stopEvent, function (e) {
link: function(scope, element, attr) {
element.bind(attr.stopEvent, function(e) {
e.stopPropagation();
});
}
};
});
JamStash.directive('ngEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
JamStash.directive('ngEnter', function() {
return function(scope, element, attrs) {
element.bind("keydown keypress", function(event) {
if (event.which === 13) {
scope.$apply(function () {
scope.$apply(function() {
scope.$eval(attrs.ngEnter);
});
@ -327,13 +328,18 @@ JamStash.directive('ngEnter', function () {
});
};
});
JamStash.directive('ngDownload', function ($compile) {
JamStash.directive('ngDownload', function($compile) {
return {
restrict: 'E',
scope: { data: '=' },
link: function (scope, elm, attrs) {
scope: {
data: '='
},
link: function(scope, elm, attrs) {
function getUrl() {
return URL.createObjectURL(new Blob([JSON.stringify(scope.data)], { type: "application/json" }));
return URL.createObjectURL(new Blob([JSON.stringify(scope.data)], {
type: "application/json"
}));
}
elm.append($compile(
@ -343,7 +349,7 @@ JamStash.directive('ngDownload', function ($compile) {
'</a>'
)(scope));
scope.$watch(scope.data, function () {
scope.$watch(scope.data, function() {
elm.children()[0].href = getUrl();
});
}
@ -351,47 +357,45 @@ JamStash.directive('ngDownload', function ($compile) {
});
/* Factory */
JamStash.factory('json', function ($http) { // Deferred loading
JamStash.factory('json', function($http) { // Deferred loading
return {
getCollections: function (callback) {
getCollections: function(callback) {
$http.get('js/json_collections.js').success(callback);
},
getChangeLog: function (callback) {
getChangeLog: function(callback) {
$http.get('js/json_changelog.js').success(callback);
}
}
};
});
JamStash.factory('template', function ($http, $compile, $http, $templateCache) { // Deferred loading
JamStash.factory('template', function($compile, $http, $templateCache) { // Deferred loading
return {
getCollections: function (callback) {
$http.get('js/json_collections.js', { cache: $templateCache }).success(callback);
getCollections: function(callback) {
$http.get('js/json_collections.js', {
cache: $templateCache
}).success(callback);
},
getChangeLog: function (callback) {
$http.get('js/json_changelog.js', { cache: $templateCache }).success(callback);
getChangeLog: function(callback) {
$http.get('js/json_changelog.js', {
cache: $templateCache
}).success(callback);
},
getSongs: function (callback) {
getSongs: function(callback) {
templateUrl = 'js/partials/songs.html';
$http.get(templateUrl, { cache: $templateCache }).success(callback);
}
$http.get(templateUrl, {
cache: $templateCache
}).success(callback);
}
};
});
JamStash.factory('subsonic', function ($http, globals, utils) {
JamStash.factory('subsonic', function($http, globals, utils) {
return {
getSongTemplate: function (callback) {
getSongTemplate: function(callback) {
var id = '16608';
var url = globals.BaseURL() + '/getMusicDirectory.view?' + globals.BaseParams() + '&id=' + id;
/*
$.ajax({
url: url,
method: 'GET',
dataType: globals.settings.Protocol,
timeout: globals.settings.Timeout,
success: function (data) {
}
});
*/
$http.get(url).success(function (data) {
$http.get(url).success(function(data) {
var items = [];
var song = [];
if (typeof data["subsonic-response"].directory.child != 'undefined') {
@ -400,7 +404,7 @@ JamStash.factory('subsonic', function ($http, globals, utils) {
} else {
items[0] = data["subsonic-response"].directory.child;
}
angular.forEach(items, function (item, key) {
angular.forEach(items, function(item, key) {
if (!item.isDir) {
song.push(utils.mapSong(item));
}
@ -409,47 +413,54 @@ JamStash.factory('subsonic', function ($http, globals, utils) {
}
});
}
}
};
});
/* Filters */
JamStash.filter('capitalize', function () {
return function (input, scope) {
JamStash.filter('capitalize', function() {
return function(input, scope) {
return input.substring(0, 1).toUpperCase() + input.substring(1);
}
};
});
JamStash.service('notifications', function ($rootScope, globals) {
JamStash.service('notifications', function($rootScope, globals) {
var msgIndex = 1;
this.updateMessage = function (msg, autohide) {
if (msg != '') {
this.updateMessage = function(msg, autohide) {
if (msg !== '') {
var id = msgIndex;
$('#messages').append('<span id=\"msg_' + id + '\" class="message">' + msg + '</span>');
$('#messages').fadeIn();
$("#messages").scrollTo('100%');
var el = '#msg_' + id;
if (autohide) {
setTimeout(function () {
$(el).fadeOut(function () { $(this).remove(); });
setTimeout(function() {
$(el).fadeOut(function() {
$(this).remove();
});
}, globals.settings.NotificationTimeout);
}
$(el).click(function () {
$(el).fadeOut(function () { $(this).remove(); });
$(el).click(function() {
$(el).fadeOut(function() {
$(this).remove();
});
return false;
});
msgIndex++;
}
}
this.requestPermissionIfRequired = function () {
};
this.requestPermissionIfRequired = function() {
if (!this.hasNotificationPermission() && (window.webkitNotifications)) {
window.webkitNotifications.requestPermission();
}
}
this.hasNotificationPermission = function () {
return !!(window.webkitNotifications) && (window.webkitNotifications.checkPermission() == 0);
}
var notifications = new Array();
this.showNotification = function (pic, title, text, type, bind) {
};
this.hasNotificationPermission = function() {
return !!(window.webkitNotifications) && (window.webkitNotifications.checkPermission() === 0);
};
var notifications = [];
this.showNotification = function(pic, title, text, type, bind) {
if (this.hasNotificationPermission()) {
//closeAllNotifications()
var popup;
@ -458,25 +469,26 @@ JamStash.service('notifications', function ($rootScope, globals) {
} else if (type == 'html') {
popup = window.webkitNotifications.createHTMLNotification(text);
}
if (bind = '#NextTrack') {
popup.addEventListener('click', function (bind) {
if (bind == '#NextTrack') {
popup.addEventListener('click', function(bind) {
//$(bind).click();
$rootScope.nextTrack();
this.cancel();
})
});
}
notifications.push(popup);
setTimeout(function (notWin) {
setTimeout(function(notWin) {
notWin.cancel();
}, globals.settings.NotificationTimeout, popup);
popup.show();
} else {
console.log("showNotification: No Permission");
}
}
this.closeAllNotifications = function () {
for (notification in notifications) {
};
this.closeAllNotifications = function() {
for (var notification in notifications) {
notifications[notification].cancel();
}
}
};
});

View file

@ -1 +0,0 @@


View file

@ -1,15 +1,17 @@
JamStash.service('utils', function ($cookieStore, globals, model) {
this.safeApply = function (fn) {
JamStash.service('utils', function($cookieStore, globals, model) {
this.safeApply = function(fn) {
var phase = this.$root.$$phase;
if (phase == '$apply' || phase == '$digest') {
if (fn && (typeof (fn) === 'function')) {
if (fn && (typeof(fn) === 'function')) {
fn();
}
} else {
this.$apply(fn);
}
};
this.setValue = function (key, value, notify) {
this.setValue = function(key, value, notify) {
/*
if (value !== null) {
$cookieStore.put(key, value);
@ -22,10 +24,13 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch (e) {
if (globals.settings.Debug) { console.log(e); }
if (globals.settings.Debug) {
console.log(e);
}
}
this.getValue = function (value) {
};
this.getValue = function(value) {
/*
if ($cookieStore.get(value)) {
return $cookieStore.get(value);
@ -35,57 +40,93 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
*/
try {
var item = localStorage.getItem(value);
if (item != '' && typeof item != 'undefined') {
if (item !== '' && typeof item != 'undefined') {
return JSON.parse(item);
} else {
return false;
}
} catch (e) {
if (globals.settings.Debug) { console.log(e); }
if (globals.settings.Debug) {
console.log(e);
}
}
this.mapSong = function (data) {
};
this.mapSong = function(data) {
var song = data;
var url, title, track, rating, starred, contenttype, suffix, description;
var specs = '', coverartthumb = '', coverartfull = '';
var specs = '',
coverartthumb = '',
coverartfull = '';
if (typeof song.coverArt != 'undefined') {
coverartthumb = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&size=60&id=' + song.coverArt;
coverartfull = globals.BaseURL() + '/getCoverArt.view?' + globals.BaseParams() + '&id=' + song.coverArt;
}
if (typeof song.description == 'undefined') { description = ''; } else { description = song.description; }
if (typeof song.title == 'undefined') { title = '&nbsp;'; } else { title = song.title.toString(); }
if (typeof song.track == 'undefined') { track = '&nbsp;'; } else { track = song.track.toString(); }
if (typeof song.starred !== 'undefined') { starred = true; } else { starred = false; }
if (song.bitRate !== undefined) { specs += song.bitRate + ' Kbps'; }
if (song.transcodedSuffix !== undefined) { specs += ', transcoding:' + song.suffix + ' > ' + song.transcodedSuffix; } else { specs += ', ' + song.suffix; }
if (song.transcodedSuffix !== undefined) { suffix = song.transcodedSuffix; } else { suffix = song.suffix; }
if (suffix == 'ogg') { suffix = 'oga'; }
if (typeof song.description == 'undefined') {
description = '';
} else {
description = song.description;
}
if (typeof song.title == 'undefined') {
title = '&nbsp;';
} else {
title = song.title.toString();
}
if (typeof song.track == 'undefined') {
track = '&nbsp;';
} else {
track = song.track.toString();
}
if (typeof song.starred !== 'undefined') {
starred = true;
} else {
starred = false;
}
if (song.bitRate !== undefined) {
specs += song.bitRate + ' Kbps';
}
if (song.transcodedSuffix !== undefined) {
specs += ', transcoding:' + song.suffix + ' > ' + song.transcodedSuffix;
} else {
specs += ', ' + song.suffix;
}
if (song.transcodedSuffix !== undefined) {
suffix = song.transcodedSuffix;
} else {
suffix = song.suffix;
}
if (suffix == 'ogg') {
suffix = 'oga';
}
var salt = Math.floor(Math.random() * 100000);
url = globals.BaseURL() + '/stream.view?' + globals.BaseParams() + '&id=' + song.id + '&salt=' + salt;
return new model.Song(song.id, song.parent, track, title, song.artist, song.artistId, song.album, song.albumId, coverartthumb, coverartfull, song.duration, song.userRating, starred, suffix, specs, url, 0, description);
}
this.confirmDelete = function (text) {
};
this.confirmDelete = function(text) {
var question = confirm(text);
if (question) {
return true;
}
else {
} else {
return false;
}
}
this.makeBaseAuth = function (user, password) {
};
this.makeBaseAuth = function(user, password) {
var tok = user + ':' + password;
var hash = $.base64Encode(tok);
return "Basic " + hash;
}
this.HexEncode = function (n) {
};
this.HexEncode = function(n) {
for (var u = "0123456789abcdef", i = [], r = [], t = 0; t < 256; t++)
i[t] = u.charAt(t >> 4) + u.charAt(t & 15);
for (t = 0; t < n.length; t++)
r[t] = i[n.charCodeAt(t)];
return r.join("")
}
this.switchTheme = function (theme) {
return r.join("");
};
this.switchTheme = function(theme) {
switch (theme.toLowerCase()) {
case 'dark':
$('link[data-name=theme]').attr('href', 'style/Dark.css');
@ -96,16 +137,18 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
default:
break;
}
}
};
// HTML5
this.browserStorageCheck = function () {
if (typeof (localStorage) == 'undefined') {
this.browserStorageCheck = function() {
if (typeof(localStorage) == 'undefined') {
return false;
} else {
return true;
}
}
this.timeToSeconds = function (time) {
};
this.timeToSeconds = function(time) {
var a = time.split(':'); // split it at the colons
var seconds;
switch (a.length) {
@ -122,8 +165,9 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
break;
}
return seconds;
}
this.secondsToTime = function (secs) {
};
this.secondsToTime = function(secs) {
// secs = 4729
var times = new Array(3600, 60, 1);
var time = '';
@ -135,12 +179,10 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
// 2: 49/1 = 49
if (tmp < 1) {
tmp = '00';
}
else if (tmp < 10) {
} else if (tmp < 10) {
tmp = '0' + tmp;
}
if (i == 0 && tmp == '00') {
} else {
if (i === 0 && tmp == '00') {} else {
time += tmp;
if (i < 2) {
time += ':';
@ -149,27 +191,30 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
secs = secs % times[i];
}
return time;
}
this.arrayObjectIndexOf = function (myArray, searchTerm, property) {
};
this.arrayObjectIndexOf = function(myArray, searchTerm, property) {
for (var i = 0, len = myArray.length; i < len; i++) {
if (myArray[i][property] === searchTerm) return i;
}
return -1;
}
this.logObjectProperties = function (obj) {
$.each(obj, function (key, value) {
};
this.logObjectProperties = function(obj) {
$.each(obj, function(key, value) {
var parent = key;
if (typeof value === "object") {
$.each(value, function (key, value) {
$.each(value, function(key, value) {
console.log(parent + ' > ' + key + ' : ' + value);
});
} else {
console.log(key + ' : ' + value);
}
});
}
this.clickButton = function (el) {
var el = $(el);
};
this.clickButton = function(el) {
el = $(el);
if (el) {
var classes = $(el).attr('class').split(" ");
for (var i = 0, l = classes.length; i < l; ++i) {
@ -186,86 +231,143 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
}
}
}
}
this.findKeyForCode = function (code) {
var map = { 'keymap': [
{ 'key': 'a', 'code': 65 },
{ 'key': 'b', 'code': 66 },
{ 'key': 'c', 'code': 67 },
{ 'key': 'd', 'code': 68 },
{ 'key': 'e', 'code': 69 },
{ 'key': 'f', 'code': 70 },
{ 'key': 'g', 'code': 71 },
{ 'key': 'h', 'code': 72 },
{ 'key': 'i', 'code': 73 },
{ 'key': 'j', 'code': 74 },
{ 'key': 'k', 'code': 75 },
{ 'key': 'l', 'code': 76 },
{ 'key': 'm', 'code': 77 },
{ 'key': 'n', 'code': 78 },
{ 'key': 'o', 'code': 79 },
{ 'key': 'p', 'code': 80 },
{ 'key': 'q', 'code': 81 },
{ 'key': 'r', 'code': 82 },
{ 'key': 's', 'code': 83 },
{ 'key': 't', 'code': 84 },
{ 'key': 'u', 'code': 85 },
{ 'key': 'v', 'code': 86 },
{ 'key': 'w', 'code': 87 },
{ 'key': 'x', 'code': 88 },
{ 'key': 'y', 'code': 89 },
{ 'key': 'z', 'code': 90 }
]
};
this.findKeyForCode = function(code) {
var map = {
'keymap': [{
'key': 'a',
'code': 65
}, {
'key': 'b',
'code': 66
}, {
'key': 'c',
'code': 67
}, {
'key': 'd',
'code': 68
}, {
'key': 'e',
'code': 69
}, {
'key': 'f',
'code': 70
}, {
'key': 'g',
'code': 71
}, {
'key': 'h',
'code': 72
}, {
'key': 'i',
'code': 73
}, {
'key': 'j',
'code': 74
}, {
'key': 'k',
'code': 75
}, {
'key': 'l',
'code': 76
}, {
'key': 'm',
'code': 77
}, {
'key': 'n',
'code': 78
}, {
'key': 'o',
'code': 79
}, {
'key': 'p',
'code': 80
}, {
'key': 'q',
'code': 81
}, {
'key': 'r',
'code': 82
}, {
'key': 's',
'code': 83
}, {
'key': 't',
'code': 84
}, {
'key': 'u',
'code': 85
}, {
'key': 'v',
'code': 86
}, {
'key': 'w',
'code': 87
}, {
'key': 'x',
'code': 88
}, {
'key': 'y',
'code': 89
}, {
'key': 'z',
'code': 90
}]
};
var keyFound = 0;
$.each(map.keymap, function (i, mapping) {
$.each(map.keymap, function(i, mapping) {
if (mapping.code === code) {
keyFound = mapping.key;
}
});
return keyFound;
}
};
this.toHTML = {
on: function (str) {
on: function(str) {
var a = [],
i = 0;
for (; i < str.length; ) a[i] = str.charCodeAt(i++);
return "&#" + a.join(";&#") + ";"
for (; i < str.length;) a[i] = str.charCodeAt(i++);
return "&#" + a.join(";&#") + ";";
},
un: function (str) {
un: function(str) {
return str.replace(/&#(x)?([^;]{1,5});?/g,
function (a, b, c) {
return String.fromCharCode(parseInt(c, b ? 16 : 10))
})
function(a, b, c) {
return String.fromCharCode(parseInt(c, b ? 16 : 10));
});
}
};
this.getParameterByName = function (name) {
this.getParameterByName = function(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.search);
if (results == null)
if (results === null)
return "";
else
return decodeURIComponent(results[1].replace(/\+/g, " "));
}
this.getPathFromUrl = function (url) {
};
this.getPathFromUrl = function(url) {
var strurl = url.toString();
var u = strurl.substring(0, strurl.indexOf('?'));
return u
}
this.setTitle = function (text) {
if (text != "") {
return u;
};
this.setTitle = function(text) {
if (text !== "") {
document.title = text;
}
}
};
var timer = 0;
this.scrollTitle = function (text) {
this.scrollTitle = function(text) {
var shift = {
"left": function (a) {
"left": function(a) {
a.push(a.shift());
},
"right": function (a) {
"right": function(a) {
a.unshift(a.pop());
}
};
@ -281,23 +383,19 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
}
t.push(" ");
clearInterval(timer);
timer = setInterval(function () {
timer = setInterval(function() {
var f = shift[opts.dir];
if (f) {
f(t);
document.title = t.join("");
}
}, opts.speed);
/*
$.marqueeTitle({
text: text,
dir: "left",
speed: 1200
});
*/
};
this.parseVersionString = function(str) {
if (typeof(str) != 'string') {
return false;
}
this.parseVersionString = function (str) {
if (typeof (str) != 'string') { return false; }
var x = str.split('.');
// parse from string or default to 0 if can't parse
var maj = parseInt(x[0]) || 0;
@ -307,9 +405,10 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
major: maj,
minor: min,
patch: pat
}
}
this.checkVersion = function (runningVersion, minimumVersion) {
};
};
this.checkVersion = function(runningVersion, minimumVersion) {
if (runningVersion.major >= minimumVersion.major) {
if (runningVersion.minor >= minimumVersion.minor) {
if (runningVersion.patch >= minimumVersion.patch) {
@ -323,8 +422,9 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
} else {
return false;
}
}
this.checkVersionNewer = function (runningVersion, newVersion) {
};
this.checkVersionNewer = function(runningVersion, newVersion) {
if (runningVersion.major < newVersion.major) {
return true;
} else {
@ -338,14 +438,14 @@ JamStash.service('utils', function ($cookieStore, globals, model) {
}
}
}
}
this.parseDate = function (date) {
};
this.parseDate = function(date) {
// input: "2012-09-23 20:00:00.0"
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var parts = date.split(" ");
var dateParts = parts[0].split("-");
var month = parseInt(dateParts[1], 10) - 1;
var date = months[month] + " " + dateParts[2] + ", " + dateParts[0];
return date;
}
return months[month] + " " + dateParts[2] + ", " + dateParts[0];
};
});