// lib/handlebars/base.js /*jshint eqnull:true*/this.Handlebars={},function(e){e.VERSION="1.0.rc.1",e.helpers={},e.partials={},e.registerHelper=function(e,t,n){n&&(t.not=n),this.helpers[e]=t},e.registerPartial=function(e,t){this.partials[e]=t},e.registerHelper("helperMissing",function(e){if(arguments.length===2)return undefined;throw new Error("Could not find property '"+e+"'")});var t=Object.prototype.toString,n="[object Function]";e.registerHelper("blockHelperMissing",function(r,i){var s=i.inverse||function(){},o=i.fn,u="",a=t.call(r);return a===n&&(r=r.call(this)),r===!0?o(this):r===!1||r==null?s(this):a==="[object Array]"?r.length>0?e.helpers.each(r,i):s(this):o(r)}),e.K=function(){},e.createFrame=Object.create||function(t){e.K.prototype=t;var n=new e.K;return e.K.prototype=null,n},e.registerHelper("each",function(t,n){var r=n.fn,i=n.inverse,s=0,o="",u;n.data&&(u=e.createFrame(n.data));if(t&&typeof t=="object")if(t instanceof Array)for(var a=t.length;s2&&k.push("'"+this.terminals_[T]+"'");this.lexer.showPosition?L="Parse error on line "+(a+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[g]||g)+"'":L="Parse error on line "+(a+1)+": Unexpected "+(g==1?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(L,{text:this.lexer.match,token:this.terminals_[g]||g,line:this.lexer.yylineno,loc:p,expected:k})}}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+g);switch(w[0]){case 1:r.push(g),i.push(this.lexer.yytext),s.push(this.lexer.yylloc),r.push(w[1]),g=null,y?(g=y,y=null):(f=this.lexer.yyleng,u=this.lexer.yytext,a=this.lexer.yylineno,p=this.lexer.yylloc,l>0&&l--);break;case 2:N=this.productions_[w[1]][1],x.$=i[i.length-N],x._$={first_line:s[s.length-(N||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(N||1)].first_column,last_column:s[s.length-1].last_column},d&&(x._$.range=[s[s.length-(N||1)].range[0],s[s.length-1].range[1]]),S=this.performAction.call(x,u,f,a,this.yy,w[1],i,s);if(typeof S!="undefined")return S;N&&(r=r.slice(0,-1*N*2),i=i.slice(0,-1*N),s=s.slice(0,-1*N)),r.push(this.productions_[w[1]][0]),i.push(x.$),s.push(x._$),C=o[r[r.length-2]][r[r.length-1]],r.push(C);break;case 3:return!0}}return!0}},t=function(){var e={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(e){return this._input=e,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e;var t=e.match(/(?:\r\n?|\n).*/g);return t?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,n=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t-1),this.offset-=t;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-t]),this},more:function(){return this._more=!0,this},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=(new Array(e.length+1)).join("-");return e+this.upcomingInput()+"\n"+t+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var e,t,n,r,i,s;this._more||(this.yytext="",this.match="");var o=this._currentRules();for(var u=0;ut[0].length)){t=n,r=u;if(!this.options.flex)break}}if(t){s=t[0].match(/(?:\r\n?|\n).*/g),s&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,o[r],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1);if(e)return e;return}return this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return typeof t!="undefined"?t:this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(t){this.begin(t)}};return e.options={},e.performAction=function(t,n,r,i){var s=i;switch(r){case 0:n.yytext.slice(-1)!=="\\"&&this.begin("mu"),n.yytext.slice(-1)==="\\"&&(n.yytext=n.yytext.substr(0,n.yyleng-1),this.begin("emu"));if(n.yytext)return 14;break;case 1:return 14;case 2:return n.yytext.slice(-1)!=="\\"&&this.popState(),n.yytext.slice(-1)==="\\"&&(n.yytext=n.yytext.substr(0,n.yyleng-1)),14;case 3:return n.yytext=n.yytext.substr(0,n.yyleng-4),this.popState(),15;case 4:return 24;case 5:return 16;case 6:return 20;case 7:return 19;case 8:return 19;case 9:return 23;case 10:return 23;case 11:this.popState(),this.begin("com");break;case 12:return n.yytext=n.yytext.substr(3,n.yyleng-5),this.popState(),15;case 13:return 22;case 14:return 35;case 15:return 34;case 16:return 34;case 17:return 37;case 18:break;case 19:return this.popState(),18;case 20:return this.popState(),18;case 21:return n.yytext=n.yytext.substr(1,n.yyleng-2).replace(/\\"/g,'"'),29;case 22:return n.yytext=n.yytext.substr(1,n.yyleng-2).replace(/\\'/g,"'"),29;case 23:return n.yytext=n.yytext.substr(1),27;case 24:return 31;case 25:return 31;case 26:return 30;case 27:return 34;case 28:return n.yytext=n.yytext.substr(1,n.yyleng-2),34;case 29:return"INVALID";case 30:return 5}},e.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/],e.conditions={mu:{rules:[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[3],inclusive:!1},INITIAL:{rules:[0,1,30],inclusive:!0}},e}();return e.lexer=t,n.prototype=e,e.Parser=n,new n}();typeof require!="undefined"&&typeof exports!="undefined"&&(exports.parser=handlebars,exports.Parser=handlebars.Parser,exports.parse=function(){return handlebars.parse.apply(handlebars,arguments)},exports.main=function(t){if(!t[1])throw new Error("Usage: "+t[0]+" FILE");var n,r;return typeof process!="undefined"?n=require("fs").readFileSync(require("path").resolve(t[1]),"utf8"):n=require("file").path(require("file").cwd()).join(t[1]).read({charset:"utf-8"}),exports.parser.parse(n)},typeof module!="undefined"&&require.main===module&&exports.main(typeof process!="undefined"?process.argv.slice(1):require("system").args)),Handlebars.Parser=handlebars,Handlebars.parse=function(e){return Handlebars.Parser.yy=Handlebars.AST,Handlebars.Parser.parse(e)},Handlebars.print=function(e){return(new Handlebars.PrintVisitor).accept(e)},Handlebars.logger={DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(e,t){}},Handlebars.log=function(e,t){Handlebars.logger.log(e,t)},function(){Handlebars.AST={},Handlebars.AST.ProgramNode=function(e,t){this.type="program",this.statements=e,t&&(this.inverse=new Handlebars.AST.ProgramNode(t))},Handlebars.AST.MustacheNode=function(e,t,n){this.type="mustache",this.escaped=!n,this.hash=t;var r=this.id=e[0],i=this.params=e.slice(1),s=this.eligibleHelper=r.isSimple;this.isHelper=s&&(i.length||t)},Handlebars.AST.PartialNode=function(e,t){this.type="partial",this.id=e,this.context=t};var e=function(e,t){if(e.original!==t.original)throw new Handlebars.Exception(e.original+" doesn't match "+t.original)};Handlebars.AST.BlockNode=function(t,n,r,i){e(t.id,i),this.type="block",this.mustache=t,this.program=n,this.inverse=r,this.inverse&&!this.program&&(this.isInverse=!0)},Handlebars.AST.ContentNode=function(e){this.type="content",this.string=e},Handlebars.AST.HashNode=function(e){this.type="hash",this.pairs=e},Handlebars.AST.IdNode=function(e){this.type="ID",this.original=e.join(".");var t=[],n=0;for(var r=0,i=e.length;r":">",'"':""","'":"'","`":"`"},t=/[&<>"'`]/g,n=/[&<>"'`]/,r=function(t){return e[t]||"&"};Handlebars.Utils={escapeExpression:function(e){return e instanceof Handlebars.SafeString?e.toString():e==null||e===!1?"":n.test(e)?e.replace(t,r):e},isEmpty:function(e){return typeof e=="undefined"?!0:e===null?!0:e===!1?!0:Object.prototype.toString.call(e)==="[object Array]"&&e.length===0?!0:!1}}}(),Handlebars.Compiler=function(){},Handlebars.JavaScriptCompiler=function(){},function(e,t){e.prototype={compiler:e,disassemble:function(){var e=this.opcodes,t,n=[],r,i;for(var s=0,o=e.length;sthis.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),"stack"+this.stackSlot},popStack:function(){var e=this.compileStack.pop();return e instanceof n?e.value:(this.stackSlot--,e)},topStack:function(){var e=this.compileStack[this.compileStack.length-1];return e instanceof n?e.value:e},quotedString:function(e){return'"'+e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r")+'"'},setupHelper:function(e,t){var n=[];this.setupParams(e,n);var r=this.nameLookup("helpers",t,"helper");return{params:n,name:r,callParams:["depth0"].concat(n).join(", "),helperMissingParams:["depth0",this.quotedString(t)].concat(n).join(", ")}},setupParams:function(e,t){var n=[],r=[],i,s,o;n.push("hash:"+this.popStack()),s=this.popStack(),o=this.popStack();if(o||s)o||(this.context.aliases.self="this",o="self.noop"),s||(this.context.aliases.self="this",s="self.noop"),n.push("inverse:"+s),n.push("fn:"+o);for(var u=0;udelete').insertAfter($('.f,.r', div)); div.addClass('confirmDel'); }); $('.uploadMini').on('click', '.f i.icon-exclamation-sign,.r i.icon-exclamation-sign', function () { var pThis = $(this); var div = pThis.closest('div'); div.removeClass('confirmDel'); pThis.addClass('icon-trash').removeClass('icon-exclamation-sign'); $('.delattach', div).remove(); }); $('.uploadMini').on('click', '.delattach', function () { $(this).closest('div').remove(); updateAttachmentCount(); }); window.onbeforeunload = confirmUnload; }); function confirmUnload() { if ($('.ajaxsaving').length > 0) { return "Please allow time for the system to finish processing."; } } Handlebars.registerHelper("fromnow", function (dt) { return moment.utc(dt).local().calendar(); }); function getTagHtml(tag) { return '' + tag + ''; } Handlebars.registerHelper("tag", function (tag) { return new Handlebars.SafeString(getTagHtml(tag)); }); Handlebars.registerHelper("tagList", function (tag) { var items = tag.split(','); var ret = ''; for (var i = 0; i < items.length; i++) { if (items[i].length > 0) { ret += getTagHtml(items[i]); } } return new Handlebars.SafeString(ret); }); Handlebars.registerHelper("hashcolor", function (txt) { return hashColor(txt); }); function wService(service, data, onSuccess) { $.ajax({ type: 'POST', contentType: "application/json; charset=utf-8", url: dpJsTilde + '/WService.asmx/' + service, dataType: 'json', data: data, success: onSuccess, error: function () { $('.ajaxsaving').ajaxSavingComplete(); showErrorBackdrop('

