@@ -152,6 +161,10 @@
+
+
+
+
diff --git a/htrace-core/src/web/lib/js/moment-2.9.0.min.js b/htrace-core/src/web/lib/js/moment-2.9.0.min.js
new file mode 100644
index 0000000..c7f6dcd
--- /dev/null
+++ b/htrace-core/src/web/lib/js/moment-2.9.0.min.js
@@ -0,0 +1,7 @@
+//! moment.js
+//! version : 2.9.0
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
+(function(a){function b(a,b,c){switch(arguments.length){case 2:return null!=a?a:b;case 3:return null!=a?a:null!=b?b:c;default:throw new Error("Implement me")}}function c(a,b){return Bb.call(a,b)}function d(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function e(a){vb.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+a)}function f(a,b){var c=!0;return o(function(){return c&&(e(a),c=!1),b.apply(this,arguments)},b)}function g(a,b){sc[a]||(e(b),sc[a]=!0)}function h(a,b){return function(c){return r(a.call(this,c),b)}}function i(a,b){return function(c){return this.localeData().ordinal(a.call(this,c),b)}}function j(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)}function k(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function l(){}function m(a,b){b!==!1&&H(a),p(this,a),this._d=new Date(+a._d),uc===!1&&(uc=!0,vb.updateOffset(this),uc=!1)}function n(a){var b=A(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=vb.localeData(),this._bubble()}function o(a,b){for(var d in b)c(b,d)&&(a[d]=b[d]);return c(b,"toString")&&(a.toString=b.toString),c(b,"valueOf")&&(a.valueOf=b.valueOf),a}function p(a,b){var c,d,e;if("undefined"!=typeof b._isAMomentObject&&(a._isAMomentObject=b._isAMomentObject),"undefined"!=typeof b._i&&(a._i=b._i),"undefined"!=typeof b._f&&(a._f=b._f),"undefined"!=typeof b._l&&(a._l=b._l),"undefined"!=typeof b._strict&&(a._strict=b._strict),"undefined"!=typeof b._tzm&&(a._tzm=b._tzm),"undefined"!=typeof b._isUTC&&(a._isUTC=b._isUTC),"undefined"!=typeof b._offset&&(a._offset=b._offset),"undefined"!=typeof b._pf&&(a._pf=b._pf),"undefined"!=typeof b._locale&&(a._locale=b._locale),Kb.length>0)for(c in Kb)d=Kb[c],e=b[d],"undefined"!=typeof e&&(a[d]=e);return a}function q(a){return 0>a?Math.ceil(a):Math.floor(a)}function r(a,b,c){for(var d=""+Math.abs(a),e=a>=0;d.length
d;d++)(c&&a[d]!==b[d]||!c&&C(a[d])!==C(b[d]))&&g++;return g+f}function z(a){if(a){var b=a.toLowerCase().replace(/(.)s$/,"$1");a=lc[a]||mc[b]||b}return a}function A(a){var b,d,e={};for(d in a)c(a,d)&&(b=z(d),b&&(e[b]=a[d]));return e}function B(b){var c,d;if(0===b.indexOf("week"))c=7,d="day";else{if(0!==b.indexOf("month"))return;c=12,d="month"}vb[b]=function(e,f){var g,h,i=vb._locale[b],j=[];if("number"==typeof e&&(f=e,e=a),h=function(a){var b=vb().utc().set(d,a);return i.call(vb._locale,b,e||"")},null!=f)return h(f);for(g=0;c>g;g++)j.push(h(g));return j}}function C(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function D(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function E(a,b,c){return jb(vb([a,11,31+b-c]),b,c).week}function F(a){return G(a)?366:365}function G(a){return a%4===0&&a%100!==0||a%400===0}function H(a){var b;a._a&&-2===a._pf.overflow&&(b=a._a[Db]<0||a._a[Db]>11?Db:a._a[Eb]<1||a._a[Eb]>D(a._a[Cb],a._a[Db])?Eb:a._a[Fb]<0||a._a[Fb]>24||24===a._a[Fb]&&(0!==a._a[Gb]||0!==a._a[Hb]||0!==a._a[Ib])?Fb:a._a[Gb]<0||a._a[Gb]>59?Gb:a._a[Hb]<0||a._a[Hb]>59?Hb:a._a[Ib]<0||a._a[Ib]>999?Ib:-1,a._pf._overflowDayOfYear&&(Cb>b||b>Eb)&&(b=Eb),a._pf.overflow=b)}function I(b){return null==b._isValid&&(b._isValid=!isNaN(b._d.getTime())&&b._pf.overflow<0&&!b._pf.empty&&!b._pf.invalidMonth&&!b._pf.nullInput&&!b._pf.invalidFormat&&!b._pf.userInvalidated,b._strict&&(b._isValid=b._isValid&&0===b._pf.charsLeftOver&&0===b._pf.unusedTokens.length&&b._pf.bigHour===a)),b._isValid}function J(a){return a?a.toLowerCase().replace("_","-"):a}function K(a){for(var b,c,d,e,f=0;f0;){if(d=L(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&y(e,c,!0)>=b-1)break;b--}f++}return null}function L(a){var b=null;if(!Jb[a]&&Lb)try{b=vb.locale(),require("./locale/"+a),vb.locale(b)}catch(c){}return Jb[a]}function M(a,b){var c,d;return b._isUTC?(c=b.clone(),d=(vb.isMoment(a)||x(a)?+a:+vb(a))-+c,c._d.setTime(+c._d+d),vb.updateOffset(c,!1),c):vb(a).local()}function N(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function O(a){var b,c,d=a.match(Pb);for(b=0,c=d.length;c>b;b++)d[b]=rc[d[b]]?rc[d[b]]:N(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function P(a,b){return a.isValid()?(b=Q(b,a.localeData()),nc[b]||(nc[b]=O(b)),nc[b](a)):a.localeData().invalidDate()}function Q(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Qb.lastIndex=0;d>=0&&Qb.test(a);)a=a.replace(Qb,c),Qb.lastIndex=0,d-=1;return a}function R(a,b){var c,d=b._strict;switch(a){case"Q":return _b;case"DDDD":return bc;case"YYYY":case"GGGG":case"gggg":return d?cc:Tb;case"Y":case"G":case"g":return ec;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return d?dc:Ub;case"S":if(d)return _b;case"SS":if(d)return ac;case"SSS":if(d)return bc;case"DDD":return Sb;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Wb;case"a":case"A":return b._locale._meridiemParse;case"x":return Zb;case"X":return $b;case"Z":case"ZZ":return Xb;case"T":return Yb;case"SSSS":return Vb;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return d?ac:Rb;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return Rb;case"Do":return d?b._locale._ordinalParse:b._locale._ordinalParseLenient;default:return c=new RegExp($(Z(a.replace("\\","")),"i"))}}function S(a){a=a||"";var b=a.match(Xb)||[],c=b[b.length-1]||[],d=(c+"").match(jc)||["-",0,0],e=+(60*d[1])+C(d[2]);return"+"===d[0]?e:-e}function T(a,b,c){var d,e=c._a;switch(a){case"Q":null!=b&&(e[Db]=3*(C(b)-1));break;case"M":case"MM":null!=b&&(e[Db]=C(b)-1);break;case"MMM":case"MMMM":d=c._locale.monthsParse(b,a,c._strict),null!=d?e[Db]=d:c._pf.invalidMonth=b;break;case"D":case"DD":null!=b&&(e[Eb]=C(b));break;case"Do":null!=b&&(e[Eb]=C(parseInt(b.match(/\d{1,2}/)[0],10)));break;case"DDD":case"DDDD":null!=b&&(c._dayOfYear=C(b));break;case"YY":e[Cb]=vb.parseTwoDigitYear(b);break;case"YYYY":case"YYYYY":case"YYYYYY":e[Cb]=C(b);break;case"a":case"A":c._meridiem=b;break;case"h":case"hh":c._pf.bigHour=!0;case"H":case"HH":e[Fb]=C(b);break;case"m":case"mm":e[Gb]=C(b);break;case"s":case"ss":e[Hb]=C(b);break;case"S":case"SS":case"SSS":case"SSSS":e[Ib]=C(1e3*("0."+b));break;case"x":c._d=new Date(C(b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=S(b);break;case"dd":case"ddd":case"dddd":d=c._locale.weekdaysParse(b),null!=d?(c._w=c._w||{},c._w.d=d):c._pf.invalidWeekday=b;break;case"w":case"ww":case"W":case"WW":case"d":case"e":case"E":a=a.substr(0,1);case"gggg":case"GGGG":case"GGGGG":a=a.substr(0,2),b&&(c._w=c._w||{},c._w[a]=C(b));break;case"gg":case"GG":c._w=c._w||{},c._w[a]=vb.parseTwoDigitYear(b)}}function U(a){var c,d,e,f,g,h,i;c=a._w,null!=c.GG||null!=c.W||null!=c.E?(g=1,h=4,d=b(c.GG,a._a[Cb],jb(vb(),1,4).year),e=b(c.W,1),f=b(c.E,1)):(g=a._locale._week.dow,h=a._locale._week.doy,d=b(c.gg,a._a[Cb],jb(vb(),g,h).year),e=b(c.w,1),null!=c.d?(f=c.d,g>f&&++e):f=null!=c.e?c.e+g:g),i=kb(d,e,f,h,g),a._a[Cb]=i.year,a._dayOfYear=i.dayOfYear}function V(a){var c,d,e,f,g=[];if(!a._d){for(e=X(a),a._w&&null==a._a[Eb]&&null==a._a[Db]&&U(a),a._dayOfYear&&(f=b(a._a[Cb],e[Cb]),a._dayOfYear>F(f)&&(a._pf._overflowDayOfYear=!0),d=fb(f,0,a._dayOfYear),a._a[Db]=d.getUTCMonth(),a._a[Eb]=d.getUTCDate()),c=0;3>c&&null==a._a[c];++c)a._a[c]=g[c]=e[c];for(;7>c;c++)a._a[c]=g[c]=null==a._a[c]?2===c?1:0:a._a[c];24===a._a[Fb]&&0===a._a[Gb]&&0===a._a[Hb]&&0===a._a[Ib]&&(a._nextDay=!0,a._a[Fb]=0),a._d=(a._useUTC?fb:eb).apply(null,g),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[Fb]=24)}}function W(a){var b;a._d||(b=A(a._i),a._a=[b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],V(a))}function X(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function Y(b){if(b._f===vb.ISO_8601)return void ab(b);b._a=[],b._pf.empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=Q(b._f,b._locale).match(Pb)||[],c=0;c0&&b._pf.unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),rc[f]?(d?b._pf.empty=!1:b._pf.unusedTokens.push(f),T(f,d,b)):b._strict&&!d&&b._pf.unusedTokens.push(f);b._pf.charsLeftOver=i-j,h.length>0&&b._pf.unusedInput.push(h),b._pf.bigHour===!0&&b._a[Fb]<=12&&(b._pf.bigHour=a),b._a[Fb]=k(b._locale,b._a[Fb],b._meridiem),V(b),H(b)}function Z(a){return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e})}function $(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function _(a){var b,c,e,f,g;if(0===a._f.length)return a._pf.invalidFormat=!0,void(a._d=new Date(0/0));for(f=0;fg)&&(e=g,c=b));o(a,c||b)}function ab(a){var b,c,d=a._i,e=fc.exec(d);if(e){for(a._pf.iso=!0,b=0,c=hc.length;c>b;b++)if(hc[b][1].exec(d)){a._f=hc[b][0]+(e[6]||" ");break}for(b=0,c=ic.length;c>b;b++)if(ic[b][1].exec(d)){a._f+=ic[b][0];break}d.match(Xb)&&(a._f+="Z"),Y(a)}else a._isValid=!1}function bb(a){ab(a),a._isValid===!1&&(delete a._isValid,vb.createFromInputFallback(a))}function cb(a,b){var c,d=[];for(c=0;ca&&h.setFullYear(a),h}function fb(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function gb(a,b){if("string"==typeof a)if(isNaN(a)){if(a=b.weekdaysParse(a),"number"!=typeof a)return null}else a=parseInt(a,10);return a}function hb(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function ib(a,b,c){var d=vb.duration(a).abs(),e=Ab(d.as("s")),f=Ab(d.as("m")),g=Ab(d.as("h")),h=Ab(d.as("d")),i=Ab(d.as("M")),j=Ab(d.as("y")),k=e0,k[4]=c,hb.apply({},k)}function jb(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=vb(a).add(f,"d"),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function kb(a,b,c,d,e){var f,g,h=fb(a,0,1).getUTCDay();return h=0===h?7:h,c=null!=c?c:e,f=e-h+(h>d?7:0)-(e>h?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:F(a-1)+g}}function lb(b){var c,d=b._i,e=b._f;return b._locale=b._locale||vb.localeData(b._l),null===d||e===a&&""===d?vb.invalid({nullInput:!0}):("string"==typeof d&&(b._i=d=b._locale.preparse(d)),vb.isMoment(d)?new m(d,!0):(e?w(e)?_(b):Y(b):db(b),c=new m(b),c._nextDay&&(c.add(1,"d"),c._nextDay=a),c))}function mb(a,b){var c,d;if(1===b.length&&w(b[0])&&(b=b[0]),!b.length)return vb();for(c=b[0],d=1;d=0?"+":"-";return b+r(Math.abs(a),6)},gg:function(){return r(this.weekYear()%100,2)},gggg:function(){return r(this.weekYear(),4)},ggggg:function(){return r(this.weekYear(),5)},GG:function(){return r(this.isoWeekYear()%100,2)},GGGG:function(){return r(this.isoWeekYear(),4)},GGGGG:function(){return r(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!1)},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 C(this.milliseconds()/100)},SS:function(){return r(C(this.milliseconds()/10),2)},SSS:function(){return r(this.milliseconds(),3)},SSSS:function(){return r(this.milliseconds(),3)},Z:function(){var a=this.utcOffset(),b="+";return 0>a&&(a=-a,b="-"),b+r(C(a/60),2)+":"+r(C(a)%60,2)},ZZ:function(){var a=this.utcOffset(),b="+";return 0>a&&(a=-a,b="-"),b+r(C(a/60),2)+r(C(a)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},x:function(){return this.valueOf()},X:function(){return this.unix()},Q:function(){return this.quarter()}},sc={},tc=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"],uc=!1;pc.length;)xb=pc.pop(),rc[xb+"o"]=i(rc[xb],xb);for(;qc.length;)xb=qc.pop(),rc[xb+xb]=h(rc[xb],2);rc.DDDD=h(rc.DDD,3),o(l.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a,b,c){var d,e,f;for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=vb.utc([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=vb([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LTS:"h:mm:ss A",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(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"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(a,b,c){var d=this._calendar[a];return"function"==typeof d?d.apply(b,[c]):d},_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(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",_ordinalParse:/\d{1,2}/,preparse:function(a){return a},postformat:function(a){return a},week:function(a){return jb(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},firstDayOfWeek:function(){return this._week.dow},firstDayOfYear:function(){return this._week.doy},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),vb=function(b,c,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._i=b,g._f=c,g._l=e,g._strict=f,g._isUTC=!1,g._pf=d(),lb(g)},vb.suppressDeprecationWarnings=!1,vb.createFromInputFallback=f("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),vb.min=function(){var a=[].slice.call(arguments,0);return mb("isBefore",a)},vb.max=function(){var a=[].slice.call(arguments,0);return mb("isAfter",a)},vb.utc=function(b,c,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._useUTC=!0,g._isUTC=!0,g._l=e,g._i=b,g._f=c,g._strict=f,g._pf=d(),lb(g).utc()},vb.unix=function(a){return vb(1e3*a)},vb.duration=function(a,b){var d,e,f,g,h=a,i=null;return vb.isDuration(a)?h={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(h={},b?h[b]=a:h.milliseconds=a):(i=Nb.exec(a))?(d="-"===i[1]?-1:1,h={y:0,d:C(i[Eb])*d,h:C(i[Fb])*d,m:C(i[Gb])*d,s:C(i[Hb])*d,ms:C(i[Ib])*d}):(i=Ob.exec(a))?(d="-"===i[1]?-1:1,f=function(a){var b=a&&parseFloat(a.replace(",","."));return(isNaN(b)?0:b)*d},h={y:f(i[2]),M:f(i[3]),d:f(i[4]),h:f(i[5]),m:f(i[6]),s:f(i[7]),w:f(i[8])}):null==h?h={}:"object"==typeof h&&("from"in h||"to"in h)&&(g=t(vb(h.from),vb(h.to)),h={},h.ms=g.milliseconds,h.M=g.months),e=new n(h),vb.isDuration(a)&&c(a,"_locale")&&(e._locale=a._locale),e},vb.version=yb,vb.defaultFormat=gc,vb.ISO_8601=function(){},vb.momentProperties=Kb,vb.updateOffset=function(){},vb.relativeTimeThreshold=function(b,c){return oc[b]===a?!1:c===a?oc[b]:(oc[b]=c,!0)},vb.lang=f("moment.lang is deprecated. Use moment.locale instead.",function(a,b){return vb.locale(a,b)}),vb.locale=function(a,b){var c;return a&&(c="undefined"!=typeof b?vb.defineLocale(a,b):vb.localeData(a),c&&(vb.duration._locale=vb._locale=c)),vb._locale._abbr},vb.defineLocale=function(a,b){return null!==b?(b.abbr=a,Jb[a]||(Jb[a]=new l),Jb[a].set(b),vb.locale(a),Jb[a]):(delete Jb[a],null)},vb.langData=f("moment.langData is deprecated. Use moment.localeData instead.",function(a){return vb.localeData(a)}),vb.localeData=function(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return vb._locale;if(!w(a)){if(b=L(a))return b;a=[a]}return K(a)},vb.isMoment=function(a){return a instanceof m||null!=a&&c(a,"_isAMomentObject")},vb.isDuration=function(a){return a instanceof n};for(xb=tc.length-1;xb>=0;--xb)B(tc[xb]);vb.normalizeUnits=function(a){return z(a)},vb.invalid=function(a){var b=vb.utc(0/0);return null!=a?o(b._pf,a):b._pf.userInvalidated=!0,b},vb.parseZone=function(){return vb.apply(null,arguments).parseZone()},vb.parseTwoDigitYear=function(a){return C(a)+(C(a)>68?1900:2e3)},vb.isDate=x,o(vb.fn=m.prototype,{clone:function(){return vb(this)},valueOf:function(){return+this._d-6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var a=vb(this).utc();return 00:!1},parsingFlags:function(){return o({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(a){return this.utcOffset(0,a)},local:function(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(this._dateUtcOffset(),"m")),this},format:function(a){var b=P(this,a||vb.defaultFormat);return this.localeData().postformat(b)},add:u(1,"add"),subtract:u(-1,"subtract"),diff:function(a,b,c){var d,e,f=M(a,this),g=6e4*(f.utcOffset()-this.utcOffset());return b=z(b),"year"===b||"month"===b||"quarter"===b?(e=j(this,f),"quarter"===b?e/=3:"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:q(e)},from:function(a,b){return vb.duration({to:this,from:a}).locale(this.locale()).humanize(!b)},fromNow:function(a){return this.from(vb(),a)},calendar:function(a){var b=a||vb(),c=M(b,this).startOf("day"),d=this.diff(c,"days",!0),e=-6>d?"sameElse":-1>d?"lastWeek":0>d?"lastDay":1>d?"sameDay":2>d?"nextDay":7>d?"nextWeek":"sameElse";return this.format(this.localeData().calendar(e,this,vb(b)))},isLeapYear:function(){return G(this.year())},isDST:function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},day:function(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=gb(a,this.localeData()),this.add(a-b,"d")):b},month:qb("Month",!0),startOf:function(a){switch(a=z(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a?this.weekday(0):"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this},endOf:function(b){return b=z(b),b===a||"millisecond"===b?this:this.startOf(b).add(1,"isoWeek"===b?"week":b).subtract(1,"ms")},isAfter:function(a,b){var c;return b=z("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=vb.isMoment(a)?a:vb(a),+this>+a):(c=vb.isMoment(a)?+a:+vb(a),c<+this.clone().startOf(b))},isBefore:function(a,b){var c;return b=z("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=vb.isMoment(a)?a:vb(a),+a>+this):(c=vb.isMoment(a)?+a:+vb(a),+this.clone().endOf(b)a?this:a}),max:f("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(a){return a=vb.apply(null,arguments),a>this?this:a}),zone:f("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",function(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}),utcOffset:function(a,b){var c,d=this._offset||0;return null!=a?("string"==typeof a&&(a=S(a)),Math.abs(a)<16&&(a=60*a),!this._isUTC&&b&&(c=this._dateUtcOffset()),this._offset=a,this._isUTC=!0,null!=c&&this.add(c,"m"),d!==a&&(!b||this._changeInProgress?v(this,vb.duration(a-d,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,vb.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?d:this._dateUtcOffset()},isLocal:function(){return!this._isUTC},isUtcOffset:function(){return this._isUTC},isUtc:function(){return this._isUTC&&0===this._offset},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(S(this._i)),this},hasAlignedHourOffset:function(a){return a=a?vb(a).utcOffset():0,(this.utcOffset()-a)%60===0},daysInMonth:function(){return D(this.year(),this.month())},dayOfYear:function(a){var b=Ab((vb(this).startOf("day")-vb(this).startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")},quarter:function(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)},weekYear:function(a){var b=jb(this,this.localeData()._week.dow,this.localeData()._week.doy).year;return null==a?b:this.add(a-b,"y")},isoWeekYear:function(a){var b=jb(this,1,4).year;return null==a?b:this.add(a-b,"y")},week:function(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")},isoWeek:function(a){var b=jb(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")},weekday:function(a){var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},isoWeeksInYear:function(){return E(this.year(),1,4)},weeksInYear:function(){var a=this.localeData()._week;return E(this.year(),a.dow,a.doy)},get:function(a){return a=z(a),this[a]()},set:function(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else a=z(a),"function"==typeof this[a]&&this[a](b);return this},locale:function(b){var c;return b===a?this._locale._abbr:(c=vb.localeData(b),null!=c&&(this._locale=c),this)},lang:f("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(b){return b===a?this.localeData():this.locale(b)}),localeData:function(){return this._locale},_dateUtcOffset:function(){return 15*-Math.round(this._d.getTimezoneOffset()/15)}}),vb.fn.millisecond=vb.fn.milliseconds=qb("Milliseconds",!1),vb.fn.second=vb.fn.seconds=qb("Seconds",!1),vb.fn.minute=vb.fn.minutes=qb("Minutes",!1),vb.fn.hour=vb.fn.hours=qb("Hours",!0),vb.fn.date=qb("Date",!0),vb.fn.dates=f("dates accessor is deprecated. Use date instead.",qb("Date",!0)),vb.fn.year=qb("FullYear",!0),vb.fn.years=f("years accessor is deprecated. Use year instead.",qb("FullYear",!0)),vb.fn.days=vb.fn.day,vb.fn.months=vb.fn.month,vb.fn.weeks=vb.fn.week,vb.fn.isoWeeks=vb.fn.isoWeek,vb.fn.quarters=vb.fn.quarter,vb.fn.toJSON=vb.fn.toISOString,vb.fn.isUTC=vb.fn.isUtc,o(vb.duration.fn=n.prototype,{_bubble:function(){var a,b,c,d=this._milliseconds,e=this._days,f=this._months,g=this._data,h=0;g.milliseconds=d%1e3,a=q(d/1e3),g.seconds=a%60,b=q(a/60),g.minutes=b%60,c=q(b/60),g.hours=c%24,e+=q(c/24),h=q(rb(e)),e-=q(sb(h)),f+=q(e/30),e%=30,h+=q(f/12),f%=12,g.days=e,g.months=f,g.years=h},abs:function(){return this._milliseconds=Math.abs(this._milliseconds),this._days=Math.abs(this._days),this._months=Math.abs(this._months),this._data.milliseconds=Math.abs(this._data.milliseconds),this._data.seconds=Math.abs(this._data.seconds),this._data.minutes=Math.abs(this._data.minutes),this._data.hours=Math.abs(this._data.hours),this._data.months=Math.abs(this._data.months),this._data.years=Math.abs(this._data.years),this},weeks:function(){return q(this.days()/7)},valueOf:function(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*C(this._months/12)
+},humanize:function(a){var b=ib(this,!a,this.localeData());return a&&(b=this.localeData().pastFuture(+this,b)),this.localeData().postformat(b)},add:function(a,b){var c=vb.duration(a,b);return this._milliseconds+=c._milliseconds,this._days+=c._days,this._months+=c._months,this._bubble(),this},subtract:function(a,b){var c=vb.duration(a,b);return this._milliseconds-=c._milliseconds,this._days-=c._days,this._months-=c._months,this._bubble(),this},get:function(a){return a=z(a),this[a.toLowerCase()+"s"]()},as:function(a){var b,c;if(a=z(a),"month"===a||"year"===a)return b=this._days+this._milliseconds/864e5,c=this._months+12*rb(b),"month"===a?c:c/12;switch(b=this._days+Math.round(sb(this._months/12)),a){case"week":return b/7+this._milliseconds/6048e5;case"day":return b+this._milliseconds/864e5;case"hour":return 24*b+this._milliseconds/36e5;case"minute":return 24*b*60+this._milliseconds/6e4;case"second":return 24*b*60*60+this._milliseconds/1e3;case"millisecond":return Math.floor(24*b*60*60*1e3)+this._milliseconds;default:throw new Error("Unknown unit "+a)}},lang:vb.fn.lang,locale:vb.fn.locale,toIsoString:f("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",function(){return this.toISOString()}),toISOString:function(){var a=Math.abs(this.years()),b=Math.abs(this.months()),c=Math.abs(this.days()),d=Math.abs(this.hours()),e=Math.abs(this.minutes()),f=Math.abs(this.seconds()+this.milliseconds()/1e3);return this.asSeconds()?(this.asSeconds()<0?"-":"")+"P"+(a?a+"Y":"")+(b?b+"M":"")+(c?c+"D":"")+(d||e||f?"T":"")+(d?d+"H":"")+(e?e+"M":"")+(f?f+"S":""):"P0D"},localeData:function(){return this._locale},toJSON:function(){return this.toISOString()}}),vb.duration.fn.toString=vb.duration.fn.toISOString;for(xb in kc)c(kc,xb)&&tb(xb.toLowerCase());vb.duration.fn.asMilliseconds=function(){return this.as("ms")},vb.duration.fn.asSeconds=function(){return this.as("s")},vb.duration.fn.asMinutes=function(){return this.as("m")},vb.duration.fn.asHours=function(){return this.as("h")},vb.duration.fn.asDays=function(){return this.as("d")},vb.duration.fn.asWeeks=function(){return this.as("weeks")},vb.duration.fn.asMonths=function(){return this.as("M")},vb.duration.fn.asYears=function(){return this.as("y")},vb.locale("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===C(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),Lb?module.exports=vb:"function"==typeof define&&define.amd?(define(function(a,b,c){return c.config&&c.config()&&c.config().noGlobal===!0&&(zb.moment=wb),vb}),ub(!0)):ub()}).call(this);
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/legacy.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/legacy.js
new file mode 100755
index 0000000..a5c8fa5
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/legacy.js
@@ -0,0 +1,10 @@
+/*!
+ * Legacy browser support
+ */
+[].map||(Array.prototype.map=function(a,b){for(var c=this,d=c.length,e=new Array(d),f=0;d>f;f++)f in c&&(e[f]=a.call(b,c[f],f,c));return e}),[].filter||(Array.prototype.filter=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if("function"!=typeof a)throw new TypeError;for(var d=[],e=arguments[1],f=0;c>f;f++)if(f in b){var g=b[f];a.call(e,g,f,b)&&d.push(g)}return d}),[].indexOf||(Array.prototype.indexOf=function(a){if(null==this)throw new TypeError;var b=Object(this),c=b.length>>>0;if(0===c)return-1;var d=0;if(arguments.length>1&&(d=Number(arguments[1]),d!=d?d=0:0!==d&&1/0!=d&&d!=-1/0&&(d=(d>0||-1)*Math.floor(Math.abs(d)))),d>=c)return-1;for(var e=d>=0?d:Math.max(c-Math.abs(d),0);c>e;e++)if(e in b&&b[e]===a)return e;return-1});/*!
+ * Cross-Browser Split 1.1.1
+ * Copyright 2007-2012 Steven Levithan
+ * Available under the MIT License
+ * http://blog.stevenlevithan.com/archives/cross-browser-split
+ */
+var nativeSplit=String.prototype.split,compliantExecNpcg=void 0===/()??/.exec("")[1];String.prototype.split=function(a,b){var c=this;if("[object RegExp]"!==Object.prototype.toString.call(a))return nativeSplit.call(c,a,b);var d,e,f,g,h=[],i=(a.ignoreCase?"i":"")+(a.multiline?"m":"")+(a.extended?"x":"")+(a.sticky?"y":""),j=0;for(a=new RegExp(a.source,i+"g"),c+="",compliantExecNpcg||(d=new RegExp("^"+a.source+"$(?!\\s)",i)),b=void 0===b?-1>>>0:b>>>0;(e=a.exec(c))&&(f=e.index+e[0].length,!(f>j&&(h.push(c.slice(j,e.index)),!compliantExecNpcg&&e.length>1&&e[0].replace(d,function(){for(var a=1;a1&&e.index=b)));)a.lastIndex===e.index&&a.lastIndex++;return j===c.length?(g||!a.test(""))&&h.push(""):h.push(c.slice(j)),h.length>b?h.slice(0,b):h};
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/picker.date.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/picker.date.js
new file mode 100755
index 0000000..d3fd96a
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/picker.date.js
@@ -0,0 +1,5 @@
+/*!
+ * Date picker for pickadate.js v3.5.0
+ * http://amsul.github.io/pickadate.js/date.htm
+ */
+!function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0].value,e=a.$node.data("value"),f=e||d,g=e?b.formatSubmit:b.format,h=function(){return"rtl"===getComputedStyle(a.$root[0]).direction};c.settings=b,c.$node=a.$node,c.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),f?c.set("select",f,{format:g}):c.set("select",null).set("highlight",c.item.now),c.key={40:7,38:-7,39:function(){return h()?-1:1},37:function(){return h()?1:-1},go:function(a){var b=c.item.highlight,d=new Date(b.year,b.month,b.date+a);c.set("highlight",[d.getFullYear(),d.getMonth(),d.getDate()],{interval:a}),this.render()}},a.on("render",function(){a.$root.find("."+b.klass.selectMonth).on("change",function(){var c=this.value;c&&(a.set("highlight",[a.get("view").year,c,a.get("highlight").date]),a.$root.find("."+b.klass.selectMonth).trigger("focus"))}),a.$root.find("."+b.klass.selectYear).on("change",function(){var c=this.value;c&&(a.set("highlight",[c,a.get("view").month,a.get("highlight").date]),a.$root.find("."+b.klass.selectYear).trigger("focus"))})}).on("open",function(){a.$root.find("button, select").attr("disabled",!1)}).on("close",function(){a.$root.find("button, select").attr("disabled",!0)})}var d=7,e=6,f=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,d){var e,g=this;return c=void 0===c?a:c,c==-1/0||1/0==c?e=c:b.isPlainObject(c)&&f.isInteger(c.pick)?c=c.obj:b.isArray(c)?(c=new Date(c[0],c[1],c[2]),c=f.isDate(c)?c:g.create().obj):c=f.isInteger(c)||f.isDate(c)?g.normalize(new Date(c),d):g.now(a,c,d),{year:e||c.getFullYear(),month:e||c.getMonth(),date:e||c.getDate(),day:e||c.getDay(),obj:e||c,pick:e||c.getTime()}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return a===!0||b.isArray(a)||f.isDate(a)?d.create(a):a};return f.isInteger(a)||(a=e(a)),f.isInteger(c)||(c=e(c)),f.isInteger(a)&&b.isPlainObject(c)?a=[c.year,c.month,c.date+a]:f.isInteger(c)&&b.isPlainObject(a)&&(c=[a.year,a.month,a.date+c]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b,c){return b=new Date,c&&c.rel&&b.setDate(b.getDate()+c.rel),this.normalize(b,c)},c.prototype.navigate=function(a,c,d){var e,f,g,h,i=b.isArray(c),j=b.isPlainObject(c),k=this.item.view;if(i||j){for(j?(f=c.year,g=c.month,h=c.date):(f=+c[0],g=+c[1],h=+c[2]),d&&d.nav&&k&&k.month!==g&&(f=k.year,g=k.month),e=new Date(f,g+(d&&d.nav?d.nav:0),1),f=e.getFullYear(),g=e.getMonth();new Date(f,g,h).getMonth()!==g;)h-=1;c=[f,g,h]}return c},c.prototype.normalize=function(a){return a.setHours(0,0,0,0),a},c.prototype.measure=function(a,b){var c=this;return b?f.isInteger(b)&&(b=c.now(a,b,{rel:b})):b="min"==a?-1/0:1/0,b},c.prototype.viewset=function(a,b){return this.create([b.year,b.month,1])},c.prototype.validate=function(a,c,d){var e,g,h,i,j=this,k=c,l=d&&d.interval?d.interval:1,m=-1===j.item.enable,n=j.item.min,o=j.item.max,p=m&&j.item.disable.filter(function(a){if(b.isArray(a)){var d=j.create(a).pick;dc.pick&&(g=!0)}return f.isInteger(a)}).length;if((!d||!d.nav)&&(!m&&j.disabled(c)||m&&j.disabled(c)&&(p||e||g)||!m&&(c.pick<=n.pick||c.pick>=o.pick)))for(m&&!p&&(!g&&l>0||!e&&0>l)&&(l*=-1);j.disabled(c)&&(Math.abs(l)>1&&(c.monthk.month)&&(c=k,l=l>0?1:-1),c.pick<=n.pick?(h=!0,l=1,c=j.create([n.year,n.month,n.date+(c.pick===n.pick?0:-1)])):c.pick>=o.pick&&(i=!0,l=-1,c=j.create([o.year,o.month,o.date+(c.pick===o.pick?0:1)])),!h||!i);)c=j.create([c.year,c.month,c.date+l]);return c},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return f.isInteger(d)?a.day===(c.settings.firstDay?d:d-1)%7:b.isArray(d)||f.isDate(d)?a.pick===c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[3]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pickc.item.max.pick},c.prototype.parse=function(a,b,c){var d=this,e={};return b&&"string"==typeof b?(c&&c.format||(c=c||{},c.format=d.settings.format),d.formats.toArray(c.format).map(function(a){var c=d.formats[a],g=c?f.trigger(c,d,[b,e]):a.replace(/^!/,"").length;c&&(e[a]=b.substr(0,g)),b=b.substr(g)}),[e.yyyy||e.yy,+(e.mm||e.m)-1,e.dd||e.d]):b},c.prototype.formats=function(){function a(a,b,c){var d=a.match(/\w+/)[0];return c.mm||c.m||(c.m=b.indexOf(d)+1),d.length}function b(a){return a.match(/\w+/)[0].length}return{d:function(a,b){return a?f.digits(a):b.date},dd:function(a,b){return a?2:f.lead(b.date)},ddd:function(a,c){return a?b(a):this.settings.weekdaysShort[c.day]},dddd:function(a,c){return a?b(a):this.settings.weekdaysFull[c.day]},m:function(a,b){return a?f.digits(a):b.month+1},mm:function(a,b){return a?2:f.lead(b.month+1)},mmm:function(b,c){var d=this.settings.monthsShort;return b?a(b,d,c):d[c.month]},mmmm:function(b,c){var d=this.settings.monthsFull;return b?a(b,d,c):d[c.month]},yy:function(a,b){return a?2:(""+b.year).slice(2)},yyyy:function(a,b){return a?4:b.year},toArray:function(a){return a.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return f.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}}}(),c.prototype.isDateExact=function(a,c){var d=this;return f.isInteger(a)&&f.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(f.isDate(a)||b.isArray(a))&&(f.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:b.isPlainObject(a)&&b.isPlainObject(c)?d.isDateExact(a.from,c.from)&&d.isDateExact(a.to,c.to):!1},c.prototype.isDateOverlap=function(a,c){var d=this,e=d.settings.firstDay?1:0;return f.isInteger(a)&&(f.isDate(c)||b.isArray(c))?(a=a%7+e,a===d.create(c).day+1):f.isInteger(c)&&(f.isDate(a)||b.isArray(a))?(c=c%7+e,c===d.create(a).day+1):b.isPlainObject(a)&&b.isPlainObject(c)?d.overlapRanges(a,c):!1},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,g=0;gi;i+=1){if(h=e[i],d.isDateExact(h,a)){c=e[i]=null,j=!0;break}if(d.isDateOverlap(h,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[3]||c.push("inverted")):f.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;g>i;i+=1)if(d.isDateExact(e[i],a)){e[i]=null;break}if(j)for(i=0;g>i;i+=1)if(d.isDateOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.nodes=function(a){var b=this,c=b.settings,g=b.item,h=g.now,i=g.select,j=g.highlight,k=g.view,l=g.disable,m=g.min,n=g.max,o=function(a,b){return c.firstDay&&(a.push(a.shift()),b.push(b.shift())),f.node("thead",f.node("tr",f.group({min:0,max:d-1,i:1,node:"th",item:function(d){return[a[d],c.klass.weekdays,'scope=col title="'+b[d]+'"']}})))}((c.showWeekdaysFull?c.weekdaysFull:c.weekdaysShort).slice(0),c.weekdaysFull.slice(0)),p=function(a){return f.node("div"," ",c.klass["nav"+(a?"Next":"Prev")]+(a&&k.year>=n.year&&k.month>=n.month||!a&&k.year<=m.year&&k.month<=m.month?" "+c.klass.navDisabled:""),"data-nav="+(a||-1)+" "+f.ariaAttr({role:"button",controls:b.$node[0].id+"_table"})+' title="'+(a?c.labelMonthNext:c.labelMonthPrev)+'"')},q=function(){var d=c.showMonthsShort?c.monthsShort:c.monthsFull;return c.selectMonths?f.node("select",f.group({min:0,max:11,i:1,node:"option",item:function(a){return[d[a],0,"value="+a+(k.month==a?" selected":"")+(k.year==m.year&&an.month?" disabled":"")]}}),c.klass.selectMonth,(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelMonthSelect+'"'):f.node("div",d[k.month],c.klass.month)},r=function(){var d=k.year,e=c.selectYears===!0?5:~~(c.selectYears/2);if(e){var g=m.year,h=n.year,i=d-e,j=d+e;if(g>i&&(j+=g-i,i=g),j>h){var l=i-g,o=j-h;i-=l>o?o:l,j=h}return f.node("select",f.group({min:i,max:j,i:1,node:"option",item:function(a){return[a,0,"value="+a+(d==a?" selected":"")]}}),c.klass.selectYear,(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelYearSelect+'"')}return f.node("div",d,c.klass.year)};return f.node("div",(c.selectYears?r()+q():q()+r())+p()+p(1),c.klass.header)+f.node("table",o+f.node("tbody",f.group({min:0,max:e-1,i:1,node:"tr",item:function(a){var e=c.firstDay&&0===b.create([k.year,k.month,1]).day?-7:0;return[f.group({min:d*a-k.day+e+1,max:function(){return this.min+d-1},i:1,node:"td",item:function(a){a=b.create([k.year,k.month,a+(c.firstDay?1:0)]);var d=i&&i.pick==a.pick,e=j&&j.pick==a.pick,g=l&&b.disabled(a)||a.pickn.pick;return[f.node("div",a.date,function(b){return b.push(k.month==a.month?c.klass.infocus:c.klass.outfocus),h.pick==a.pick&&b.push(c.klass.now),d&&b.push(c.klass.selected),e&&b.push(c.klass.highlighted),g&&b.push(c.klass.disabled),b.join(" ")}([c.klass.day]),"data-pick="+a.pick+" "+f.ariaAttr({role:"gridcell",selected:d&&b.$node.val()===f.trigger(b.formats.toString,b,[c.format,a])?!0:null,activedescendant:e?!0:null,disabled:g?!0:null})),"",f.ariaAttr({role:"presentation"})]}})]}})),c.klass.table,'id="'+b.$node[0].id+'_table" '+f.ariaAttr({role:"grid",controls:b.$node[0].id,readonly:!0}))+f.node("div",f.node("button",c.today,c.klass.buttonToday,"type=button data-pick="+h.pick+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id})),c.klass.footer)},c.defaults=function(a){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],today:"Today",clear:"Clear",format:"d mmmm, yyyy",klass:{table:a+"table",header:a+"header",navPrev:a+"nav--prev",navNext:a+"nav--next",navDisabled:a+"nav--disabled",month:a+"month",year:a+"year",selectMonth:a+"select--month",selectYear:a+"select--year",weekdays:a+"weekday",day:a+"day",disabled:a+"day--disabled",selected:a+"day--selected",highlighted:a+"day--highlighted",now:a+"day--today",infocus:a+"day--infocus",outfocus:a+"day--outfocus",footer:a+"footer",buttonClear:a+"button--clear",buttonToday:a+"button--today"}}}(a.klasses().picker+"__"),a.extend("pickadate",c)});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/picker.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/picker.js
new file mode 100755
index 0000000..f92b618
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/picker.js
@@ -0,0 +1,7 @@
+/*!
+ * pickadate.js v3.5.0, 2014/04/13
+ * By Amsul, http://amsul.ca
+ * Hosted on http://amsul.github.io/pickadate.js
+ * Licensed under MIT
+ */
+!function(a){"function"==typeof define&&define.amd?define("picker",["jquery"],a):this.Picker=a(jQuery)}(function(a){function b(f,g,h,k){function l(){return b._.node("div",b._.node("div",b._.node("div",b._.node("div",w.component.nodes(r.open),t.box),t.wrap),t.frame),t.holder)}function m(){u.data(g,w).addClass(t.input).val(u.data("value")?w.get("select",s.format):f.value).on("focus."+r.id+" click."+r.id,p),s.editable||u.on("keydown."+r.id,function(a){var b=a.keyCode,c=/^(8|46)$/.test(b);return 27==b?(w.close(),!1):void((32==b||c||!r.open&&w.component.key[b])&&(a.preventDefault(),a.stopPropagation(),c?w.clear().close():w.open()))}),e(f,{haspopup:!0,expanded:!1,readonly:!1,owns:f.id+"_root"+(w._hidden?" "+w._hidden.id:"")})}function n(){w.$root.on({focusin:function(a){w.$root.removeClass(t.focused),a.stopPropagation()},"mousedown click":function(b){var c=b.target;c!=w.$root.children()[0]&&(b.stopPropagation(),"mousedown"!=b.type||a(c).is(":input")||"OPTION"==c.nodeName||(b.preventDefault(),f.focus()))}}).on("click","[data-pick], [data-nav], [data-clear]",function(){var c=a(this),d=c.data(),e=c.hasClass(t.navDisabled)||c.hasClass(t.disabled),g=document.activeElement;g=g&&(g.type||g.href)&&g,(e||g&&!a.contains(w.$root[0],g))&&f.focus(),d.nav&&!e?w.set("highlight",w.component.item.highlight,{nav:d.nav}):b._.isInteger(d.pick)&&!e?w.set("select",d.pick).close(!0):d.clear&&w.clear().close(!0)}),e(w.$root[0],"hidden",!0)}function o(){var b,c;s.hiddenName===!0?(b=f.name+"_hidden",c=f.name,f.name=""):(c=["string"==typeof s.hiddenPrefix?s.hiddenPrefix:"","string"==typeof s.hiddenSuffix?s.hiddenSuffix:"_submit"],c=b=c[0]+f.name+c[1]),w._hidden=a('")[0],u.on("change."+r.id,function(){w._hidden.value=f.value?w.get("select",s.formatSubmit):""}).after(w._hidden)}function p(a){a.stopPropagation(),"focus"==a.type&&w.$root.addClass(t.focused),w.open()}if(!f)return b;var q=!1,r={id:f.id||"P"+Math.abs(~~(Math.random()*new Date))},s=h?a.extend(!0,{},h.defaults,k):k||{},t=a.extend({},b.klasses(),s.klass),u=a(f),v=function(){return this.start()},w=v.prototype={constructor:v,$node:u,start:function(){return r&&r.start?w:(r.methods={},r.start=!0,r.open=!1,r.type=f.type,f.autofocus=f==document.activeElement,f.type="text",f.readOnly=!s.editable,f.id=f.id||r.id,w.component=new h(w,s),w.$root=a(b._.node("div",l(),t.picker,'id="'+f.id+'_root"')),n(),s.formatSubmit&&o(),m(),s.container?a(s.container).append(w.$root):u.after(w.$root),w.on({start:w.component.onStart,render:w.component.onRender,stop:w.component.onStop,open:w.component.onOpen,close:w.component.onClose,set:w.component.onSet}).on({start:s.onStart,render:s.onRender,stop:s.onStop,open:s.onOpen,close:s.onClose,set:s.onSet}),q=c(w.$root.children()[0]),f.autofocus&&w.open(),w.trigger("start").trigger("render"))},render:function(a){return a?w.$root.html(l()):w.$root.find("."+t.box).html(w.component.nodes(r.open)),w.trigger("render")},stop:function(){return r.start?(w.close(),w._hidden&&w._hidden.parentNode.removeChild(w._hidden),w.$root.remove(),u.removeClass(t.input).removeData(g),setTimeout(function(){u.off("."+r.id)},0),f.type=r.type,f.readOnly=!1,w.trigger("stop"),r.methods={},r.start=!1,w):w},open:function(c){return r.open?w:(u.addClass(t.active),e(f,"expanded",!0),setTimeout(function(){w.$root.addClass(t.opened),e(w.$root[0],"hidden",!1)},0),c!==!1&&(r.open=!0,q&&j.css("overflow","hidden").css("padding-right","+="+d()),u.trigger("focus"),i.on("click."+r.id+" focusin."+r.id,function(a){var b=a.target;b!=f&&b!=document&&3!=a.which&&w.close(b===w.$root.children()[0])}).on("keydown."+r.id,function(c){var d=c.keyCode,e=w.component.key[d],g=c.target;27==d?w.close(!0):g!=f||!e&&13!=d?a.contains(w.$root[0],g)&&13==d&&(c.preventDefault(),g.click()):(c.preventDefault(),e?b._.trigger(w.component.key.go,w,[b._.trigger(e)]):w.$root.find("."+t.highlighted).hasClass(t.disabled)||w.set("select",w.component.item.highlight).close())})),w.trigger("open"))},close:function(a){return a&&(u.off("focus."+r.id).trigger("focus"),setTimeout(function(){u.on("focus."+r.id,p)},0)),u.removeClass(t.active),e(f,"expanded",!1),setTimeout(function(){w.$root.removeClass(t.opened+" "+t.focused),e(w.$root[0],"hidden",!0)},0),r.open?(r.open=!1,q&&j.css("overflow","").css("padding-right","-="+d()),i.off("."+r.id),w.trigger("close")):w},clear:function(){return w.set("clear")},set:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(d=g&&a.isPlainObject(c)?c:d||{},b){g||(h[b]=c);for(e in h)f=h[e],e in w.component.item&&(void 0===f&&(f=null),w.component.set(e,f,d)),("select"==e||"clear"==e)&&u.val("clear"==e?"":w.get(e,s.format)).trigger("change");w.render()}return d.muted?w:w.trigger("set",h)},get:function(a,c){if(a=a||"value",null!=r[a])return r[a];if("value"==a)return f.value;if(a in w.component.item){if("string"==typeof c){var d=w.component.get(a);return d?b._.trigger(w.component.formats.toString,w.component,[c,d]):""}return w.component.get(a)}},on:function(b,c){var d,e,f=a.isPlainObject(b),g=f?b:{};if(b){f||(g[b]=c);for(d in g)e=g[d],r.methods[d]=r.methods[d]||[],r.methods[d].push(e)}return w},off:function(){var a,b,c=arguments;for(a=0,namesCount=c.length;namesCount>a;a+=1)b=c[a],b in r.methods&&delete r.methods[b];return w},trigger:function(a,c){var d=r.methods[a];return d&&d.map(function(a){b._.trigger(a,w,[c])}),w}};return new v}function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[c]:window.getComputedStyle&&(b=getComputedStyle(a)[c]),"fixed"==b}function d(){if(j.height()<=h.height())return 0;var b=a('').appendTo("body"),c=b[0].offsetWidth;b.css("overflow","scroll");var d=a('').appendTo(b),e=d[0].offsetWidth;return b.remove(),c-e}function e(b,c,d){if(a.isPlainObject(c))for(var e in c)f(b,e,c[e]);else f(b,c,d)}function f(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}function g(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in b){var e=("role"==d?"":"aria-")+d,f=b[d];c+=null==f?"":e+'="'+b[d]+'"'}return c}var h=a(window),i=a(document),j=a(document.documentElement);return b.klasses=function(a){return a=a||"picker",{picker:a,opened:a+"--opened",focused:a+"--focused",input:a+"__input",active:a+"__input--active",holder:a+"__holder",frame:a+"__frame",wrap:a+"__wrap",box:a+"__box"}},b._={group:function(a){for(var c,d="",e=b._.trigger(a.min,a);e<=b._.trigger(a.max,a,[e]);e+=a.i)c=b._.trigger(a.item,a,[e]),d+=b._.node(a.node,c[0],c[1],c[2]);return d},node:function(b,c,d,e){return c?(c=a.isArray(c)?c.join(""):c,d=d?' class="'+d+'"':"",e=e?" "+e:"","<"+b+d+e+">"+c+""+b+">"):""},lead:function(a){return(10>a?"0":"")+a},trigger:function(a,b,c){return"function"==typeof a?a.apply(b,c||[]):a},digits:function(a){return/\d/.test(a[1])?2:1},isDate:function(a){return{}.toString.call(a).indexOf("Date")>-1&&this.isInteger(a.getDate())},isInteger:function(a){return{}.toString.call(a).indexOf("Number")>-1&&a%1===0},ariaAttr:g},b.extend=function(c,d){a.fn[c]=function(e,f){var g=this.data(c);return"picker"==e?g:g&&"string"==typeof e?b._.trigger(g[e],g,[f]):this.each(function(){var f=a(this);f.data(c)||new b(this,c,d,e)})},a.fn[c].defaults=d.defaults},b});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/picker.time.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/picker.time.js
new file mode 100755
index 0000000..2256d9e
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/picker.time.js
@@ -0,0 +1,5 @@
+/*!
+ * Time picker for pickadate.js v3.5.0
+ * http://amsul.github.io/pickadate.js/time.htm
+ */
+!function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0].value,e=a.$node.data("value"),f=e||d,g=e?b.formatSubmit:b.format;c.settings=b,c.$node=a.$node,c.queue={interval:"i",min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse create validate",view:"parse create validate",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.interval=b.interval||30,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),f?c.set("select",f,{format:g,fromValue:!!d}):c.set("select",null).set("highlight",c.item.now),c.key={40:1,38:-1,39:1,37:-1,go:function(a){c.set("highlight",c.item.highlight.pick+a*c.item.interval,{interval:a*c.item.interval}),this.render()}},a.on("render",function(){var c=a.$root.children(),d=c.find("."+b.klass.viewset);d.length&&(c[0].scrollTop=~~d.position().top-2*d[0].clientHeight)}).on("open",function(){a.$root.find("button").attr("disabled",!1)}).on("close",function(){a.$root.find("button").attr("disabled",!0)})}var d=24,e=60,f=12,g=d*e,h=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):"interval"==a?d.set("min",e.min,c).set("max",e.max,c):a.match(/^(flip|min|max|disable|enable)$/)&&("min"==a&&d.set("max",e.max,c),e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,f){var i=this;return c=void 0===c?a:c,h.isDate(c)&&(c=[c.getHours(),c.getMinutes()]),b.isPlainObject(c)&&h.isInteger(c.pick)?c=c.pick:b.isArray(c)?c=+c[0]*e+ +c[1]:h.isInteger(c)||(c=i.now(a,c,f)),"max"==a&&c=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b){var c,d=this.item.interval,f=new Date,g=f.getHours()*e+f.getMinutes(),i=h.isInteger(b);return g-=g%d,c=0>b&&-d>=d*b+g,g+="min"==a&&c?0:d,i&&(g+=d*(c&&"max"!=a?b+1:b)),g},c.prototype.normalize=function(a,b){var c=this.item.interval,d=this.item.min&&this.item.min.pick||0;return b-="min"==a?0:(b-d)%c},c.prototype.measure=function(a,c,f){var g=this;return c?c===!0||h.isInteger(c)?c=g.now(a,c,f):b.isPlainObject(c)&&h.isInteger(c.pick)&&(c=g.normalize(a,c.pick,f)):c="min"==a?[0,0]:[d-1,e-1],c},c.prototype.validate=function(a,b,c){var d=this,e=c&&c.interval?c.interval:d.item.interval;return d.disabled(b)&&(b=d.shift(b,e)),b=d.scope(b),d.disabled(b)&&(b=d.shift(b,-1*e)),b},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return h.isInteger(d)?a.hour==d:b.isArray(d)||h.isDate(d)?a.pick==c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[2]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pickc.item.max.pick},c.prototype.shift=function(a,b){var c=this,d=c.item.min.pick,e=c.item.max.pick;for(b=b||c.item.interval;c.disabled(a)&&(a=c.create(a.pick+=b),!(a.pick<=d||a.pick>=e)););return a},c.prototype.scope=function(a){var b=this.item.min.pick,c=this.item.max.pick;return this.create(a.pick>c?c:a.pickb.time%g?"a.m.":"p.m."},A:function(a,b){return a?2:g/2>b.time%g?"AM":"PM"},toArray:function(a){return a.split(/(h{1,2}|H{1,2}|i|a|A|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return h.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}},c.prototype.isTimeExact=function(a,c){var d=this;return h.isInteger(a)&&h.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(h.isDate(a)||b.isArray(a))&&(h.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:b.isPlainObject(a)&&b.isPlainObject(c)?d.isTimeExact(a.from,c.from)&&d.isTimeExact(a.to,c.to):!1},c.prototype.isTimeOverlap=function(a,c){var d=this;return h.isInteger(a)&&(h.isDate(c)||b.isArray(c))?a===d.create(c).hour:h.isInteger(c)&&(h.isDate(a)||b.isArray(a))?c===d.create(a).hour:b.isPlainObject(a)&&b.isPlainObject(c)?d.overlapRanges(a,c):!1},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,f=0;fi;i+=1){if(g=e[i],d.isTimeExact(g,a)){c=e[i]=null,j=!0;break}if(d.isTimeOverlap(g,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[2]||c.push("inverted")):h.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;f>i;i+=1)if(d.isTimeExact(e[i],a)){e[i]=null;break}if(j)for(i=0;f>i;i+=1)if(d.isTimeOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.i=function(a,b){return h.isInteger(b)&&b>0?b:this.item.interval},c.prototype.nodes=function(a){var b=this,c=b.settings,d=b.item.select,e=b.item.highlight,f=b.item.view,g=b.item.disable;return h.node("ul",h.group({min:b.item.min.pick,max:b.item.max.pick,i:b.item.interval,node:"li",item:function(a){a=b.create(a);var i=a.pick,j=d&&d.pick==i,k=e&&e.pick==i,l=g&&b.disabled(a);return[h.trigger(b.formats.toString,b,[h.trigger(c.formatLabel,b,[a])||c.format,a]),function(a){return j&&a.push(c.klass.selected),k&&a.push(c.klass.highlighted),f&&f.pick==i&&a.push(c.klass.viewset),l&&a.push(c.klass.disabled),a.join(" ")}([c.klass.listItem]),"data-pick="+a.pick+" "+h.ariaAttr({role:"option",selected:j&&b.$node.val()===h.trigger(b.formats.toString,b,[c.format,a])?!0:null,activedescendant:k?!0:null,disabled:l?!0:null})]}})+h.node("li",h.node("button",c.clear,c.klass.buttonClear,"type=button data-clear=1"+(a?"":" disabled")+" "+h.ariaAttr({controls:b.$node[0].id})),"",h.ariaAttr({role:"presentation"})),c.klass.list,h.ariaAttr({role:"listbox",controls:b.$node[0].id}))},c.defaults=function(a){return{clear:"Clear",format:"h:i A",interval:30,klass:{picker:a+" "+a+"--time",holder:a+"__holder",list:a+"__list",listItem:a+"__list-item",disabled:a+"__list-item--disabled",selected:a+"__list-item--selected",highlighted:a+"__list-item--highlighted",viewset:a+"__list-item--viewset",now:a+"__list-item--now",buttonClear:a+"__button--clear"}}}(a.klasses().picker),a.extend("pickatime",c)});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/classic.css b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/classic.css
new file mode 100755
index 0000000..9b1e79e
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/classic.css
@@ -0,0 +1,4 @@
+.picker{font-size:16px;text-align:left;line-height:1.2;color:#000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}/*!
+ * Classic picker styling for pickadate.js
+ * Demo: http://amsul.github.io/pickadate.js
+ */.picker{width:100%}.picker__holder{position:absolute;background:#fff;border:1px solid #aaa;border-top-width:0;border-bottom-width:0;-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;min-width:176px;max-width:466px;max-height:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;-webkit-transform:translateY(-1em) perspective(600px) rotateX(10deg);-moz-transform:translateY(-1em) perspective(600px) rotateX(10deg);transform:translateY(-1em) perspective(600px) rotateX(10deg);-webkit-transition:-webkit-transform .15s ease-out,opacity .15s ease-out,max-height 0s .15s,border-width 0s .15s;-moz-transition:-moz-transform .15s ease-out,opacity .15s ease-out,max-height 0s .15s,border-width 0s .15s;transition:transform .15s ease-out,opacity .15s ease-out,max-height 0s .15s,border-width 0s .15s}.picker__frame{padding:1px}.picker__wrap{margin:-1px}.picker--opened .picker__holder{max-height:25em;-ms-filter:"alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1;border-top-width:1px;border-bottom-width:1px;-webkit-transform:translateY(0) perspective(600px) rotateX(0);-moz-transform:translateY(0) perspective(600px) rotateX(0);transform:translateY(0) perspective(600px) rotateX(0);-webkit-transition:-webkit-transform .15s ease-out,opacity .15s ease-out,max-height 0s,border-width 0s;-moz-transition:-moz-transform .15s ease-out,opacity .15s ease-out,max-height 0s,border-width 0s;transition:transform .15s ease-out,opacity .15s ease-out,max-height 0s,border-width 0s;-webkit-box-shadow:0 6px 18px 1px rgba(0,0,0,.12);-moz-box-shadow:0 6px 18px 1px rgba(0,0,0,.12);box-shadow:0 6px 18px 1px rgba(0,0,0,.12)}
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/classic.date.css b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/classic.date.css
new file mode 100755
index 0000000..2417e7c
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/classic.date.css
@@ -0,0 +1 @@
+.picker__box{padding:0 1em}.picker__header{text-align:center;position:relative;margin-top:.75em}.picker__month,.picker__year{font-weight:500;display:inline-block;margin-left:.25em;margin-right:.25em}.picker__year{color:#999;font-size:.8em;font-style:italic}.picker__select--month,.picker__select--year{border:1px solid #b7b7b7;height:2em;padding:.5em;margin-left:.25em;margin-right:.25em}@media (min-width:24.5em){.picker__select--month,.picker__select--year{margin-top:-.5em}}.picker__select--month{width:35%}.picker__select--year{width:22.5%}.picker__select--month:focus,.picker__select--year:focus{border-color:#0089ec}.picker__nav--next,.picker__nav--prev{position:absolute;padding:.5em 1.25em;width:1em;height:1em;box-sizing:content-box;top:-.25em}@media (min-width:24.5em){.picker__nav--next,.picker__nav--prev{top:-.33em}}.picker__nav--prev{left:-1em;padding-right:1.25em}@media (min-width:24.5em){.picker__nav--prev{padding-right:1.5em}}.picker__nav--next{right:-1em;padding-left:1.25em}@media (min-width:24.5em){.picker__nav--next{padding-left:1.5em}}.picker__nav--next:before,.picker__nav--prev:before{content:" ";border-top:.5em solid transparent;border-bottom:.5em solid transparent;border-right:.75em solid #000;width:0;height:0;display:block;margin:0 auto}.picker__nav--next:before{border-right:0;border-left:.75em solid #000}.picker__nav--next:hover,.picker__nav--prev:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker__nav--disabled,.picker__nav--disabled:before,.picker__nav--disabled:before:hover,.picker__nav--disabled:hover{cursor:default;background:0 0;border-right-color:#f5f5f5;border-left-color:#f5f5f5}.picker__table{text-align:center;border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:inherit;width:100%;margin-top:.75em;margin-bottom:.5em}@media (min-height:33.875em){.picker__table{margin-bottom:.75em}}.picker__table td{margin:0;padding:0}.picker__weekday{width:14.285714286%;font-size:.75em;padding-bottom:.25em;color:#999;font-weight:500}@media (min-height:33.875em){.picker__weekday{padding-bottom:.5em}}.picker__day{padding:.3125em 0;font-weight:200;border:1px solid transparent}.picker__day--today{position:relative}.picker__day--today:before{content:" ";position:absolute;top:2px;right:2px;width:0;height:0;border-top:.5em solid #0059bc;border-left:.5em solid transparent}.picker__day--disabled:before{border-top-color:#aaa}.picker__day--outfocus{color:#ddd}.picker__day--infocus:hover,.picker__day--outfocus:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker__day--highlighted{border-color:#0089ec}.picker--focused .picker__day--highlighted,.picker__day--highlighted:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker--focused .picker__day--selected,.picker__day--selected,.picker__day--selected:hover{background:#0089ec;color:#fff}.picker__day--disabled,.picker__day--disabled:hover{background:#f5f5f5;border-color:#f5f5f5;color:#ddd;cursor:default}.picker__day--highlighted.picker__day--disabled,.picker__day--highlighted.picker__day--disabled:hover{background:#bbb}.picker__footer{text-align:center}.picker__button--clear,.picker__button--today{border:1px solid #fff;background:#fff;font-size:.8em;padding:.66em 0;font-weight:700;width:50%;display:inline-block;vertical-align:bottom}.picker__button--clear:hover,.picker__button--today:hover{cursor:pointer;color:#000;background:#b1dcfb;border-bottom-color:#b1dcfb}.picker__button--clear:focus,.picker__button--today:focus{background:#b1dcfb;border-color:#0089ec;outline:0}.picker__button--clear:before,.picker__button--today:before{position:relative;display:inline-block;height:0}.picker__button--today:before{content:" ";margin-right:.45em;top:-.05em;width:0;border-top:.66em solid #0059bc;border-left:.66em solid transparent}.picker__button--clear:before{content:"\D7";margin-right:.35em;top:-.1em;color:#e20;vertical-align:top;font-size:1.1em}
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/classic.time.css b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/classic.time.css
new file mode 100755
index 0000000..10cb576
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/classic.time.css
@@ -0,0 +1 @@
+.picker__list{list-style:none;padding:.75em 0 4.2em;margin:0}.picker__list-item{border-bottom:1px solid #ddd;border-top:1px solid #ddd;margin-bottom:-1px;position:relative;background:#fff;padding:.75em 1.25em}@media (min-height:46.75em){.picker__list-item{padding:.5em 1em}}.picker__list-item:hover{cursor:pointer;color:#000;background:#b1dcfb;border-color:#0089ec;z-index:10}.picker__list-item--highlighted{border-color:#0089ec;z-index:10}.picker--focused .picker__list-item--highlighted,.picker__list-item--highlighted:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker--focused .picker__list-item--selected,.picker__list-item--selected,.picker__list-item--selected:hover{background:#0089ec;color:#fff;z-index:10}.picker--focused .picker__list-item--disabled,.picker__list-item--disabled,.picker__list-item--disabled:hover{background:#f5f5f5;color:#ddd;cursor:default;border-color:#ddd;z-index:auto}.picker--time .picker__button--clear{display:block;width:80%;margin:1em auto 0;padding:1em 1.25em;background:0 0;border:0;font-weight:500;font-size:.67em;text-align:center;text-transform:uppercase;color:#666}.picker--time .picker__button--clear:focus,.picker--time .picker__button--clear:hover{background:#b1dcfb;background:#e20;border-color:#e20;cursor:pointer;color:#fff;outline:0}.picker--time .picker__button--clear:before{top:-.25em;color:#666;font-size:1.25em;font-weight:700}.picker--time .picker__button--clear:focus:before,.picker--time .picker__button--clear:hover:before{color:#fff}.picker--time{min-width:256px;max-width:320px}.picker--time .picker__holder{background:#f2f2f2}@media (min-height:40.125em){.picker--time .picker__holder{font-size:.875em}}.picker--time .picker__box{padding:0;position:relative}
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/default.css b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/default.css
new file mode 100755
index 0000000..2dd16bb
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/default.css
@@ -0,0 +1,4 @@
+.picker{font-size:16px;text-align:left;line-height:1.2;color:#000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}/*!
+ * Default mobile-first, responsive styling for pickadate.js
+ * Demo: http://amsul.github.io/pickadate.js
+ */.picker__frame,.picker__holder{bottom:0;left:0;right:0;top:100%}.picker__holder{position:fixed;-webkit-transition:background .15s ease-out,top 0s .15s;-moz-transition:background .15s ease-out,top 0s .15s;transition:background .15s ease-out,top 0s .15s}.picker__frame{position:absolute;margin:0 auto;min-width:256px;max-width:666px;width:100%;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;-webkit-transition:all .15s ease-out;-moz-transition:all .15s ease-out;transition:all .15s ease-out}@media (min-height:33.875em){.picker__frame{overflow:visible;top:auto;bottom:-100%;max-height:80%}}@media (min-height:40.125em){.picker__frame{margin-bottom:7.5%}}.picker__wrap{display:table;width:100%;height:100%}@media (min-height:33.875em){.picker__wrap{display:block}}.picker__box{background:#fff;display:table-cell;vertical-align:middle}@media (min-height:26.5em){.picker__box{font-size:1.25em}}@media (min-height:33.875em){.picker__box{display:block;font-size:1.33em;border:1px solid #777;border-top-color:#898989;border-bottom-width:0;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;-webkit-box-shadow:0 12px 36px 16px rgba(0,0,0,.24);-moz-box-shadow:0 12px 36px 16px rgba(0,0,0,.24);box-shadow:0 12px 36px 16px rgba(0,0,0,.24)}}@media (min-height:40.125em){.picker__box{font-size:1.5em;border-bottom-width:1px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}}.picker--opened .picker__holder{top:0;zoom:1;background:rgba(0,0,0,.32);-webkit-transition:background .15s ease-out;-moz-transition:background .15s ease-out;transition:background .15s ease-out}.picker--opened .picker__frame{top:0;-ms-filter:"alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1}@media (min-height:33.875em){.picker--opened .picker__frame{top:auto;bottom:0}}
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/default.date.css b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/default.date.css
new file mode 100755
index 0000000..2417e7c
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/default.date.css
@@ -0,0 +1 @@
+.picker__box{padding:0 1em}.picker__header{text-align:center;position:relative;margin-top:.75em}.picker__month,.picker__year{font-weight:500;display:inline-block;margin-left:.25em;margin-right:.25em}.picker__year{color:#999;font-size:.8em;font-style:italic}.picker__select--month,.picker__select--year{border:1px solid #b7b7b7;height:2em;padding:.5em;margin-left:.25em;margin-right:.25em}@media (min-width:24.5em){.picker__select--month,.picker__select--year{margin-top:-.5em}}.picker__select--month{width:35%}.picker__select--year{width:22.5%}.picker__select--month:focus,.picker__select--year:focus{border-color:#0089ec}.picker__nav--next,.picker__nav--prev{position:absolute;padding:.5em 1.25em;width:1em;height:1em;box-sizing:content-box;top:-.25em}@media (min-width:24.5em){.picker__nav--next,.picker__nav--prev{top:-.33em}}.picker__nav--prev{left:-1em;padding-right:1.25em}@media (min-width:24.5em){.picker__nav--prev{padding-right:1.5em}}.picker__nav--next{right:-1em;padding-left:1.25em}@media (min-width:24.5em){.picker__nav--next{padding-left:1.5em}}.picker__nav--next:before,.picker__nav--prev:before{content:" ";border-top:.5em solid transparent;border-bottom:.5em solid transparent;border-right:.75em solid #000;width:0;height:0;display:block;margin:0 auto}.picker__nav--next:before{border-right:0;border-left:.75em solid #000}.picker__nav--next:hover,.picker__nav--prev:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker__nav--disabled,.picker__nav--disabled:before,.picker__nav--disabled:before:hover,.picker__nav--disabled:hover{cursor:default;background:0 0;border-right-color:#f5f5f5;border-left-color:#f5f5f5}.picker__table{text-align:center;border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:inherit;width:100%;margin-top:.75em;margin-bottom:.5em}@media (min-height:33.875em){.picker__table{margin-bottom:.75em}}.picker__table td{margin:0;padding:0}.picker__weekday{width:14.285714286%;font-size:.75em;padding-bottom:.25em;color:#999;font-weight:500}@media (min-height:33.875em){.picker__weekday{padding-bottom:.5em}}.picker__day{padding:.3125em 0;font-weight:200;border:1px solid transparent}.picker__day--today{position:relative}.picker__day--today:before{content:" ";position:absolute;top:2px;right:2px;width:0;height:0;border-top:.5em solid #0059bc;border-left:.5em solid transparent}.picker__day--disabled:before{border-top-color:#aaa}.picker__day--outfocus{color:#ddd}.picker__day--infocus:hover,.picker__day--outfocus:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker__day--highlighted{border-color:#0089ec}.picker--focused .picker__day--highlighted,.picker__day--highlighted:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker--focused .picker__day--selected,.picker__day--selected,.picker__day--selected:hover{background:#0089ec;color:#fff}.picker__day--disabled,.picker__day--disabled:hover{background:#f5f5f5;border-color:#f5f5f5;color:#ddd;cursor:default}.picker__day--highlighted.picker__day--disabled,.picker__day--highlighted.picker__day--disabled:hover{background:#bbb}.picker__footer{text-align:center}.picker__button--clear,.picker__button--today{border:1px solid #fff;background:#fff;font-size:.8em;padding:.66em 0;font-weight:700;width:50%;display:inline-block;vertical-align:bottom}.picker__button--clear:hover,.picker__button--today:hover{cursor:pointer;color:#000;background:#b1dcfb;border-bottom-color:#b1dcfb}.picker__button--clear:focus,.picker__button--today:focus{background:#b1dcfb;border-color:#0089ec;outline:0}.picker__button--clear:before,.picker__button--today:before{position:relative;display:inline-block;height:0}.picker__button--today:before{content:" ";margin-right:.45em;top:-.05em;width:0;border-top:.66em solid #0059bc;border-left:.66em solid transparent}.picker__button--clear:before{content:"\D7";margin-right:.35em;top:-.1em;color:#e20;vertical-align:top;font-size:1.1em}
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/default.time.css b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/default.time.css
new file mode 100755
index 0000000..f1783ca
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/default.time.css
@@ -0,0 +1 @@
+.picker__list{list-style:none;padding:.75em 0 4.2em;margin:0}.picker__list-item{border-bottom:1px solid #ddd;border-top:1px solid #ddd;margin-bottom:-1px;position:relative;background:#fff;padding:.75em 1.25em}@media (min-height:46.75em){.picker__list-item{padding:.5em 1em}}.picker__list-item:hover{cursor:pointer;color:#000;background:#b1dcfb;border-color:#0089ec;z-index:10}.picker__list-item--highlighted{border-color:#0089ec;z-index:10}.picker--focused .picker__list-item--highlighted,.picker__list-item--highlighted:hover{cursor:pointer;color:#000;background:#b1dcfb}.picker--focused .picker__list-item--selected,.picker__list-item--selected,.picker__list-item--selected:hover{background:#0089ec;color:#fff;z-index:10}.picker--focused .picker__list-item--disabled,.picker__list-item--disabled,.picker__list-item--disabled:hover{background:#f5f5f5;color:#ddd;cursor:default;border-color:#ddd;z-index:auto}.picker--time .picker__button--clear{display:block;width:80%;margin:1em auto 0;padding:1em 1.25em;background:0 0;border:0;font-weight:500;font-size:.67em;text-align:center;text-transform:uppercase;color:#666}.picker--time .picker__button--clear:focus,.picker--time .picker__button--clear:hover{background:#b1dcfb;background:#e20;border-color:#e20;cursor:pointer;color:#fff;outline:0}.picker--time .picker__button--clear:before{top:-.25em;color:#666;font-size:1.25em;font-weight:700}.picker--time .picker__button--clear:focus:before,.picker--time .picker__button--clear:hover:before{color:#fff}.picker--time .picker__frame{min-width:256px;max-width:320px}.picker--time .picker__box{font-size:1em;background:#f2f2f2;padding:0}@media (min-height:40.125em){.picker--time .picker__box{margin-bottom:5em}}
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/rtl.css b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/rtl.css
new file mode 100755
index 0000000..0b9d69f
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/themes/rtl.css
@@ -0,0 +1,3 @@
+/*!
+ * Styling for RTL (right-to-left) languages using pickadate.js
+ */.picker{direction:rtl}.picker__nav--next{right:auto;left:-1em}.picker__nav--prev{left:auto;right:-1em}.picker__nav--next:before{border-left:0;border-right:.75em solid #000}.picker__nav--prev:before{border-right:0;border-left:.75em solid #000}
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ar.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ar.js
new file mode 100755
index 0000000..cf62b8d
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ar.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["يناير","فبراير","مارس","ابريل","مايو","يونيو","يوليو","اغسطس","سبتمبر","اكتوبر","نوفمبر","ديسمبر"],monthsShort:["يناير","فبراير","مارس","ابريل","مايو","يونيو","يوليو","اغسطس","سبتمبر","اكتوبر","نوفمبر","ديسمبر"],weekdaysFull:["الاحد","الاثنين","الثلاثاء","الاربعاء","الخميس","الجمعة","السبت"],weekdaysShort:["الاحد","الاثنين","الثلاثاء","الاربعاء","الخميس","الجمعة","السبت"],today:"اليوم",clear:"مسح",format:"yyyy mmmm dd",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/bg_BG.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/bg_BG.js
new file mode 100755
index 0000000..ca1d2f1
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/bg_BG.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["януари","февруари","март","април","май","юни","юли","август","септември","октомври","ноември","декември"],monthsShort:["янр","фев","мар","апр","май","юни","юли","авг","сеп","окт","ное","дек"],weekdaysFull:["неделя","понеделник","вторник","сряда","четвъртък","петък","събота"],weekdaysShort:["нд","пн","вт","ср","чт","пт","сб"],today:"днес",clear:"изтривам",firstDay:1,format:"d mmmm yyyy г.",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/bs_BA.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/bs_BA.js
new file mode 100755
index 0000000..7cbf3a1
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/bs_BA.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januar","februar","mart","april","maj","juni","juli","august","septembar","oktobar","novembar","decembar"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],weekdaysFull:["nedjelja","ponedjeljak","utorak","srijeda","cetvrtak","petak","subota"],weekdaysShort:["ne","po","ut","sr","če","pe","su"],today:"danas",clear:"izbrisati",firstDay:1,format:"dd. mmmm yyyy.",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ca_ES.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ca_ES.js
new file mode 100755
index 0000000..583126b
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ca_ES.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Gener","Febrer","Març","Abril","Maig","juny","Juliol","Agost","Setembre","Octubre","Novembre","Desembre"],monthsShort:["Gen","Feb","Mar","Abr","Mai","Jun","Jul","Ago","Set","Oct","Nov","Des"],weekdaysFull:["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"],weekdaysShort:["diu","dil","dim","dmc","dij","div","dis"],today:"avui",clear:"esborrar",firstDay:1,format:"dddd d !de mmmm !de yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/cs_CZ.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/cs_CZ.js
new file mode 100755
index 0000000..1a67bfc
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/cs_CZ.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["leden","únor","březen","duben","květen","červen","červenec","srpen","září","říjen","listopad","prosinec"],monthsShort:["led","úno","bře","dub","kvě","čer","čvc","srp","zář","říj","lis","pro"],weekdaysFull:["neděle","pondělí","úterý","středa","čtvrtek","pátek","sobota"],weekdaysShort:["ne","po","út","st","čt","pá","so"],today:"dnes",clear:"vymazat",firstDay:1,format:"d. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/da_DK.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/da_DK.js
new file mode 100755
index 0000000..adc6d38
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/da_DK.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januar","februar","marts","april","maj","juni","juli","august","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],weekdaysFull:["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],weekdaysShort:["søn","man","tir","ons","tor","fre","lør"],today:"i dag",clear:"slet",firstDay:1,format:"d. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/de_DE.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/de_DE.js
new file mode 100755
index 0000000..aa961d8
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/de_DE.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],weekdaysFull:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],weekdaysShort:["So","Mo","Di","Mi","Do","Fr","Sa"],today:"Heute",clear:"Löschen",firstDay:1,format:"dddd, dd. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/el_GR.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/el_GR.js
new file mode 100755
index 0000000..0228109
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/el_GR.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάιος","Ιούνιος","Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος"],monthsShort:["Ιαν","Φεβ","Μαρ","Απρ","Μαι","Ιουν","Ιουλ","Αυγ","Σεπ","Οκτ","Νοε","Δεκ"],weekdaysFull:["Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο"],weekdaysShort:["Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ"],today:"σήμερα",clear:"Διαγραφή",firstDay:1,format:"d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/es_ES.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/es_ES.js
new file mode 100755
index 0000000..774ba68
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/es_ES.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre"],monthsShort:["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic"],weekdaysFull:["domingo","lunes","martes","miércoles","jueves","viernes","sábado"],weekdaysShort:["dom","lun","mar","mié","jue","vie","sáb"],today:"hoy",clear:"borrar",firstDay:1,format:"dddd d !de mmmm !de yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/et_EE.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/et_EE.js
new file mode 100755
index 0000000..30226ab
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/et_EE.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["jaanuar","veebruar","märts","aprill","mai","juuni","juuli","august","september","oktoober","november","detsember"],monthsShort:["jaan","veebr","märts","apr","mai","juuni","juuli","aug","sept","okt","nov","dets"],weekdaysFull:["pühapäev","esmaspäev","teisipäev","kolmapäev","neljapäev","reede","laupäev"],weekdaysShort:["püh","esm","tei","kol","nel","ree","lau"],today:"täna",clear:"kustutama",firstDay:1,format:"d. mmmm yyyy. a",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/eu_ES.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/eu_ES.js
new file mode 100755
index 0000000..5407040
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/eu_ES.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["urtarrila","otsaila","martxoa","apirila","maiatza","ekaina","uztaila","abuztua","iraila","urria","azaroa","abendua"],monthsShort:["urt","ots","mar","api","mai","eka","uzt","abu","ira","urr","aza","abe"],weekdaysFull:["igandea","astelehena","asteartea","asteazkena","osteguna","ostirala","larunbata"],weekdaysShort:["ig.","al.","ar.","az.","og.","or.","lr."],today:"gaur",clear:"garbitu",firstDay:1,format:"dddd, yyyy(e)ko mmmmren da",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/fi_FI.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/fi_FI.js
new file mode 100755
index 0000000..d55e1bb
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/fi_FI.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu","heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu"],monthsShort:["tammi","helmi","maalis","huhti","touko","kesä","heinä","elo","syys","loka","marras","joulu"],weekdaysFull:["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"],weekdaysShort:["su","ma","ti","ke","to","pe","la"],today:"tänään",clear:"tyhjennä",firstDay:1,format:"d.m.yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/fr_FR.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/fr_FR.js
new file mode 100755
index 0000000..bc435da
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/fr_FR.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],monthsShort:["Jan","Fev","Mar","Avr","Mai","Juin","Juil","Aou","Sep","Oct","Nov","Dec"],weekdaysFull:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],weekdaysShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],today:"Aujourd'hui",clear:"Effacer",firstDay:1,format:"dd mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/gl_ES.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/gl_ES.js
new file mode 100755
index 0000000..d67e6ad
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/gl_ES.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Xaneiro","Febreiro","Marzo","Abril","Maio","Xuño","Xullo","Agosto","Setembro","Outubro","Novembro","Decembro"],monthsShort:["xan","feb","mar","abr","mai","xun","xul","ago","sep","out","nov","dec"],weekdaysFull:["domingo","luns","martes","mércores","xoves","venres","sábado"],weekdaysShort:["dom","lun","mar","mér","xov","ven","sab"],today:"hoxe",clear:"borrar",firstDay:1,format:"dddd d !de mmmm !de yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/he_IL.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/he_IL.js
new file mode 100755
index 0000000..6d03986
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/he_IL.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"],monthsShort:["ינו","פבר","מרץ","אפר","מאי","יונ","יול","אוג","ספט","אוק","נוב","דצמ"],weekdaysFull:["יום ראשון","יום שני","יום שלישי","יום רביעי","יום חמישי","יום ששי","יום שבת"],weekdaysShort:["א","ב","ג","ד","ה","ו","ש"],today:"היום",clear:"למחוק",format:"yyyy mmmmב d dddd",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/hr_HR.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/hr_HR.js
new file mode 100755
index 0000000..9115d13
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/hr_HR.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["sijećanj","veljača","ožujak","travanj","svibanj","lipanj","srpanj","kolovoz","rujan","listopad","studeni","prosinac"],monthsShort:["sij","velj","ožu","tra","svi","lip","srp","kol","ruj","lis","stu","pro"],weekdaysFull:["nedjelja","ponedjeljak","utorak","srijeda","četvrtak","petak","subota"],weekdaysShort:["ned","pon","uto","sri","čet","pet","sub"],today:"danas",clear:"izbrisati",firstDay:1,format:"d. mmmm yyyy.",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/hu_HU.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/hu_HU.js
new file mode 100755
index 0000000..5d6b68f
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/hu_HU.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["január","február","március","április","május","június","július","augusztus","szeptember","október","november","december"],monthsShort:["jan","febr","márc","ápr","máj","jún","júl","aug","szept","okt","nov","dec"],weekdaysFull:["vasárnap","hétfő","kedd","szerda","csütörtök","péntek","szombat"],weekdaysShort:["V","H","K","SZe","CS","P","SZo"],today:"Ma",clear:"Törlés",firstDay:1,format:"yyyy. mmmm dd.",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/id_ID.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/id_ID.js
new file mode 100755
index 0000000..3cf2e6b
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/id_ID.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"],monthsShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agu","Sep","Okt","Nov","Des"],weekdaysFull:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],weekdaysShort:["Min","Sen","Sel","Rab","Kam","Jum","Sab"],today:"hari ini",clear:"menghapus",firstDay:1,format:"d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/is_IS.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/is_IS.js
new file mode 100755
index 0000000..cb9d91e
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/is_IS.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["janúar","febrúar","mars","apríl","maí","júní","júlí","ágúst","september","október","nóvember","desember"],monthsShort:["jan","feb","mar","apr","maí","jún","júl","ágú","sep","okt","nóv","des"],weekdaysFull:["sunnudagur","mánudagur","þriðjudagur","miðvikudagur","fimmtudagur","föstudagur","laugardagur"],weekdaysShort:["sun","mán","þri","mið","fim","fös","lau"],today:"Í dag",clear:"Hreinsa",firstDay:1,format:"dd. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/it_IT.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/it_IT.js
new file mode 100755
index 0000000..eed9016
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/it_IT.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["gennaio","febbraio","marzo","aprile","maggio","giugno","luglio","agosto","settembre","ottobre","novembre","dicembre"],monthsShort:["gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic"],weekdaysFull:["domenica","lunedì","martedì","mercoledì","giovedì","venerdì","sabato"],weekdaysShort:["dom","lun","mar","mer","gio","ven","sab"],today:"oggi",clear:"cancellare",firstDay:1,format:"dddd d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ja_JP.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ja_JP.js
new file mode 100755
index 0000000..86d508d
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ja_JP.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],weekdaysFull:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],weekdaysShort:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],today:"今日",clear:"消去",firstDay:1,format:"yyyy mm dd",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ko_KR.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ko_KR.js
new file mode 100755
index 0000000..76eaa84
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ko_KR.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],monthsShort:["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],weekdaysFull:["일요일","월요일","화요일","수요일","목요일","금요일","토요일"],weekdaysShort:["일","월","화","수","목","금","토"],today:"오늘",clear:"취소",firstDay:1,format:"yyyy 년 mm 월 dd 일",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ne_NP.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ne_NP.js
new file mode 100755
index 0000000..393df81
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ne_NP.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["जनवरी","फेब्रुअरी","मार्च","अप्रिल","मे","जुन","जुलाई","अगस्त","सेप्टेम्बर","अक्टोबर","नोवेम्बर","डिसेम्बर"],monthsShort:["जन","फेब्रु","मार्च","अप्रिल","मे","जुन","जुल","अग","सेप्टे","अक्टो","नोभे","डिसे"],weekdaysFull:["सोमबार","मङ्लबार","बुधबार","बिहीबार","शुक्रबार","शनिबार","आईतबार"],weekdaysShort:["सोम","मंगल्","बुध","बिही","शुक्र","शनि","आईत"],numbers:["०","१","२","३","४","५","६","७","८","९"],today:"आज",clear:"मेटाउनुहोस्",format:"dddd, dd mmmm, yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/nl_NL.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/nl_NL.js
new file mode 100755
index 0000000..59e6882
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/nl_NL.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"],monthsShort:["jan","feb","maa","apr","mei","jun","jul","aug","sep","okt","nov","dec"],weekdaysFull:["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],weekdaysShort:["zo","ma","di","wo","do","vr","za"],today:"vandaag",clear:"verwijderen",firstDay:1,format:"dddd d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/no_NO.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/no_NO.js
new file mode 100755
index 0000000..bdcf262
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/no_NO.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember"],monthsShort:["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des"],weekdaysFull:["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],weekdaysShort:["søn","man","tir","ons","tor","fre","lør"],today:"i dag",clear:"nullstill",firstDay:1,format:"dd. mmm. yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/pl_PL.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/pl_PL.js
new file mode 100755
index 0000000..aacfc04
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/pl_PL.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["styczeń","luty","marzec","kwiecień","maj","czerwiec","lipiec","sierpień","wrzesień","październik","listopad","grudzień"],monthsShort:["sty","lut","mar","kwi","maj","cze","lip","sie","wrz","paź","lis","gru"],weekdaysFull:["niedziela","poniedziałek","wtorek","środa","czwartek","piątek","sobota"],weekdaysShort:["N","Pn","Wt","Śr","Cz","Pt","So"],today:"dzisiaj",clear:"usunąć",firstDay:1,format:"d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/pt_BR.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/pt_BR.js
new file mode 100755
index 0000000..cab7934
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/pt_BR.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"],monthsShort:["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez"],weekdaysFull:["domingo","segunda-feira","terça-feira","quarta-feira","quinta-feira","sexta-feira","sábado"],weekdaysShort:["dom","seg","ter","qua","qui","sex","sab"],today:"hoje",clear:"excluir",format:"dddd, d !de mmmm !de yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/pt_PT.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/pt_PT.js
new file mode 100755
index 0000000..5485df3
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/pt_PT.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"],monthsShort:["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez"],weekdaysFull:["domingo","segunda","terça","quarta","quinta","sexta","sábado"],weekdaysShort:["dom","seg","ter","qua","qui","sex","sab"],today:"hoje",clear:"excluir",format:"d !de mmmm !de yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ro_RO.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ro_RO.js
new file mode 100755
index 0000000..3a53e7f
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ro_RO.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["ianuarie","februarie","martie","aprilie","mai","iunie","iulie","august","septembrie","octombrie","noiembrie","decembrie"],monthsShort:["ian","feb","mar","apr","mai","iun","iul","aug","sep","oct","noi","dec"],weekdaysFull:["duminică","luni","marţi","miercuri","joi","vineri","sâmbătă"],weekdaysShort:["D","L","Ma","Mi","J","V","S"],today:"azi",clear:"șterge",firstDay:1,format:"dd mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ru_RU.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ru_RU.js
new file mode 100755
index 0000000..0b16e0b
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/ru_RU.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Января","Февраля","Марта","Апреля","Мая","Июня","Июля","Августа","Сентября","Октября","Ноября","Декабря"],monthsShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],weekdaysFull:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],weekdaysShort:["вс","пн","вт","ср","чт","пт","сб"],today:"сегодня",clear:"удалить",firstDay:1,format:"d mmmm yyyy г.",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/sk_SK.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/sk_SK.js
new file mode 100755
index 0000000..f867b08
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/sk_SK.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["január","február","marec","apríl","máj","jún","júl","august","september","október","november","december"],monthsShort:["I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII"],weekdaysFull:["nedeļľa","pondelok","utorok","streda","š̌švrtok","piatok","sobota"],weekdaysShort:["Ne","Po","Ut","St","Št","Pi","So"],today:"dnes",clear:"vymazať",firstDay:1,format:"d. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/sl_SI.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/sl_SI.js
new file mode 100755
index 0000000..5eac8e2
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/sl_SI.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januar","februar","marec","april","maj","junij","julij","avgust","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","avg","sep","okt","nov","dec"],weekdaysFull:["nedelja","ponedeljek","torek","sreda","četrtek","petek","sobota"],weekdaysShort:["ned","pon","tor","sre","čet","pet","sob"],today:"danes",clear:"izbriši",firstDay:1,format:"d. mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/sv_SE.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/sv_SE.js
new file mode 100755
index 0000000..e537bb1
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/sv_SE.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthsShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],weekdaysFull:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],weekdaysShort:["sön","mån","tis","ons","tor","fre","lör"],today:"i dag",clear:"bort",firstDay:1,format:"d/m yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/th_TH.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/th_TH.js
new file mode 100755
index 0000000..72f2e7d
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/th_TH.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม"],monthsShort:["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."],weekdaysFull:["อาทติย","จันทร","องัคาร","พุธ","พฤหสั บดี","ศกุร","เสาร"],weekdaysShort:["อ.","จ.","อ.","พ.","พฤ.","ศ.","ส."],today:"วันนี้",clear:"ลบ",format:"d mmmm yyyy",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/tr_TR.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/tr_TR.js
new file mode 100755
index 0000000..f957781
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/tr_TR.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık"],monthsShort:["Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Eki","Kas","Ara"],weekdaysFull:["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"],weekdaysShort:["Pzr","Pzt","Sal","Çrş","Prş","Cum","Cmt"],today:"bugün",clear:"sil",firstDay:1,format:"dd mmmm yyyy dddd",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/uk_UA.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/uk_UA.js
new file mode 100755
index 0000000..874e474
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/uk_UA.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["січень","лютий","березень","квітень","травень","червень","липень","серпень","вересень","жовтень","листопад","грудень"],monthsShort:["січ","лют","бер","кві","тра","чер","лип","сер","вер","жов","лис","гру"],weekdaysFull:["неділя","понеділок","вівторок","середа","четвер","п‘ятниця","субота"],weekdaysShort:["нд","пн","вт","ср","чт","пт","сб"],today:"сьогодні",clear:"викреслити",firstDay:1,format:"dd mmmm yyyy p.",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/vi_VN.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/vi_VN.js
new file mode 100755
index 0000000..8ab8f07
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/vi_VN.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["Tháng Một","Tháng Hai","Tháng Ba","Tháng Tư","Tháng Năm","Tháng Sáu","Tháng Bảy","Tháng Tám","Tháng Chín","Tháng Mười","Tháng Mười Một","Tháng Mười Hai"],monthsShort:["Một","Hai","Ba","Tư","Năm","Sáu","Bảy","Tám","Chín","Mưới","Mười Một","Mười Hai"],weekdaysFull:["Chủ Nhật","Thứ Hai","Thứ Ba","Thứ Tư","Thứ Năm","Thứ Sáu","Thứ Bảy"],weekdaysShort:["C.Nhật","T.Hai","T.Ba","T.Tư","T.Năm","T.Sáu","T.Bảy"],today:"Hôm Nay",clear:"Xoá",firstDay:1});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/zh_CN.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/zh_CN.js
new file mode 100755
index 0000000..2eb9cea
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/zh_CN.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["一","二","三","四","五","六","七","八","九","十","十一","十二"],weekdaysFull:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],weekdaysShort:["日","一","二","三","四","五","六"],today:"今日",clear:"删",firstDay:1,format:"yyyy 年 mm 月 dd 日",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/zh_TW.js b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/zh_TW.js
new file mode 100755
index 0000000..d8845a3
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/compressed/translations/zh_TW.js
@@ -0,0 +1 @@
+jQuery.extend(jQuery.fn.pickadate.defaults,{monthsFull:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["一","二","三","四","五","六","七","八","九","十","十一","十二"],weekdaysFull:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],weekdaysShort:["日","一","二","三","四","五","六"],today:"今天",clear:"清除",firstDay:1,format:"yyyy 年 mm 月 dd 日",formatSubmit:"yyyy/mm/dd"});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/legacy.js b/htrace-core/src/web/lib/pickadate-3.5.2/legacy.js
new file mode 100755
index 0000000..6af504e
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/legacy.js
@@ -0,0 +1,133 @@
+
+/*jshint
+ asi: true,
+ unused: true,
+ boss: true,
+ loopfunc: true,
+ eqnull: true
+ */
+
+
+/*!
+ * Legacy browser support
+ */
+
+
+// Map array support
+if ( ![].map ) {
+ Array.prototype.map = function ( callback, self ) {
+ var array = this, len = array.length, newArray = new Array( len )
+ for ( var i = 0; i < len; i++ ) {
+ if ( i in array ) {
+ newArray[ i ] = callback.call( self, array[ i ], i, array )
+ }
+ }
+ return newArray
+ }
+}
+
+
+// Filter array support
+if ( ![].filter ) {
+ Array.prototype.filter = function( callback ) {
+ if ( this == null ) throw new TypeError()
+ var t = Object( this ), len = t.length >>> 0
+ if ( typeof callback != 'function' ) throw new TypeError()
+ var newArray = [], thisp = arguments[ 1 ]
+ for ( var i = 0; i < len; i++ ) {
+ if ( i in t ) {
+ var val = t[ i ]
+ if ( callback.call( thisp, val, i, t ) ) newArray.push( val )
+ }
+ }
+ return newArray
+ }
+}
+
+
+// Index of array support
+if ( ![].indexOf ) {
+ Array.prototype.indexOf = function( searchElement ) {
+ if ( this == null ) throw new TypeError()
+ var t = Object( this ), len = t.length >>> 0
+ if ( len === 0 ) return -1
+ var n = 0
+ if ( arguments.length > 1 ) {
+ n = Number( arguments[ 1 ] )
+ if ( n != n ) {
+ n = 0
+ }
+ else if ( n !== 0 && n != Infinity && n != -Infinity ) {
+ n = ( n > 0 || -1 ) * Math.floor( Math.abs( n ) )
+ }
+ }
+ if ( n >= len ) return -1
+ var k = n >= 0 ? n : Math.max( len - Math.abs( n ), 0 )
+ for ( ; k < len; k++ ) {
+ if ( k in t && t[ k ] === searchElement ) return k
+ }
+ return -1
+ }
+}
+
+
+/*!
+ * Cross-Browser Split 1.1.1
+ * Copyright 2007-2012 Steven Levithan
+ * Available under the MIT License
+ * http://blog.stevenlevithan.com/archives/cross-browser-split
+ */
+var nativeSplit = String.prototype.split, compliantExecNpcg = /()??/.exec('')[1] === undefined
+String.prototype.split = function(separator, limit) {
+ var str = this
+ if (Object.prototype.toString.call(separator) !== '[object RegExp]') {
+ return nativeSplit.call(str, separator, limit)
+ }
+ var output = [],
+ flags = (separator.ignoreCase ? 'i' : '') +
+ (separator.multiline ? 'm' : '') +
+ (separator.extended ? 'x' : '') +
+ (separator.sticky ? 'y' : ''),
+ lastLastIndex = 0,
+ separator2, match, lastIndex, lastLength
+ separator = new RegExp(separator.source, flags + 'g')
+ str += ''
+ if (!compliantExecNpcg) {
+ separator2 = new RegExp('^' + separator.source + '$(?!\\s)', flags)
+ }
+ limit = limit === undefined ? -1 >>> 0 : limit >>> 0
+ while (match = separator.exec(str)) {
+ lastIndex = match.index + match[0].length
+ if (lastIndex > lastLastIndex) {
+ output.push(str.slice(lastLastIndex, match.index))
+ if (!compliantExecNpcg && match.length > 1) {
+ match[0].replace(separator2, function () {
+ for (var i = 1; i < arguments.length - 2; i++) {
+ if (arguments[i] === undefined) {
+ match[i] = undefined
+ }
+ }
+ })
+ }
+ if (match.length > 1 && match.index < str.length) {
+ Array.prototype.push.apply(output, match.slice(1))
+ }
+ lastLength = match[0].length
+ lastLastIndex = lastIndex
+ if (output.length >= limit) {
+ break
+ }
+ }
+ if (separator.lastIndex === match.index) {
+ separator.lastIndex++
+ }
+ }
+ if (lastLastIndex === str.length) {
+ if (lastLength || !separator.test('')) {
+ output.push('')
+ }
+ } else {
+ output.push(str.slice(lastLastIndex))
+ }
+ return output.length > limit ? output.slice(0, limit) : output
+};
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/picker.date.js b/htrace-core/src/web/lib/pickadate-3.5.2/picker.date.js
new file mode 100755
index 0000000..217ab19
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/picker.date.js
@@ -0,0 +1,1322 @@
+
+/*!
+ * Date picker for pickadate.js v3.5.0
+ * http://amsul.github.io/pickadate.js/date.htm
+ */
+
+(function ( factory ) {
+
+ // Register as an anonymous module.
+ if ( typeof define == 'function' && define.amd )
+ define( ['picker','jquery'], factory )
+
+ // Or using browser globals.
+ else factory( Picker, jQuery )
+
+}(function( Picker, $ ) {
+
+
+/**
+ * Globals and constants
+ */
+var DAYS_IN_WEEK = 7,
+ WEEKS_IN_CALENDAR = 6,
+ _ = Picker._
+
+
+
+/**
+ * The date picker constructor
+ */
+function DatePicker( picker, settings ) {
+
+ var calendar = this,
+ elementValue = picker.$node[ 0 ].value,
+ elementDataValue = picker.$node.data( 'value' ),
+ valueString = elementDataValue || elementValue,
+ formatString = elementDataValue ? settings.formatSubmit : settings.format,
+ isRTL = function() {
+ return getComputedStyle( picker.$root[0] ).direction === 'rtl'
+ }
+
+ calendar.settings = settings
+ calendar.$node = picker.$node
+
+ // The queue of methods that will be used to build item objects.
+ calendar.queue = {
+ min: 'measure create',
+ max: 'measure create',
+ now: 'now create',
+ select: 'parse create validate',
+ highlight: 'parse navigate create validate',
+ view: 'parse create validate viewset',
+ disable: 'deactivate',
+ enable: 'activate'
+ }
+
+ // The component's item object.
+ calendar.item = {}
+
+ calendar.item.clear = null
+ calendar.item.disable = ( settings.disable || [] ).slice( 0 )
+ calendar.item.enable = -(function( collectionDisabled ) {
+ return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1
+ })( calendar.item.disable )
+
+ calendar.
+ set( 'min', settings.min ).
+ set( 'max', settings.max ).
+ set( 'now' )
+
+ // When there’s a value, set the `select`, which in turn
+ // also sets the `highlight` and `view`.
+ if ( valueString ) {
+ calendar.set( 'select', valueString, { format: formatString })
+ }
+
+ // If there’s no value, default to highlighting “today”.
+ else {
+ calendar.
+ set( 'select', null ).
+ set( 'highlight', calendar.item.now )
+ }
+
+
+ // The keycode to movement mapping.
+ calendar.key = {
+ 40: 7, // Down
+ 38: -7, // Up
+ 39: function() { return isRTL() ? -1 : 1 }, // Right
+ 37: function() { return isRTL() ? 1 : -1 }, // Left
+ go: function( timeChange ) {
+ var highlightedObject = calendar.item.highlight,
+ targetDate = new Date( highlightedObject.year, highlightedObject.month, highlightedObject.date + timeChange )
+ calendar.set(
+ 'highlight',
+ [ targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate() ],
+ { interval: timeChange }
+ )
+ this.render()
+ }
+ }
+
+
+ // Bind some picker events.
+ picker.
+ on( 'render', function() {
+ picker.$root.find( '.' + settings.klass.selectMonth ).on( 'change', function() {
+ var value = this.value
+ if ( value ) {
+ picker.set( 'highlight', [ picker.get( 'view' ).year, value, picker.get( 'highlight' ).date ] )
+ picker.$root.find( '.' + settings.klass.selectMonth ).trigger( 'focus' )
+ }
+ })
+ picker.$root.find( '.' + settings.klass.selectYear ).on( 'change', function() {
+ var value = this.value
+ if ( value ) {
+ picker.set( 'highlight', [ value, picker.get( 'view' ).month, picker.get( 'highlight' ).date ] )
+ picker.$root.find( '.' + settings.klass.selectYear ).trigger( 'focus' )
+ }
+ })
+ }).
+ on( 'open', function() {
+ picker.$root.find( 'button, select' ).attr( 'disabled', false )
+ }).
+ on( 'close', function() {
+ picker.$root.find( 'button, select' ).attr( 'disabled', true )
+ })
+
+} //DatePicker
+
+
+/**
+ * Set a datepicker item object.
+ */
+DatePicker.prototype.set = function( type, value, options ) {
+
+ var calendar = this,
+ calendarItem = calendar.item
+
+ // If the value is `null` just set it immediately.
+ if ( value === null ) {
+ if ( type == 'clear' ) type = 'select'
+ calendarItem[ type ] = value
+ return calendar
+ }
+
+ // Otherwise go through the queue of methods, and invoke the functions.
+ // Update this as the time unit, and set the final value as this item.
+ // * In the case of `enable`, keep the queue but set `disable` instead.
+ // And in the case of `flip`, keep the queue but set `enable` instead.
+ calendarItem[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = calendar.queue[ type ].split( ' ' ).map( function( method ) {
+ value = calendar[ method ]( type, value, options )
+ return value
+ }).pop()
+
+ // Check if we need to cascade through more updates.
+ if ( type == 'select' ) {
+ calendar.set( 'highlight', calendarItem.select, options )
+ }
+ else if ( type == 'highlight' ) {
+ calendar.set( 'view', calendarItem.highlight, options )
+ }
+ else if ( type.match( /^(flip|min|max|disable|enable)$/ ) ) {
+ if ( calendarItem.select && calendar.disabled( calendarItem.select ) ) {
+ calendar.set( 'select', calendarItem.select, options )
+ }
+ if ( calendarItem.highlight && calendar.disabled( calendarItem.highlight ) ) {
+ calendar.set( 'highlight', calendarItem.highlight, options )
+ }
+ }
+
+ return calendar
+} //DatePicker.prototype.set
+
+
+/**
+ * Get a datepicker item object.
+ */
+DatePicker.prototype.get = function( type ) {
+ return this.item[ type ]
+} //DatePicker.prototype.get
+
+
+/**
+ * Create a picker date object.
+ */
+DatePicker.prototype.create = function( type, value, options ) {
+
+ var isInfiniteValue,
+ calendar = this
+
+ // If there’s no value, use the type as the value.
+ value = value === undefined ? type : value
+
+
+ // If it’s infinity, update the value.
+ if ( value == -Infinity || value == Infinity ) {
+ isInfiniteValue = value
+ }
+
+ // If it’s an object, use the native date object.
+ else if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) {
+ value = value.obj
+ }
+
+ // If it’s an array, convert it into a date and make sure
+ // that it’s a valid date – otherwise default to today.
+ else if ( $.isArray( value ) ) {
+ value = new Date( value[ 0 ], value[ 1 ], value[ 2 ] )
+ value = _.isDate( value ) ? value : calendar.create().obj
+ }
+
+ // If it’s a number or date object, make a normalized date.
+ else if ( _.isInteger( value ) || _.isDate( value ) ) {
+ value = calendar.normalize( new Date( value ), options )
+ }
+
+ // If it’s a literal true or any other case, set it to now.
+ else /*if ( value === true )*/ {
+ value = calendar.now( type, value, options )
+ }
+
+ // Return the compiled object.
+ return {
+ year: isInfiniteValue || value.getFullYear(),
+ month: isInfiniteValue || value.getMonth(),
+ date: isInfiniteValue || value.getDate(),
+ day: isInfiniteValue || value.getDay(),
+ obj: isInfiniteValue || value,
+ pick: isInfiniteValue || value.getTime()
+ }
+} //DatePicker.prototype.create
+
+
+/**
+ * Create a range limit object using an array, date object,
+ * literal “true”, or integer relative to another time.
+ */
+DatePicker.prototype.createRange = function( from, to ) {
+
+ var calendar = this,
+ createDate = function( date ) {
+ if ( date === true || $.isArray( date ) || _.isDate( date ) ) {
+ return calendar.create( date )
+ }
+ return date
+ }
+
+ // Create objects if possible.
+ if ( !_.isInteger( from ) ) {
+ from = createDate( from )
+ }
+ if ( !_.isInteger( to ) ) {
+ to = createDate( to )
+ }
+
+ // Create relative dates.
+ if ( _.isInteger( from ) && $.isPlainObject( to ) ) {
+ from = [ to.year, to.month, to.date + from ];
+ }
+ else if ( _.isInteger( to ) && $.isPlainObject( from ) ) {
+ to = [ from.year, from.month, from.date + to ];
+ }
+
+ return {
+ from: createDate( from ),
+ to: createDate( to )
+ }
+} //DatePicker.prototype.createRange
+
+
+/**
+ * Check if a date unit falls within a date range object.
+ */
+DatePicker.prototype.withinRange = function( range, dateUnit ) {
+ range = this.createRange(range.from, range.to)
+ return dateUnit.pick >= range.from.pick && dateUnit.pick <= range.to.pick
+}
+
+
+/**
+ * Check if two date range objects overlap.
+ */
+DatePicker.prototype.overlapRanges = function( one, two ) {
+
+ var calendar = this
+
+ // Convert the ranges into comparable dates.
+ one = calendar.createRange( one.from, one.to )
+ two = calendar.createRange( two.from, two.to )
+
+ return calendar.withinRange( one, two.from ) || calendar.withinRange( one, two.to ) ||
+ calendar.withinRange( two, one.from ) || calendar.withinRange( two, one.to )
+}
+
+
+/**
+ * Get the date today.
+ */
+DatePicker.prototype.now = function( type, value, options ) {
+ value = new Date()
+ if ( options && options.rel ) {
+ value.setDate( value.getDate() + options.rel )
+ }
+ return this.normalize( value, options )
+}
+
+
+/**
+ * Navigate to next/prev month.
+ */
+DatePicker.prototype.navigate = function( type, value, options ) {
+
+ var targetDateObject,
+ targetYear,
+ targetMonth,
+ targetDate,
+ isTargetArray = $.isArray( value ),
+ isTargetObject = $.isPlainObject( value ),
+ viewsetObject = this.item.view/*,
+ safety = 100*/
+
+
+ if ( isTargetArray || isTargetObject ) {
+
+ if ( isTargetObject ) {
+ targetYear = value.year
+ targetMonth = value.month
+ targetDate = value.date
+ }
+ else {
+ targetYear = +value[0]
+ targetMonth = +value[1]
+ targetDate = +value[2]
+ }
+
+ // If we’re navigating months but the view is in a different
+ // month, navigate to the view’s year and month.
+ if ( options && options.nav && viewsetObject && viewsetObject.month !== targetMonth ) {
+ targetYear = viewsetObject.year
+ targetMonth = viewsetObject.month
+ }
+
+ // Figure out the expected target year and month.
+ targetDateObject = new Date( targetYear, targetMonth + ( options && options.nav ? options.nav : 0 ), 1 )
+ targetYear = targetDateObject.getFullYear()
+ targetMonth = targetDateObject.getMonth()
+
+ // If the month we’re going to doesn’t have enough days,
+ // keep decreasing the date until we reach the month’s last date.
+ while ( /*safety &&*/ new Date( targetYear, targetMonth, targetDate ).getMonth() !== targetMonth ) {
+ targetDate -= 1
+ /*safety -= 1
+ if ( !safety ) {
+ throw 'Fell into an infinite loop while navigating to ' + new Date( targetYear, targetMonth, targetDate ) + '.'
+ }*/
+ }
+
+ value = [ targetYear, targetMonth, targetDate ]
+ }
+
+ return value
+} //DatePicker.prototype.navigate
+
+
+/**
+ * Normalize a date by setting the hours to midnight.
+ */
+DatePicker.prototype.normalize = function( value/*, options*/ ) {
+ value.setHours( 0, 0, 0, 0 )
+ return value
+}
+
+
+/**
+ * Measure the range of dates.
+ */
+DatePicker.prototype.measure = function( type, value/*, options*/ ) {
+
+ var calendar = this
+
+ // If it's anything false-y, remove the limits.
+ if ( !value ) {
+ value = type == 'min' ? -Infinity : Infinity
+ }
+
+ // If it's an integer, get a date relative to today.
+ else if ( _.isInteger( value ) ) {
+ value = calendar.now( type, value, { rel: value } )
+ }
+
+ return value
+} ///DatePicker.prototype.measure
+
+
+/**
+ * Create a viewset object based on navigation.
+ */
+DatePicker.prototype.viewset = function( type, dateObject/*, options*/ ) {
+ return this.create([ dateObject.year, dateObject.month, 1 ])
+}
+
+
+/**
+ * Validate a date as enabled and shift if needed.
+ */
+DatePicker.prototype.validate = function( type, dateObject, options ) {
+
+ var calendar = this,
+
+ // Keep a reference to the original date.
+ originalDateObject = dateObject,
+
+ // Make sure we have an interval.
+ interval = options && options.interval ? options.interval : 1,
+
+ // Check if the calendar enabled dates are inverted.
+ isFlippedBase = calendar.item.enable === -1,
+
+ // Check if we have any enabled dates after/before now.
+ hasEnabledBeforeTarget, hasEnabledAfterTarget,
+
+ // The min & max limits.
+ minLimitObject = calendar.item.min,
+ maxLimitObject = calendar.item.max,
+
+ // Check if we’ve reached the limit during shifting.
+ reachedMin, reachedMax,
+
+ // Check if the calendar is inverted and at least one weekday is enabled.
+ hasEnabledWeekdays = isFlippedBase && calendar.item.disable.filter( function( value ) {
+
+ // If there’s a date, check where it is relative to the target.
+ if ( $.isArray( value ) ) {
+ var dateTime = calendar.create( value ).pick
+ if ( dateTime < dateObject.pick ) hasEnabledBeforeTarget = true
+ else if ( dateTime > dateObject.pick ) hasEnabledAfterTarget = true
+ }
+
+ // Return only integers for enabled weekdays.
+ return _.isInteger( value )
+ }).length/*,
+
+ safety = 100*/
+
+
+
+ // Cases to validate for:
+ // [1] Not inverted and date disabled.
+ // [2] Inverted and some dates enabled.
+ // [3] Not inverted and out of range.
+ //
+ // Cases to **not** validate for:
+ // • Navigating months.
+ // • Not inverted and date enabled.
+ // • Inverted and all dates disabled.
+ // • ..and anything else.
+ if ( !options || !options.nav ) if (
+ /* 1 */ ( !isFlippedBase && calendar.disabled( dateObject ) ) ||
+ /* 2 */ ( isFlippedBase && calendar.disabled( dateObject ) && ( hasEnabledWeekdays || hasEnabledBeforeTarget || hasEnabledAfterTarget ) ) ||
+ /* 3 */ ( !isFlippedBase && (dateObject.pick <= minLimitObject.pick || dateObject.pick >= maxLimitObject.pick) )
+ ) {
+
+
+ // When inverted, flip the direction if there aren’t any enabled weekdays
+ // and there are no enabled dates in the direction of the interval.
+ if ( isFlippedBase && !hasEnabledWeekdays && ( ( !hasEnabledAfterTarget && interval > 0 ) || ( !hasEnabledBeforeTarget && interval < 0 ) ) ) {
+ interval *= -1
+ }
+
+
+ // Keep looping until we reach an enabled date.
+ while ( /*safety &&*/ calendar.disabled( dateObject ) ) {
+
+ /*safety -= 1
+ if ( !safety ) {
+ throw 'Fell into an infinite loop while validating ' + dateObject.obj + '.'
+ }*/
+
+
+ // If we’ve looped into the next/prev month with a large interval, return to the original date and flatten the interval.
+ if ( Math.abs( interval ) > 1 && ( dateObject.month < originalDateObject.month || dateObject.month > originalDateObject.month ) ) {
+ dateObject = originalDateObject
+ interval = interval > 0 ? 1 : -1
+ }
+
+
+ // If we’ve reached the min/max limit, reverse the direction, flatten the interval and set it to the limit.
+ if ( dateObject.pick <= minLimitObject.pick ) {
+ reachedMin = true
+ interval = 1
+ dateObject = calendar.create([
+ minLimitObject.year,
+ minLimitObject.month,
+ minLimitObject.date + (dateObject.pick === minLimitObject.pick ? 0 : -1)
+ ])
+ }
+ else if ( dateObject.pick >= maxLimitObject.pick ) {
+ reachedMax = true
+ interval = -1
+ dateObject = calendar.create([
+ maxLimitObject.year,
+ maxLimitObject.month,
+ maxLimitObject.date + (dateObject.pick === maxLimitObject.pick ? 0 : 1)
+ ])
+ }
+
+
+ // If we’ve reached both limits, just break out of the loop.
+ if ( reachedMin && reachedMax ) {
+ break
+ }
+
+
+ // Finally, create the shifted date using the interval and keep looping.
+ dateObject = calendar.create([ dateObject.year, dateObject.month, dateObject.date + interval ])
+ }
+
+ } //endif
+
+
+ // Return the date object settled on.
+ return dateObject
+} //DatePicker.prototype.validate
+
+
+/**
+ * Check if a date is disabled.
+ */
+DatePicker.prototype.disabled = function( dateToVerify ) {
+
+ var
+ calendar = this,
+
+ // Filter through the disabled dates to check if this is one.
+ isDisabledMatch = calendar.item.disable.filter( function( dateToDisable ) {
+
+ // If the date is a number, match the weekday with 0index and `firstDay` check.
+ if ( _.isInteger( dateToDisable ) ) {
+ return dateToVerify.day === ( calendar.settings.firstDay ? dateToDisable : dateToDisable - 1 ) % 7
+ }
+
+ // If it’s an array or a native JS date, create and match the exact date.
+ if ( $.isArray( dateToDisable ) || _.isDate( dateToDisable ) ) {
+ return dateToVerify.pick === calendar.create( dateToDisable ).pick
+ }
+
+ // If it’s an object, match a date within the “from” and “to” range.
+ if ( $.isPlainObject( dateToDisable ) ) {
+ return calendar.withinRange( dateToDisable, dateToVerify )
+ }
+ })
+
+ // If this date matches a disabled date, confirm it’s not inverted.
+ isDisabledMatch = isDisabledMatch.length && !isDisabledMatch.filter(function( dateToDisable ) {
+ return $.isArray( dateToDisable ) && dateToDisable[3] == 'inverted' ||
+ $.isPlainObject( dateToDisable ) && dateToDisable.inverted
+ }).length
+
+ // Check the calendar “enabled” flag and respectively flip the
+ // disabled state. Then also check if it’s beyond the min/max limits.
+ return calendar.item.enable === -1 ? !isDisabledMatch : isDisabledMatch ||
+ dateToVerify.pick < calendar.item.min.pick ||
+ dateToVerify.pick > calendar.item.max.pick
+
+} //DatePicker.prototype.disabled
+
+
+/**
+ * Parse a string into a usable type.
+ */
+DatePicker.prototype.parse = function( type, value, options ) {
+
+ var calendar = this,
+ parsingObject = {}
+
+ // If it’s already parsed, we’re good.
+ if ( !value || typeof value != 'string' ) {
+ return value
+ }
+
+ // We need a `.format` to parse the value with.
+ if ( !( options && options.format ) ) {
+ options = options || {}
+ options.format = calendar.settings.format
+ }
+
+ // Convert the format into an array and then map through it.
+ calendar.formats.toArray( options.format ).map( function( label ) {
+
+ var
+ // Grab the formatting label.
+ formattingLabel = calendar.formats[ label ],
+
+ // The format length is from the formatting label function or the
+ // label length without the escaping exclamation (!) mark.
+ formatLength = formattingLabel ? _.trigger( formattingLabel, calendar, [ value, parsingObject ] ) : label.replace( /^!/, '' ).length
+
+ // If there's a format label, split the value up to the format length.
+ // Then add it to the parsing object with appropriate label.
+ if ( formattingLabel ) {
+ parsingObject[ label ] = value.substr( 0, formatLength )
+ }
+
+ // Update the value as the substring from format length to end.
+ value = value.substr( formatLength )
+ })
+
+ // Compensate for month 0index.
+ return [
+ parsingObject.yyyy || parsingObject.yy,
+ +( parsingObject.mm || parsingObject.m ) - 1,
+ parsingObject.dd || parsingObject.d
+ ]
+} //DatePicker.prototype.parse
+
+
+/**
+ * Various formats to display the object in.
+ */
+DatePicker.prototype.formats = (function() {
+
+ // Return the length of the first word in a collection.
+ function getWordLengthFromCollection( string, collection, dateObject ) {
+
+ // Grab the first word from the string.
+ var word = string.match( /\w+/ )[ 0 ]
+
+ // If there's no month index, add it to the date object
+ if ( !dateObject.mm && !dateObject.m ) {
+ dateObject.m = collection.indexOf( word ) + 1
+ }
+
+ // Return the length of the word.
+ return word.length
+ }
+
+ // Get the length of the first word in a string.
+ function getFirstWordLength( string ) {
+ return string.match( /\w+/ )[ 0 ].length
+ }
+
+ return {
+
+ d: function( string, dateObject ) {
+
+ // If there's string, then get the digits length.
+ // Otherwise return the selected date.
+ return string ? _.digits( string ) : dateObject.date
+ },
+ dd: function( string, dateObject ) {
+
+ // If there's a string, then the length is always 2.
+ // Otherwise return the selected date with a leading zero.
+ return string ? 2 : _.lead( dateObject.date )
+ },
+ ddd: function( string, dateObject ) {
+
+ // If there's a string, then get the length of the first word.
+ // Otherwise return the short selected weekday.
+ return string ? getFirstWordLength( string ) : this.settings.weekdaysShort[ dateObject.day ]
+ },
+ dddd: function( string, dateObject ) {
+
+ // If there's a string, then get the length of the first word.
+ // Otherwise return the full selected weekday.
+ return string ? getFirstWordLength( string ) : this.settings.weekdaysFull[ dateObject.day ]
+ },
+ m: function( string, dateObject ) {
+
+ // If there's a string, then get the length of the digits
+ // Otherwise return the selected month with 0index compensation.
+ return string ? _.digits( string ) : dateObject.month + 1
+ },
+ mm: function( string, dateObject ) {
+
+ // If there's a string, then the length is always 2.
+ // Otherwise return the selected month with 0index and leading zero.
+ return string ? 2 : _.lead( dateObject.month + 1 )
+ },
+ mmm: function( string, dateObject ) {
+
+ var collection = this.settings.monthsShort
+
+ // If there's a string, get length of the relevant month from the short
+ // months collection. Otherwise return the selected month from that collection.
+ return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ]
+ },
+ mmmm: function( string, dateObject ) {
+
+ var collection = this.settings.monthsFull
+
+ // If there's a string, get length of the relevant month from the full
+ // months collection. Otherwise return the selected month from that collection.
+ return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ]
+ },
+ yy: function( string, dateObject ) {
+
+ // If there's a string, then the length is always 2.
+ // Otherwise return the selected year by slicing out the first 2 digits.
+ return string ? 2 : ( '' + dateObject.year ).slice( 2 )
+ },
+ yyyy: function( string, dateObject ) {
+
+ // If there's a string, then the length is always 4.
+ // Otherwise return the selected year.
+ return string ? 4 : dateObject.year
+ },
+
+ // Create an array by splitting the formatting string passed.
+ toArray: function( formatString ) { return formatString.split( /(d{1,4}|m{1,4}|y{4}|yy|!.)/g ) },
+
+ // Format an object into a string using the formatting options.
+ toString: function ( formatString, itemObject ) {
+ var calendar = this
+ return calendar.formats.toArray( formatString ).map( function( label ) {
+ return _.trigger( calendar.formats[ label ], calendar, [ 0, itemObject ] ) || label.replace( /^!/, '' )
+ }).join( '' )
+ }
+ }
+})() //DatePicker.prototype.formats
+
+
+
+
+/**
+ * Check if two date units are the exact.
+ */
+DatePicker.prototype.isDateExact = function( one, two ) {
+
+ var calendar = this
+
+ // When we’re working with weekdays, do a direct comparison.
+ if (
+ ( _.isInteger( one ) && _.isInteger( two ) ) ||
+ ( typeof one == 'boolean' && typeof two == 'boolean' )
+ ) {
+ return one === two
+ }
+
+ // When we’re working with date representations, compare the “pick” value.
+ if (
+ ( _.isDate( one ) || $.isArray( one ) ) &&
+ ( _.isDate( two ) || $.isArray( two ) )
+ ) {
+ return calendar.create( one ).pick === calendar.create( two ).pick
+ }
+
+ // When we’re working with range objects, compare the “from” and “to”.
+ if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
+ return calendar.isDateExact( one.from, two.from ) && calendar.isDateExact( one.to, two.to )
+ }
+
+ return false
+}
+
+
+/**
+ * Check if two date units overlap.
+ */
+DatePicker.prototype.isDateOverlap = function( one, two ) {
+
+ var calendar = this,
+ firstDay = calendar.settings.firstDay ? 1 : 0
+
+ // When we’re working with a weekday index, compare the days.
+ if ( _.isInteger( one ) && ( _.isDate( two ) || $.isArray( two ) ) ) {
+ one = one % 7 + firstDay
+ return one === calendar.create( two ).day + 1
+ }
+ if ( _.isInteger( two ) && ( _.isDate( one ) || $.isArray( one ) ) ) {
+ two = two % 7 + firstDay
+ return two === calendar.create( one ).day + 1
+ }
+
+ // When we’re working with range objects, check if the ranges overlap.
+ if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
+ return calendar.overlapRanges( one, two )
+ }
+
+ return false
+}
+
+
+/**
+ * Flip the “enabled” state.
+ */
+DatePicker.prototype.flipEnable = function(val) {
+ var itemObject = this.item
+ itemObject.enable = val || (itemObject.enable == -1 ? 1 : -1)
+}
+
+
+/**
+ * Mark a collection of dates as “disabled”.
+ */
+DatePicker.prototype.deactivate = function( type, datesToDisable ) {
+
+ var calendar = this,
+ disabledItems = calendar.item.disable.slice(0)
+
+
+ // If we’re flipping, that’s all we need to do.
+ if ( datesToDisable == 'flip' ) {
+ calendar.flipEnable()
+ }
+
+ else if ( datesToDisable === false ) {
+ calendar.flipEnable(1)
+ disabledItems = []
+ }
+
+ else if ( datesToDisable === true ) {
+ calendar.flipEnable(-1)
+ disabledItems = []
+ }
+
+ // Otherwise go through the dates to disable.
+ else {
+
+ datesToDisable.map(function( unitToDisable ) {
+
+ var matchFound
+
+ // When we have disabled items, check for matches.
+ // If something is matched, immediately break out.
+ for ( var index = 0; index < disabledItems.length; index += 1 ) {
+ if ( calendar.isDateExact( unitToDisable, disabledItems[index] ) ) {
+ matchFound = true
+ break
+ }
+ }
+
+ // If nothing was found, add the validated unit to the collection.
+ if ( !matchFound ) {
+ if (
+ _.isInteger( unitToDisable ) ||
+ _.isDate( unitToDisable ) ||
+ $.isArray( unitToDisable ) ||
+ ( $.isPlainObject( unitToDisable ) && unitToDisable.from && unitToDisable.to )
+ ) {
+ disabledItems.push( unitToDisable )
+ }
+ }
+ })
+ }
+
+ // Return the updated collection.
+ return disabledItems
+} //DatePicker.prototype.deactivate
+
+
+/**
+ * Mark a collection of dates as “enabled”.
+ */
+DatePicker.prototype.activate = function( type, datesToEnable ) {
+
+ var calendar = this,
+ disabledItems = calendar.item.disable,
+ disabledItemsCount = disabledItems.length
+
+ // If we’re flipping, that’s all we need to do.
+ if ( datesToEnable == 'flip' ) {
+ calendar.flipEnable()
+ }
+
+ else if ( datesToEnable === true ) {
+ calendar.flipEnable(1)
+ disabledItems = []
+ }
+
+ else if ( datesToEnable === false ) {
+ calendar.flipEnable(-1)
+ disabledItems = []
+ }
+
+ // Otherwise go through the disabled dates.
+ else {
+
+ datesToEnable.map(function( unitToEnable ) {
+
+ var matchFound,
+ disabledUnit,
+ index,
+ isExactRange
+
+ // Go through the disabled items and try to find a match.
+ for ( index = 0; index < disabledItemsCount; index += 1 ) {
+
+ disabledUnit = disabledItems[index]
+
+ // When an exact match is found, remove it from the collection.
+ if ( calendar.isDateExact( disabledUnit, unitToEnable ) ) {
+ matchFound = disabledItems[index] = null
+ isExactRange = true
+ break
+ }
+
+ // When an overlapped match is found, add the “inverted” state to it.
+ else if ( calendar.isDateOverlap( disabledUnit, unitToEnable ) ) {
+ if ( $.isPlainObject( unitToEnable ) ) {
+ unitToEnable.inverted = true
+ matchFound = unitToEnable
+ }
+ else if ( $.isArray( unitToEnable ) ) {
+ matchFound = unitToEnable
+ if ( !matchFound[3] ) matchFound.push( 'inverted' )
+ }
+ else if ( _.isDate( unitToEnable ) ) {
+ matchFound = [ unitToEnable.getFullYear(), unitToEnable.getMonth(), unitToEnable.getDate(), 'inverted' ]
+ }
+ break
+ }
+ }
+
+ // If a match was found, remove a previous duplicate entry.
+ if ( matchFound ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
+ if ( calendar.isDateExact( disabledItems[index], unitToEnable ) ) {
+ disabledItems[index] = null
+ break
+ }
+ }
+
+ // In the event that we’re dealing with an exact range of dates,
+ // make sure there are no “inverted” dates because of it.
+ if ( isExactRange ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
+ if ( calendar.isDateOverlap( disabledItems[index], unitToEnable ) ) {
+ disabledItems[index] = null
+ break
+ }
+ }
+
+ // If something is still matched, add it into the collection.
+ if ( matchFound ) {
+ disabledItems.push( matchFound )
+ }
+ })
+ }
+
+ // Return the updated collection.
+ return disabledItems.filter(function( val ) { return val != null })
+} //DatePicker.prototype.activate
+
+
+/**
+ * Create a string for the nodes in the picker.
+ */
+DatePicker.prototype.nodes = function( isOpen ) {
+
+ var
+ calendar = this,
+ settings = calendar.settings,
+ calendarItem = calendar.item,
+ nowObject = calendarItem.now,
+ selectedObject = calendarItem.select,
+ highlightedObject = calendarItem.highlight,
+ viewsetObject = calendarItem.view,
+ disabledCollection = calendarItem.disable,
+ minLimitObject = calendarItem.min,
+ maxLimitObject = calendarItem.max,
+
+
+ // Create the calendar table head using a copy of weekday labels collection.
+ // * We do a copy so we don't mutate the original array.
+ tableHead = (function( collection, fullCollection ) {
+
+ // If the first day should be Monday, move Sunday to the end.
+ if ( settings.firstDay ) {
+ collection.push( collection.shift() )
+ fullCollection.push( fullCollection.shift() )
+ }
+
+ // Create and return the table head group.
+ return _.node(
+ 'thead',
+ _.node(
+ 'tr',
+ _.group({
+ min: 0,
+ max: DAYS_IN_WEEK - 1,
+ i: 1,
+ node: 'th',
+ item: function( counter ) {
+ return [
+ collection[ counter ],
+ settings.klass.weekdays,
+ 'scope=col title="' + fullCollection[ counter ] + '"'
+ ]
+ }
+ })
+ )
+ ) //endreturn
+ })( ( settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysShort ).slice( 0 ), settings.weekdaysFull.slice( 0 ) ), //tableHead
+
+
+ // Create the nav for next/prev month.
+ createMonthNav = function( next ) {
+
+ // Otherwise, return the created month tag.
+ return _.node(
+ 'div',
+ ' ',
+ settings.klass[ 'nav' + ( next ? 'Next' : 'Prev' ) ] + (
+
+ // If the focused month is outside the range, disabled the button.
+ ( next && viewsetObject.year >= maxLimitObject.year && viewsetObject.month >= maxLimitObject.month ) ||
+ ( !next && viewsetObject.year <= minLimitObject.year && viewsetObject.month <= minLimitObject.month ) ?
+ ' ' + settings.klass.navDisabled : ''
+ ),
+ 'data-nav=' + ( next || -1 ) + ' ' +
+ _.ariaAttr({
+ role: 'button',
+ controls: calendar.$node[0].id + '_table'
+ }) + ' ' +
+ 'title="' + (next ? settings.labelMonthNext : settings.labelMonthPrev ) + '"'
+ ) //endreturn
+ }, //createMonthNav
+
+
+ // Create the month label.
+ createMonthLabel = function() {
+
+ var monthsCollection = settings.showMonthsShort ? settings.monthsShort : settings.monthsFull
+
+ // If there are months to select, add a dropdown menu.
+ if ( settings.selectMonths ) {
+
+ return _.node( 'select',
+ _.group({
+ min: 0,
+ max: 11,
+ i: 1,
+ node: 'option',
+ item: function( loopedMonth ) {
+
+ return [
+
+ // The looped month and no classes.
+ monthsCollection[ loopedMonth ], 0,
+
+ // Set the value and selected index.
+ 'value=' + loopedMonth +
+ ( viewsetObject.month == loopedMonth ? ' selected' : '' ) +
+ (
+ (
+ ( viewsetObject.year == minLimitObject.year && loopedMonth < minLimitObject.month ) ||
+ ( viewsetObject.year == maxLimitObject.year && loopedMonth > maxLimitObject.month )
+ ) ?
+ ' disabled' : ''
+ )
+ ]
+ }
+ }),
+ settings.klass.selectMonth,
+ ( isOpen ? '' : 'disabled' ) + ' ' +
+ _.ariaAttr({ controls: calendar.$node[0].id + '_table' }) + ' ' +
+ 'title="' + settings.labelMonthSelect + '"'
+ )
+ }
+
+ // If there's a need for a month selector
+ return _.node( 'div', monthsCollection[ viewsetObject.month ], settings.klass.month )
+ }, //createMonthLabel
+
+
+ // Create the year label.
+ createYearLabel = function() {
+
+ var focusedYear = viewsetObject.year,
+
+ // If years selector is set to a literal "true", set it to 5. Otherwise
+ // divide in half to get half before and half after focused year.
+ numberYears = settings.selectYears === true ? 5 : ~~( settings.selectYears / 2 )
+
+ // If there are years to select, add a dropdown menu.
+ if ( numberYears ) {
+
+ var
+ minYear = minLimitObject.year,
+ maxYear = maxLimitObject.year,
+ lowestYear = focusedYear - numberYears,
+ highestYear = focusedYear + numberYears
+
+ // If the min year is greater than the lowest year, increase the highest year
+ // by the difference and set the lowest year to the min year.
+ if ( minYear > lowestYear ) {
+ highestYear += minYear - lowestYear
+ lowestYear = minYear
+ }
+
+ // If the max year is less than the highest year, decrease the lowest year
+ // by the lower of the two: available and needed years. Then set the
+ // highest year to the max year.
+ if ( maxYear < highestYear ) {
+
+ var availableYears = lowestYear - minYear,
+ neededYears = highestYear - maxYear
+
+ lowestYear -= availableYears > neededYears ? neededYears : availableYears
+ highestYear = maxYear
+ }
+
+ return _.node( 'select',
+ _.group({
+ min: lowestYear,
+ max: highestYear,
+ i: 1,
+ node: 'option',
+ item: function( loopedYear ) {
+ return [
+
+ // The looped year and no classes.
+ loopedYear, 0,
+
+ // Set the value and selected index.
+ 'value=' + loopedYear + ( focusedYear == loopedYear ? ' selected' : '' )
+ ]
+ }
+ }),
+ settings.klass.selectYear,
+ ( isOpen ? '' : 'disabled' ) + ' ' + _.ariaAttr({ controls: calendar.$node[0].id + '_table' }) + ' ' +
+ 'title="' + settings.labelYearSelect + '"'
+ )
+ }
+
+ // Otherwise just return the year focused
+ return _.node( 'div', focusedYear, settings.klass.year )
+ } //createYearLabel
+
+
+ // Create and return the entire calendar.
+ return _.node(
+ 'div',
+ ( settings.selectYears ? createYearLabel() + createMonthLabel() : createMonthLabel() + createYearLabel() ) +
+ createMonthNav() + createMonthNav( 1 ),
+ settings.klass.header
+ ) + _.node(
+ 'table',
+ tableHead +
+ _.node(
+ 'tbody',
+ _.group({
+ min: 0,
+ max: WEEKS_IN_CALENDAR - 1,
+ i: 1,
+ node: 'tr',
+ item: function( rowCounter ) {
+
+ // If Monday is the first day and the month starts on Sunday, shift the date back a week.
+ var shiftDateBy = settings.firstDay && calendar.create([ viewsetObject.year, viewsetObject.month, 1 ]).day === 0 ? -7 : 0
+
+ return [
+ _.group({
+ min: DAYS_IN_WEEK * rowCounter - viewsetObject.day + shiftDateBy + 1, // Add 1 for weekday 0index
+ max: function() {
+ return this.min + DAYS_IN_WEEK - 1
+ },
+ i: 1,
+ node: 'td',
+ item: function( targetDate ) {
+
+ // Convert the time date from a relative date to a target date.
+ targetDate = calendar.create([ viewsetObject.year, viewsetObject.month, targetDate + ( settings.firstDay ? 1 : 0 ) ])
+
+ var isSelected = selectedObject && selectedObject.pick == targetDate.pick,
+ isHighlighted = highlightedObject && highlightedObject.pick == targetDate.pick,
+ isDisabled = disabledCollection && calendar.disabled( targetDate ) || targetDate.pick < minLimitObject.pick || targetDate.pick > maxLimitObject.pick
+
+ return [
+ _.node(
+ 'div',
+ targetDate.date,
+ (function( klasses ) {
+
+ // Add the `infocus` or `outfocus` classes based on month in view.
+ klasses.push( viewsetObject.month == targetDate.month ? settings.klass.infocus : settings.klass.outfocus )
+
+ // Add the `today` class if needed.
+ if ( nowObject.pick == targetDate.pick ) {
+ klasses.push( settings.klass.now )
+ }
+
+ // Add the `selected` class if something's selected and the time matches.
+ if ( isSelected ) {
+ klasses.push( settings.klass.selected )
+ }
+
+ // Add the `highlighted` class if something's highlighted and the time matches.
+ if ( isHighlighted ) {
+ klasses.push( settings.klass.highlighted )
+ }
+
+ // Add the `disabled` class if something's disabled and the object matches.
+ if ( isDisabled ) {
+ klasses.push( settings.klass.disabled )
+ }
+
+ return klasses.join( ' ' )
+ })([ settings.klass.day ]),
+ 'data-pick=' + targetDate.pick + ' ' + _.ariaAttr({
+ role: 'gridcell',
+ selected: isSelected && calendar.$node.val() === _.trigger(
+ calendar.formats.toString,
+ calendar,
+ [ settings.format, targetDate ]
+ ) ? true : null,
+ activedescendant: isHighlighted ? true : null,
+ disabled: isDisabled ? true : null
+ })
+ ),
+ '',
+ _.ariaAttr({ role: 'presentation' })
+ ] //endreturn
+ }
+ })
+ ] //endreturn
+ }
+ })
+ ),
+ settings.klass.table,
+ 'id="' + calendar.$node[0].id + '_table' + '" ' + _.ariaAttr({
+ role: 'grid',
+ controls: calendar.$node[0].id,
+ readonly: true
+ })
+ ) +
+
+ // * For Firefox forms to submit, make sure to set the buttons’ `type` attributes as “button”.
+ _.node(
+ 'div',
+ _.node( 'button', settings.today, settings.klass.buttonToday,
+ 'type=button data-pick=' + nowObject.pick +
+ ( isOpen ? '' : ' disabled' ) + ' ' +
+ _.ariaAttr({ controls: calendar.$node[0].id }) ) +
+ _.node( 'button', settings.clear, settings.klass.buttonClear,
+ 'type=button data-clear=1' +
+ ( isOpen ? '' : ' disabled' ) + ' ' +
+ _.ariaAttr({ controls: calendar.$node[0].id }) ),
+ settings.klass.footer
+ ) //endreturn
+} //DatePicker.prototype.nodes
+
+
+
+
+/**
+ * The date picker defaults.
+ */
+DatePicker.defaults = (function( prefix ) {
+
+ return {
+
+ // The title label to use for the month nav buttons
+ labelMonthNext: 'Next month',
+ labelMonthPrev: 'Previous month',
+
+ // The title label to use for the dropdown selectors
+ labelMonthSelect: 'Select a month',
+ labelYearSelect: 'Select a year',
+
+ // Months and weekdays
+ monthsFull: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
+ monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
+ weekdaysFull: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
+ weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
+
+ // Today and clear
+ today: 'Today',
+ clear: 'Clear',
+
+ // The format to show on the `input` element
+ format: 'd mmmm, yyyy',
+
+ // Classes
+ klass: {
+
+ table: prefix + 'table',
+
+ header: prefix + 'header',
+
+ navPrev: prefix + 'nav--prev',
+ navNext: prefix + 'nav--next',
+ navDisabled: prefix + 'nav--disabled',
+
+ month: prefix + 'month',
+ year: prefix + 'year',
+
+ selectMonth: prefix + 'select--month',
+ selectYear: prefix + 'select--year',
+
+ weekdays: prefix + 'weekday',
+
+ day: prefix + 'day',
+ disabled: prefix + 'day--disabled',
+ selected: prefix + 'day--selected',
+ highlighted: prefix + 'day--highlighted',
+ now: prefix + 'day--today',
+ infocus: prefix + 'day--infocus',
+ outfocus: prefix + 'day--outfocus',
+
+ footer: prefix + 'footer',
+
+ buttonClear: prefix + 'button--clear',
+ buttonToday: prefix + 'button--today'
+ }
+ }
+})( Picker.klasses().picker + '__' )
+
+
+
+
+
+/**
+ * Extend the picker to add the date picker.
+ */
+Picker.extend( 'pickadate', DatePicker )
+
+
+}));
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/picker.js b/htrace-core/src/web/lib/pickadate-3.5.2/picker.js
new file mode 100755
index 0000000..5700b6d
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/picker.js
@@ -0,0 +1,1061 @@
+/*!
+ * pickadate.js v3.5.0, 2014/04/13
+ * By Amsul, http://amsul.ca
+ * Hosted on http://amsul.github.io/pickadate.js
+ * Licensed under MIT
+ */
+
+(function ( factory ) {
+
+ // Register as an anonymous module.
+ if ( typeof define === 'function' && define.amd )
+ define( 'picker', ['jquery'], factory )
+
+ // Or using browser globals.
+ else this.Picker = factory( jQuery )
+
+}(function( $ ) {
+
+var $window = $( window )
+var $document = $( document )
+var $html = $( document.documentElement )
+
+
+/**
+ * The picker constructor that creates a blank picker.
+ */
+function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
+
+ // If there’s no element, return the picker constructor.
+ if ( !ELEMENT ) return PickerConstructor
+
+
+ var
+ IS_DEFAULT_THEME = false,
+
+
+ // The state of the picker.
+ STATE = {
+ id: ELEMENT.id || 'P' + Math.abs( ~~(Math.random() * new Date()) )
+ },
+
+
+ // Merge the defaults and options passed.
+ SETTINGS = COMPONENT ? $.extend( true, {}, COMPONENT.defaults, OPTIONS ) : OPTIONS || {},
+
+
+ // Merge the default classes with the settings classes.
+ CLASSES = $.extend( {}, PickerConstructor.klasses(), SETTINGS.klass ),
+
+
+ // The element node wrapper into a jQuery object.
+ $ELEMENT = $( ELEMENT ),
+
+
+ // Pseudo picker constructor.
+ PickerInstance = function() {
+ return this.start()
+ },
+
+
+ // The picker prototype.
+ P = PickerInstance.prototype = {
+
+ constructor: PickerInstance,
+
+ $node: $ELEMENT,
+
+
+ /**
+ * Initialize everything
+ */
+ start: function() {
+
+ // If it’s already started, do nothing.
+ if ( STATE && STATE.start ) return P
+
+
+ // Update the picker states.
+ STATE.methods = {}
+ STATE.start = true
+ STATE.open = false
+ STATE.type = ELEMENT.type
+
+
+ // Confirm focus state, convert into text input to remove UA stylings,
+ // and set as readonly to prevent keyboard popup.
+ ELEMENT.autofocus = ELEMENT == document.activeElement
+ ELEMENT.type = 'text'
+ ELEMENT.readOnly = !SETTINGS.editable
+ ELEMENT.id = ELEMENT.id || STATE.id
+
+
+ // Create a new picker component with the settings.
+ P.component = new COMPONENT(P, SETTINGS)
+
+
+ // Create the picker root with a holder and then prepare it.
+ P.$root = $( PickerConstructor._.node('div', createWrappedComponent(), CLASSES.picker, 'id="' + ELEMENT.id + '_root"') )
+ prepareElementRoot()
+
+
+ // If there’s a format for the hidden input element, create the element.
+ if ( SETTINGS.formatSubmit ) {
+ prepareElementHidden()
+ }
+
+
+ // Prepare the input element.
+ prepareElement()
+
+
+ // Insert the root as specified in the settings.
+ if ( SETTINGS.container ) $( SETTINGS.container ).append( P.$root )
+ else $ELEMENT.after( P.$root )
+
+
+ // Bind the default component and settings events.
+ P.on({
+ start: P.component.onStart,
+ render: P.component.onRender,
+ stop: P.component.onStop,
+ open: P.component.onOpen,
+ close: P.component.onClose,
+ set: P.component.onSet
+ }).on({
+ start: SETTINGS.onStart,
+ render: SETTINGS.onRender,
+ stop: SETTINGS.onStop,
+ open: SETTINGS.onOpen,
+ close: SETTINGS.onClose,
+ set: SETTINGS.onSet
+ })
+
+
+ // Once we’re all set, check the theme in use.
+ IS_DEFAULT_THEME = isUsingDefaultTheme( P.$root.children()[ 0 ] )
+
+
+ // If the element has autofocus, open the picker.
+ if ( ELEMENT.autofocus ) {
+ P.open()
+ }
+
+
+ // Trigger queued the “start” and “render” events.
+ return P.trigger( 'start' ).trigger( 'render' )
+ }, //start
+
+
+ /**
+ * Render a new picker
+ */
+ render: function( entireComponent ) {
+
+ // Insert a new component holder in the root or box.
+ if ( entireComponent ) P.$root.html( createWrappedComponent() )
+ else P.$root.find( '.' + CLASSES.box ).html( P.component.nodes( STATE.open ) )
+
+ // Trigger the queued “render” events.
+ return P.trigger( 'render' )
+ }, //render
+
+
+ /**
+ * Destroy everything
+ */
+ stop: function() {
+
+ // If it’s already stopped, do nothing.
+ if ( !STATE.start ) return P
+
+ // Then close the picker.
+ P.close()
+
+ // Remove the hidden field.
+ if ( P._hidden ) {
+ P._hidden.parentNode.removeChild( P._hidden )
+ }
+
+ // Remove the root.
+ P.$root.remove()
+
+ // Remove the input class, remove the stored data, and unbind
+ // the events (after a tick for IE - see `P.close`).
+ $ELEMENT.removeClass( CLASSES.input ).removeData( NAME )
+ setTimeout( function() {
+ $ELEMENT.off( '.' + STATE.id )
+ }, 0)
+
+ // Restore the element state
+ ELEMENT.type = STATE.type
+ ELEMENT.readOnly = false
+
+ // Trigger the queued “stop” events.
+ P.trigger( 'stop' )
+
+ // Reset the picker states.
+ STATE.methods = {}
+ STATE.start = false
+
+ return P
+ }, //stop
+
+
+ /*
+ * Open up the picker
+ */
+ open: function( dontGiveFocus ) {
+
+ // If it’s already open, do nothing.
+ if ( STATE.open ) return P
+
+ // Add the “active” class.
+ $ELEMENT.addClass( CLASSES.active )
+ aria( ELEMENT, 'expanded', true )
+
+ // * A Firefox bug, when `html` has `overflow:hidden`, results in
+ // killing transitions :(. So add the “opened” state on the next tick.
+ // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
+ setTimeout( function() {
+
+ // Add the “opened” class to the picker root.
+ P.$root.addClass( CLASSES.opened )
+ aria( P.$root[0], 'hidden', false )
+
+ }, 0 )
+
+ // If we have to give focus, bind the element and doc events.
+ if ( dontGiveFocus !== false ) {
+
+ // Set it as open.
+ STATE.open = true
+
+ // Prevent the page from scrolling.
+ if ( IS_DEFAULT_THEME ) {
+ $html.
+ css( 'overflow', 'hidden' ).
+ css( 'padding-right', '+=' + getScrollbarWidth() )
+ }
+
+ // Pass focus to the element’s jQuery object.
+ $ELEMENT.trigger( 'focus' )
+
+ // Bind the document events.
+ $document.on( 'click.' + STATE.id + ' focusin.' + STATE.id, function( event ) {
+
+ var target = event.target
+
+ // If the target of the event is not the element, close the picker picker.
+ // * Don’t worry about clicks or focusins on the root because those don’t bubble up.
+ // Also, for Firefox, a click on an `option` element bubbles up directly
+ // to the doc. So make sure the target wasn't the doc.
+ // * In Firefox stopPropagation() doesn’t prevent right-click events from bubbling,
+ // which causes the picker to unexpectedly close when right-clicking it. So make
+ // sure the event wasn’t a right-click.
+ if ( target != ELEMENT && target != document && event.which != 3 ) {
+
+ // If the target was the holder that covers the screen,
+ // keep the element focused to maintain tabindex.
+ P.close( target === P.$root.children()[0] )
+ }
+
+ }).on( 'keydown.' + STATE.id, function( event ) {
+
+ var
+ // Get the keycode.
+ keycode = event.keyCode,
+
+ // Translate that to a selection change.
+ keycodeToMove = P.component.key[ keycode ],
+
+ // Grab the target.
+ target = event.target
+
+
+ // On escape, close the picker and give focus.
+ if ( keycode == 27 ) {
+ P.close( true )
+ }
+
+
+ // Check if there is a key movement or “enter” keypress on the element.
+ else if ( target == ELEMENT && ( keycodeToMove || keycode == 13 ) ) {
+
+ // Prevent the default action to stop page movement.
+ event.preventDefault()
+
+ // Trigger the key movement action.
+ if ( keycodeToMove ) {
+ PickerConstructor._.trigger( P.component.key.go, P, [ PickerConstructor._.trigger( keycodeToMove ) ] )
+ }
+
+ // On “enter”, if the highlighted item isn’t disabled, set the value and close.
+ else if ( !P.$root.find( '.' + CLASSES.highlighted ).hasClass( CLASSES.disabled ) ) {
+ P.set( 'select', P.component.item.highlight ).close()
+ }
+ }
+
+
+ // If the target is within the root and “enter” is pressed,
+ // prevent the default action and trigger a click on the target instead.
+ else if ( $.contains( P.$root[0], target ) && keycode == 13 ) {
+ event.preventDefault()
+ target.click()
+ }
+ })
+ }
+
+ // Trigger the queued “open” events.
+ return P.trigger( 'open' )
+ }, //open
+
+
+ /**
+ * Close the picker
+ */
+ close: function( giveFocus ) {
+
+ // If we need to give focus, do it before changing states.
+ if ( giveFocus ) {
+ // ....ah yes! It would’ve been incomplete without a crazy workaround for IE :|
+ // The focus is triggered *after* the close has completed - causing it
+ // to open again. So unbind and rebind the event at the next tick.
+ $ELEMENT.off( 'focus.' + STATE.id ).trigger( 'focus' )
+ setTimeout( function() {
+ $ELEMENT.on( 'focus.' + STATE.id, focusToOpen )
+ }, 0 )
+ }
+
+ // Remove the “active” class.
+ $ELEMENT.removeClass( CLASSES.active )
+ aria( ELEMENT, 'expanded', false )
+
+ // * A Firefox bug, when `html` has `overflow:hidden`, results in
+ // killing transitions :(. So remove the “opened” state on the next tick.
+ // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
+ setTimeout( function() {
+
+ // Remove the “opened” and “focused” class from the picker root.
+ P.$root.removeClass( CLASSES.opened + ' ' + CLASSES.focused )
+ aria( P.$root[0], 'hidden', true )
+
+ }, 0 )
+
+ // If it’s already closed, do nothing more.
+ if ( !STATE.open ) return P
+
+ // Set it as closed.
+ STATE.open = false
+
+ // Allow the page to scroll.
+ if ( IS_DEFAULT_THEME ) {
+ $html.
+ css( 'overflow', '' ).
+ css( 'padding-right', '-=' + getScrollbarWidth() )
+ }
+
+ // Unbind the document events.
+ $document.off( '.' + STATE.id )
+
+ // Trigger the queued “close” events.
+ return P.trigger( 'close' )
+ }, //close
+
+
+ /**
+ * Clear the values
+ */
+ clear: function() {
+ return P.set( 'clear' )
+ }, //clear
+
+
+ /**
+ * Set something
+ */
+ set: function( thing, value, options ) {
+
+ var thingItem, thingValue,
+ thingIsObject = $.isPlainObject( thing ),
+ thingObject = thingIsObject ? thing : {}
+
+ // Make sure we have usable options.
+ options = thingIsObject && $.isPlainObject( value ) ? value : options || {}
+
+ if ( thing ) {
+
+ // If the thing isn’t an object, make it one.
+ if ( !thingIsObject ) {
+ thingObject[ thing ] = value
+ }
+
+ // Go through the things of items to set.
+ for ( thingItem in thingObject ) {
+
+ // Grab the value of the thing.
+ thingValue = thingObject[ thingItem ]
+
+ // First, if the item exists and there’s a value, set it.
+ if ( thingItem in P.component.item ) {
+ if ( thingValue === undefined ) thingValue = null
+ P.component.set( thingItem, thingValue, options )
+ }
+
+ // Then, check to update the element value and broadcast a change.
+ if ( thingItem == 'select' || thingItem == 'clear' ) {
+ $ELEMENT.
+ val( thingItem == 'clear' ? '' : P.get( thingItem, SETTINGS.format ) ).
+ trigger( 'change' )
+ }
+ }
+
+ // Render a new picker.
+ P.render()
+ }
+
+ // When the method isn’t muted, trigger queued “set” events and pass the `thingObject`.
+ return options.muted ? P : P.trigger( 'set', thingObject )
+ }, //set
+
+
+ /**
+ * Get something
+ */
+ get: function( thing, format ) {
+
+ // Make sure there’s something to get.
+ thing = thing || 'value'
+
+ // If a picker state exists, return that.
+ if ( STATE[ thing ] != null ) {
+ return STATE[ thing ]
+ }
+
+ // Return the value, if that.
+ if ( thing == 'value' ) {
+ return ELEMENT.value
+ }
+
+ // Check if a component item exists, return that.
+ if ( thing in P.component.item ) {
+ if ( typeof format == 'string' ) {
+ var thingValue = P.component.get( thing )
+ return thingValue ?
+ PickerConstructor._.trigger(
+ P.component.formats.toString,
+ P.component,
+ [ format, thingValue ]
+ ) : ''
+ }
+ return P.component.get( thing )
+ }
+ }, //get
+
+
+
+ /**
+ * Bind events on the things.
+ */
+ on: function( thing, method ) {
+
+ var thingName, thingMethod,
+ thingIsObject = $.isPlainObject( thing ),
+ thingObject = thingIsObject ? thing : {}
+
+ if ( thing ) {
+
+ // If the thing isn’t an object, make it one.
+ if ( !thingIsObject ) {
+ thingObject[ thing ] = method
+ }
+
+ // Go through the things to bind to.
+ for ( thingName in thingObject ) {
+
+ // Grab the method of the thing.
+ thingMethod = thingObject[ thingName ]
+
+ // Make sure the thing methods collection exists.
+ STATE.methods[ thingName ] = STATE.methods[ thingName ] || []
+
+ // Add the method to the relative method collection.
+ STATE.methods[ thingName ].push( thingMethod )
+ }
+ }
+
+ return P
+ }, //on
+
+
+
+ /**
+ * Unbind events on the things.
+ */
+ off: function() {
+ var i, thingName,
+ names = arguments;
+ for ( i = 0, namesCount = names.length; i < namesCount; i += 1 ) {
+ thingName = names[i]
+ if ( thingName in STATE.methods ) {
+ delete STATE.methods[thingName]
+ }
+ }
+ return P
+ },
+
+
+ /**
+ * Fire off method events.
+ */
+ trigger: function( name, data ) {
+ var methodList = STATE.methods[ name ]
+ if ( methodList ) {
+ methodList.map( function( method ) {
+ PickerConstructor._.trigger( method, P, [ data ] )
+ })
+ }
+ return P
+ } //trigger
+ } //PickerInstance.prototype
+
+
+ /**
+ * Wrap the picker holder components together.
+ */
+ function createWrappedComponent() {
+
+ // Create a picker wrapper holder
+ return PickerConstructor._.node( 'div',
+
+ // Create a picker wrapper node
+ PickerConstructor._.node( 'div',
+
+ // Create a picker frame
+ PickerConstructor._.node( 'div',
+
+ // Create a picker box node
+ PickerConstructor._.node( 'div',
+
+ // Create the components nodes.
+ P.component.nodes( STATE.open ),
+
+ // The picker box class
+ CLASSES.box
+ ),
+
+ // Picker wrap class
+ CLASSES.wrap
+ ),
+
+ // Picker frame class
+ CLASSES.frame
+ ),
+
+ // Picker holder class
+ CLASSES.holder
+ ) //endreturn
+ } //createWrappedComponent
+
+
+
+ /**
+ * Prepare the input element with all bindings.
+ */
+ function prepareElement() {
+
+ $ELEMENT.
+
+ // Store the picker data by component name.
+ data(NAME, P).
+
+ // Add the “input” class name.
+ addClass(CLASSES.input).
+
+ // If there’s a `data-value`, update the value of the element.
+ val( $ELEMENT.data('value') ?
+ P.get('select', SETTINGS.format) :
+ ELEMENT.value
+ ).
+
+ // On focus/click, open the picker and adjust the root “focused” state.
+ on('focus.' + STATE.id + ' click.' + STATE.id, focusToOpen)
+
+
+ // Only bind keydown events if the element isn’t editable.
+ if ( !SETTINGS.editable ) {
+
+ // Handle keyboard event based on the picker being opened or not.
+ $ELEMENT.on('keydown.' + STATE.id, function(event) {
+
+ var keycode = event.keyCode,
+
+ // Check if one of the delete keys was pressed.
+ isKeycodeDelete = /^(8|46)$/.test(keycode)
+
+ // For some reason IE clears the input value on “escape”.
+ if ( keycode == 27 ) {
+ P.close()
+ return false
+ }
+
+ // Check if `space` or `delete` was pressed or the picker is closed with a key movement.
+ if ( keycode == 32 || isKeycodeDelete || !STATE.open && P.component.key[keycode] ) {
+
+ // Prevent it from moving the page and bubbling to doc.
+ event.preventDefault()
+ event.stopPropagation()
+
+ // If `delete` was pressed, clear the values and close the picker.
+ // Otherwise open the picker.
+ if ( isKeycodeDelete ) { P.clear().close() }
+ else { P.open() }
+ }
+ })
+ }
+
+
+ // Update the aria attributes.
+ aria(ELEMENT, {
+ haspopup: true,
+ expanded: false,
+ readonly: false,
+ owns: ELEMENT.id + '_root' + (P._hidden ? ' ' + P._hidden.id : '')
+ })
+ }
+
+
+ /**
+ * Prepare the root picker element with all bindings.
+ */
+ function prepareElementRoot() {
+
+ P.$root.
+
+ on({
+
+ // When something within the root is focused, stop from bubbling
+ // to the doc and remove the “focused” state from the root.
+ focusin: function( event ) {
+ P.$root.removeClass( CLASSES.focused )
+ event.stopPropagation()
+ },
+
+ // When something within the root holder is clicked, stop it
+ // from bubbling to the doc.
+ 'mousedown click': function( event ) {
+
+ var target = event.target
+
+ // Make sure the target isn’t the root holder so it can bubble up.
+ if ( target != P.$root.children()[ 0 ] ) {
+
+ event.stopPropagation()
+
+ // * For mousedown events, cancel the default action in order to
+ // prevent cases where focus is shifted onto external elements
+ // when using things like jQuery mobile or MagnificPopup (ref: #249 & #120).
+ // Also, for Firefox, don’t prevent action on the `option` element.
+ if ( event.type == 'mousedown' && !$( target ).is( ':input' ) && target.nodeName != 'OPTION' ) {
+
+ event.preventDefault()
+
+ // Re-focus onto the element so that users can click away
+ // from elements focused within the picker.
+ ELEMENT.focus()
+ }
+ }
+ }
+ }).
+
+ // If there’s a click on an actionable element, carry out the actions.
+ on( 'click', '[data-pick], [data-nav], [data-clear]', function() {
+
+ var $target = $( this ),
+ targetData = $target.data(),
+ targetDisabled = $target.hasClass( CLASSES.navDisabled ) || $target.hasClass( CLASSES.disabled ),
+
+ // * For IE, non-focusable elements can be active elements as well
+ // (http://stackoverflow.com/a/2684561).
+ activeElement = document.activeElement
+ activeElement = activeElement && ( activeElement.type || activeElement.href ) && activeElement
+
+ // If it’s disabled or nothing inside is actively focused, re-focus the element.
+ if ( targetDisabled || activeElement && !$.contains( P.$root[0], activeElement ) ) {
+ ELEMENT.focus()
+ }
+
+ // If something is superficially changed, update the `highlight` based on the `nav`.
+ if ( targetData.nav && !targetDisabled ) {
+ P.set( 'highlight', P.component.item.highlight, { nav: targetData.nav } )
+ }
+
+ // If something is picked, set `select` then close with focus.
+ else if ( PickerConstructor._.isInteger( targetData.pick ) && !targetDisabled ) {
+ P.set( 'select', targetData.pick ).close( true )
+ }
+
+ // If a “clear” button is pressed, empty the values and close with focus.
+ else if ( targetData.clear ) {
+ P.clear().close( true )
+ }
+ }) //P.$root
+
+ aria( P.$root[0], 'hidden', true )
+ }
+
+
+ /**
+ * Prepare the hidden input element along with all bindings.
+ */
+ function prepareElementHidden() {
+
+ var id,
+ name
+
+ if ( SETTINGS.hiddenName === true ) {
+ id = ELEMENT.name + '_hidden'
+ name = ELEMENT.name
+ ELEMENT.name = ''
+ }
+ else {
+ name = [
+ typeof SETTINGS.hiddenPrefix == 'string' ? SETTINGS.hiddenPrefix : '',
+ typeof SETTINGS.hiddenSuffix == 'string' ? SETTINGS.hiddenSuffix : '_submit'
+ ]
+ name = id = name[0] + ELEMENT.name + name[1]
+ }
+
+ P._hidden = $(
+ ''
+ )[0]
+
+ $ELEMENT.
+
+ // If the value changes, update the hidden input with the correct format.
+ on('change.' + STATE.id, function() {
+ P._hidden.value = ELEMENT.value ?
+ P.get('select', SETTINGS.formatSubmit) :
+ ''
+ }).
+
+ // Insert the hidden input after the element.
+ after(P._hidden)
+ }
+
+
+ // Separated for IE
+ function focusToOpen( event ) {
+
+ // Stop the event from propagating to the doc.
+ event.stopPropagation()
+
+ // If it’s a focus event, add the “focused” class to the root.
+ if ( event.type == 'focus' ) {
+ P.$root.addClass( CLASSES.focused )
+ }
+
+ // And then finally open the picker.
+ P.open()
+ }
+
+
+ // Return a new picker instance.
+ return new PickerInstance()
+} //PickerConstructor
+
+
+
+/**
+ * The default classes and prefix to use for the HTML classes.
+ */
+PickerConstructor.klasses = function( prefix ) {
+ prefix = prefix || 'picker'
+ return {
+
+ picker: prefix,
+ opened: prefix + '--opened',
+ focused: prefix + '--focused',
+
+ input: prefix + '__input',
+ active: prefix + '__input--active',
+
+ holder: prefix + '__holder',
+
+ frame: prefix + '__frame',
+ wrap: prefix + '__wrap',
+
+ box: prefix + '__box'
+ }
+} //PickerConstructor.klasses
+
+
+
+/**
+ * Check if the default theme is being used.
+ */
+function isUsingDefaultTheme( element ) {
+
+ var theme,
+ prop = 'position'
+
+ // For IE.
+ if ( element.currentStyle ) {
+ theme = element.currentStyle[prop]
+ }
+
+ // For normal browsers.
+ else if ( window.getComputedStyle ) {
+ theme = getComputedStyle( element )[prop]
+ }
+
+ return theme == 'fixed'
+}
+
+
+
+/**
+ * Get the width of the browser’s scrollbar.
+ * Taken from: https://github.com/VodkaBears/Remodal/blob/master/src/jquery.remodal.js
+ */
+function getScrollbarWidth() {
+
+ if ( $html.height() <= $window.height() ) {
+ return 0
+ }
+
+ var $outer = $( '' ).
+ appendTo( 'body' )
+
+ // Get the width without scrollbars.
+ var widthWithoutScroll = $outer[0].offsetWidth
+
+ // Force adding scrollbars.
+ $outer.css( 'overflow', 'scroll' )
+
+ // Add the inner div.
+ var $inner = $( '' ).appendTo( $outer )
+
+ // Get the width with scrollbars.
+ var widthWithScroll = $inner[0].offsetWidth
+
+ // Remove the divs.
+ $outer.remove()
+
+ // Return the difference between the widths.
+ return widthWithoutScroll - widthWithScroll
+}
+
+
+
+/**
+ * PickerConstructor helper methods.
+ */
+PickerConstructor._ = {
+
+ /**
+ * Create a group of nodes. Expects:
+ * `
+ {
+ min: {Integer},
+ max: {Integer},
+ i: {Integer},
+ node: {String},
+ item: {Function}
+ }
+ * `
+ */
+ group: function( groupObject ) {
+
+ var
+ // Scope for the looped object
+ loopObjectScope,
+
+ // Create the nodes list
+ nodesList = '',
+
+ // The counter starts from the `min`
+ counter = PickerConstructor._.trigger( groupObject.min, groupObject )
+
+
+ // Loop from the `min` to `max`, incrementing by `i`
+ for ( ; counter <= PickerConstructor._.trigger( groupObject.max, groupObject, [ counter ] ); counter += groupObject.i ) {
+
+ // Trigger the `item` function within scope of the object
+ loopObjectScope = PickerConstructor._.trigger( groupObject.item, groupObject, [ counter ] )
+
+ // Splice the subgroup and create nodes out of the sub nodes
+ nodesList += PickerConstructor._.node(
+ groupObject.node,
+ loopObjectScope[ 0 ], // the node
+ loopObjectScope[ 1 ], // the classes
+ loopObjectScope[ 2 ] // the attributes
+ )
+ }
+
+ // Return the list of nodes
+ return nodesList
+ }, //group
+
+
+ /**
+ * Create a dom node string
+ */
+ node: function( wrapper, item, klass, attribute ) {
+
+ // If the item is false-y, just return an empty string
+ if ( !item ) return ''
+
+ // If the item is an array, do a join
+ item = $.isArray( item ) ? item.join( '' ) : item
+
+ // Check for the class
+ klass = klass ? ' class="' + klass + '"' : ''
+
+ // Check for any attributes
+ attribute = attribute ? ' ' + attribute : ''
+
+ // Return the wrapped item
+ return '<' + wrapper + klass + attribute + '>' + item + '' + wrapper + '>'
+ }, //node
+
+
+ /**
+ * Lead numbers below 10 with a zero.
+ */
+ lead: function( number ) {
+ return ( number < 10 ? '0': '' ) + number
+ },
+
+
+ /**
+ * Trigger a function otherwise return the value.
+ */
+ trigger: function( callback, scope, args ) {
+ return typeof callback == 'function' ? callback.apply( scope, args || [] ) : callback
+ },
+
+
+ /**
+ * If the second character is a digit, length is 2 otherwise 1.
+ */
+ digits: function( string ) {
+ return ( /\d/ ).test( string[ 1 ] ) ? 2 : 1
+ },
+
+
+ /**
+ * Tell if something is a date object.
+ */
+ isDate: function( value ) {
+ return {}.toString.call( value ).indexOf( 'Date' ) > -1 && this.isInteger( value.getDate() )
+ },
+
+
+ /**
+ * Tell if something is an integer.
+ */
+ isInteger: function( value ) {
+ return {}.toString.call( value ).indexOf( 'Number' ) > -1 && value % 1 === 0
+ },
+
+
+ /**
+ * Create ARIA attribute strings.
+ */
+ ariaAttr: ariaAttr
+} //PickerConstructor._
+
+
+
+/**
+ * Extend the picker with a component and defaults.
+ */
+PickerConstructor.extend = function( name, Component ) {
+
+ // Extend jQuery.
+ $.fn[ name ] = function( options, action ) {
+
+ // Grab the component data.
+ var componentData = this.data( name )
+
+ // If the picker is requested, return the data object.
+ if ( options == 'picker' ) {
+ return componentData
+ }
+
+ // If the component data exists and `options` is a string, carry out the action.
+ if ( componentData && typeof options == 'string' ) {
+ return PickerConstructor._.trigger( componentData[ options ], componentData, [ action ] )
+ }
+
+ // Otherwise go through each matched element and if the component
+ // doesn’t exist, create a new picker using `this` element
+ // and merging the defaults and options with a deep copy.
+ return this.each( function() {
+ var $this = $( this )
+ if ( !$this.data( name ) ) {
+ new PickerConstructor( this, name, Component, options )
+ }
+ })
+ }
+
+ // Set the defaults.
+ $.fn[ name ].defaults = Component.defaults
+} //PickerConstructor.extend
+
+
+
+function aria(element, attribute, value) {
+ if ( $.isPlainObject(attribute) ) {
+ for ( var key in attribute ) {
+ ariaSet(element, key, attribute[key])
+ }
+ }
+ else {
+ ariaSet(element, attribute, value)
+ }
+}
+function ariaSet(element, attribute, value) {
+ element.setAttribute(
+ (attribute == 'role' ? '' : 'aria-') + attribute,
+ value
+ )
+}
+function ariaAttr(attribute, data) {
+ if ( !$.isPlainObject(attribute) ) {
+ attribute = { attribute: data }
+ }
+ data = ''
+ for ( var key in attribute ) {
+ var attr = (key == 'role' ? '' : 'aria-') + key,
+ attrVal = attribute[key]
+ data += attrVal == null ? '' : attr + '="' + attribute[key] + '"'
+ }
+ return data
+}
+
+
+
+// Expose the picker constructor.
+return PickerConstructor
+
+
+}));
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/picker.time.js b/htrace-core/src/web/lib/pickadate-3.5.2/picker.time.js
new file mode 100755
index 0000000..a9c4342
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/picker.time.js
@@ -0,0 +1,990 @@
+
+/*!
+ * Time picker for pickadate.js v3.5.0
+ * http://amsul.github.io/pickadate.js/time.htm
+ */
+
+(function ( factory ) {
+
+ // Register as an anonymous module.
+ if ( typeof define == 'function' && define.amd )
+ define( ['picker','jquery'], factory )
+
+ // Or using browser globals.
+ else factory( Picker, jQuery )
+
+}(function( Picker, $ ) {
+
+
+/**
+ * Globals and constants
+ */
+var HOURS_IN_DAY = 24,
+ MINUTES_IN_HOUR = 60,
+ HOURS_TO_NOON = 12,
+ MINUTES_IN_DAY = HOURS_IN_DAY * MINUTES_IN_HOUR,
+ _ = Picker._
+
+
+
+/**
+ * The time picker constructor
+ */
+function TimePicker( picker, settings ) {
+
+ var clock = this,
+ elementValue = picker.$node[ 0 ].value,
+ elementDataValue = picker.$node.data( 'value' ),
+ valueString = elementDataValue || elementValue,
+ formatString = elementDataValue ? settings.formatSubmit : settings.format
+
+ clock.settings = settings
+ clock.$node = picker.$node
+
+ // The queue of methods that will be used to build item objects.
+ clock.queue = {
+ interval: 'i',
+ min: 'measure create',
+ max: 'measure create',
+ now: 'now create',
+ select: 'parse create validate',
+ highlight: 'parse create validate',
+ view: 'parse create validate',
+ disable: 'deactivate',
+ enable: 'activate'
+ }
+
+ // The component's item object.
+ clock.item = {}
+
+ clock.item.clear = null
+ clock.item.interval = settings.interval || 30
+ clock.item.disable = ( settings.disable || [] ).slice( 0 )
+ clock.item.enable = -(function( collectionDisabled ) {
+ return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1
+ })( clock.item.disable )
+
+ clock.
+ set( 'min', settings.min ).
+ set( 'max', settings.max ).
+ set( 'now' )
+
+ // When there’s a value, set the `select`, which in turn
+ // also sets the `highlight` and `view`.
+ if ( valueString ) {
+ clock.set( 'select', valueString, {
+ format: formatString,
+ fromValue: !!elementValue
+ })
+ }
+
+ // If there’s no value, default to highlighting “today”.
+ else {
+ clock.
+ set( 'select', null ).
+ set( 'highlight', clock.item.now )
+ }
+
+ // The keycode to movement mapping.
+ clock.key = {
+ 40: 1, // Down
+ 38: -1, // Up
+ 39: 1, // Right
+ 37: -1, // Left
+ go: function( timeChange ) {
+ clock.set(
+ 'highlight',
+ clock.item.highlight.pick + timeChange * clock.item.interval,
+ { interval: timeChange * clock.item.interval }
+ )
+ this.render()
+ }
+ }
+
+
+ // Bind some picker events.
+ picker.
+ on( 'render', function() {
+ var $pickerHolder = picker.$root.children(),
+ $viewset = $pickerHolder.find( '.' + settings.klass.viewset )
+ if ( $viewset.length ) {
+ $pickerHolder[ 0 ].scrollTop = ~~$viewset.position().top - ( $viewset[ 0 ].clientHeight * 2 )
+ }
+ }).
+ on( 'open', function() {
+ picker.$root.find( 'button' ).attr( 'disabled', false )
+ }).
+ on( 'close', function() {
+ picker.$root.find( 'button' ).attr( 'disabled', true )
+ })
+
+} //TimePicker
+
+
+/**
+ * Set a timepicker item object.
+ */
+TimePicker.prototype.set = function( type, value, options ) {
+
+ var clock = this,
+ clockItem = clock.item
+
+ // If the value is `null` just set it immediately.
+ if ( value === null ) {
+ if ( type == 'clear' ) type = 'select'
+ clockItem[ type ] = value
+ return clock
+ }
+
+ // Otherwise go through the queue of methods, and invoke the functions.
+ // Update this as the time unit, and set the final value as this item.
+ // * In the case of `enable`, keep the queue but set `disable` instead.
+ // And in the case of `flip`, keep the queue but set `enable` instead.
+ clockItem[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = clock.queue[ type ].split( ' ' ).map( function( method ) {
+ value = clock[ method ]( type, value, options )
+ return value
+ }).pop()
+
+ // Check if we need to cascade through more updates.
+ if ( type == 'select' ) {
+ clock.set( 'highlight', clockItem.select, options )
+ }
+ else if ( type == 'highlight' ) {
+ clock.set( 'view', clockItem.highlight, options )
+ }
+ else if ( type == 'interval' ) {
+ clock.
+ set( 'min', clockItem.min, options ).
+ set( 'max', clockItem.max, options )
+ }
+ else if ( type.match( /^(flip|min|max|disable|enable)$/ ) ) {
+ if ( type == 'min' ) {
+ clock.set( 'max', clockItem.max, options )
+ }
+ if ( clockItem.select && clock.disabled( clockItem.select ) ) {
+ clock.set( 'select', clockItem.select, options )
+ }
+ if ( clockItem.highlight && clock.disabled( clockItem.highlight ) ) {
+ clock.set( 'highlight', clockItem.highlight, options )
+ }
+ }
+
+ return clock
+} //TimePicker.prototype.set
+
+
+/**
+ * Get a timepicker item object.
+ */
+TimePicker.prototype.get = function( type ) {
+ return this.item[ type ]
+} //TimePicker.prototype.get
+
+
+/**
+ * Create a picker time object.
+ */
+TimePicker.prototype.create = function( type, value, options ) {
+
+ var clock = this
+
+ // If there’s no value, use the type as the value.
+ value = value === undefined ? type : value
+
+ // If it’s a date object, convert it into an array.
+ if ( _.isDate( value ) ) {
+ value = [ value.getHours(), value.getMinutes() ]
+ }
+
+ // If it’s an object, use the “pick” value.
+ if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) {
+ value = value.pick
+ }
+
+ // If it’s an array, convert it into minutes.
+ else if ( $.isArray( value ) ) {
+ value = +value[ 0 ] * MINUTES_IN_HOUR + (+value[ 1 ])
+ }
+
+ // If no valid value is passed, set it to “now”.
+ else if ( !_.isInteger( value ) ) {
+ value = clock.now( type, value, options )
+ }
+
+ // If we’re setting the max, make sure it’s greater than the min.
+ if ( type == 'max' && value < clock.item.min.pick ) {
+ value += MINUTES_IN_DAY
+ }
+
+ // If the value doesn’t fall directly on the interval,
+ // add one interval to indicate it as “passed”.
+ if ( type != 'min' && type != 'max' && (value - clock.item.min.pick) % clock.item.interval !== 0 ) {
+ value += clock.item.interval
+ }
+
+ // Normalize it into a “reachable” interval.
+ value = clock.normalize( type, value, options )
+
+ // Return the compiled object.
+ return {
+
+ // Divide to get hours from minutes.
+ hour: ~~( HOURS_IN_DAY + value / MINUTES_IN_HOUR ) % HOURS_IN_DAY,
+
+ // The remainder is the minutes.
+ mins: ( MINUTES_IN_HOUR + value % MINUTES_IN_HOUR ) % MINUTES_IN_HOUR,
+
+ // The time in total minutes.
+ time: ( MINUTES_IN_DAY + value ) % MINUTES_IN_DAY,
+
+ // Reference to the “relative” value to pick.
+ pick: value
+ }
+} //TimePicker.prototype.create
+
+
+/**
+ * Create a range limit object using an array, date object,
+ * literal “true”, or integer relative to another time.
+ */
+TimePicker.prototype.createRange = function( from, to ) {
+
+ var clock = this,
+ createTime = function( time ) {
+ if ( time === true || $.isArray( time ) || _.isDate( time ) ) {
+ return clock.create( time )
+ }
+ return time
+ }
+
+ // Create objects if possible.
+ if ( !_.isInteger( from ) ) {
+ from = createTime( from )
+ }
+ if ( !_.isInteger( to ) ) {
+ to = createTime( to )
+ }
+
+ // Create relative times.
+ if ( _.isInteger( from ) && $.isPlainObject( to ) ) {
+ from = [ to.hour, to.mins + ( from * clock.settings.interval ) ];
+ }
+ else if ( _.isInteger( to ) && $.isPlainObject( from ) ) {
+ to = [ from.hour, from.mins + ( to * clock.settings.interval ) ];
+ }
+
+ return {
+ from: createTime( from ),
+ to: createTime( to )
+ }
+} //TimePicker.prototype.createRange
+
+
+/**
+ * Check if a time unit falls within a time range object.
+ */
+TimePicker.prototype.withinRange = function( range, timeUnit ) {
+ range = this.createRange(range.from, range.to)
+ return timeUnit.pick >= range.from.pick && timeUnit.pick <= range.to.pick
+}
+
+
+/**
+ * Check if two time range objects overlap.
+ */
+TimePicker.prototype.overlapRanges = function( one, two ) {
+
+ var clock = this
+
+ // Convert the ranges into comparable times.
+ one = clock.createRange( one.from, one.to )
+ two = clock.createRange( two.from, two.to )
+
+ return clock.withinRange( one, two.from ) || clock.withinRange( one, two.to ) ||
+ clock.withinRange( two, one.from ) || clock.withinRange( two, one.to )
+}
+
+
+/**
+ * Get the time relative to now.
+ */
+TimePicker.prototype.now = function( type, value/*, options*/ ) {
+
+ var interval = this.item.interval,
+ date = new Date(),
+ nowMinutes = date.getHours() * MINUTES_IN_HOUR + date.getMinutes(),
+ isValueInteger = _.isInteger( value ),
+ isBelowInterval
+
+ // Make sure “now” falls within the interval range.
+ nowMinutes -= nowMinutes % interval
+
+ // Check if the difference is less than the interval itself.
+ isBelowInterval = value < 0 && interval * value + nowMinutes <= -interval
+
+ // Add an interval because the time has “passed”.
+ nowMinutes += type == 'min' && isBelowInterval ? 0 : interval
+
+ // If the value is a number, adjust by that many intervals.
+ if ( isValueInteger ) {
+ nowMinutes += interval * (
+ isBelowInterval && type != 'max' ?
+ value + 1 :
+ value
+ )
+ }
+
+ // Return the final calculation.
+ return nowMinutes
+} //TimePicker.prototype.now
+
+
+/**
+ * Normalize minutes to be “reachable” based on the min and interval.
+ */
+TimePicker.prototype.normalize = function( type, value/*, options*/ ) {
+
+ var interval = this.item.interval,
+ minTime = this.item.min && this.item.min.pick || 0
+
+ // If setting min time, don’t shift anything.
+ // Otherwise get the value and min difference and then
+ // normalize the difference with the interval.
+ value -= type == 'min' ? 0 : ( value - minTime ) % interval
+
+ // Return the adjusted value.
+ return value
+} //TimePicker.prototype.normalize
+
+
+/**
+ * Measure the range of minutes.
+ */
+TimePicker.prototype.measure = function( type, value, options ) {
+
+ var clock = this
+
+ // If it’s anything false-y, set it to the default.
+ if ( !value ) {
+ value = type == 'min' ? [ 0, 0 ] : [ HOURS_IN_DAY - 1, MINUTES_IN_HOUR - 1 ]
+ }
+
+ // If it’s a literal true, or an integer, make it relative to now.
+ else if ( value === true || _.isInteger( value ) ) {
+ value = clock.now( type, value, options )
+ }
+
+ // If it’s an object already, just normalize it.
+ else if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) {
+ value = clock.normalize( type, value.pick, options )
+ }
+
+ return value
+} ///TimePicker.prototype.measure
+
+
+/**
+ * Validate an object as enabled.
+ */
+TimePicker.prototype.validate = function( type, timeObject, options ) {
+
+ var clock = this,
+ interval = options && options.interval ? options.interval : clock.item.interval
+
+ // Check if the object is disabled.
+ if ( clock.disabled( timeObject ) ) {
+
+ // Shift with the interval until we reach an enabled time.
+ timeObject = clock.shift( timeObject, interval )
+ }
+
+ // Scope the object into range.
+ timeObject = clock.scope( timeObject )
+
+ // Do a second check to see if we landed on a disabled min/max.
+ // In that case, shift using the opposite interval as before.
+ if ( clock.disabled( timeObject ) ) {
+ timeObject = clock.shift( timeObject, interval * -1 )
+ }
+
+ // Return the final object.
+ return timeObject
+} //TimePicker.prototype.validate
+
+
+/**
+ * Check if an object is disabled.
+ */
+TimePicker.prototype.disabled = function( timeToVerify ) {
+
+ var clock = this,
+
+ // Filter through the disabled times to check if this is one.
+ isDisabledMatch = clock.item.disable.filter( function( timeToDisable ) {
+
+ // If the time is a number, match the hours.
+ if ( _.isInteger( timeToDisable ) ) {
+ return timeToVerify.hour == timeToDisable
+ }
+
+ // If it’s an array, create the object and match the times.
+ if ( $.isArray( timeToDisable ) || _.isDate( timeToDisable ) ) {
+ return timeToVerify.pick == clock.create( timeToDisable ).pick
+ }
+
+ // If it’s an object, match a time within the “from” and “to” range.
+ if ( $.isPlainObject( timeToDisable ) ) {
+ return clock.withinRange( timeToDisable, timeToVerify )
+ }
+ })
+
+ // If this time matches a disabled time, confirm it’s not inverted.
+ isDisabledMatch = isDisabledMatch.length && !isDisabledMatch.filter(function( timeToDisable ) {
+ return $.isArray( timeToDisable ) && timeToDisable[2] == 'inverted' ||
+ $.isPlainObject( timeToDisable ) && timeToDisable.inverted
+ }).length
+
+ // If the clock is "enabled" flag is flipped, flip the condition.
+ return clock.item.enable === -1 ? !isDisabledMatch : isDisabledMatch ||
+ timeToVerify.pick < clock.item.min.pick ||
+ timeToVerify.pick > clock.item.max.pick
+} //TimePicker.prototype.disabled
+
+
+/**
+ * Shift an object by an interval until we reach an enabled object.
+ */
+TimePicker.prototype.shift = function( timeObject, interval ) {
+
+ var clock = this,
+ minLimit = clock.item.min.pick,
+ maxLimit = clock.item.max.pick/*,
+ safety = 1000*/
+
+ interval = interval || clock.item.interval
+
+ // Keep looping as long as the time is disabled.
+ while ( /*safety &&*/ clock.disabled( timeObject ) ) {
+
+ /*safety -= 1
+ if ( !safety ) {
+ throw 'Fell into an infinite loop while shifting to ' + timeObject.hour + ':' + timeObject.mins + '.'
+ }*/
+
+ // Increase/decrease the time by the interval and keep looping.
+ timeObject = clock.create( timeObject.pick += interval )
+
+ // If we've looped beyond the limits, break out of the loop.
+ if ( timeObject.pick <= minLimit || timeObject.pick >= maxLimit ) {
+ break
+ }
+ }
+
+ // Return the final object.
+ return timeObject
+} //TimePicker.prototype.shift
+
+
+/**
+ * Scope an object to be within range of min and max.
+ */
+TimePicker.prototype.scope = function( timeObject ) {
+ var minLimit = this.item.min.pick,
+ maxLimit = this.item.max.pick
+ return this.create( timeObject.pick > maxLimit ? maxLimit : timeObject.pick < minLimit ? minLimit : timeObject )
+} //TimePicker.prototype.scope
+
+
+/**
+ * Parse a string into a usable type.
+ */
+TimePicker.prototype.parse = function( type, value, options ) {
+
+ var hour, minutes, isPM, item, parseValue,
+ clock = this,
+ parsingObject = {}
+
+ // If it’s already parsed, we’re good.
+ if ( !value || typeof value != 'string' ) {
+ return value
+ }
+
+ // We need a `.format` to parse the value with.
+ if ( !( options && options.format ) ) {
+ options = options || {}
+ options.format = clock.settings.format
+ }
+
+ // Convert the format into an array and then map through it.
+ clock.formats.toArray( options.format ).map( function( label ) {
+
+ var
+ substring,
+
+ // Grab the formatting label.
+ formattingLabel = clock.formats[ label ],
+
+ // The format length is from the formatting label function or the
+ // label length without the escaping exclamation (!) mark.
+ formatLength = formattingLabel ?
+ _.trigger( formattingLabel, clock, [ value, parsingObject ] ) :
+ label.replace( /^!/, '' ).length
+
+ // If there's a format label, split the value up to the format length.
+ // Then add it to the parsing object with appropriate label.
+ if ( formattingLabel ) {
+ substring = value.substr( 0, formatLength )
+ parsingObject[ label ] = substring.match(/^\d+$/) ? +substring : substring
+ }
+
+ // Update the time value as the substring from format length to end.
+ value = value.substr( formatLength )
+ })
+
+ // Grab the hour and minutes from the parsing object.
+ for ( item in parsingObject ) {
+ parseValue = parsingObject[item]
+ if ( _.isInteger(parseValue) ) {
+ if ( item.match(/^(h|hh)$/i) ) {
+ hour = parseValue
+ if ( item == 'h' || item == 'hh' ) {
+ hour %= 12
+ }
+ }
+ else if ( item == 'i' ) {
+ minutes = parseValue
+ }
+ }
+ else if ( item.match(/^a$/i) && parseValue.match(/^p/i) && ('h' in parsingObject || 'hh' in parsingObject) ) {
+ isPM = true
+ }
+ }
+
+ // Calculate it in minutes and return.
+ return (isPM ? hour + 12 : hour) * MINUTES_IN_HOUR + minutes
+} //TimePicker.prototype.parse
+
+
+/**
+ * Various formats to display the object in.
+ */
+TimePicker.prototype.formats = {
+
+ h: function( string, timeObject ) {
+
+ // If there's string, then get the digits length.
+ // Otherwise return the selected hour in "standard" format.
+ return string ? _.digits( string ) : timeObject.hour % HOURS_TO_NOON || HOURS_TO_NOON
+ },
+ hh: function( string, timeObject ) {
+
+ // If there's a string, then the length is always 2.
+ // Otherwise return the selected hour in "standard" format with a leading zero.
+ return string ? 2 : _.lead( timeObject.hour % HOURS_TO_NOON || HOURS_TO_NOON )
+ },
+ H: function( string, timeObject ) {
+
+ // If there's string, then get the digits length.
+ // Otherwise return the selected hour in "military" format as a string.
+ return string ? _.digits( string ) : '' + ( timeObject.hour % 24 )
+ },
+ HH: function( string, timeObject ) {
+
+ // If there's string, then get the digits length.
+ // Otherwise return the selected hour in "military" format with a leading zero.
+ return string ? _.digits( string ) : _.lead( timeObject.hour % 24 )
+ },
+ i: function( string, timeObject ) {
+
+ // If there's a string, then the length is always 2.
+ // Otherwise return the selected minutes.
+ return string ? 2 : _.lead( timeObject.mins )
+ },
+ a: function( string, timeObject ) {
+
+ // If there's a string, then the length is always 4.
+ // Otherwise check if it's more than "noon" and return either am/pm.
+ return string ? 4 : MINUTES_IN_DAY / 2 > timeObject.time % MINUTES_IN_DAY ? 'a.m.' : 'p.m.'
+ },
+ A: function( string, timeObject ) {
+
+ // If there's a string, then the length is always 2.
+ // Otherwise check if it's more than "noon" and return either am/pm.
+ return string ? 2 : MINUTES_IN_DAY / 2 > timeObject.time % MINUTES_IN_DAY ? 'AM' : 'PM'
+ },
+
+ // Create an array by splitting the formatting string passed.
+ toArray: function( formatString ) { return formatString.split( /(h{1,2}|H{1,2}|i|a|A|!.)/g ) },
+
+ // Format an object into a string using the formatting options.
+ toString: function ( formatString, itemObject ) {
+ var clock = this
+ return clock.formats.toArray( formatString ).map( function( label ) {
+ return _.trigger( clock.formats[ label ], clock, [ 0, itemObject ] ) || label.replace( /^!/, '' )
+ }).join( '' )
+ }
+} //TimePicker.prototype.formats
+
+
+
+
+/**
+ * Check if two time units are the exact.
+ */
+TimePicker.prototype.isTimeExact = function( one, two ) {
+
+ var clock = this
+
+ // When we’re working with minutes, do a direct comparison.
+ if (
+ ( _.isInteger( one ) && _.isInteger( two ) ) ||
+ ( typeof one == 'boolean' && typeof two == 'boolean' )
+ ) {
+ return one === two
+ }
+
+ // When we’re working with time representations, compare the “pick” value.
+ if (
+ ( _.isDate( one ) || $.isArray( one ) ) &&
+ ( _.isDate( two ) || $.isArray( two ) )
+ ) {
+ return clock.create( one ).pick === clock.create( two ).pick
+ }
+
+ // When we’re working with range objects, compare the “from” and “to”.
+ if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
+ return clock.isTimeExact( one.from, two.from ) && clock.isTimeExact( one.to, two.to )
+ }
+
+ return false
+}
+
+
+/**
+ * Check if two time units overlap.
+ */
+TimePicker.prototype.isTimeOverlap = function( one, two ) {
+
+ var clock = this
+
+ // When we’re working with an integer, compare the hours.
+ if ( _.isInteger( one ) && ( _.isDate( two ) || $.isArray( two ) ) ) {
+ return one === clock.create( two ).hour
+ }
+ if ( _.isInteger( two ) && ( _.isDate( one ) || $.isArray( one ) ) ) {
+ return two === clock.create( one ).hour
+ }
+
+ // When we’re working with range objects, check if the ranges overlap.
+ if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
+ return clock.overlapRanges( one, two )
+ }
+
+ return false
+}
+
+
+/**
+ * Flip the “enabled” state.
+ */
+TimePicker.prototype.flipEnable = function(val) {
+ var itemObject = this.item
+ itemObject.enable = val || (itemObject.enable == -1 ? 1 : -1)
+}
+
+
+/**
+ * Mark a collection of times as “disabled”.
+ */
+TimePicker.prototype.deactivate = function( type, timesToDisable ) {
+
+ var clock = this,
+ disabledItems = clock.item.disable.slice(0)
+
+
+ // If we’re flipping, that’s all we need to do.
+ if ( timesToDisable == 'flip' ) {
+ clock.flipEnable()
+ }
+
+ else if ( timesToDisable === false ) {
+ clock.flipEnable(1)
+ disabledItems = []
+ }
+
+ else if ( timesToDisable === true ) {
+ clock.flipEnable(-1)
+ disabledItems = []
+ }
+
+ // Otherwise go through the times to disable.
+ else {
+
+ timesToDisable.map(function( unitToDisable ) {
+
+ var matchFound
+
+ // When we have disabled items, check for matches.
+ // If something is matched, immediately break out.
+ for ( var index = 0; index < disabledItems.length; index += 1 ) {
+ if ( clock.isTimeExact( unitToDisable, disabledItems[index] ) ) {
+ matchFound = true
+ break
+ }
+ }
+
+ // If nothing was found, add the validated unit to the collection.
+ if ( !matchFound ) {
+ if (
+ _.isInteger( unitToDisable ) ||
+ _.isDate( unitToDisable ) ||
+ $.isArray( unitToDisable ) ||
+ ( $.isPlainObject( unitToDisable ) && unitToDisable.from && unitToDisable.to )
+ ) {
+ disabledItems.push( unitToDisable )
+ }
+ }
+ })
+ }
+
+ // Return the updated collection.
+ return disabledItems
+} //TimePicker.prototype.deactivate
+
+
+/**
+ * Mark a collection of times as “enabled”.
+ */
+TimePicker.prototype.activate = function( type, timesToEnable ) {
+
+ var clock = this,
+ disabledItems = clock.item.disable,
+ disabledItemsCount = disabledItems.length
+
+ // If we’re flipping, that’s all we need to do.
+ if ( timesToEnable == 'flip' ) {
+ clock.flipEnable()
+ }
+
+ else if ( timesToEnable === true ) {
+ clock.flipEnable(1)
+ disabledItems = []
+ }
+
+ else if ( timesToEnable === false ) {
+ clock.flipEnable(-1)
+ disabledItems = []
+ }
+
+ // Otherwise go through the disabled times.
+ else {
+
+ timesToEnable.map(function( unitToEnable ) {
+
+ var matchFound,
+ disabledUnit,
+ index,
+ isRangeMatched
+
+ // Go through the disabled items and try to find a match.
+ for ( index = 0; index < disabledItemsCount; index += 1 ) {
+
+ disabledUnit = disabledItems[index]
+
+ // When an exact match is found, remove it from the collection.
+ if ( clock.isTimeExact( disabledUnit, unitToEnable ) ) {
+ matchFound = disabledItems[index] = null
+ isRangeMatched = true
+ break
+ }
+
+ // When an overlapped match is found, add the “inverted” state to it.
+ else if ( clock.isTimeOverlap( disabledUnit, unitToEnable ) ) {
+ if ( $.isPlainObject( unitToEnable ) ) {
+ unitToEnable.inverted = true
+ matchFound = unitToEnable
+ }
+ else if ( $.isArray( unitToEnable ) ) {
+ matchFound = unitToEnable
+ if ( !matchFound[2] ) matchFound.push( 'inverted' )
+ }
+ else if ( _.isDate( unitToEnable ) ) {
+ matchFound = [ unitToEnable.getFullYear(), unitToEnable.getMonth(), unitToEnable.getDate(), 'inverted' ]
+ }
+ break
+ }
+ }
+
+ // If a match was found, remove a previous duplicate entry.
+ if ( matchFound ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
+ if ( clock.isTimeExact( disabledItems[index], unitToEnable ) ) {
+ disabledItems[index] = null
+ break
+ }
+ }
+
+ // In the event that we’re dealing with an overlap of range times,
+ // make sure there are no “inverted” times because of it.
+ if ( isRangeMatched ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
+ if ( clock.isTimeOverlap( disabledItems[index], unitToEnable ) ) {
+ disabledItems[index] = null
+ break
+ }
+ }
+
+ // If something is still matched, add it into the collection.
+ if ( matchFound ) {
+ disabledItems.push( matchFound )
+ }
+ })
+ }
+
+ // Return the updated collection.
+ return disabledItems.filter(function( val ) { return val != null })
+} //TimePicker.prototype.activate
+
+
+/**
+ * The division to use for the range intervals.
+ */
+TimePicker.prototype.i = function( type, value/*, options*/ ) {
+ return _.isInteger( value ) && value > 0 ? value : this.item.interval
+}
+
+
+/**
+ * Create a string for the nodes in the picker.
+ */
+TimePicker.prototype.nodes = function( isOpen ) {
+
+ var
+ clock = this,
+ settings = clock.settings,
+ selectedObject = clock.item.select,
+ highlightedObject = clock.item.highlight,
+ viewsetObject = clock.item.view,
+ disabledCollection = clock.item.disable
+
+ return _.node(
+ 'ul',
+ _.group({
+ min: clock.item.min.pick,
+ max: clock.item.max.pick,
+ i: clock.item.interval,
+ node: 'li',
+ item: function( loopedTime ) {
+ loopedTime = clock.create( loopedTime )
+ var timeMinutes = loopedTime.pick,
+ isSelected = selectedObject && selectedObject.pick == timeMinutes,
+ isHighlighted = highlightedObject && highlightedObject.pick == timeMinutes,
+ isDisabled = disabledCollection && clock.disabled( loopedTime )
+ return [
+ _.trigger( clock.formats.toString, clock, [ _.trigger( settings.formatLabel, clock, [ loopedTime ] ) || settings.format, loopedTime ] ),
+ (function( klasses ) {
+
+ if ( isSelected ) {
+ klasses.push( settings.klass.selected )
+ }
+
+ if ( isHighlighted ) {
+ klasses.push( settings.klass.highlighted )
+ }
+
+ if ( viewsetObject && viewsetObject.pick == timeMinutes ) {
+ klasses.push( settings.klass.viewset )
+ }
+
+ if ( isDisabled ) {
+ klasses.push( settings.klass.disabled )
+ }
+
+ return klasses.join( ' ' )
+ })( [ settings.klass.listItem ] ),
+ 'data-pick=' + loopedTime.pick + ' ' + _.ariaAttr({
+ role: 'option',
+ selected: isSelected && clock.$node.val() === _.trigger(
+ clock.formats.toString,
+ clock,
+ [ settings.format, loopedTime ]
+ ) ? true : null,
+ activedescendant: isHighlighted ? true : null,
+ disabled: isDisabled ? true : null
+ })
+ ]
+ }
+ }) +
+
+ // * For Firefox forms to submit, make sure to set the button’s `type` attribute as “button”.
+ _.node(
+ 'li',
+ _.node(
+ 'button',
+ settings.clear,
+ settings.klass.buttonClear,
+ 'type=button data-clear=1' + ( isOpen ? '' : ' disabled' ) + ' ' +
+ _.ariaAttr({ controls: clock.$node[0].id })
+ ),
+ '', _.ariaAttr({ role: 'presentation' })
+ ),
+ settings.klass.list,
+ _.ariaAttr({ role: 'listbox', controls: clock.$node[0].id })
+ )
+} //TimePicker.prototype.nodes
+
+
+
+
+
+
+
+/* ==========================================================================
+ Extend the picker to add the component with the defaults.
+ ========================================================================== */
+
+TimePicker.defaults = (function( prefix ) {
+
+ return {
+
+ // Clear
+ clear: 'Clear',
+
+ // The format to show on the `input` element
+ format: 'h:i A',
+
+ // The interval between each time
+ interval: 30,
+
+ // Classes
+ klass: {
+
+ picker: prefix + ' ' + prefix + '--time',
+ holder: prefix + '__holder',
+
+ list: prefix + '__list',
+ listItem: prefix + '__list-item',
+
+ disabled: prefix + '__list-item--disabled',
+ selected: prefix + '__list-item--selected',
+ highlighted: prefix + '__list-item--highlighted',
+ viewset: prefix + '__list-item--viewset',
+ now: prefix + '__list-item--now',
+
+ buttonClear: prefix + '__button--clear'
+ }
+ }
+})( Picker.klasses().picker )
+
+
+
+
+
+/**
+ * Extend the picker to add the time picker.
+ */
+Picker.extend( 'pickatime', TimePicker )
+
+
+}));
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/_variables.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/_variables.less
new file mode 100755
index 0000000..c62577c
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/_variables.less
@@ -0,0 +1,208 @@
+
+// ==========================================================================
+// $VARIABLES
+// ==========================================================================
+
+
+//
+// Base colors
+//
+@blue: #0089ec;
+@blue-hover: #b1dcfb;
+@black: #000;
+@white: #fff;
+
+
+//
+// Backgrounds
+//
+@bg-white: @white;
+@bg-grey-light: #f2f2f2;
+
+
+//
+// Borders
+//
+@border-grey: #777;
+@border-grey-light: #ddd;
+@border-select: darken( @border-grey-light, 15% );
+
+
+//
+// Buttons
+//
+@clear-red: #e20;
+
+
+
+
+
+//
+// Picker base
+//
+
+// Make sure nothing is above the picker.
+@picker-z-index: 10000;
+
+// Animation speeds.
+@speed-animate-in: .15s;
+
+// Focused input border color.
+@input-active-border: @blue;
+
+// Typography.
+@base-font-size: 16px;
+@base-line-height: 1.2;
+
+// Corners.
+@picker-border-radius: 5px;
+
+// Drop shadows.
+@picker-box-shadow: 0 12px 36px 16px rgba(0,0,0,.24);
+@picker-box-shadow-light: 0 6px 18px 1px rgba(0,0,0,.12);
+
+// Height breakpoints.
+@breakpoint-tiny: 26.5em; // 424px @ 16px
+@breakpoint-small: 33.875em; // 542px @ 16px
+@breakpoint-medium: 40.125em; // 642px @ 16px
+@breakpoint-large: 46.75em; // 748px @ 16px
+
+// Width breakpoints.
+@breakpoint-width-tiny: 24.5em; // 392px @ 16px
+
+
+
+
+//
+// Date picker options
+//
+
+// The year and weekday labels.
+@year-weekday-label: #999;
+
+// “Today” tag indicators.
+@blue-tag: #0059bc;
+@disabled-tag: #aaa;
+
+// Disabled things.. such as days, month nav, etc.
+@disabled-things-bg: #f5f5f5;
+@disabled-things-text: #ddd;
+@disabled-highlighted-things-bg: #bbb;
+
+
+
+
+
+//
+// Theme configurations
+//
+
+// The “default” min & max widths.
+@picker-min-width: 256px;
+@picker-max-width: 666px;
+
+// The time picker min & max widths.
+@time-min-width: @picker-min-width;
+@time-max-width: 320px;
+
+// The “classic” theme settings.
+@classic-max-width: @picker-max-width - 200px;
+@classic-min-width: @picker-min-width - 80px;
+@classic-max-height: 25em;
+@classic-box-shadow: 0 6px 18px 1px rgba(0,0,0,.12);
+
+
+
+
+
+
+
+
+// ==========================================================================
+// $MIXINS
+// ==========================================================================
+
+
+//
+// Common picker item states
+//
+
+// Highlighted.
+.picker-item-highlighted () {
+ border-color: @blue;
+}
+
+// Hovered.
+.picker-item-hovered () {
+ cursor: pointer;
+ color: @black;
+ background: @blue-hover;
+}
+
+// Selected.
+.picker-item-selected () {
+ background: @blue;
+ color: @white;
+}
+
+// Disabled.
+.picker-item-disabled () {
+ background: @disabled-things-bg;
+ border-color: @disabled-things-bg;
+ color: @disabled-things-text;
+ cursor: default;
+}
+
+
+
+
+//
+// Opacity
+//
+.opacity( @decimal ) {
+ @percent: @decimal * 100;
+ -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=@{percent})";
+ filter: ~"alpha(opacity=@{percent})";
+ -moz-opacity: @decimal;
+ opacity: @decimal;
+}
+
+
+
+//
+// Vendor prefixes
+//
+.box-shadow ( @rest... ) {
+ -webkit-box-shadow: @rest;
+ -moz-box-shadow: @rest;
+ box-shadow: @rest;
+}
+.box-sizing ( @rest... ) {
+ -webkit-box-sizing: @rest;
+ -moz-box-sizing: @rest;
+ box-sizing: @rest;
+}
+.border-radius ( @rest... ) {
+ -webkit-border-radius: @rest;
+ -moz-border-radius: @rest;
+ border-radius: @rest;
+}
+.transition ( ... ) {
+ -webkit-transition: @arguments;
+ -moz-transition: @arguments;
+ transition: @arguments;
+}
+.transform ( @rest... ) {
+ -webkit-transform: @rest;
+ -moz-transform: @rest;
+ transform: @rest;
+}
+.user-select ( @rest... ) {
+ -webkit-user-select: @rest;
+ -moz-user-select: @rest;
+ -ms-user-select: @rest;
+ user-select: @rest;
+}
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/base.date.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/base.date.less
new file mode 100755
index 0000000..021158e
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/base.date.less
@@ -0,0 +1,311 @@
+
+/* ==========================================================================
+ $BASE-DATE-PICKER
+ ========================================================================== */
+
+@import "_variables.less";
+
+
+/**
+ * The picker box.
+ */
+.picker__box {
+ padding: 0 1em;
+}
+
+
+/**
+ * The header containing the month and year stuff.
+ */
+.picker__header {
+ text-align: center;
+ position: relative;
+ margin-top: .75em;
+}
+
+
+/**
+ * The month and year labels.
+ */
+.picker__month,
+.picker__year {
+ font-weight: 500;
+ display: inline-block;
+ margin-left: .25em;
+ margin-right: .25em;
+}
+.picker__year {
+ color: @year-weekday-label;
+ font-size: .8em;
+ font-style: italic;
+}
+
+
+/**
+ * The month and year selectors.
+ */
+.picker__select--month,
+.picker__select--year {
+ border: 1px solid @border-select;
+ height: 2em;
+ padding: .5em; // For firefox
+ margin-left: .25em;
+ margin-right: .25em;
+
+ // For `tiny` width screens, move it up a bit.
+ @media ( min-width: @breakpoint-width-tiny ) {
+ margin-top: -.5em;
+ }
+}
+.picker__select--month {
+ width: 35%;
+}
+.picker__select--year {
+ width: 22.5%;
+}
+.picker__select--month:focus,
+.picker__select--year:focus {
+ border-color: @blue;
+}
+
+
+/**
+ * The month navigation buttons.
+ */
+.picker__nav--prev,
+.picker__nav--next {
+ position: absolute;
+ padding: .5em 1.25em;
+ width: 1em;
+ height: 1em;
+ box-sizing: content-box;
+ top: -.25em;
+
+ // For `tiny` width screens, move it up a bit.
+ @media ( min-width: @breakpoint-width-tiny ) {
+ top: -.33em;
+ }
+}
+.picker__nav--prev {
+ left: -1em;
+ padding-right: 1.25em;
+
+ // For `tiny` width screens, increase the padding a bit.
+ @media ( min-width: @breakpoint-width-tiny ) {
+ padding-right: 1.5em;
+ }
+}
+.picker__nav--next {
+ right: -1em;
+ padding-left: 1.25em;
+
+ // For `tiny` width screens, increase the padding a bit.
+ @media ( min-width: @breakpoint-width-tiny ) {
+ padding-left: 1.5em;
+ }
+}
+.picker__nav--prev:before,
+.picker__nav--next:before {
+ content: " ";
+ border-top: .5em solid transparent;
+ border-bottom: .5em solid transparent;
+ border-right: .75em solid @black;
+ width: 0;
+ height: 0;
+ display: block;
+ margin: 0 auto;
+}
+.picker__nav--next:before {
+ border-right: 0;
+ border-left: .75em solid @black;
+}
+
+// Hovered date picker items.
+.picker__nav--prev:hover,
+.picker__nav--next:hover {
+ .picker-item-hovered;
+}
+
+// Disabled month nav.
+.picker__nav--disabled,
+.picker__nav--disabled:hover,
+.picker__nav--disabled:before,
+.picker__nav--disabled:before:hover {
+ cursor: default;
+ background: none;
+ border-right-color: @disabled-things-bg;
+ border-left-color: @disabled-things-bg;
+}
+
+
+
+
+/**
+ * The calendar table of dates
+ */
+.picker__table {
+ text-align: center;
+ border-collapse: collapse;
+ border-spacing: 0;
+ table-layout: fixed;
+ font-size: inherit;
+ width: 100%;
+ margin-top: .75em;
+ margin-bottom: .5em;
+
+ // For `small` screens, increase the spacing a tad.
+ @media ( min-height: @breakpoint-small ) {
+ margin-bottom: .75em;
+ }
+}
+
+// Remove browser stylings on a table cell.
+.picker__table td {
+ margin: 0;
+ padding: 0;
+}
+
+
+/**
+ * The weekday labels
+ */
+.picker__weekday {
+ width: 14.285714286%; // 100/7
+ font-size: .75em;
+ padding-bottom: .25em;
+ color: @year-weekday-label;
+ font-weight: 500;
+
+ /* Increase the spacing a tad */
+ @media ( min-height: @breakpoint-small ) {
+ padding-bottom: .5em;
+ }
+}
+
+
+/**
+ * The days on the calendar
+ */
+.picker__day {
+ padding: .3125em 0;
+ font-weight: 200;
+ border: 1px solid transparent;
+}
+
+// Today.
+.picker__day--today {
+ position: relative;
+}
+.picker__day--today:before {
+ content: " ";
+ position: absolute;
+ top: 2px;
+ right: 2px;
+ width: 0;
+ height: 0;
+ border-top: .5em solid @blue-tag;
+ border-left: .5em solid transparent;
+}
+
+// Disabled day.
+.picker__day--disabled:before {
+ border-top-color: @disabled-tag;
+}
+
+// Out of focus days.
+.picker__day--outfocus {
+ color: @disabled-things-text;
+}
+
+// Hovered date picker items.
+.picker__day--infocus:hover,
+.picker__day--outfocus:hover {
+ .picker-item-hovered;
+}
+
+// Highlighted and hovered/focused dates.
+.picker__day--highlighted {
+ .picker-item-highlighted;
+}
+.picker__day--highlighted:hover,
+.picker--focused .picker__day--highlighted {
+ .picker-item-hovered;
+}
+
+// Selected and hovered/focused dates.
+.picker__day--selected,
+.picker__day--selected:hover,
+.picker--focused .picker__day--selected {
+ .picker-item-selected;
+}
+
+// Disabled dates.
+.picker__day--disabled,
+.picker__day--disabled:hover {
+ .picker-item-disabled;
+}
+
+// Disabled and highlighted dates.
+.picker__day--highlighted.picker__day--disabled,
+.picker__day--highlighted.picker__day--disabled:hover {
+ background: @disabled-highlighted-things-bg;
+}
+
+
+/**
+ * The footer containing the "today" and "clear" buttons.
+ */
+.picker__footer {
+ text-align: center;
+}
+
+// Today and clear buttons.
+.picker__button--today,
+.picker__button--clear {
+ border: 1px solid @white;
+ background: @white;
+ font-size: .8em;
+ padding: .66em 0;
+ font-weight: bold;
+ width: 50%;
+ display: inline-block;
+ vertical-align: bottom;
+}
+.picker__button--today:hover,
+.picker__button--clear:hover {
+ .picker-item-hovered;
+ border-bottom-color: @blue-hover;
+}
+.picker__button--today:focus,
+.picker__button--clear:focus {
+ background: @blue-hover;
+ border-color: @blue;
+ outline: none;
+}
+
+// Today and clear “indicators”.
+.picker__button--today:before,
+.picker__button--clear:before {
+ position: relative;
+ display: inline-block;
+ height: 0;
+}
+.picker__button--today:before {
+ content: " ";
+ margin-right: .45em;
+ top: -.05em;
+ width: 0;
+ border-top: .66em solid @blue-tag;
+ border-left: .66em solid transparent;
+}
+.picker__button--clear:before {
+ content: "\D7"; // ×
+ margin-right: .35em;
+ top: -.1em;
+ color: @clear-red;
+ vertical-align: top;
+ font-size: 1.1em;
+}
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/base.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/base.less
new file mode 100755
index 0000000..4ca710e
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/base.less
@@ -0,0 +1,55 @@
+
+/* ==========================================================================
+ $BASE-PICKER
+ ========================================================================== */
+
+@import "_variables.less";
+
+
+/**
+ * Note: the root picker element should *NOT* be styled more than what’s here.
+ */
+.picker {
+
+ // The base font stylings.
+ font-size: @base-font-size;
+ text-align: left;
+ line-height: @base-line-height;
+ color: @black;
+
+ // The picker shouldn’t affect or be affected by elements around it.
+ position: absolute;
+ z-index: @picker-z-index;
+
+ // The picker shouldn’t be selectable.
+ .user-select( none );
+}
+
+
+/**
+ * The picker input element.
+ */
+.picker__input {
+ cursor: default;
+}
+
+
+/**
+ * When the picker is opened, the input element is “activated”.
+ */
+.picker__input.picker__input--active {
+ border-color: @input-active-border;
+}
+
+
+/**
+ * The holder is the only “scrollable” top-level container element.
+ */
+.picker__holder {
+ width: 100%;
+ overflow-y: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/base.time.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/base.time.less
new file mode 100755
index 0000000..5dfaa54
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/base.time.less
@@ -0,0 +1,118 @@
+
+/* ==========================================================================
+ $BASE-TIME-PICKER
+ ========================================================================== */
+
+@import "_variables.less";
+
+
+/**
+ * The list of times.
+ */
+.picker__list {
+ list-style: none;
+ padding: 0.75em 0 4.2em;
+ margin: 0;
+}
+
+
+/**
+ * The times on the clock.
+ */
+.picker__list-item {
+ border-bottom: 1px solid @border-grey-light;
+ border-top: 1px solid @border-grey-light;
+ margin-bottom: -1px; // Prevent border from doubling up.
+ position: relative;
+ background: @bg-white;
+ padding: .75em 1.25em;
+
+ // For `large` screens, reduce the padding to show more in view.
+ @media ( min-height: @breakpoint-large ) {
+ padding: .5em 1em;
+ }
+}
+
+/* Hovered time */
+.picker__list-item:hover {
+ .picker-item-hovered;
+ border-color: @blue;
+ z-index: 10;
+}
+
+/* Highlighted and hovered/focused time */
+.picker__list-item--highlighted {
+ .picker-item-highlighted;
+ z-index: 10;
+}
+.picker__list-item--highlighted:hover,
+.picker--focused .picker__list-item--highlighted {
+ .picker-item-hovered;
+}
+
+/* Selected and hovered/focused time */
+.picker__list-item--selected,
+.picker__list-item--selected:hover,
+.picker--focused .picker__list-item--selected {
+ .picker-item-selected;
+ z-index: 10;
+}
+
+/* Disabled time */
+.picker__list-item--disabled,
+.picker__list-item--disabled:hover,
+.picker--focused .picker__list-item--disabled {
+ .picker-item-disabled;
+ border-color: @border-grey-light;
+ z-index: auto;
+}
+
+
+
+
+/**
+ * The clear button
+ */
+.picker--time {
+
+ .picker__button--clear {
+ display: block;
+ width: 80%;
+ margin: 1em auto 0;
+ padding: 1em 1.25em;
+
+ background: none;
+ border: 0;
+
+ font-weight: 500;
+ font-size: .67em;
+ text-align: center;
+ text-transform: uppercase;
+ color: #666;
+ }
+
+ .picker__button--clear:hover,
+ .picker__button--clear:focus {
+ .picker-item-hovered;
+ background: @clear-red;
+ border-color: @clear-red;
+ cursor: pointer;
+ color: @white;
+ outline: none;
+ }
+
+ .picker__button--clear:before {
+ top: -.25em;
+ color: #666;
+ font-size: 1.25em;
+ font-weight: bold;
+ }
+
+ .picker__button--clear:hover:before,
+ .picker__button--clear:focus:before {
+ color: @white;
+ }
+}
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/classic.date.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/classic.date.less
new file mode 100755
index 0000000..a8f834e
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/classic.date.less
@@ -0,0 +1,9 @@
+
+/* ==========================================================================
+ $CLASSIC-DATE-PICKER
+ ========================================================================== */
+
+@import "_variables.less";
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/classic.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/classic.less
new file mode 100755
index 0000000..af0b326
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/classic.less
@@ -0,0 +1,119 @@
+/*!
+ * Classic picker styling for pickadate.js
+ * Demo: http://amsul.github.io/pickadate.js
+ */
+
+@import "_variables.less";
+
+
+/**
+ * Note: the root picker element should *NOT* be styled more than what’s here.
+ */
+.picker {
+
+ // Make it full-width so that it doesn’t collapse.
+ width: 100%;
+}
+
+
+
+/**
+ * The holder is the base of the picker.
+ */
+.picker__holder {
+
+ // The base stylings.
+ position: absolute;
+ background: @bg-white;
+
+ // Add a light border - except top & bottom to let it collapse.
+ border: 1px solid lighten( @border-grey, 20% );
+ border-top-width: 0;
+ border-bottom-width: 0;
+
+ // Round the bottom corners.
+ .border-radius( 0 0 @picker-border-radius @picker-border-radius );
+
+ // Let’s not go 100% + 2px.
+ .box-sizing( border-box );
+
+ // Specify the min & max widths.
+ min-width: @classic-min-width;
+ max-width: @classic-max-width;
+
+ // Hide everything to begin with.
+ max-height: 0;
+ .opacity( 0 );
+
+ // Tilt the picker.
+ .transform( translateY( -1em ) perspective( 600px ) rotateX( 10deg ) );
+
+ // Everything should be smoothly animated – the height & border should wait till the rest is done.
+ -webkit-transition: -webkit-transform @speed-animate-in ease-out,
+ opacity @speed-animate-in ease-out,
+ max-height 0s @speed-animate-in,
+ border-width 0s @speed-animate-in;
+ -moz-transition: -moz-transform @speed-animate-in ease-out,
+ opacity @speed-animate-in ease-out,
+ max-height 0s @speed-animate-in,
+ border-width 0s @speed-animate-in;
+ transition: transform @speed-animate-in ease-out,
+ opacity @speed-animate-in ease-out,
+ max-height 0s @speed-animate-in,
+ border-width 0s @speed-animate-in;
+}
+
+
+
+/**
+ * The frame and wrap work together to ensure that
+ * clicks within the picker don’t reach the holder.
+ */
+.picker__frame {
+ padding: 1px;
+}
+.picker__wrap {
+ margin: -1px;
+}
+
+
+
+/**
+ * When the picker opens...
+ */
+.picker--opened {
+
+ .picker__holder {
+
+ // Reveal the content.
+ max-height: @classic-max-height;
+ .opacity( 1 );
+
+ // Expand the top & bottom borders.
+ border-top-width: 1px;
+ border-bottom-width: 1px;
+
+ // Straighten the picker.
+ .transform( translateY( 0 ) perspective( 600px ) rotateX( 0 ) );
+
+ // Everything should be smoothly animated – except the height & border.
+ -webkit-transition: -webkit-transform @speed-animate-in ease-out,
+ opacity @speed-animate-in ease-out,
+ max-height 0s,
+ border-width 0s;
+ -moz-transition: -moz-transform @speed-animate-in ease-out,
+ opacity @speed-animate-in ease-out,
+ max-height 0s,
+ border-width 0s;
+ transition: transform @speed-animate-in ease-out,
+ opacity @speed-animate-in ease-out,
+ max-height 0s,
+ border-width 0s;
+
+ // Add a light shadow.
+ .box-shadow( @classic-box-shadow );
+ }
+}
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/classic.time.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/classic.time.less
new file mode 100755
index 0000000..615adfa
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/classic.time.less
@@ -0,0 +1,49 @@
+
+/* ==========================================================================
+ $CLASSIC-TIME-PICKER
+ ========================================================================== */
+
+@import "_variables.less";
+
+
+/**
+ * Note: the root picker element should __NOT__ be styled
+ * more than what’s here. Style the `.picker__holder` instead.
+ */
+.picker--time {
+
+ // Adjust the min & max widths.
+ min-width: @time-min-width;
+ max-width: @time-max-width;
+}
+
+
+/**
+ * The holder is the base of the picker.
+ */
+.picker--time .picker__holder {
+
+ // Add a slight background color.
+ background: @bg-grey-light;
+
+ // For `medium` screens, reduce the font-size a bit to get more in view.
+ @media ( min-height: @breakpoint-medium ) {
+ font-size: .875em;
+ }
+}
+
+
+/**
+ * The box contains the list of times.
+ */
+.picker--time .picker__box {
+
+ // Remove any stylings overflowing from the date picker.
+ padding: 0;
+
+ // Make the “viewset” time position relative to the box.
+ position: relative;
+}
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/default.date.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/default.date.less
new file mode 100755
index 0000000..5636ec5
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/default.date.less
@@ -0,0 +1,9 @@
+
+/* ==========================================================================
+ $DEFAULT-DATE-PICKER
+ ========================================================================== */
+
+@import "_variables.less";
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/default.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/default.less
new file mode 100755
index 0000000..cadffc8
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/default.less
@@ -0,0 +1,243 @@
+/*!
+ * Default mobile-first, responsive styling for pickadate.js
+ * Demo: http://amsul.github.io/pickadate.js
+ */
+
+@import "_variables.less";
+
+
+/**
+ * Note: the root picker element should *NOT* be styled more than what’s here.
+ */
+.picker {}
+
+
+/**
+ * Make the holder and frame fullscreen.
+ */
+.picker__holder,
+.picker__frame {
+ bottom: 0;
+ left: 0;
+ right: 0;
+
+ // Nudge everything off-screen to begin with.
+ top: 100%;
+}
+
+
+/**
+ * The holder should overlay the entire screen.
+ */
+.picker__holder {
+
+ // Fill the screen and fix the position.
+ position: fixed;
+
+ // Fade out the background, then immediately shift the holder out of view.
+ @transition: background @speed-animate-in ease-out, top 0s @speed-animate-in;
+ .transition( @transition );
+}
+
+
+
+/**
+ * The frame that bounds the box contents of the picker.
+ */
+.picker__frame {
+
+ position: absolute;
+
+ // Specify the min & max widths and center align it.
+ margin: 0 auto;
+ min-width: @picker-min-width;
+ max-width: @picker-max-width;
+ width: 100%; // For IE9 & 10 to keep it centered.
+
+ // Hide it to begin with.
+ .opacity( 0 );
+
+ // Animate the frame in and out of view.
+ .transition( all @speed-animate-in ease-out );
+
+ // For `small` screens...
+ @media ( min-height: @breakpoint-small ) {
+
+ // Reveal what’s beyond to allow drop shadows, et al.
+ overflow: visible;
+
+ // Align to the bottom edge instead of top.
+ top: auto;
+ bottom: -100%;
+
+ // Prevent it from overflowing over the top edge.
+ max-height: 80%;
+ }
+
+ // For `medium` screens...
+ @media ( min-height: @breakpoint-medium ) {
+
+ // Move away from the bottom edge.
+ margin-bottom: 7.5%;
+ }
+}
+
+/**
+ * The wrapper sets the stage to vertically align the box contents.
+ */
+.picker__wrap {
+ display: table;
+ width: 100%;
+ height: 100%;
+
+ // For `small` screens, remove the “middle-aligned” styling
+ @media ( min-height: @breakpoint-small ) {
+ display: block;
+ }
+}
+
+
+
+/**
+ * The box contains all the picker contents.
+ */
+.picker__box {
+ background: @bg-white;
+
+ // To start with, vertically align to center
+ display: table-cell;
+ vertical-align: middle;
+
+ // For `tiny` screens, increase the font size a bit
+ @media ( min-height: @breakpoint-tiny ) {
+ font-size: 1.25em;
+ }
+
+ // For `small` screens...
+ @media ( min-height: @breakpoint-small ) {
+
+ // Remove the “middle-aligned” styling
+ display: block;
+
+ // Increase the font size a bit more
+ font-size: 1.33em;
+
+ // Add the borders except the bottom one
+ border: 1px solid @border-grey;
+ border-top-color: lighten( @border-grey, 7% );
+ border-bottom-width: 0;
+
+ // Make ‘em rounded at the top corners
+ .border-radius( @picker-border-radius @picker-border-radius 0 0 );
+
+ // And finally, add a nice shadow
+ .box-shadow( @picker-box-shadow );
+ }
+
+ // For `medium` screens...
+ @media ( min-height: @breakpoint-medium ) {
+
+ // Increase the font size.
+ font-size: 1.5em;
+
+ // Reveal all borders and round all corners.
+ border-bottom-width: 1px;
+ .border-radius( @picker-border-radius );
+ }
+}
+
+
+/**
+ * When the picker opens...
+ */
+.picker--opened {
+
+ // Immediately move the holder to the top edge then fade in an overlay
+ .picker__holder {
+
+ // Move it to the top edge
+ top: 0;
+
+ // Show a translucent black background (order is important for IE)
+ background: transparent;
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)"; // IE8
+ zoom: 1;
+ background: rgba(0,0,0,.32); // Normal browsers
+
+ // Animate in the background
+ @transition: background @speed-animate-in ease-out;
+ .transition( @transition );
+ }
+
+
+ // Smoothly move the content to the top edge while fading it in
+ .picker__frame {
+
+ // Move to the top edge
+ top: 0;
+
+ // Ånd then reveal the content
+ .opacity( 1 );
+
+ // For `small` screens, move to the bottom edge instead
+ @media ( min-height: @breakpoint-small ) {
+ top: auto;
+ bottom: 0;
+ }
+ }
+}
+
+
+
+
+
+
+/**
+ * For `large` screens, transform into an inline picker.
+ */
+// @include min-screen( large ) {
+
+// .picker {
+// width: 100%;
+// }
+
+// .picker__holder,
+// .picker--opened .picker__holder {
+// background: @white;
+// @include prefix( transition, all @speed-animate-in ease-out );
+// }
+
+// .picker__holder {
+// font-size: 12px;
+// position: relative;
+// max-height: 0;
+// border: 1px solid transparent;
+// @include prefix( border-radius, @picker-border-radius );
+// @include prefix( box-sizing, border-box );
+// }
+// .picker--opened .picker__holder {
+// @include picker-holder-open;
+// @include prefix( box-shadow, @picker-box-shadow-light );
+// }
+
+// .picker__frame,
+// .picker--opened .picker__frame {
+// max-width: none !important;
+// }
+
+// .picker__frame {
+// position: initial;
+// margin: 0;
+// @include opacity( 1 );
+// }
+
+// .picker__box {
+// border: 0;
+// margin-top: 0;
+// @include prefix( border-radius, 0 );
+// @include prefix( box-shadow, none );
+// }
+// }
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/default.time.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/default.time.less
new file mode 100755
index 0000000..3120cb6
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/default.time.less
@@ -0,0 +1,41 @@
+
+/* ==========================================================================
+ $DEFAULT-TIME-PICKER
+ ========================================================================== */
+
+@import "_variables.less";
+
+
+/**
+ * The frame the bounds the time picker.
+ */
+.picker--time .picker__frame {
+
+ // Adjust the min & max widths.
+ min-width: @time-min-width;
+ max-width: @time-max-width;
+}
+
+
+/**
+ * The picker box.
+ */
+.picker--time .picker__box {
+
+ // Keep the font-size small to show more in view.
+ font-size: 1em;
+
+ // Add a slight background color.
+ background: @bg-grey-light;
+
+ // Remove the side paddings.
+ padding: 0;
+
+ // For `medium` screens, move it away from the bottom edge of the screen.
+ @media ( min-height: @breakpoint-medium ) {
+ margin-bottom: 5em;
+ }
+}
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/rtl.less b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/rtl.less
new file mode 100755
index 0000000..01ec53f
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes-source/rtl.less
@@ -0,0 +1,38 @@
+/*!
+ * Styling for RTL (right-to-left) languages using pickadate.js
+ */
+
+@import "_variables.less";
+
+
+/**
+ * Switch the direction - only really necessary if
+ * it hasn’t already been applied higher up in the DOM.
+ */
+.picker {
+ direction: rtl;
+}
+
+
+/**
+ * Flip around the “next” and “previous” buttons.
+ */
+.picker__nav--next {
+ right: auto;
+ left: -1em;
+}
+.picker__nav--prev {
+ left: auto;
+ right: -1em;
+}
+.picker__nav--next:before {
+ border-left: 0;
+ border-right: .75em solid @black;
+}
+.picker__nav--prev:before {
+ border-right: 0;
+ border-left: .75em solid @black;
+}
+
+
+
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes/classic.css b/htrace-core/src/web/lib/pickadate-3.5.2/themes/classic.css
new file mode 100755
index 0000000..a7f799c
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes/classic.css
@@ -0,0 +1,109 @@
+/* ==========================================================================
+ $BASE-PICKER
+ ========================================================================== */
+/**
+ * Note: the root picker element should *NOT* be styled more than what’s here.
+ */
+.picker {
+ font-size: 16px;
+ text-align: left;
+ line-height: 1.2;
+ color: #000000;
+ position: absolute;
+ z-index: 10000;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+/**
+ * The picker input element.
+ */
+.picker__input {
+ cursor: default;
+}
+/**
+ * When the picker is opened, the input element is “activated”.
+ */
+.picker__input.picker__input--active {
+ border-color: #0089ec;
+}
+/**
+ * The holder is the only “scrollable” top-level container element.
+ */
+.picker__holder {
+ width: 100%;
+ overflow-y: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+/*!
+ * Classic picker styling for pickadate.js
+ * Demo: http://amsul.github.io/pickadate.js
+ */
+/**
+ * Note: the root picker element should *NOT* be styled more than what’s here.
+ */
+.picker {
+ width: 100%;
+}
+/**
+ * The holder is the base of the picker.
+ */
+.picker__holder {
+ position: absolute;
+ background: #ffffff;
+ border: 1px solid #aaaaaa;
+ border-top-width: 0;
+ border-bottom-width: 0;
+ -webkit-border-radius: 0 0 5px 5px;
+ -moz-border-radius: 0 0 5px 5px;
+ border-radius: 0 0 5px 5px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ min-width: 176px;
+ max-width: 466px;
+ max-height: 0;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
+ filter: alpha(opacity=0);
+ -moz-opacity: 0;
+ opacity: 0;
+ -webkit-transform: translateY(-1em) perspective(600px) rotateX(10deg);
+ -moz-transform: translateY(-1em) perspective(600px) rotateX(10deg);
+ transform: translateY(-1em) perspective(600px) rotateX(10deg);
+ -webkit-transition: -webkit-transform 0.15s ease-out, opacity 0.15s ease-out, max-height 0s 0.15s, border-width 0s 0.15s;
+ -moz-transition: -moz-transform 0.15s ease-out, opacity 0.15s ease-out, max-height 0s 0.15s, border-width 0s 0.15s;
+ transition: transform 0.15s ease-out, opacity 0.15s ease-out, max-height 0s 0.15s, border-width 0s 0.15s;
+}
+/**
+ * The frame and wrap work together to ensure that
+ * clicks within the picker don’t reach the holder.
+ */
+.picker__frame {
+ padding: 1px;
+}
+.picker__wrap {
+ margin: -1px;
+}
+/**
+ * When the picker opens...
+ */
+.picker--opened .picker__holder {
+ max-height: 25em;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
+ filter: alpha(opacity=100);
+ -moz-opacity: 1;
+ opacity: 1;
+ border-top-width: 1px;
+ border-bottom-width: 1px;
+ -webkit-transform: translateY(0) perspective(600px) rotateX(0);
+ -moz-transform: translateY(0) perspective(600px) rotateX(0);
+ transform: translateY(0) perspective(600px) rotateX(0);
+ -webkit-transition: -webkit-transform 0.15s ease-out, opacity 0.15s ease-out, max-height 0s, border-width 0s;
+ -moz-transition: -moz-transform 0.15s ease-out, opacity 0.15s ease-out, max-height 0s, border-width 0s;
+ transition: transform 0.15s ease-out, opacity 0.15s ease-out, max-height 0s, border-width 0s;
+ -webkit-box-shadow: 0 6px 18px 1px rgba(0, 0, 0, 0.12);
+ -moz-box-shadow: 0 6px 18px 1px rgba(0, 0, 0, 0.12);
+ box-shadow: 0 6px 18px 1px rgba(0, 0, 0, 0.12);
+}
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes/classic.date.css b/htrace-core/src/web/lib/pickadate-3.5.2/themes/classic.date.css
new file mode 100755
index 0000000..ebcf910
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes/classic.date.css
@@ -0,0 +1,278 @@
+/* ==========================================================================
+ $BASE-DATE-PICKER
+ ========================================================================== */
+/**
+ * The picker box.
+ */
+.picker__box {
+ padding: 0 1em;
+}
+/**
+ * The header containing the month and year stuff.
+ */
+.picker__header {
+ text-align: center;
+ position: relative;
+ margin-top: .75em;
+}
+/**
+ * The month and year labels.
+ */
+.picker__month,
+.picker__year {
+ font-weight: 500;
+ display: inline-block;
+ margin-left: .25em;
+ margin-right: .25em;
+}
+.picker__year {
+ color: #999999;
+ font-size: .8em;
+ font-style: italic;
+}
+/**
+ * The month and year selectors.
+ */
+.picker__select--month,
+.picker__select--year {
+ border: 1px solid #b7b7b7;
+ height: 2em;
+ padding: .5em;
+ margin-left: .25em;
+ margin-right: .25em;
+}
+@media (min-width: 24.5em) {
+ .picker__select--month,
+ .picker__select--year {
+ margin-top: -0.5em;
+ }
+}
+.picker__select--month {
+ width: 35%;
+}
+.picker__select--year {
+ width: 22.5%;
+}
+.picker__select--month:focus,
+.picker__select--year:focus {
+ border-color: #0089ec;
+}
+/**
+ * The month navigation buttons.
+ */
+.picker__nav--prev,
+.picker__nav--next {
+ position: absolute;
+ padding: .5em 1.25em;
+ width: 1em;
+ height: 1em;
+ box-sizing: content-box;
+ top: -0.25em;
+}
+@media (min-width: 24.5em) {
+ .picker__nav--prev,
+ .picker__nav--next {
+ top: -0.33em;
+ }
+}
+.picker__nav--prev {
+ left: -1em;
+ padding-right: 1.25em;
+}
+@media (min-width: 24.5em) {
+ .picker__nav--prev {
+ padding-right: 1.5em;
+ }
+}
+.picker__nav--next {
+ right: -1em;
+ padding-left: 1.25em;
+}
+@media (min-width: 24.5em) {
+ .picker__nav--next {
+ padding-left: 1.5em;
+ }
+}
+.picker__nav--prev:before,
+.picker__nav--next:before {
+ content: " ";
+ border-top: .5em solid transparent;
+ border-bottom: .5em solid transparent;
+ border-right: 0.75em solid #000000;
+ width: 0;
+ height: 0;
+ display: block;
+ margin: 0 auto;
+}
+.picker__nav--next:before {
+ border-right: 0;
+ border-left: 0.75em solid #000000;
+}
+.picker__nav--prev:hover,
+.picker__nav--next:hover {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+}
+.picker__nav--disabled,
+.picker__nav--disabled:hover,
+.picker__nav--disabled:before,
+.picker__nav--disabled:before:hover {
+ cursor: default;
+ background: none;
+ border-right-color: #f5f5f5;
+ border-left-color: #f5f5f5;
+}
+/**
+ * The calendar table of dates
+ */
+.picker__table {
+ text-align: center;
+ border-collapse: collapse;
+ border-spacing: 0;
+ table-layout: fixed;
+ font-size: inherit;
+ width: 100%;
+ margin-top: .75em;
+ margin-bottom: .5em;
+}
+@media (min-height: 33.875em) {
+ .picker__table {
+ margin-bottom: .75em;
+ }
+}
+.picker__table td {
+ margin: 0;
+ padding: 0;
+}
+/**
+ * The weekday labels
+ */
+.picker__weekday {
+ width: 14.285714286%;
+ font-size: .75em;
+ padding-bottom: .25em;
+ color: #999999;
+ font-weight: 500;
+ /* Increase the spacing a tad */
+}
+@media (min-height: 33.875em) {
+ .picker__weekday {
+ padding-bottom: .5em;
+ }
+}
+/**
+ * The days on the calendar
+ */
+.picker__day {
+ padding: .3125em 0;
+ font-weight: 200;
+ border: 1px solid transparent;
+}
+.picker__day--today {
+ position: relative;
+}
+.picker__day--today:before {
+ content: " ";
+ position: absolute;
+ top: 2px;
+ right: 2px;
+ width: 0;
+ height: 0;
+ border-top: 0.5em solid #0059bc;
+ border-left: .5em solid transparent;
+}
+.picker__day--disabled:before {
+ border-top-color: #aaaaaa;
+}
+.picker__day--outfocus {
+ color: #dddddd;
+}
+.picker__day--infocus:hover,
+.picker__day--outfocus:hover {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+}
+.picker__day--highlighted {
+ border-color: #0089ec;
+}
+.picker__day--highlighted:hover,
+.picker--focused .picker__day--highlighted {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+}
+.picker__day--selected,
+.picker__day--selected:hover,
+.picker--focused .picker__day--selected {
+ background: #0089ec;
+ color: #ffffff;
+}
+.picker__day--disabled,
+.picker__day--disabled:hover {
+ background: #f5f5f5;
+ border-color: #f5f5f5;
+ color: #dddddd;
+ cursor: default;
+}
+.picker__day--highlighted.picker__day--disabled,
+.picker__day--highlighted.picker__day--disabled:hover {
+ background: #bbbbbb;
+}
+/**
+ * The footer containing the "today" and "clear" buttons.
+ */
+.picker__footer {
+ text-align: center;
+}
+.picker__button--today,
+.picker__button--clear {
+ border: 1px solid #ffffff;
+ background: #ffffff;
+ font-size: .8em;
+ padding: .66em 0;
+ font-weight: bold;
+ width: 50%;
+ display: inline-block;
+ vertical-align: bottom;
+}
+.picker__button--today:hover,
+.picker__button--clear:hover {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+ border-bottom-color: #b1dcfb;
+}
+.picker__button--today:focus,
+.picker__button--clear:focus {
+ background: #b1dcfb;
+ border-color: #0089ec;
+ outline: none;
+}
+.picker__button--today:before,
+.picker__button--clear:before {
+ position: relative;
+ display: inline-block;
+ height: 0;
+}
+.picker__button--today:before {
+ content: " ";
+ margin-right: .45em;
+ top: -0.05em;
+ width: 0;
+ border-top: 0.66em solid #0059bc;
+ border-left: .66em solid transparent;
+}
+.picker__button--clear:before {
+ content: "\D7";
+ margin-right: .35em;
+ top: -0.1em;
+ color: #ee2200;
+ vertical-align: top;
+ font-size: 1.1em;
+}
+
+/* ==========================================================================
+ $CLASSIC-DATE-PICKER
+ ========================================================================== */
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes/classic.time.css b/htrace-core/src/web/lib/pickadate-3.5.2/themes/classic.time.css
new file mode 100755
index 0000000..8737c78
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes/classic.time.css
@@ -0,0 +1,131 @@
+/* ==========================================================================
+ $BASE-TIME-PICKER
+ ========================================================================== */
+/**
+ * The list of times.
+ */
+.picker__list {
+ list-style: none;
+ padding: 0.75em 0 4.2em;
+ margin: 0;
+}
+/**
+ * The times on the clock.
+ */
+.picker__list-item {
+ border-bottom: 1px solid #dddddd;
+ border-top: 1px solid #dddddd;
+ margin-bottom: -1px;
+ position: relative;
+ background: #ffffff;
+ padding: .75em 1.25em;
+}
+@media (min-height: 46.75em) {
+ .picker__list-item {
+ padding: .5em 1em;
+ }
+}
+/* Hovered time */
+.picker__list-item:hover {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+ border-color: #0089ec;
+ z-index: 10;
+}
+/* Highlighted and hovered/focused time */
+.picker__list-item--highlighted {
+ border-color: #0089ec;
+ z-index: 10;
+}
+.picker__list-item--highlighted:hover,
+.picker--focused .picker__list-item--highlighted {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+}
+/* Selected and hovered/focused time */
+.picker__list-item--selected,
+.picker__list-item--selected:hover,
+.picker--focused .picker__list-item--selected {
+ background: #0089ec;
+ color: #ffffff;
+ z-index: 10;
+}
+/* Disabled time */
+.picker__list-item--disabled,
+.picker__list-item--disabled:hover,
+.picker--focused .picker__list-item--disabled {
+ background: #f5f5f5;
+ border-color: #f5f5f5;
+ color: #dddddd;
+ cursor: default;
+ border-color: #dddddd;
+ z-index: auto;
+}
+/**
+ * The clear button
+ */
+.picker--time .picker__button--clear {
+ display: block;
+ width: 80%;
+ margin: 1em auto 0;
+ padding: 1em 1.25em;
+ background: none;
+ border: 0;
+ font-weight: 500;
+ font-size: .67em;
+ text-align: center;
+ text-transform: uppercase;
+ color: #666;
+}
+.picker--time .picker__button--clear:hover,
+.picker--time .picker__button--clear:focus {
+ color: #000000;
+ background: #b1dcfb;
+ background: #ee2200;
+ border-color: #ee2200;
+ cursor: pointer;
+ color: #ffffff;
+ outline: none;
+}
+.picker--time .picker__button--clear:before {
+ top: -0.25em;
+ color: #666;
+ font-size: 1.25em;
+ font-weight: bold;
+}
+.picker--time .picker__button--clear:hover:before,
+.picker--time .picker__button--clear:focus:before {
+ color: #ffffff;
+}
+
+/* ==========================================================================
+ $CLASSIC-TIME-PICKER
+ ========================================================================== */
+/**
+ * Note: the root picker element should __NOT__ be styled
+ * more than what’s here. Style the `.picker__holder` instead.
+ */
+.picker--time {
+ min-width: 256px;
+ max-width: 320px;
+}
+/**
+ * The holder is the base of the picker.
+ */
+.picker--time .picker__holder {
+ background: #f2f2f2;
+}
+@media (min-height: 40.125em) {
+ .picker--time .picker__holder {
+ font-size: .875em;
+ }
+}
+/**
+ * The box contains the list of times.
+ */
+.picker--time .picker__box {
+ padding: 0;
+ position: relative;
+}
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes/default.css b/htrace-core/src/web/lib/pickadate-3.5.2/themes/default.css
new file mode 100755
index 0000000..cc903d5
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes/default.css
@@ -0,0 +1,174 @@
+/* ==========================================================================
+ $BASE-PICKER
+ ========================================================================== */
+/**
+ * Note: the root picker element should *NOT* be styled more than what’s here.
+ */
+.picker {
+ font-size: 16px;
+ text-align: left;
+ line-height: 1.2;
+ color: #000000;
+ position: absolute;
+ z-index: 10000;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+/**
+ * The picker input element.
+ */
+.picker__input {
+ cursor: default;
+}
+/**
+ * When the picker is opened, the input element is “activated”.
+ */
+.picker__input.picker__input--active {
+ border-color: #0089ec;
+}
+/**
+ * The holder is the only “scrollable” top-level container element.
+ */
+.picker__holder {
+ width: 100%;
+ overflow-y: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+/*!
+ * Default mobile-first, responsive styling for pickadate.js
+ * Demo: http://amsul.github.io/pickadate.js
+ */
+/**
+ * Note: the root picker element should *NOT* be styled more than what’s here.
+ */
+/**
+ * Make the holder and frame fullscreen.
+ */
+.picker__holder,
+.picker__frame {
+ bottom: 0;
+ left: 0;
+ right: 0;
+ top: 100%;
+}
+/**
+ * The holder should overlay the entire screen.
+ */
+.picker__holder {
+ position: fixed;
+ -webkit-transition: background 0.15s ease-out, top 0s 0.15s;
+ -moz-transition: background 0.15s ease-out, top 0s 0.15s;
+ transition: background 0.15s ease-out, top 0s 0.15s;
+}
+/**
+ * The frame that bounds the box contents of the picker.
+ */
+.picker__frame {
+ position: absolute;
+ margin: 0 auto;
+ min-width: 256px;
+ max-width: 666px;
+ width: 100%;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
+ filter: alpha(opacity=0);
+ -moz-opacity: 0;
+ opacity: 0;
+ -webkit-transition: all 0.15s ease-out;
+ -moz-transition: all 0.15s ease-out;
+ transition: all 0.15s ease-out;
+}
+@media (min-height: 33.875em) {
+ .picker__frame {
+ overflow: visible;
+ top: auto;
+ bottom: -100%;
+ max-height: 80%;
+ }
+}
+@media (min-height: 40.125em) {
+ .picker__frame {
+ margin-bottom: 7.5%;
+ }
+}
+/**
+ * The wrapper sets the stage to vertically align the box contents.
+ */
+.picker__wrap {
+ display: table;
+ width: 100%;
+ height: 100%;
+}
+@media (min-height: 33.875em) {
+ .picker__wrap {
+ display: block;
+ }
+}
+/**
+ * The box contains all the picker contents.
+ */
+.picker__box {
+ background: #ffffff;
+ display: table-cell;
+ vertical-align: middle;
+}
+@media (min-height: 26.5em) {
+ .picker__box {
+ font-size: 1.25em;
+ }
+}
+@media (min-height: 33.875em) {
+ .picker__box {
+ display: block;
+ font-size: 1.33em;
+ border: 1px solid #777777;
+ border-top-color: #898989;
+ border-bottom-width: 0;
+ -webkit-border-radius: 5px 5px 0 0;
+ -moz-border-radius: 5px 5px 0 0;
+ border-radius: 5px 5px 0 0;
+ -webkit-box-shadow: 0 12px 36px 16px rgba(0, 0, 0, 0.24);
+ -moz-box-shadow: 0 12px 36px 16px rgba(0, 0, 0, 0.24);
+ box-shadow: 0 12px 36px 16px rgba(0, 0, 0, 0.24);
+ }
+}
+@media (min-height: 40.125em) {
+ .picker__box {
+ font-size: 1.5em;
+ border-bottom-width: 1px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ }
+}
+/**
+ * When the picker opens...
+ */
+.picker--opened .picker__holder {
+ top: 0;
+ background: transparent;
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)";
+ zoom: 1;
+ background: rgba(0, 0, 0, 0.32);
+ -webkit-transition: background 0.15s ease-out;
+ -moz-transition: background 0.15s ease-out;
+ transition: background 0.15s ease-out;
+}
+.picker--opened .picker__frame {
+ top: 0;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
+ filter: alpha(opacity=100);
+ -moz-opacity: 1;
+ opacity: 1;
+}
+@media (min-height: 33.875em) {
+ .picker--opened .picker__frame {
+ top: auto;
+ bottom: 0;
+ }
+}
+/**
+ * For `large` screens, transform into an inline picker.
+ */
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes/default.date.css b/htrace-core/src/web/lib/pickadate-3.5.2/themes/default.date.css
new file mode 100755
index 0000000..7abfbaa
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes/default.date.css
@@ -0,0 +1,278 @@
+/* ==========================================================================
+ $BASE-DATE-PICKER
+ ========================================================================== */
+/**
+ * The picker box.
+ */
+.picker__box {
+ padding: 0 1em;
+}
+/**
+ * The header containing the month and year stuff.
+ */
+.picker__header {
+ text-align: center;
+ position: relative;
+ margin-top: .75em;
+}
+/**
+ * The month and year labels.
+ */
+.picker__month,
+.picker__year {
+ font-weight: 500;
+ display: inline-block;
+ margin-left: .25em;
+ margin-right: .25em;
+}
+.picker__year {
+ color: #999999;
+ font-size: .8em;
+ font-style: italic;
+}
+/**
+ * The month and year selectors.
+ */
+.picker__select--month,
+.picker__select--year {
+ border: 1px solid #b7b7b7;
+ height: 2em;
+ padding: .5em;
+ margin-left: .25em;
+ margin-right: .25em;
+}
+@media (min-width: 24.5em) {
+ .picker__select--month,
+ .picker__select--year {
+ margin-top: -0.5em;
+ }
+}
+.picker__select--month {
+ width: 35%;
+}
+.picker__select--year {
+ width: 22.5%;
+}
+.picker__select--month:focus,
+.picker__select--year:focus {
+ border-color: #0089ec;
+}
+/**
+ * The month navigation buttons.
+ */
+.picker__nav--prev,
+.picker__nav--next {
+ position: absolute;
+ padding: .5em 1.25em;
+ width: 1em;
+ height: 1em;
+ box-sizing: content-box;
+ top: -0.25em;
+}
+@media (min-width: 24.5em) {
+ .picker__nav--prev,
+ .picker__nav--next {
+ top: -0.33em;
+ }
+}
+.picker__nav--prev {
+ left: -1em;
+ padding-right: 1.25em;
+}
+@media (min-width: 24.5em) {
+ .picker__nav--prev {
+ padding-right: 1.5em;
+ }
+}
+.picker__nav--next {
+ right: -1em;
+ padding-left: 1.25em;
+}
+@media (min-width: 24.5em) {
+ .picker__nav--next {
+ padding-left: 1.5em;
+ }
+}
+.picker__nav--prev:before,
+.picker__nav--next:before {
+ content: " ";
+ border-top: .5em solid transparent;
+ border-bottom: .5em solid transparent;
+ border-right: 0.75em solid #000000;
+ width: 0;
+ height: 0;
+ display: block;
+ margin: 0 auto;
+}
+.picker__nav--next:before {
+ border-right: 0;
+ border-left: 0.75em solid #000000;
+}
+.picker__nav--prev:hover,
+.picker__nav--next:hover {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+}
+.picker__nav--disabled,
+.picker__nav--disabled:hover,
+.picker__nav--disabled:before,
+.picker__nav--disabled:before:hover {
+ cursor: default;
+ background: none;
+ border-right-color: #f5f5f5;
+ border-left-color: #f5f5f5;
+}
+/**
+ * The calendar table of dates
+ */
+.picker__table {
+ text-align: center;
+ border-collapse: collapse;
+ border-spacing: 0;
+ table-layout: fixed;
+ font-size: inherit;
+ width: 100%;
+ margin-top: .75em;
+ margin-bottom: .5em;
+}
+@media (min-height: 33.875em) {
+ .picker__table {
+ margin-bottom: .75em;
+ }
+}
+.picker__table td {
+ margin: 0;
+ padding: 0;
+}
+/**
+ * The weekday labels
+ */
+.picker__weekday {
+ width: 14.285714286%;
+ font-size: .75em;
+ padding-bottom: .25em;
+ color: #999999;
+ font-weight: 500;
+ /* Increase the spacing a tad */
+}
+@media (min-height: 33.875em) {
+ .picker__weekday {
+ padding-bottom: .5em;
+ }
+}
+/**
+ * The days on the calendar
+ */
+.picker__day {
+ padding: .3125em 0;
+ font-weight: 200;
+ border: 1px solid transparent;
+}
+.picker__day--today {
+ position: relative;
+}
+.picker__day--today:before {
+ content: " ";
+ position: absolute;
+ top: 2px;
+ right: 2px;
+ width: 0;
+ height: 0;
+ border-top: 0.5em solid #0059bc;
+ border-left: .5em solid transparent;
+}
+.picker__day--disabled:before {
+ border-top-color: #aaaaaa;
+}
+.picker__day--outfocus {
+ color: #dddddd;
+}
+.picker__day--infocus:hover,
+.picker__day--outfocus:hover {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+}
+.picker__day--highlighted {
+ border-color: #0089ec;
+}
+.picker__day--highlighted:hover,
+.picker--focused .picker__day--highlighted {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+}
+.picker__day--selected,
+.picker__day--selected:hover,
+.picker--focused .picker__day--selected {
+ background: #0089ec;
+ color: #ffffff;
+}
+.picker__day--disabled,
+.picker__day--disabled:hover {
+ background: #f5f5f5;
+ border-color: #f5f5f5;
+ color: #dddddd;
+ cursor: default;
+}
+.picker__day--highlighted.picker__day--disabled,
+.picker__day--highlighted.picker__day--disabled:hover {
+ background: #bbbbbb;
+}
+/**
+ * The footer containing the "today" and "clear" buttons.
+ */
+.picker__footer {
+ text-align: center;
+}
+.picker__button--today,
+.picker__button--clear {
+ border: 1px solid #ffffff;
+ background: #ffffff;
+ font-size: .8em;
+ padding: .66em 0;
+ font-weight: bold;
+ width: 50%;
+ display: inline-block;
+ vertical-align: bottom;
+}
+.picker__button--today:hover,
+.picker__button--clear:hover {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+ border-bottom-color: #b1dcfb;
+}
+.picker__button--today:focus,
+.picker__button--clear:focus {
+ background: #b1dcfb;
+ border-color: #0089ec;
+ outline: none;
+}
+.picker__button--today:before,
+.picker__button--clear:before {
+ position: relative;
+ display: inline-block;
+ height: 0;
+}
+.picker__button--today:before {
+ content: " ";
+ margin-right: .45em;
+ top: -0.05em;
+ width: 0;
+ border-top: 0.66em solid #0059bc;
+ border-left: .66em solid transparent;
+}
+.picker__button--clear:before {
+ content: "\D7";
+ margin-right: .35em;
+ top: -0.1em;
+ color: #ee2200;
+ vertical-align: top;
+ font-size: 1.1em;
+}
+
+/* ==========================================================================
+ $DEFAULT-DATE-PICKER
+ ========================================================================== */
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes/default.time.css b/htrace-core/src/web/lib/pickadate-3.5.2/themes/default.time.css
new file mode 100755
index 0000000..0b159c8
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes/default.time.css
@@ -0,0 +1,125 @@
+/* ==========================================================================
+ $BASE-TIME-PICKER
+ ========================================================================== */
+/**
+ * The list of times.
+ */
+.picker__list {
+ list-style: none;
+ padding: 0.75em 0 4.2em;
+ margin: 0;
+}
+/**
+ * The times on the clock.
+ */
+.picker__list-item {
+ border-bottom: 1px solid #dddddd;
+ border-top: 1px solid #dddddd;
+ margin-bottom: -1px;
+ position: relative;
+ background: #ffffff;
+ padding: .75em 1.25em;
+}
+@media (min-height: 46.75em) {
+ .picker__list-item {
+ padding: .5em 1em;
+ }
+}
+/* Hovered time */
+.picker__list-item:hover {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+ border-color: #0089ec;
+ z-index: 10;
+}
+/* Highlighted and hovered/focused time */
+.picker__list-item--highlighted {
+ border-color: #0089ec;
+ z-index: 10;
+}
+.picker__list-item--highlighted:hover,
+.picker--focused .picker__list-item--highlighted {
+ cursor: pointer;
+ color: #000000;
+ background: #b1dcfb;
+}
+/* Selected and hovered/focused time */
+.picker__list-item--selected,
+.picker__list-item--selected:hover,
+.picker--focused .picker__list-item--selected {
+ background: #0089ec;
+ color: #ffffff;
+ z-index: 10;
+}
+/* Disabled time */
+.picker__list-item--disabled,
+.picker__list-item--disabled:hover,
+.picker--focused .picker__list-item--disabled {
+ background: #f5f5f5;
+ border-color: #f5f5f5;
+ color: #dddddd;
+ cursor: default;
+ border-color: #dddddd;
+ z-index: auto;
+}
+/**
+ * The clear button
+ */
+.picker--time .picker__button--clear {
+ display: block;
+ width: 80%;
+ margin: 1em auto 0;
+ padding: 1em 1.25em;
+ background: none;
+ border: 0;
+ font-weight: 500;
+ font-size: .67em;
+ text-align: center;
+ text-transform: uppercase;
+ color: #666;
+}
+.picker--time .picker__button--clear:hover,
+.picker--time .picker__button--clear:focus {
+ color: #000000;
+ background: #b1dcfb;
+ background: #ee2200;
+ border-color: #ee2200;
+ cursor: pointer;
+ color: #ffffff;
+ outline: none;
+}
+.picker--time .picker__button--clear:before {
+ top: -0.25em;
+ color: #666;
+ font-size: 1.25em;
+ font-weight: bold;
+}
+.picker--time .picker__button--clear:hover:before,
+.picker--time .picker__button--clear:focus:before {
+ color: #ffffff;
+}
+
+/* ==========================================================================
+ $DEFAULT-TIME-PICKER
+ ========================================================================== */
+/**
+ * The frame the bounds the time picker.
+ */
+.picker--time .picker__frame {
+ min-width: 256px;
+ max-width: 320px;
+}
+/**
+ * The picker box.
+ */
+.picker--time .picker__box {
+ font-size: 1em;
+ background: #f2f2f2;
+ padding: 0;
+}
+@media (min-height: 40.125em) {
+ .picker--time .picker__box {
+ margin-bottom: 5em;
+ }
+}
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/themes/rtl.css b/htrace-core/src/web/lib/pickadate-3.5.2/themes/rtl.css
new file mode 100755
index 0000000..6de4820
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/themes/rtl.css
@@ -0,0 +1,29 @@
+/*!
+ * Styling for RTL (right-to-left) languages using pickadate.js
+ */
+/**
+ * Switch the direction - only really necessary if
+ * it hasn’t already been applied higher up in the DOM.
+ */
+.picker {
+ direction: rtl;
+}
+/**
+ * Flip around the “next” and “previous” buttons.
+ */
+.picker__nav--next {
+ right: auto;
+ left: -1em;
+}
+.picker__nav--prev {
+ left: auto;
+ right: -1em;
+}
+.picker__nav--next:before {
+ border-left: 0;
+ border-right: 0.75em solid #000000;
+}
+.picker__nav--prev:before {
+ border-right: 0;
+ border-left: 0.75em solid #000000;
+}
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/FORMATTING.md b/htrace-core/src/web/lib/pickadate-3.5.2/translations/FORMATTING.md
new file mode 100755
index 0000000..3efb84a
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/FORMATTING.md
@@ -0,0 +1,7 @@
+### The following convention is used for choosing a format for the translation files:
+
+1. Google for “Microsoft Style Guide LANGUAGE COUNTRY”.
+2. Check the standard suggestions for Long Date Formats.
+3. Set this as the `format` option using [pickadate’s formatting rules](http://amsul.ca/pickadate.js/date.htm#formatting-rules).
+
+Make sure `formatSubmit` is always `yyyy/mm/dd` to ensure our servers always get the value formatted the same.
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/NAMING.md b/htrace-core/src/web/lib/pickadate-3.5.2/translations/NAMING.md
new file mode 100755
index 0000000..2376d6f
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/NAMING.md
@@ -0,0 +1,21 @@
+### The following convention is used for naming the translation files:
+
+```
+LANGUAGE_COUNTRY.js
+```
+
+#### Where:
+
+```
+LANGUAGE = The lowercase ISO 639-1 language code.
+```
+
+> See http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+
+```
+COUNTRY = The uppercase ISO 3166-1 country code.
+```
+
+> See http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements
+
+When there is no `COUNTRY` in the filename, it is assumed the generic language is used in multiple countries.
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/ar.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ar.js
new file mode 100755
index 0000000..173246f
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ar.js
@@ -0,0 +1,12 @@
+// Arabic
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'يناير', 'فبراير', 'مارس', 'ابريل', 'مايو', 'يونيو', 'يوليو', 'اغسطس', 'سبتمبر', 'اكتوبر', 'نوفمبر', 'ديسمبر' ],
+ monthsShort: [ 'يناير', 'فبراير', 'مارس', 'ابريل', 'مايو', 'يونيو', 'يوليو', 'اغسطس', 'سبتمبر', 'اكتوبر', 'نوفمبر', 'ديسمبر' ],
+ weekdaysFull: [ 'الاحد', 'الاثنين', 'الثلاثاء', 'الاربعاء', 'الخميس', 'الجمعة', 'السبت' ],
+ weekdaysShort: [ 'الاحد', 'الاثنين', 'الثلاثاء', 'الاربعاء', 'الخميس', 'الجمعة', 'السبت' ],
+ today: 'اليوم',
+ clear: 'مسح',
+ format: 'yyyy mmmm dd',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/bg_BG.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/bg_BG.js
new file mode 100755
index 0000000..a7b9295
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/bg_BG.js
@@ -0,0 +1,13 @@
+// Bulgarian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'януари','февруари','март','април','май','юни','юли','август','септември','октомври','ноември','декември' ],
+ monthsShort: [ 'янр','фев','мар','апр','май','юни','юли','авг','сеп','окт','ное','дек' ],
+ weekdaysFull: [ 'неделя', 'понеделник', 'вторник', 'сряда', 'четвъртък', 'петък', 'събота' ],
+ weekdaysShort: [ 'нд', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб' ],
+ today: 'днес',
+ clear: 'изтривам',
+ firstDay: 1,
+ format: 'd mmmm yyyy г.',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/bs_BA.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/bs_BA.js
new file mode 100755
index 0000000..cf2a617
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/bs_BA.js
@@ -0,0 +1,13 @@
+// Bosnian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'januar', 'februar', 'mart', 'april', 'maj', 'juni', 'juli', 'august', 'septembar', 'oktobar', 'novembar', 'decembar' ],
+ monthsShort: [ 'jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec' ],
+ weekdaysFull: [ 'nedjelja', 'ponedjeljak', 'utorak', 'srijeda', 'cetvrtak', 'petak', 'subota' ],
+ weekdaysShort: [ 'ne', 'po', 'ut', 'sr', 'če', 'pe', 'su' ],
+ today: 'danas',
+ clear: 'izbrisati',
+ firstDay: 1,
+ format: 'dd. mmmm yyyy.',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/ca_ES.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ca_ES.js
new file mode 100755
index 0000000..03b8197
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ca_ES.js
@@ -0,0 +1,13 @@
+// Catalan
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'Gener', 'Febrer', 'Març', 'Abril', 'Maig', 'juny', 'Juliol', 'Agost', 'Setembre', 'Octubre', 'Novembre', 'Desembre' ],
+ monthsShort: [ 'Gen', 'Feb', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Oct', 'Nov', 'Des' ],
+ weekdaysFull: [ 'diumenge', 'dilluns', 'dimarts', 'dimecres', 'dijous', 'divendres', 'dissabte' ],
+ weekdaysShort: [ 'diu', 'dil', 'dim', 'dmc', 'dij', 'div', 'dis' ],
+ today: 'avui',
+ clear: 'esborrar',
+ firstDay: 1,
+ format: 'dddd d !de mmmm !de yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/cs_CZ.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/cs_CZ.js
new file mode 100755
index 0000000..2c69b85
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/cs_CZ.js
@@ -0,0 +1,13 @@
+// Czech
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec' ],
+ monthsShort: [ 'led', 'úno', 'bře', 'dub', 'kvě', 'čer', 'čvc', 'srp', 'zář', 'říj', 'lis', 'pro' ],
+ weekdaysFull: [ 'neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota' ],
+ weekdaysShort: [ 'ne', 'po', 'út', 'st', 'čt', 'pá', 'so' ],
+ today: 'dnes',
+ clear: 'vymazat',
+ firstDay: 1,
+ format: 'd. mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/da_DK.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/da_DK.js
new file mode 100755
index 0000000..12defbf
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/da_DK.js
@@ -0,0 +1,13 @@
+// Danish
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'januar', 'februar', 'marts', 'april', 'maj', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'december' ],
+ monthsShort: [ 'jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec' ],
+ weekdaysFull: [ 'søndag', 'mandag', 'tirsdag', 'onsdag', 'torsdag', 'fredag', 'lørdag' ],
+ weekdaysShort: [ 'søn', 'man', 'tir', 'ons', 'tor', 'fre', 'lør' ],
+ today: 'i dag',
+ clear: 'slet',
+ firstDay: 1,
+ format: 'd. mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/de_DE.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/de_DE.js
new file mode 100755
index 0000000..c42fbc7
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/de_DE.js
@@ -0,0 +1,13 @@
+// German
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember' ],
+ monthsShort: [ 'Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez' ],
+ weekdaysFull: [ 'Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag' ],
+ weekdaysShort: [ 'So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa' ],
+ today: 'Heute',
+ clear: 'Löschen',
+ firstDay: 1,
+ format: 'dddd, dd. mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/el_GR.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/el_GR.js
new file mode 100755
index 0000000..4997296
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/el_GR.js
@@ -0,0 +1,13 @@
+// Greek
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'Ιανουάριος', 'Φεβρουάριος', 'Μάρτιος', 'Απρίλιος', 'Μάιος', 'Ιούνιος', 'Ιούλιος', 'Αύγουστος', 'Σεπτέμβριος', 'Οκτώβριος', 'Νοέμβριος', 'Δεκέμβριος' ],
+ monthsShort: [ 'Ιαν', 'Φεβ', 'Μαρ', 'Απρ', 'Μαι', 'Ιουν', 'Ιουλ', 'Αυγ', 'Σεπ', 'Οκτ', 'Νοε', 'Δεκ' ],
+ weekdaysFull: [ 'Κυριακή', 'Δευτέρα', 'Τρίτη', 'Τετάρτη', 'Πέμπτη', 'Παρασκευή', 'Σάββατο' ],
+ weekdaysShort: [ 'Κυρ', 'Δευ', 'Τρι', 'Τετ', 'Πεμ', 'Παρ', 'Σαβ' ],
+ today: 'σήμερα',
+ clear: 'Διαγραφή',
+ firstDay: 1,
+ format: 'd mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/es_ES.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/es_ES.js
new file mode 100755
index 0000000..e6ba56b
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/es_ES.js
@@ -0,0 +1,13 @@
+// Spanish
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre' ],
+ monthsShort: [ 'ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic' ],
+ weekdaysFull: [ 'domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado' ],
+ weekdaysShort: [ 'dom', 'lun', 'mar', 'mié', 'jue', 'vie', 'sáb' ],
+ today: 'hoy',
+ clear: 'borrar',
+ firstDay: 1,
+ format: 'dddd d !de mmmm !de yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/et_EE.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/et_EE.js
new file mode 100755
index 0000000..9fb3f76
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/et_EE.js
@@ -0,0 +1,13 @@
+// Estonian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'jaanuar', 'veebruar', 'märts', 'aprill', 'mai', 'juuni', 'juuli', 'august', 'september', 'oktoober', 'november', 'detsember' ],
+ monthsShort: [ 'jaan', 'veebr', 'märts', 'apr', 'mai', 'juuni', 'juuli', 'aug', 'sept', 'okt', 'nov', 'dets' ],
+ weekdaysFull: [ 'pühapäev', 'esmaspäev', 'teisipäev', 'kolmapäev', 'neljapäev', 'reede', 'laupäev' ],
+ weekdaysShort: [ 'püh', 'esm', 'tei', 'kol', 'nel', 'ree', 'lau' ],
+ today: 'täna',
+ clear: 'kustutama',
+ firstDay: 1,
+ format: 'd. mmmm yyyy. a',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/eu_ES.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/eu_ES.js
new file mode 100755
index 0000000..19d3ad7
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/eu_ES.js
@@ -0,0 +1,13 @@
+// Basque
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'urtarrila', 'otsaila', 'martxoa', 'apirila', 'maiatza', 'ekaina', 'uztaila', 'abuztua', 'iraila', 'urria', 'azaroa', 'abendua' ],
+ monthsShort: [ 'urt', 'ots', 'mar', 'api', 'mai', 'eka', 'uzt', 'abu', 'ira', 'urr', 'aza', 'abe' ],
+ weekdaysFull: [ 'igandea', 'astelehena', 'asteartea', 'asteazkena', 'osteguna', 'ostirala', 'larunbata' ],
+ weekdaysShort: [ 'ig.', 'al.', 'ar.', 'az.', 'og.', 'or.', 'lr.' ],
+ today: 'gaur',
+ clear: 'garbitu',
+ firstDay: 1,
+ format: 'dddd, yyyy(e)ko mmmmren da',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/fi_FI.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/fi_FI.js
new file mode 100755
index 0000000..702e246
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/fi_FI.js
@@ -0,0 +1,13 @@
+// Finnish
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'tammikuu', 'helmikuu', 'maaliskuu', 'huhtikuu', 'toukokuu', 'kesäkuu', 'heinäkuu', 'elokuu', 'syyskuu', 'lokakuu', 'marraskuu', 'joulukuu' ],
+ monthsShort: [ 'tammi', 'helmi', 'maalis', 'huhti', 'touko', 'kesä', 'heinä', 'elo', 'syys', 'loka', 'marras', 'joulu' ],
+ weekdaysFull: [ 'sunnuntai', 'maanantai', 'tiistai', 'keskiviikko', 'torstai', 'perjantai', 'lauantai' ],
+ weekdaysShort: [ 'su', 'ma', 'ti', 'ke', 'to', 'pe', 'la' ],
+ today: 'tänään',
+ clear: 'tyhjennä',
+ firstDay: 1,
+ format: 'd.m.yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/fr_FR.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/fr_FR.js
new file mode 100755
index 0000000..a056147
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/fr_FR.js
@@ -0,0 +1,13 @@
+// French
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre' ],
+ monthsShort: [ 'Jan', 'Fev', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Aou', 'Sep', 'Oct', 'Nov', 'Dec' ],
+ weekdaysFull: [ 'Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi' ],
+ weekdaysShort: [ 'Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam' ],
+ today: 'Aujourd\'hui',
+ clear: 'Effacer',
+ firstDay: 1,
+ format: 'dd mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/gl_ES.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/gl_ES.js
new file mode 100755
index 0000000..09f213c
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/gl_ES.js
@@ -0,0 +1,13 @@
+// Galician
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'Xaneiro', 'Febreiro', 'Marzo', 'Abril', 'Maio', 'Xuño', 'Xullo', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Decembro' ],
+ monthsShort: [ 'xan', 'feb', 'mar', 'abr', 'mai', 'xun', 'xul', 'ago', 'sep', 'out', 'nov', 'dec' ],
+ weekdaysFull: [ 'domingo', 'luns', 'martes', 'mércores', 'xoves', 'venres', 'sábado' ],
+ weekdaysShort: [ 'dom', 'lun', 'mar', 'mér', 'xov', 'ven', 'sab' ],
+ today: 'hoxe',
+ clear: 'borrar',
+ firstDay: 1,
+ format: 'dddd d !de mmmm !de yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/he_IL.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/he_IL.js
new file mode 100755
index 0000000..7a2a1d5
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/he_IL.js
@@ -0,0 +1,12 @@
+// Hebrew
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר' ],
+ monthsShort: [ 'ינו', 'פבר', 'מרץ', 'אפר', 'מאי', 'יונ', 'יול', 'אוג', 'ספט', 'אוק', 'נוב', 'דצמ' ],
+ weekdaysFull: [ 'יום ראשון', 'יום שני', 'יום שלישי', 'יום רביעי', 'יום חמישי', 'יום ששי', 'יום שבת' ],
+ weekdaysShort: [ 'א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ש' ],
+ today: 'היום',
+ clear: 'למחוק',
+ format: 'yyyy mmmmב d dddd',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/hr_HR.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/hr_HR.js
new file mode 100755
index 0000000..4334ea6
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/hr_HR.js
@@ -0,0 +1,13 @@
+// Croatian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'sijećanj', 'veljača', 'ožujak', 'travanj', 'svibanj', 'lipanj', 'srpanj', 'kolovoz', 'rujan', 'listopad', 'studeni', 'prosinac' ],
+ monthsShort: [ 'sij', 'velj', 'ožu', 'tra', 'svi', 'lip', 'srp', 'kol', 'ruj', 'lis', 'stu', 'pro' ],
+ weekdaysFull: [ 'nedjelja', 'ponedjeljak', 'utorak', 'srijeda', 'četvrtak', 'petak', 'subota' ],
+ weekdaysShort: [ 'ned', 'pon', 'uto', 'sri', 'čet', 'pet', 'sub' ],
+ today: 'danas',
+ clear: 'izbrisati',
+ firstDay: 1,
+ format: 'd. mmmm yyyy.',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/hu_HU.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/hu_HU.js
new file mode 100755
index 0000000..daf8305
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/hu_HU.js
@@ -0,0 +1,13 @@
+// Hungarian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'január', 'február', 'március', 'április', 'május', 'június', 'július', 'augusztus', 'szeptember', 'október', 'november', 'december' ],
+ monthsShort: [ 'jan', 'febr', 'márc', 'ápr', 'máj', 'jún', 'júl', 'aug', 'szept', 'okt', 'nov', 'dec' ],
+ weekdaysFull: [ 'vasárnap', 'hétfő', 'kedd', 'szerda', 'csütörtök', 'péntek', 'szombat' ],
+ weekdaysShort: [ 'V', 'H', 'K', 'SZe', 'CS', 'P', 'SZo' ],
+ today: 'Ma',
+ clear: 'Törlés',
+ firstDay: 1,
+ format: 'yyyy. mmmm dd.',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/id_ID.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/id_ID.js
new file mode 100755
index 0000000..f83efa8
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/id_ID.js
@@ -0,0 +1,13 @@
+// Indonesian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember' ],
+ monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des' ],
+ weekdaysFull: [ 'Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu' ],
+ weekdaysShort: [ 'Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab' ],
+ today: 'hari ini',
+ clear: 'menghapus',
+ firstDay: 1,
+ format: 'd mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/is_IS.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/is_IS.js
new file mode 100755
index 0000000..89afa73
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/is_IS.js
@@ -0,0 +1,13 @@
+// Icelandic
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'janúar', 'febrúar', 'mars', 'apríl', 'maí', 'júní', 'júlí', 'ágúst', 'september', 'október', 'nóvember', 'desember' ],
+ monthsShort: [ 'jan', 'feb', 'mar', 'apr', 'maí', 'jún', 'júl', 'ágú', 'sep', 'okt', 'nóv', 'des' ],
+ weekdaysFull: [ 'sunnudagur', 'mánudagur', 'þriðjudagur', 'miðvikudagur', 'fimmtudagur', 'föstudagur', 'laugardagur' ],
+ weekdaysShort: [ 'sun', 'mán', 'þri', 'mið', 'fim', 'fös', 'lau' ],
+ today: 'Í dag',
+ clear: 'Hreinsa',
+ firstDay: 1,
+ format: 'dd. mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/it_IT.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/it_IT.js
new file mode 100755
index 0000000..77df696
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/it_IT.js
@@ -0,0 +1,13 @@
+// Italian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre' ],
+ monthsShort: [ 'gen', 'feb', 'mar', 'apr', 'mag', 'giu', 'lug', 'ago', 'set', 'ott', 'nov', 'dic' ],
+ weekdaysFull: [ 'domenica', 'lunedì', 'martedì', 'mercoledì', 'giovedì', 'venerdì', 'sabato' ],
+ weekdaysShort: [ 'dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab' ],
+ today: 'oggi',
+ clear: 'cancellare',
+ firstDay: 1,
+ format: 'dddd d mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/ja_JP.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ja_JP.js
new file mode 100755
index 0000000..bc9133f
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ja_JP.js
@@ -0,0 +1,13 @@
+// Japanese
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ '1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月' ],
+ monthsShort: [ '1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月' ],
+ weekdaysFull: [ '日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日' ],
+ weekdaysShort: [ '日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日' ],
+ today: '今日',
+ clear: '消去',
+ firstDay: 1,
+ format: 'yyyy mm dd',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/ko_KR.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ko_KR.js
new file mode 100755
index 0000000..fb525f0
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ko_KR.js
@@ -0,0 +1,13 @@
+// Korean
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ '1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월' ],
+ monthsShort: [ '1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월' ],
+ weekdaysFull: [ '일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일' ],
+ weekdaysShort: [ '일', '월', '화', '수', '목', '금', '토' ],
+ today: '오늘',
+ clear: '취소',
+ firstDay: 1,
+ format: 'yyyy 년 mm 월 dd 일',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/ne_NP.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ne_NP.js
new file mode 100755
index 0000000..3ef4223
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ne_NP.js
@@ -0,0 +1,13 @@
+// Nepali
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'जनवरी', 'फेब्रुअरी', 'मार्च', 'अप्रिल', 'मे', 'जुन', 'जुलाई', 'अगस्त', 'सेप्टेम्बर', 'अक्टोबर', 'नोवेम्बर', 'डिसेम्बर' ],
+ monthsShort: [ 'जन', 'फेब्रु', 'मार्च', 'अप्रिल', 'मे', 'जुन', 'जुल', 'अग', 'सेप्टे', 'अक्टो', 'नोभे', 'डिसे' ],
+ weekdaysFull: [ 'सोमबार', 'मङ्लबार', 'बुधबार', 'बिहीबार', 'शुक्रबार', 'शनिबार', 'आईतबार' ],
+ weekdaysShort: [ 'सोम', 'मंगल्', 'बुध', 'बिही', 'शुक्र', 'शनि', 'आईत' ],
+ numbers: [ '०', '१', '२', '३', '४', '५', '६', '७', '८', '९' ],
+ today: 'आज',
+ clear: 'मेटाउनुहोस्',
+ format: 'dddd, dd mmmm, yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/nl_NL.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/nl_NL.js
new file mode 100755
index 0000000..757b887
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/nl_NL.js
@@ -0,0 +1,13 @@
+// Dutch
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december' ],
+ monthsShort: [ 'jan', 'feb', 'maa', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec' ],
+ weekdaysFull: [ 'zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag' ],
+ weekdaysShort: [ 'zo', 'ma', 'di', 'wo', 'do', 'vr', 'za' ],
+ today: 'vandaag',
+ clear: 'verwijderen',
+ firstDay: 1,
+ format: 'dddd d mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/no_NO.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/no_NO.js
new file mode 100755
index 0000000..e2e0687
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/no_NO.js
@@ -0,0 +1,13 @@
+// Norwegian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'januar', 'februar', 'mars', 'april', 'mai', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'desember' ],
+ monthsShort: [ 'jan', 'feb', 'mar', 'apr', 'mai', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'des' ],
+ weekdaysFull: [ 'søndag', 'mandag', 'tirsdag', 'onsdag', 'torsdag', 'fredag', 'lørdag' ],
+ weekdaysShort: [ 'søn','man','tir', 'ons', 'tor', 'fre', 'lør' ],
+ today: 'i dag',
+ clear: 'nullstill',
+ firstDay: 1,
+ format: 'dd. mmm. yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/pl_PL.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/pl_PL.js
new file mode 100755
index 0000000..cefbf5a
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/pl_PL.js
@@ -0,0 +1,13 @@
+// Polish
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'styczeń', 'luty', 'marzec', 'kwiecień', 'maj', 'czerwiec', 'lipiec', 'sierpień', 'wrzesień', 'październik', 'listopad', 'grudzień' ],
+ monthsShort: [ 'sty', 'lut', 'mar', 'kwi', 'maj', 'cze', 'lip', 'sie', 'wrz', 'paź', 'lis', 'gru' ],
+ weekdaysFull: [ 'niedziela', 'poniedziałek', 'wtorek', 'środa', 'czwartek', 'piątek', 'sobota' ],
+ weekdaysShort: [ 'N', 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'So' ],
+ today: 'dzisiaj',
+ clear: 'usunąć',
+ firstDay: 1,
+ format: 'd mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/pt_BR.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/pt_BR.js
new file mode 100755
index 0000000..b8523e3
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/pt_BR.js
@@ -0,0 +1,12 @@
+// Brazilian Portuguese
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro' ],
+ monthsShort: [ 'jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez' ],
+ weekdaysFull: [ 'domingo', 'segunda-feira', 'terça-feira', 'quarta-feira', 'quinta-feira', 'sexta-feira', 'sábado' ],
+ weekdaysShort: [ 'dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sab' ],
+ today: 'hoje',
+ clear: 'excluir',
+ format: 'dddd, d !de mmmm !de yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/pt_PT.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/pt_PT.js
new file mode 100755
index 0000000..fddbc96
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/pt_PT.js
@@ -0,0 +1,12 @@
+// Portuguese
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro' ],
+ monthsShort: [ 'jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez' ],
+ weekdaysFull: [ 'domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado' ],
+ weekdaysShort: [ 'dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sab' ],
+ today: 'hoje',
+ clear: 'excluir',
+ format: 'd !de mmmm !de yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/ro_RO.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ro_RO.js
new file mode 100755
index 0000000..f06f1c0
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ro_RO.js
@@ -0,0 +1,13 @@
+// Romanian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'ianuarie', 'februarie', 'martie', 'aprilie', 'mai', 'iunie', 'iulie', 'august', 'septembrie', 'octombrie', 'noiembrie', 'decembrie' ],
+ monthsShort: [ 'ian', 'feb', 'mar', 'apr', 'mai', 'iun', 'iul', 'aug', 'sep', 'oct', 'noi', 'dec' ],
+ weekdaysFull: [ 'duminică', 'luni', 'marţi', 'miercuri', 'joi', 'vineri', 'sâmbătă' ],
+ weekdaysShort: [ 'D', 'L', 'Ma', 'Mi', 'J', 'V', 'S' ],
+ today: 'azi',
+ clear: 'șterge',
+ firstDay: 1,
+ format: 'dd mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/ru_RU.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ru_RU.js
new file mode 100755
index 0000000..984dc1f
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/ru_RU.js
@@ -0,0 +1,13 @@
+// Russian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня', 'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря' ],
+ monthsShort: [ 'Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек' ],
+ weekdaysFull: [ 'воскресенье', 'понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота' ],
+ weekdaysShort: [ 'вс', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб' ],
+ today: 'сегодня',
+ clear: 'удалить',
+ firstDay: 1,
+ format: 'd mmmm yyyy г.',
+ formatSubmit: 'yyyy/mm/dd'
+});
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/sk_SK.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/sk_SK.js
new file mode 100755
index 0000000..e243c48
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/sk_SK.js
@@ -0,0 +1,13 @@
+// Slovak
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'január', 'február', 'marec', 'apríl', 'máj', 'jún', 'júl', 'august', 'september', 'október', 'november', 'december' ],
+ monthsShort: [ 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII' ],
+ weekdaysFull: [ 'nedeļľa', 'pondelok', 'utorok', 'streda', 'š̌švrtok', 'piatok', 'sobota' ],
+ weekdaysShort: [ 'Ne', 'Po', 'Ut', 'St', 'Št', 'Pi', 'So' ],
+ today: 'dnes',
+ clear: 'vymazať',
+ firstDay: 1,
+ format: 'd. mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/sl_SI.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/sl_SI.js
new file mode 100755
index 0000000..d20256f
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/sl_SI.js
@@ -0,0 +1,13 @@
+// Slovenian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'januar', 'februar', 'marec', 'april', 'maj', 'junij', 'julij', 'avgust', 'september', 'oktober', 'november', 'december' ],
+ monthsShort: [ 'jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'avg', 'sep', 'okt', 'nov', 'dec' ],
+ weekdaysFull: [ 'nedelja', 'ponedeljek', 'torek', 'sreda', 'četrtek', 'petek', 'sobota' ],
+ weekdaysShort: [ 'ned', 'pon', 'tor', 'sre', 'čet', 'pet', 'sob' ],
+ today: 'danes',
+ clear: 'izbriši',
+ firstDay: 1,
+ format: 'd. mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/sv_SE.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/sv_SE.js
new file mode 100755
index 0000000..ddb9be1
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/sv_SE.js
@@ -0,0 +1,13 @@
+// Swedish
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'januari', 'februari', 'mars', 'april', 'maj', 'juni', 'juli', 'augusti', 'september', 'oktober', 'november', 'december' ],
+ monthsShort: [ 'jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec' ],
+ weekdaysFull: [ 'söndag', 'måndag', 'tisdag', 'onsdag', 'torsdag', 'fredag', 'lördag' ],
+ weekdaysShort: [ 'sön', 'mån', 'tis', 'ons', 'tor', 'fre', 'lör' ],
+ today: 'i dag',
+ clear: 'bort',
+ firstDay: 1,
+ format: 'd/m yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/th_TH.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/th_TH.js
new file mode 100755
index 0000000..ff27dfd
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/th_TH.js
@@ -0,0 +1,12 @@
+// Thai
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม' ],
+ monthsShort: [ 'ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.' ],
+ weekdaysFull: [ 'อาทติย', 'จันทร', 'องัคาร', 'พุธ', 'พฤหสั บดี', 'ศกุร', 'เสาร' ],
+ weekdaysShort: [ 'อ.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.' ],
+ today: 'วันนี้',
+ clear: 'ลบ',
+ format: 'd mmmm yyyy',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/tr_TR.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/tr_TR.js
new file mode 100755
index 0000000..c97a97e
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/tr_TR.js
@@ -0,0 +1,13 @@
+// Turkish
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran', 'Temmuz', 'Ağustos', 'Eylül', 'Ekim', 'Kasım', 'Aralık' ],
+ monthsShort: [ 'Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz', 'Tem', 'Ağu', 'Eyl', 'Eki', 'Kas', 'Ara' ],
+ weekdaysFull: [ 'Pazar', 'Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi' ],
+ weekdaysShort: [ 'Pzr', 'Pzt', 'Sal', 'Çrş', 'Prş', 'Cum', 'Cmt' ],
+ today: 'bugün',
+ clear: 'sil',
+ firstDay: 1,
+ format: 'dd mmmm yyyy dddd',
+ formatSubmit: 'yyyy/mm/dd'
+});
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/uk_UA.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/uk_UA.js
new file mode 100755
index 0000000..c224401
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/uk_UA.js
@@ -0,0 +1,13 @@
+// Ukrainian
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'січень', 'лютий', 'березень', 'квітень', 'травень', 'червень', 'липень', 'серпень', 'вересень', 'жовтень', 'листопад', 'грудень' ],
+ monthsShort: [ 'січ', 'лют', 'бер', 'кві', 'тра', 'чер', 'лип', 'сер', 'вер', 'жов', 'лис', 'гру' ],
+ weekdaysFull: [ 'неділя', 'понеділок', 'вівторок', 'середа', 'четвер', 'п‘ятниця', 'субота' ],
+ weekdaysShort: [ 'нд', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб' ],
+ today: 'сьогодні',
+ clear: 'викреслити',
+ firstDay: 1,
+ format: 'dd mmmm yyyy p.',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/vi_VN.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/vi_VN.js
new file mode 100755
index 0000000..a71888d
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/vi_VN.js
@@ -0,0 +1,11 @@
+// Vietnamese
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ 'Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu', 'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai' ],
+ monthsShort: [ 'Một', 'Hai', 'Ba', 'Tư', 'Năm', 'Sáu', 'Bảy', 'Tám', 'Chín', 'Mưới', 'Mười Một', 'Mười Hai' ],
+ weekdaysFull: [ 'Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy' ],
+ weekdaysShort: [ 'C.Nhật', 'T.Hai', 'T.Ba', 'T.Tư', 'T.Năm', 'T.Sáu', 'T.Bảy' ],
+ today: 'Hôm Nay',
+ clear: 'Xoá',
+ firstDay: 1
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/zh_CN.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/zh_CN.js
new file mode 100755
index 0000000..65e857d
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/zh_CN.js
@@ -0,0 +1,13 @@
+// Simplified Chinese
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ '一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月' ],
+ monthsShort: [ '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二' ],
+ weekdaysFull: [ '星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六' ],
+ weekdaysShort: [ '日', '一', '二', '三', '四', '五', '六' ],
+ today: '今日',
+ clear: '删',
+ firstDay: 1,
+ format: 'yyyy 年 mm 月 dd 日',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file
diff --git a/htrace-core/src/web/lib/pickadate-3.5.2/translations/zh_TW.js b/htrace-core/src/web/lib/pickadate-3.5.2/translations/zh_TW.js
new file mode 100755
index 0000000..f7651d3
--- /dev/null
+++ b/htrace-core/src/web/lib/pickadate-3.5.2/translations/zh_TW.js
@@ -0,0 +1,13 @@
+// Traditional Chinese
+
+jQuery.extend( jQuery.fn.pickadate.defaults, {
+ monthsFull: [ '一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月' ],
+ monthsShort: [ '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二' ],
+ weekdaysFull: [ '星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六' ],
+ weekdaysShort: [ '日', '一', '二', '三', '四', '五', '六' ],
+ today: '今天',
+ clear: '清除',
+ firstDay: 1,
+ format: 'yyyy 年 mm 月 dd 日',
+ formatSubmit: 'yyyy/mm/dd'
+});
\ No newline at end of file