There was a problem communicating with the server.

Please check your connection and try again.

'); } }); } function showErrorBackdrop(msg) { var bd = $('').appendTo(document.body); $('span', bd).html(msg); bd.click(function () { $(this).remove(); }); } function hsv2rgb(h, s, v) { h = (h % 1 + 1) % 1; // wrap hue var i = Math.floor(h * 6), f = h * 6 - i, p = v * (1 - s), q = v * (1 - s * f), t = v * (1 - s * (1 - f)); var rgb = [v, t, p]; switch (i) { case 1: { rgb = [q, v, p]; break; } case 2: { rgb = [p, v, t]; break; } case 3: { rgb = [p, q, v]; break; } case 4: { rgb = [t, p, v]; break; } case 5: { rgb = [v, p, q]; break; } } return '#' + toHex(rgb[0] * 255) + toHex(rgb[1] * 255) + toHex(rgb[2] * 255); } function hToHash(h) { var s=0.85; var l = 0.7; if ((h > .1) && (h < .3)) { l -= 2 * (.1 - Math.abs(h - .2)); } return hsv2rgb(h, s, l); } var _crc8Table = new Array( 0x00, 0x1B, 0x36, 0x2D, 0x6C, 0x77, 0x5A, 0x41, 0xD8, 0xC3, 0xEE, 0xF5, 0xB4, 0xAF, 0x82, 0x99, 0xD3, 0xC8, 0xE5, 0xFE, 0xBF, 0xA4, 0x89, 0x92, 0x0B, 0x10, 0x3D, 0x26, 0x67, 0x7C, 0x51, 0x4A, 0xC5, 0xDE, 0xF3, 0xE8, 0xA9, 0xB2, 0x9F, 0x84, 0x1D, 0x06, 0x2B, 0x30, 0x71, 0x6A, 0x47, 0x5C, 0x16, 0x0D, 0x20, 0x3B, 0x7A, 0x61, 0x4C, 0x57, 0xCE, 0xD5, 0xF8, 0xE3, 0xA2, 0xB9, 0x94, 0x8F, 0xE9, 0xF2, 0xDF, 0xC4, 0x85, 0x9E, 0xB3, 0xA8, 0x31, 0x2A, 0x07, 0x1C, 0x5D, 0x46, 0x6B, 0x70, 0x3A, 0x21, 0x0C, 0x17, 0x56, 0x4D, 0x60, 0x7B, 0xE2, 0xF9, 0xD4, 0xCF, 0x8E, 0x95, 0xB8, 0xA3, 0x2C, 0x37, 0x1A, 0x01, 0x40, 0x5B, 0x76, 0x6D, 0xF4, 0xEF, 0xC2, 0xD9, 0x98, 0x83, 0xAE, 0xB5, 0xFF, 0xE4, 0xC9, 0xD2, 0x93, 0x88, 0xA5, 0xBE, 0x27, 0x3C, 0x11, 0x0A, 0x4B, 0x50, 0x7D, 0x66, 0xB1, 0xAA, 0x87, 0x9C, 0xDD, 0xC6, 0xEB, 0xF0, 0x69, 0x72, 0x5F, 0x44, 0x05, 0x1E, 0x33, 0x28, 0x62, 0x79, 0x54, 0x4F, 0x0E, 0x15, 0x38, 0x23, 0xBA, 0xA1, 0x8C, 0x97, 0xD6, 0xCD, 0xE0, 0xFB, 0x74, 0x6F, 0x42, 0x59, 0x18, 0x03, 0x2E, 0x35, 0xAC, 0xB7, 0x9A, 0x81, 0xC0, 0xDB, 0xF6, 0xED, 0xA7, 0xBC, 0x91, 0x8A, 0xCB, 0xD0, 0xFD, 0xE6, 0x7F, 0x64, 0x49, 0x52, 0x13, 0x08, 0x25, 0x3E, 0x58, 0x43, 0x6E, 0x75, 0x34, 0x2F, 0x02, 0x19, 0x80, 0x9B, 0xB6, 0xAD, 0xEC, 0xF7, 0xDA, 0xC1, 0x8B, 0x90, 0xBD, 0xA6, 0xE7, 0xFC, 0xD1, 0xCA, 0x53, 0x48, 0x65, 0x7E, 0x3F, 0x24, 0x09, 0x12, 0x9D, 0x86, 0xAB, 0xB0, 0xF1, 0xEA, 0xC7, 0xDC, 0x45, 0x5E, 0x73, 0x68, 0x29, 0x32, 0x1F, 0x04, 0x4E, 0x55, 0x78, 0x63, 0x22, 0x39, 0x14, 0x0F, 0x96, 0x8D, 0xA0, 0xBB, 0xFA, 0xE1, 0xCC, 0xD7 ); var _hashCache = {}; var _hashPresets= { 'open':'#AF1A1A', 'in development':'#ADAD1A', 'request closure': '#4C1AA3', 'closed':'#1BAA1B', 'request information':'#1A76A8', 'request release': '#A51A87', 'in uat': '#BC751E' }; function hashColor(str) { if (!str) return '#888888'; str = str.toLowerCase(); if (_hashPresets[str]) { return _hashPresets[str]; } var chkCache = _hashCache[str]; if (chkCache) { return chkCache; } else { var hash = 0; if (str.length == 0) return hash; for (i = 0; i < str.length; i++) { char = str.charCodeAt(i); hash = _crc8Table[(hash ^ char) & 0xFF]; } hash = hash & 255; var h = hash / 256.0; var ret = hToHash(h); _hashCache[str] = ret; return ret; } } function toHex(n) { n = parseInt(n, 10); if (isNaN(n)) { return "00"; } n = Math.max(0, Math.min(n, 255)); return "0123456789ABCDEF".charAt((n - n % 16) / 16) + "0123456789ABCDEF".charAt(n % 16); } // moment.js // version : 2.0.0 // author : Tim Wood // license : MIT // momentjs.com (function (undefined) { /************************************ Constants ************************************/ var moment, VERSION = "2.0.0", round = Math.round, i, // internal storage for language config files languages = {}, // check for nodeJS hasModule = (typeof module !== 'undefined' && module.exports), // ASP.NET json date format regex aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, // format tokens formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g, localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, // parsing tokens parseMultipleFormatChunker = /([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi, // parsing token regexes parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999 parseTokenThreeDigits = /\d{3}/, // 000 - 999 parseTokenFourDigits = /\d{1,4}/, // 0 - 9999 parseTokenSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999 parseTokenWord = /[0-9]*[a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF]+\s*?[\u0600-\u06FF]+/i, // any word (or two) characters or numbers including two word month in arabic. parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z parseTokenT = /T/i, // T (ISO seperator) parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 // preliminary iso regex // 0000-00-00 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 isoRegex = /^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/, isoFormat = 'YYYY-MM-DDTHH:mm:ssZ', // iso time formats and regexes isoTimes = [ ['HH:mm:ss.S', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/], ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], ['HH:mm', /(T| )\d\d:\d\d/], ['HH', /(T| )\d\d/] ], // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"] parseTimezoneChunker = /([\+\-]|\d\d)/gi, // getter and setter names proxyGettersAndSetters = 'Month|Date|Hours|Minutes|Seconds|Milliseconds'.split('|'), unitMillisecondFactors = { 'Milliseconds' : 1, 'Seconds' : 1e3, 'Minutes' : 6e4, 'Hours' : 36e5, 'Days' : 864e5, 'Months' : 2592e6, 'Years' : 31536e6 }, // format function strings formatFunctions = {}, // tokens to ordinalize and pad ordinalizeTokens = 'DDD w W M D d'.split(' '), paddedTokens = 'M D H h m s w W'.split(' '), formatTokenFunctions = { M : function () { return this.month() + 1; }, MMM : function (format) { return this.lang().monthsShort(this, format); }, MMMM : function (format) { return this.lang().months(this, format); }, D : function () { return this.date(); }, DDD : function () { return this.dayOfYear(); }, d : function () { return this.day(); }, dd : function (format) { return this.lang().weekdaysMin(this, format); }, ddd : function (format) { return this.lang().weekdaysShort(this, format); }, dddd : function (format) { return this.lang().weekdays(this, format); }, w : function () { return this.week(); }, W : function () { return this.isoWeek(); }, YY : function () { return leftZeroFill(this.year() % 100, 2); }, YYYY : function () { return leftZeroFill(this.year(), 4); }, YYYYY : function () { return leftZeroFill(this.year(), 5); }, a : function () { return this.lang().meridiem(this.hours(), this.minutes(), true); }, A : function () { return this.lang().meridiem(this.hours(), this.minutes(), false); }, H : function () { return this.hours(); }, h : function () { return this.hours() % 12 || 12; }, m : function () { return this.minutes(); }, s : function () { return this.seconds(); }, S : function () { return ~~(this.milliseconds() / 100); }, SS : function () { return leftZeroFill(~~(this.milliseconds() / 10), 2); }, SSS : function () { return leftZeroFill(this.milliseconds(), 3); }, Z : function () { var a = -this.zone(), b = "+"; if (a < 0) { a = -a; b = "-"; } return b + leftZeroFill(~~(a / 60), 2) + ":" + leftZeroFill(~~a % 60, 2); }, ZZ : function () { var a = -this.zone(), b = "+"; if (a < 0) { a = -a; b = "-"; } return b + leftZeroFill(~~(10 * a / 6), 4); }, X : function () { return this.unix(); } }; function padToken(func, count) { return function (a) { return leftZeroFill(func.call(this, a), count); }; } function ordinalizeToken(func) { return function (a) { return this.lang().ordinal(func.call(this, a)); }; } while (ordinalizeTokens.length) { i = ordinalizeTokens.pop(); formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i]); } while (paddedTokens.length) { i = paddedTokens.pop(); formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2); } formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3); /************************************ Constructors ************************************/ function Language() { } // Moment prototype object function Moment(config) { extend(this, config); } // Duration Constructor function Duration(duration) { var data = this._data = {}, years = duration.years || duration.year || duration.y || 0, months = duration.months || duration.month || duration.M || 0, weeks = duration.weeks || duration.week || duration.w || 0, days = duration.days || duration.day || duration.d || 0, hours = duration.hours || duration.hour || duration.h || 0, minutes = duration.minutes || duration.minute || duration.m || 0, seconds = duration.seconds || duration.second || duration.s || 0, milliseconds = duration.milliseconds || duration.millisecond || duration.ms || 0; // representation for dateAddRemove this._milliseconds = milliseconds + seconds * 1e3 + // 1000 minutes * 6e4 + // 1000 * 60 hours * 36e5; // 1000 * 60 * 60 // Because of dateAddRemove treats 24 hours as different from a // day when working around DST, we need to store them separately this._days = days + weeks * 7; // It is impossible translate months into days without knowing // which months you are are talking about, so we have to store // it separately. this._months = months + years * 12; // The following code bubbles up values, see the tests for // examples of what that means. data.milliseconds = milliseconds % 1000; seconds += absRound(milliseconds / 1000); data.seconds = seconds % 60; minutes += absRound(seconds / 60); data.minutes = minutes % 60; hours += absRound(minutes / 60); data.hours = hours % 24; days += absRound(hours / 24); days += weeks * 7; data.days = days % 30; months += absRound(days / 30); data.months = months % 12; years += absRound(months / 12); data.years = years; } /************************************ Helpers ************************************/ function extend(a, b) { for (var i in b) { if (b.hasOwnProperty(i)) { a[i] = b[i]; } } return a; } function absRound(number) { if (number < 0) { return Math.ceil(number); } else { return Math.floor(number); } } // left zero fill a number // see http://jsperf.com/left-zero-filling for performance comparison function leftZeroFill(number, targetLength) { var output = number + ''; while (output.length < targetLength) { output = '0' + output; } return output; } // helper function for _.addTime and _.subtractTime function addOrSubtractDurationFromMoment(mom, duration, isAdding) { var ms = duration._milliseconds, d = duration._days, M = duration._months, currentDate; if (ms) { mom._d.setTime(+mom + ms * isAdding); } if (d) { mom.date(mom.date() + d * isAdding); } if (M) { currentDate = mom.date(); mom.date(1) .month(mom.month() + M * isAdding) .date(Math.min(currentDate, mom.daysInMonth())); } } // check if is an array function isArray(input) { return Object.prototype.toString.call(input) === '[object Array]'; } // compare two arrays, return the number of differences function compareArrays(array1, array2) { var len = Math.min(array1.length, array2.length), lengthDiff = Math.abs(array1.length - array2.length), diffs = 0, i; for (i = 0; i < len; i++) { if (~~array1[i] !== ~~array2[i]) { diffs++; } } return diffs + lengthDiff; } /************************************ Languages ************************************/ Language.prototype = { set : function (config) { var prop, i; for (i in config) { prop = config[i]; if (typeof prop === 'function') { this[i] = prop; } else { this['_' + i] = prop; } } }, _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), months : function (m) { return this._months[m.month()]; }, _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), monthsShort : function (m) { return this._monthsShort[m.month()]; }, monthsParse : function (monthName) { var i, mom, regex, output; if (!this._monthsParse) { this._monthsParse = []; } for (i = 0; i < 12; i++) { // make the regex if we don't have it already if (!this._monthsParse[i]) { mom = moment([2000, i]); regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); } // test the regex if (this._monthsParse[i].test(monthName)) { return i; } } }, _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), weekdays : function (m) { return this._weekdays[m.day()]; }, _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), weekdaysShort : function (m) { return this._weekdaysShort[m.day()]; }, _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), weekdaysMin : function (m) { return this._weekdaysMin[m.day()]; }, _longDateFormat : { LT : "h:mm A", L : "MM/DD/YYYY", LL : "MMMM D YYYY", LLL : "MMMM D YYYY LT", LLLL : "dddd, MMMM D YYYY LT" }, longDateFormat : function (key) { var output = this._longDateFormat[key]; if (!output && this._longDateFormat[key.toUpperCase()]) { output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) { return val.slice(1); }); this._longDateFormat[key] = output; } return output; }, meridiem : function (hours, minutes, isLower) { if (hours > 11) { return isLower ? 'pm' : 'PM'; } else { return isLower ? 'am' : 'AM'; } }, _calendar : { sameDay : '[Today at] LT', nextDay : '[Tomorrow at] LT', nextWeek : 'dddd [at] LT', lastDay : '[Yesterday at] LT', lastWeek : '[last] dddd [at] LT', sameElse : 'L' }, calendar : function (key, mom) { var output = this._calendar[key]; return typeof output === 'function' ? output.apply(mom) : output; }, _relativeTime : { future : "in %s", past : "%s ago", s : "a few seconds", m : "a minute", mm : "%d minutes", h : "an hour", hh : "%d hours", d : "a day", dd : "%d days", M : "a month", MM : "%d months", y : "a year", yy : "%d years" }, relativeTime : function (number, withoutSuffix, string, isFuture) { var output = this._relativeTime[string]; return (typeof output === 'function') ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number); }, pastFuture : function (diff, output) { var format = this._relativeTime[diff > 0 ? 'future' : 'past']; return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); }, ordinal : function (number) { return this._ordinal.replace("%d", number); }, _ordinal : "%d", preparse : function (string) { return string; }, postformat : function (string) { return string; }, week : function (mom) { return weekOfYear(mom, this._week.dow, this._week.doy); }, _week : { dow : 0, // Sunday is the first day of the week. doy : 6 // The week that contains Jan 1st is the first week of the year. } }; // Loads a language definition into the `languages` cache. The function // takes a key and optionally values. If not in the browser and no values // are provided, it will load the language file module. As a convenience, // this function also returns the language values. function loadLang(key, values) { values.abbr = key; if (!languages[key]) { languages[key] = new Language(); } languages[key].set(values); return languages[key]; } // Determines which language definition to use and returns it. // // With no parameters, it will return the global language. If you // pass in a language key, such as 'en', it will return the // definition for 'en', so long as 'en' has already been loaded using // moment.lang. function getLangDefinition(key) { if (!key) { return moment.fn._lang; } if (!languages[key] && hasModule) { require('./lang/' + key); } return languages[key]; } /************************************ Formatting ************************************/ function removeFormattingTokens(input) { if (input.match(/\[.*\]/)) { return input.replace(/^\[|\]$/g, ""); } return input.replace(/\\/g, ""); } function makeFormatFunction(format) { var array = format.match(formattingTokens), i, length; for (i = 0, length = array.length; i < length; i++) { if (formatTokenFunctions[array[i]]) { array[i] = formatTokenFunctions[array[i]]; } else { array[i] = removeFormattingTokens(array[i]); } } return function (mom) { var output = ""; for (i = 0; i < length; i++) { output += typeof array[i].call === 'function' ? array[i].call(mom, format) : array[i]; } return output; }; } // format date using native date object function formatMoment(m, format) { var i = 5; function replaceLongDateFormatTokens(input) { return m.lang().longDateFormat(input) || input; } while (i-- && localFormattingTokens.test(format)) { format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); } if (!formatFunctions[format]) { formatFunctions[format] = makeFormatFunction(format); } return formatFunctions[format](m); } /************************************ Parsing ************************************/ // get the regex to find the next token function getParseRegexForToken(token) { switch (token) { case 'DDDD': return parseTokenThreeDigits; case 'YYYY': return parseTokenFourDigits; case 'YYYYY': return parseTokenSixDigits; case 'S': case 'SS': case 'SSS': case 'DDD': return parseTokenOneToThreeDigits; case 'MMM': case 'MMMM': case 'dd': case 'ddd': case 'dddd': case 'a': case 'A': return parseTokenWord; case 'X': return parseTokenTimestampMs; case 'Z': case 'ZZ': return parseTokenTimezone; case 'T': return parseTokenT; case 'MM': case 'DD': case 'YY': case 'HH': case 'hh': case 'mm': case 'ss': case 'M': case 'D': case 'd': case 'H': case 'h': case 'm': case 's': return parseTokenOneOrTwoDigits; default : return new RegExp(token.replace('\\', '')); } } // function to convert string input to date function addTimeToArrayFromToken(token, input, config) { var a, b, datePartArray = config._a; switch (token) { // MONTH case 'M' : // fall through to MM case 'MM' : datePartArray[1] = (input == null) ? 0 : ~~input - 1; break; case 'MMM' : // fall through to MMMM case 'MMMM' : a = getLangDefinition(config._l).monthsParse(input); // if we didn't find a month name, mark the date as invalid. if (a != null) { datePartArray[1] = a; } else { config._isValid = false; } break; // DAY OF MONTH case 'D' : // fall through to DDDD case 'DD' : // fall through to DDDD case 'DDD' : // fall through to DDDD case 'DDDD' : if (input != null) { datePartArray[2] = ~~input; } break; // YEAR case 'YY' : datePartArray[0] = ~~input + (~~input > 68 ? 1900 : 2000); break; case 'YYYY' : case 'YYYYY' : datePartArray[0] = ~~input; break; // AM / PM case 'a' : // fall through to A case 'A' : config._isPm = ((input + '').toLowerCase() === 'pm'); break; // 24 HOUR case 'H' : // fall through to hh case 'HH' : // fall through to hh case 'h' : // fall through to hh case 'hh' : datePartArray[3] = ~~input; break; // MINUTE case 'm' : // fall through to mm case 'mm' : datePartArray[4] = ~~input; break; // SECOND case 's' : // fall through to ss case 'ss' : datePartArray[5] = ~~input; break; // MILLISECOND case 'S' : case 'SS' : case 'SSS' : datePartArray[6] = ~~ (('0.' + input) * 1000); break; // UNIX TIMESTAMP WITH MS case 'X': config._d = new Date(parseFloat(input) * 1000); break; // TIMEZONE case 'Z' : // fall through to ZZ case 'ZZ' : config._useUTC = true; a = (input + '').match(parseTimezoneChunker); if (a && a[1]) { config._tzh = ~~a[1]; } if (a && a[2]) { config._tzm = ~~a[2]; } // reverse offsets if (a && a[0] === '+') { config._tzh = -config._tzh; config._tzm = -config._tzm; } break; } // if the input is null, the date is not valid if (input == null) { config._isValid = false; } } // convert an array to a date. // the array should mirror the parameters below // note: all values past the year are optional and will default to the lowest possible value. // [year, month, day , hour, minute, second, millisecond] function dateFromArray(config) { var i, date, input = []; if (config._d) { return; } for (i = 0; i < 7; i++) { config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; } // add the offsets to the time to be parsed so that we can have a clean array for checking isValid input[3] += config._tzh || 0; input[4] += config._tzm || 0; date = new Date(0); if (config._useUTC) { date.setUTCFullYear(input[0], input[1], input[2]); date.setUTCHours(input[3], input[4], input[5], input[6]); } else { date.setFullYear(input[0], input[1], input[2]); date.setHours(input[3], input[4], input[5], input[6]); } config._d = date; } // date from string and format string function makeDateFromStringAndFormat(config) { // This array is used to make a Date, either with `new Date` or `Date.UTC` var tokens = config._f.match(formattingTokens), string = config._i, i, parsedInput; config._a = []; for (i = 0; i < tokens.length; i++) { parsedInput = (getParseRegexForToken(tokens[i]).exec(string) || [])[0]; if (parsedInput) { string = string.slice(string.indexOf(parsedInput) + parsedInput.length); } // don't parse if its not a known token if (formatTokenFunctions[tokens[i]]) { addTimeToArrayFromToken(tokens[i], parsedInput, config); } } // handle am pm if (config._isPm && config._a[3] < 12) { config._a[3] += 12; } // if is 12 am, change hours to 0 if (config._isPm === false && config._a[3] === 12) { config._a[3] = 0; } // return dateFromArray(config); } // date from string and array of format strings function makeDateFromStringAndArray(config) { var tempConfig, tempMoment, bestMoment, scoreToBeat = 99, i, currentDate, currentScore; while (config._f.length) { tempConfig = extend({}, config); tempConfig._f = config._f.pop(); makeDateFromStringAndFormat(tempConfig); tempMoment = new Moment(tempConfig); if (tempMoment.isValid()) { bestMoment = tempMoment; break; } currentScore = compareArrays(tempConfig._a, tempMoment.toArray()); if (currentScore < scoreToBeat) { scoreToBeat = currentScore; bestMoment = tempMoment; } } extend(config, bestMoment); } // date from iso format function makeDateFromString(config) { var i, string = config._i; if (isoRegex.exec(string)) { config._f = 'YYYY-MM-DDT'; for (i = 0; i < 4; i++) { if (isoTimes[i][1].exec(string)) { config._f += isoTimes[i][0]; break; } } if (parseTokenTimezone.exec(string)) { config._f += " Z"; } makeDateFromStringAndFormat(config); } else { config._d = new Date(string); } } function makeDateFromInput(config) { var input = config._i, matched = aspNetJsonRegex.exec(input); if (input === undefined) { config._d = new Date(); } else if (matched) { config._d = new Date(+matched[1]); } else if (typeof input === 'string') { makeDateFromString(config); } else if (isArray(input)) { config._a = input.slice(0); dateFromArray(config); } else { config._d = input instanceof Date ? new Date(+input) : new Date(input); } } /************************************ Relative Time ************************************/ // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) { return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } function relativeTime(milliseconds, withoutSuffix, lang) { var seconds = round(Math.abs(milliseconds) / 1000), minutes = round(seconds / 60), hours = round(minutes / 60), days = round(hours / 24), years = round(days / 365), args = seconds < 45 && ['s', seconds] || minutes === 1 && ['m'] || minutes < 45 && ['mm', minutes] || hours === 1 && ['h'] || hours < 22 && ['hh', hours] || days === 1 && ['d'] || days <= 25 && ['dd', days] || days <= 45 && ['M'] || days < 345 && ['MM', round(days / 30)] || years === 1 && ['y'] || ['yy', years]; args[2] = withoutSuffix; args[3] = milliseconds > 0; args[4] = lang; return substituteTimeAgo.apply({}, args); } /************************************ Week of Year ************************************/ // firstDayOfWeek 0 = sun, 6 = sat // the day of the week that starts the week // (usually sunday or monday) // firstDayOfWeekOfYear 0 = sun, 6 = sat // the first week is the week that contains the first // of this day of the week // (eg. ISO weeks use thursday (4)) function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) { var end = firstDayOfWeekOfYear - firstDayOfWeek, daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(); if (daysToDayOfWeek > end) { daysToDayOfWeek -= 7; } if (daysToDayOfWeek < end - 7) { daysToDayOfWeek += 7; } return Math.ceil(moment(mom).add('d', daysToDayOfWeek).dayOfYear() / 7); } /************************************ Top Level Functions ************************************/ function makeMoment(config) { var input = config._i, format = config._f; if (input === null || input === '') { return null; } if (typeof input === 'string') { config._i = input = getLangDefinition().preparse(input); } if (moment.isMoment(input)) { config = extend({}, input); config._d = new Date(+input._d); } else if (format) { if (isArray(format)) { makeDateFromStringAndArray(config); } else { makeDateFromStringAndFormat(config); } } else { makeDateFromInput(config); } return new Moment(config); } moment = function (input, format, lang) { return makeMoment({ _i : input, _f : format, _l : lang, _isUTC : false }); }; // creating with utc moment.utc = function (input, format, lang) { return makeMoment({ _useUTC : true, _isUTC : true, _l : lang, _i : input, _f : format }); }; // creating with unix timestamp (in seconds) moment.unix = function (input) { return moment(input * 1000); }; // duration moment.duration = function (input, key) { var isDuration = moment.isDuration(input), isNumber = (typeof input === 'number'), duration = (isDuration ? input._data : (isNumber ? {} : input)), ret; if (isNumber) { if (key) { duration[key] = input; } else { duration.milliseconds = input; } } ret = new Duration(duration); if (isDuration && input.hasOwnProperty('_lang')) { ret._lang = input._lang; } return ret; }; // version number moment.version = VERSION; // default format moment.defaultFormat = isoFormat; // This function will load languages and then set the global language. If // no arguments are passed in, it will simply return the current global // language key. moment.lang = function (key, values) { var i; if (!key) { return moment.fn._lang._abbr; } if (values) { loadLang(key, values); } else if (!languages[key]) { getLangDefinition(key); } moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key); }; // returns language data moment.langData = function (key) { if (key && key._lang && key._lang._abbr) { key = key._lang._abbr; } return getLangDefinition(key); }; // compare moment object moment.isMoment = function (obj) { return obj instanceof Moment; }; // for typechecking Duration objects moment.isDuration = function (obj) { return obj instanceof Duration; }; /************************************ Moment Prototype ************************************/ moment.fn = Moment.prototype = { clone : function () { return moment(this); }, valueOf : function () { return +this._d; }, unix : function () { return Math.floor(+this._d / 1000); }, toString : function () { return this.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); }, toDate : function () { return this._d; }, toJSON : function () { return moment.utc(this).format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); }, toArray : function () { var m = this; return [ m.year(), m.month(), m.date(), m.hours(), m.minutes(), m.seconds(), m.milliseconds() ]; }, isValid : function () { if (this._isValid == null) { if (this._a) { this._isValid = !compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()); } else { this._isValid = !isNaN(this._d.getTime()); } } return !!this._isValid; }, utc : function () { this._isUTC = true; return this; }, local : function () { this._isUTC = false; return this; }, format : function (inputString) { var output = formatMoment(this, inputString || moment.defaultFormat); return this.lang().postformat(output); }, add : function (input, val) { var dur; // switch args to support add('s', 1) and add(1, 's') if (typeof input === 'string') { dur = moment.duration(+val, input); } else { dur = moment.duration(input, val); } addOrSubtractDurationFromMoment(this, dur, 1); return this; }, subtract : function (input, val) { var dur; // switch args to support subtract('s', 1) and subtract(1, 's') if (typeof input === 'string') { dur = moment.duration(+val, input); } else { dur = moment.duration(input, val); } addOrSubtractDurationFromMoment(this, dur, -1); return this; }, diff : function (input, units, asFloat) { var that = this._isUTC ? moment(input).utc() : moment(input).local(), zoneDiff = (this.zone() - that.zone()) * 6e4, diff, output; if (units) { // standardize on singular form units = units.replace(/s$/, ''); } if (units === 'year' || units === 'month') { diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2 output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); output += ((this - moment(this).startOf('month')) - (that - moment(that).startOf('month'))) / diff; if (units === 'year') { output = output / 12; } } else { diff = (this - that) - zoneDiff; output = units === 'second' ? diff / 1e3 : // 1000 units === 'minute' ? diff / 6e4 : // 1000 * 60 units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60 units === 'day' ? diff / 864e5 : // 1000 * 60 * 60 * 24 units === 'week' ? diff / 6048e5 : // 1000 * 60 * 60 * 24 * 7 diff; } return asFloat ? output : absRound(output); }, from : function (time, withoutSuffix) { return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix); }, fromNow : function (withoutSuffix) { return this.from(moment(), withoutSuffix); }, calendar : function () { var diff = this.diff(moment().startOf('day'), 'days', true), format = diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : diff < 0 ? 'lastDay' : diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse'; return this.format(this.lang().calendar(format, this)); }, isLeapYear : function () { var year = this.year(); return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; }, isDST : function () { return (this.zone() < moment([this.year()]).zone() || this.zone() < moment([this.year(), 5]).zone()); }, day : function (input) { var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); return input == null ? day : this.add({ d : input - day }); }, startOf: function (units) { units = units.replace(/s$/, ''); // the following switch intentionally omits break keywords // to utilize falling through the cases. switch (units) { case 'year': this.month(0); /* falls through */ case 'month': this.date(1); /* falls through */ case 'week': case 'day': this.hours(0); /* falls through */ case 'hour': this.minutes(0); /* falls through */ case 'minute': this.seconds(0); /* falls through */ case 'second': this.milliseconds(0); /* falls through */ } // weeks are a special case if (units === 'week') { this.day(0); } return this; }, endOf: function (units) { return this.startOf(units).add(units.replace(/s?$/, 's'), 1).subtract('ms', 1); }, isAfter: function (input, units) { units = typeof units !== 'undefined' ? units : 'millisecond'; return +this.clone().startOf(units) > +moment(input).startOf(units); }, isBefore: function (input, units) { units = typeof units !== 'undefined' ? units : 'millisecond'; return +this.clone().startOf(units) < +moment(input).startOf(units); }, isSame: function (input, units) { units = typeof units !== 'undefined' ? units : 'millisecond'; return +this.clone().startOf(units) === +moment(input).startOf(units); }, zone : function () { return this._isUTC ? 0 : this._d.getTimezoneOffset(); }, daysInMonth : function () { return moment.utc([this.year(), this.month() + 1, 0]).date(); }, dayOfYear : function (input) { var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; return input == null ? dayOfYear : this.add("d", (input - dayOfYear)); }, isoWeek : function (input) { var week = weekOfYear(this, 1, 4); return input == null ? week : this.add("d", (input - week) * 7); }, week : function (input) { var week = this.lang().week(this); return input == null ? week : this.add("d", (input - week) * 7); }, // If passed a language key, it will set the language for this // instance. Otherwise, it will return the language configuration // variables for this instance. lang : function (key) { if (key === undefined) { return this._lang; } else { this._lang = getLangDefinition(key); return this; } } }; // helper for adding shortcuts function makeGetterAndSetter(name, key) { moment.fn[name] = moment.fn[name + 's'] = function (input) { var utc = this._isUTC ? 'UTC' : ''; if (input != null) { this._d['set' + utc + key](input); return this; } else { return this._d['get' + utc + key](); } }; } // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds) for (i = 0; i < proxyGettersAndSetters.length; i ++) { makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]); } // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear') makeGetterAndSetter('year', 'FullYear'); // add plural methods moment.fn.days = moment.fn.day; moment.fn.weeks = moment.fn.week; moment.fn.isoWeeks = moment.fn.isoWeek; /************************************ Duration Prototype ************************************/ moment.duration.fn = Duration.prototype = { weeks : function () { return absRound(this.days() / 7); }, valueOf : function () { return this._milliseconds + this._days * 864e5 + this._months * 2592e6; }, humanize : function (withSuffix) { var difference = +this, output = relativeTime(difference, !withSuffix, this.lang()); if (withSuffix) { output = this.lang().pastFuture(difference, output); } return this.lang().postformat(output); }, lang : moment.fn.lang }; function makeDurationGetter(name) { moment.duration.fn[name] = function () { return this._data[name]; }; } function makeDurationAsGetter(name, factor) { moment.duration.fn['as' + name] = function () { return +this / factor; }; } for (i in unitMillisecondFactors) { if (unitMillisecondFactors.hasOwnProperty(i)) { makeDurationAsGetter(i, unitMillisecondFactors[i]); makeDurationGetter(i.toLowerCase()); } } makeDurationAsGetter('Weeks', 6048e5); /************************************ Default Lang ************************************/ // Set default language, other languages will inherit from English. moment.lang('en', { ordinal : function (number) { var b = number % 10, output = (~~ (number % 100 / 10) === 1) ? 'th' : (b === 1) ? 'st' : (b === 2) ? 'nd' : (b === 3) ? 'rd' : 'th'; return number + output; } }); /************************************ Exposing Moment ************************************/ // CommonJS module is defined if (hasModule) { module.exports = moment; } /*global ender:false */ if (typeof ender === 'undefined') { // here, `this` means `window` in the browser, or `global` on the server // add `moment` as a global object via a string identifier, // for Closure Compiler "advanced" mode this['moment'] = moment; } /*global define:false */ if (typeof define === "function" && define.amd) { define("moment", [], function () { return moment; }); } }).call(this); (function ($) { $.fn.formToJson = function () { var ret = {}; $('input,textarea', this).each(function () { var formItem = $(this); var jsonAttr = formItem.data('json'); if (jsonAttr != null) { if (formItem.data("valex") === 'date-uk') { ret[jsonAttr] = moment(formItem.val(), 'DD-MM-YYYY'); } else { ret[jsonAttr] = formItem.val(); } } }); return ret; }; $.fn.formFromJson = function (ob) { var pThis = $(this); for (var p in ob) { var ctrl = $('input[data-json="' + p + '"],textarea[data-json="' + p + '"]', this); if (ctrl.data("valex") === 'date-uk') { if (ob[p]) { var d = new Date(ob[p]); ctrl.val(d.getDate() + '/' + (d.getMonth() + 1) + '/' + d.getFullYear()); } else { ctrl.val(''); } } else { ctrl.val(ob[p]); } } return pThis; }; $.fn.enterTo = function (target) { var pThis = $(this); pThis.on('keydown', function (e) { if (e.which == 13) { $(target).click(); return false; } }); return $(this); }; $.fn.enterToFocus = function (target) { var pThis = $(this); pThis.on('keydown', function (e) { if (e.which == 13) { $(target).focus(); return false; } }); return $(this); }; })(jQuery); (function ($) { var originalVal = this.originalVal = $.fn.val; $.fn.val = function (value) { if (typeof value == 'undefined') { var input = $(this); if (input.hasClass('placeholder')) { var plAttr = input.attr('placeholder'); if (plAttr && plAttr.length > 0 && input.rawVal() == plAttr) { return ''; } else { input.removeClass('placeholder'); return originalVal.call(this); } } else { return originalVal.call(this); } } else { return originalVal.call(this, value); } }; $.fn.rawVal = function (value) { if (typeof value == 'undefined') { return originalVal.call(this); } else { return originalVal.call(this, value); } }; })(jQuery); $(function () { if (($('body').hasClass('IE8')) || ($('body').hasClass('IE9'))) { $('input[placeholder]').focus(function () { var input = $(this); if (input.rawVal() == input.attr('placeholder')) { input.rawVal(''); input.removeClass('placeholder'); } }).blur(function () { var input = $(this); if (input.rawVal() == '' || input.rawVal() == input.attr('placeholder')) { input.addClass('placeholder'); input.rawVal(input.attr('placeholder')); } }).blur(); } }); (function ($) { var _compiledTempl = {}; $.fn.applyTemplate = function (templateId, data) { if (this.length > 0) { if (_compiledTempl[templateId] == null) { var template = $('#' + templateId).html(); _compiledTempl[templateId] = Handlebars.compile(template); } this.html(_compiledTempl[templateId](data)); } }; })(jQuery); Handlebars.registerHelper("foreach", function (arr, options) { if (options.inverse && !arr.length) return options.inverse(this); return $.map(arr, function (item, index) { item.$index = index; item.$first = index === 0; item.$last = index === arr.length - 1; return options.fn(item); }).join(''); }); function multilineToHtml(txt) { if (txt) { txt = Handlebars.Utils.escapeExpression(txt); txt = txt.toString(); txt = txt.replace(/(\r\n|\n|\r)/gm, '
'); return new Handlebars.SafeString(txt); } return ""; } (function ($) { $.fn.showIntro = function () { var introBox = $(this); introBox.on('hidden', function () { $('body').toggleClass('dpIntroBody'); $.ajax({ type: 'POST', contentType: "application/json; charset=utf-8", url: introBox.data('profileservice'), dataType: 'json', data: JSON.stringify({ introId: introBox.data('introid') }) }); introBox.remove(); }); introBox.on('show', function () { $('body').toggleClass('dpIntroBody'); }); introBox.modal(); }; $.fn.introBubble = function (content) { var pThis = $(this); var bubble = $('
"').css({ visibility: 'hidden', position: 'absolute' }).appendTo('body'); $('.ibContent', bubble).html(content); var left = (pThis.offset().left) + (pThis.width() / 2) - (bubble.width() / 2); var topPos = pThis.offset().top - (bubble.height() + 5) - 10; bubble.css({ visibility: 'visible', left: left, top: topPos }).delay(350).animate({ opacity: 0, top: topPos - 300 }, 1000, function () { $(this).remove(); }); return pThis; }; })(jQuery); (function ($) { $.fn.attachRequired = function () { var pThis = $(this); pThis.checkRequiredItems().on('change', '.dpReq input,.dpReq textarea', function () { $(this).checkRequiredItem(); }); pThis.checkRequiredItems().on('keyup', '.dpReq input,.dpReq textarea', function () { $(this).checkRequiredItem(); }); pThis.checkRequiredItems().on('blur', '.dpReq input,.dpReq textarea', function () { $(this).checkRequiredItem(); }); }; $.fn.checkRequiredItems = function () { var pThis = $(this); $('.dpReq input,.dpReq textarea', pThis).each(function () { $(this).checkRequiredItem(); }); return pThis; }; $.fn.isValid = function () { var pThis = $(this); pThis.checkRequiredItems(); var reqFail = $('.dqReqFail', pThis); if (reqFail.length == 0) { return true; } else { $('input,textarea', $(reqFail[0]).parent()).focus(); return false; } } $.fn.checkRequiredItem = function () { var pThis = $(this); var pass = true; var thisVal = $.trim(pThis.val()); //check for required fields if ((pThis.attr('required') == 'required') && (thisVal.length == 0)) { pass = false; } //we have a value see if it's valid if (thisVal.length > 0) { var thisType = pThis.attr('type'); if (thisType != null) { thisType = thisType.toLowerCase(); } var patt = null; //type check if (thisType == "email") { patt = /(\s)*\w+([-+.'\w])*@\w+([-.]\w+)*\.\w+([-.]\w+)*(\s)*/g; } var regexcheck = pThis.data("regex"); if (regexcheck != null) { patt = new RegExp(regexcheck); } //if have a pattern test it if (patt != null) { if (!patt.test(thisVal)) { pass = false; } } //special cases var valEx = pThis.data("valex"); if (valEx != null) { if (valEx == "date-uk") { var splitDate = thisVal.split('/'); if (splitDate.length != 3) { splitDate = thisVal.split('-'); } if (splitDate.length != 3) { pass = false; } else { var testDate = new Date(parseInt(splitDate[2]), parseInt(splitDate[1]) - 1, parseInt(splitDate[0])); if ((Object.prototype.toString.call(testDate) != "[object Date]") || (isNaN(testDate.getTime())) || (testDate.getDate() != splitDate[0]) || (testDate.getMonth() != (splitDate[1] - 1))) { pass = false; } } } } } if (pass) { $(".dpReqF", pThis.parent()).removeClass('dqReqFail').addClass('dqReqPass'); } else { $(".dpReqF", pThis.parent()).addClass('dqReqFail').removeClass('dqReqPass'); } return pThis; }; })(jQuery); (function ($) { $.fn.ajaxSaving = function () { var pThis = $(this); if (pThis.data('savingoriginal') == null) { pThis.data('savingoriginal',pThis.text()); } pThis.addClass('disabled').addClass('ajaxsaving').text(pThis.data('savingprefix')); pThis.ajaxStillSaving(); }; $.fn.ajaxStillSaving=function () { var pThis = $(this); if (pThis.hasClass('disabled')) { pThis.text(pThis.text() + '.'); setTimeout(function () { pThis.ajaxStillSaving(); }, 1000); } }; $.fn.ajaxSavingComplete = function () { $(this).each(function(){ var pThis = $(this); pThis.removeClass('disabled').removeClass('ajaxsaving'); var saveorig=pThis.data('savingoriginal'); if(saveorig!=null) { pThis.text(saveorig); } }); }; })(jQuery);