diff options
Diffstat (limited to 'web/js')
-rw-r--r-- | web/js/Chart.min.js | 10 | ||||
-rw-r--r-- | web/js/bootstrap.js | 2317 | ||||
-rw-r--r-- | web/js/bootstrap.min.js | 7 | ||||
-rw-r--r-- | web/js/jquery.datetimepicker.full.js | 3073 | ||||
-rw-r--r-- | web/js/jquery.min.js | 4 | ||||
-rw-r--r-- | web/js/moment.min.js | 7 | ||||
-rw-r--r-- | web/js/nms-admin-pane.js | 99 | ||||
-rw-r--r-- | web/js/nms-color-util.js | 127 | ||||
-rw-r--r-- | web/js/nms-data.js | 429 | ||||
-rw-r--r-- | web/js/nms-dhcp.js | 45 | ||||
-rw-r--r-- | web/js/nms-draw-chart.js | 350 | ||||
-rw-r--r-- | web/js/nms-fetch.js | 38 | ||||
-rw-r--r-- | web/js/nms-info-box.js | 1851 | ||||
-rw-r--r-- | web/js/nms-map-handlers.js | 2137 | ||||
-rw-r--r-- | web/js/nms-map.js | 1189 | ||||
-rw-r--r-- | web/js/nms-nightmode.js | 32 | ||||
-rw-r--r-- | web/js/nms-oplog.js | 527 | ||||
-rw-r--r-- | web/js/nms-search.js | 393 | ||||
-rw-r--r-- | web/js/nms-template.js | 103 | ||||
-rw-r--r-- | web/js/nms-time.js | 231 | ||||
-rw-r--r-- | web/js/nms-types.js | 417 | ||||
-rw-r--r-- | web/js/nms-ui-boxes.js | 512 | ||||
-rw-r--r-- | web/js/nms-ui-switch-summary.js | 107 | ||||
-rw-r--r-- | web/js/nms-ui-switch.js | 616 | ||||
-rw-r--r-- | web/js/nms-ui.js | 33 | ||||
-rw-r--r-- | web/js/nms.js | 1011 | ||||
-rw-r--r-- | web/js/npm.js | 13 |
27 files changed, 5247 insertions, 10431 deletions
diff --git a/web/js/Chart.min.js b/web/js/Chart.min.js deleted file mode 100644 index dbf22c4..0000000 --- a/web/js/Chart.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * Chart.js - * http://chartjs.org/ - * Version: 2.7.2 - * - * Copyright 2018 Chart.js Contributors - * Released under the MIT license - * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md - */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Chart=t()}}(function(){return function t(e,i,n){function a(r,s){if(!i[r]){if(!e[r]){var l="function"==typeof require&&require;if(!s&&l)return l(r,!0);if(o)return o(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var d=i[r]={exports:{}};e[r][0].call(d.exports,function(t){var i=e[r][1][t];return a(i||t)},d,d.exports,t,e,i,n)}return i[r].exports}for(var o="function"==typeof require&&require,r=0;r<n.length;r++)a(n[r]);return a}({1:[function(t,e,i){},{}],2:[function(t,e,i){var n=t(6);function a(t){if(t){var e=[0,0,0],i=1,a=t.match(/^#([a-fA-F0-9]{3})$/i);if(a){a=a[1];for(var o=0;o<e.length;o++)e[o]=parseInt(a[o]+a[o],16)}else if(a=t.match(/^#([a-fA-F0-9]{6})$/i)){a=a[1];for(o=0;o<e.length;o++)e[o]=parseInt(a.slice(2*o,2*o+2),16)}else if(a=t.match(/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(o=0;o<e.length;o++)e[o]=parseInt(a[o+1]);i=parseFloat(a[4])}else if(a=t.match(/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(o=0;o<e.length;o++)e[o]=Math.round(2.55*parseFloat(a[o+1]));i=parseFloat(a[4])}else if(a=t.match(/(\w+)/)){if("transparent"==a[1])return[0,0,0,0];if(!(e=n[a[1]]))return}for(o=0;o<e.length;o++)e[o]=d(e[o],0,255);return i=i||0==i?d(i,0,1):1,e[3]=i,e}}function o(t){if(t){var e=t.match(/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var i=parseFloat(e[4]);return[d(parseInt(e[1]),0,360),d(parseFloat(e[2]),0,100),d(parseFloat(e[3]),0,100),d(isNaN(i)?1:i,0,1)]}}}function r(t){if(t){var e=t.match(/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var i=parseFloat(e[4]);return[d(parseInt(e[1]),0,360),d(parseFloat(e[2]),0,100),d(parseFloat(e[3]),0,100),d(isNaN(i)?1:i,0,1)]}}}function s(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function l(t,e){return"rgba("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%, "+(e||t[3]||1)+")"}function u(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function d(t,e,i){return Math.min(Math.max(e,t),i)}function c(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}e.exports={getRgba:a,getHsla:o,getRgb:function(t){var e=a(t);return e&&e.slice(0,3)},getHsl:function(t){var e=o(t);return e&&e.slice(0,3)},getHwb:r,getAlpha:function(t){var e=a(t);{if(e)return e[3];if(e=o(t))return e[3];if(e=r(t))return e[3]}},hexString:function(t){return"#"+c(t[0])+c(t[1])+c(t[2])},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return s(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:s,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return l(t,e);var i=Math.round(t[0]/255*100),n=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+i+"%, "+n+"%, "+a+"%)"},percentaString:l,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return u(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:u,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return h[t.slice(0,3)]}};var h={};for(var f in n)h[n[f]]=f},{6:6}],3:[function(t,e,i){var n=t(5),a=t(2),o=function(t){return t instanceof o?t:this instanceof o?(this.valid=!1,this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1},void("string"==typeof t?(e=a.getRgba(t))?this.setValues("rgb",e):(e=a.getHsla(t))?this.setValues("hsl",e):(e=a.getHwb(t))&&this.setValues("hwb",e):"object"==typeof t&&(void 0!==(e=t).r||void 0!==e.red?this.setValues("rgb",e):void 0!==e.l||void 0!==e.lightness?this.setValues("hsl",e):void 0!==e.v||void 0!==e.value?this.setValues("hsv",e):void 0!==e.w||void 0!==e.whiteness?this.setValues("hwb",e):void 0===e.c&&void 0===e.cyan||this.setValues("cmyk",e)))):new o(t);var e};o.prototype={isValid:function(){return this.valid},rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t=(t%=360)<0?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return a.hexString(this.values.rgb)},rgbString:function(){return a.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return a.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return a.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return a.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return a.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return a.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return a.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],i=0;i<t.length;i++){var n=t[i]/255;e[i]=n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),i=t.luminosity();return e>i?(e+.05)/(i+.05):(i+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,i=(e[0]+t)%360;return e[0]=i<0?360+i:i,this.setValues("hsl",e),this},mix:function(t,e){var i=this,n=t,a=void 0===e?.5:e,o=2*a-1,r=i.alpha()-n.alpha(),s=((o*r==-1?o:(o+r)/(1+o*r))+1)/2,l=1-s;return this.rgb(s*i.red()+l*n.red(),s*i.green()+l*n.green(),s*i.blue()+l*n.blue()).alpha(i.alpha()*a+n.alpha()*(1-a))},toJSON:function(){return this.rgb()},clone:function(){var t,e,i=new o,n=this.values,a=i.values;for(var r in n)n.hasOwnProperty(r)&&(t=n[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return i}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,i={},n=0;n<t.length;n++)i[t.charAt(n)]=e[t][n];return 1!==e.alpha&&(i.a=e.alpha),i},o.prototype.setValues=function(t,e){var i,a,o=this.values,r=this.spaces,s=this.maxes,l=1;if(this.valid=!0,"alpha"===t)l=e;else if(e.length)o[t]=e.slice(0,t.length),l=e[t.length];else if(void 0!==e[t.charAt(0)]){for(i=0;i<t.length;i++)o[t][i]=e[t.charAt(i)];l=e.a}else if(void 0!==e[r[t][0]]){var u=r[t];for(i=0;i<t.length;i++)o[t][i]=e[u[i]];l=e.alpha}if(o.alpha=Math.max(0,Math.min(1,void 0===l?o.alpha:l)),"alpha"===t)return!1;for(i=0;i<t.length;i++)a=Math.max(0,Math.min(s[t][i],o[t][i])),o[t][i]=Math.round(a);for(var d in r)d!==t&&(o[d]=n[t][d](o[t]));return!0},o.prototype.setSpace=function(t,e){var i=e[0];return void 0===i?this.getValues(t):("number"==typeof i&&(i=Array.prototype.slice.call(e)),this.setValues(t,i),this)},o.prototype.setChannel=function(t,e,i){var n=this.values[t];return void 0===i?n[e]:i===n[e]?this:(n[e]=i,this.setValues(t,n),this)},"undefined"!=typeof window&&(window.Color=o),e.exports=o},{2:2,5:5}],4:[function(t,e,i){function n(t){var e,i,n=t[0]/255,a=t[1]/255,o=t[2]/255,r=Math.min(n,a,o),s=Math.max(n,a,o),l=s-r;return s==r?e=0:n==s?e=(a-o)/l:a==s?e=2+(o-n)/l:o==s&&(e=4+(n-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),i=(r+s)/2,[e,100*(s==r?0:i<=.5?l/(s+r):l/(2-s-r)),100*i]}function a(t){var e,i,n=t[0],a=t[1],o=t[2],r=Math.min(n,a,o),s=Math.max(n,a,o),l=s-r;return i=0==s?0:l/s*1e3/10,s==r?e=0:n==s?e=(a-o)/l:a==s?e=2+(o-n)/l:o==s&&(e=4+(n-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),[e,i,s/255*1e3/10]}function o(t){var e=t[0],i=t[1],a=t[2];return[n(t)[0],100*(1/255*Math.min(e,Math.min(i,a))),100*(a=1-1/255*Math.max(e,Math.max(i,a)))]}function s(t){var e,i=t[0]/255,n=t[1]/255,a=t[2]/255;return[100*((1-i-(e=Math.min(1-i,1-n,1-a)))/(1-e)||0),100*((1-n-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]}function l(t){return C[JSON.stringify(t)]}function u(t){var e=t[0]/255,i=t[1]/255,n=t[2]/255;return[100*(.4124*(e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)+.1805*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)),100*(.2126*e+.7152*i+.0722*n),100*(.0193*e+.1192*i+.9505*n)]}function d(t){var e=u(t),i=e[0],n=e[1],a=e[2];return n/=100,a/=108.883,i=(i/=95.047)>.008856?Math.pow(i,1/3):7.787*i+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(i-n),200*(n-(a=a>.008856?Math.pow(a,1/3):7.787*a+16/116))]}function c(t){var e,i,n,a,o,r=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return[o=255*l,o,o];e=2*l-(i=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(n=r+1/3*-(u-1))<0&&n++,n>1&&n--,o=6*n<1?e+6*(i-e)*n:2*n<1?i:3*n<2?e+(i-e)*(2/3-n)*6:e,a[u]=255*o;return a}function h(t){var e=t[0]/60,i=t[1]/100,n=t[2]/100,a=Math.floor(e)%6,o=e-Math.floor(e),r=255*n*(1-i),s=255*n*(1-i*o),l=255*n*(1-i*(1-o));n*=255;switch(a){case 0:return[n,l,r];case 1:return[s,n,r];case 2:return[r,n,l];case 3:return[r,s,n];case 4:return[l,r,n];case 5:return[n,r,s]}}function f(t){var e,i,n,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),n=6*o-(e=Math.floor(6*o)),0!=(1&e)&&(n=1-n),a=s+n*((i=1-l)-s),e){default:case 6:case 0:r=i,g=a,b=s;break;case 1:r=a,g=i,b=s;break;case 2:r=s,g=i,b=a;break;case 3:r=s,g=a,b=i;break;case 4:r=a,g=s,b=i;break;case 5:r=i,g=s,b=a}return[255*r,255*g,255*b]}function p(t){var e=t[0]/100,i=t[1]/100,n=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a))]}function m(t){var e,i,n,a=t[0]/100,o=t[1]/100,r=t[2]/100;return i=-.9689*a+1.8758*o+.0415*r,n=.0557*a+-.204*o+1.057*r,e=(e=3.2406*a+-1.5372*o+-.4986*r)>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,[255*(e=Math.min(Math.max(0,e),1)),255*(i=Math.min(Math.max(0,i),1)),255*(n=Math.min(Math.max(0,n),1))]}function v(t){var e=t[0],i=t[1],n=t[2];return i/=100,n/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(e-i),200*(i-(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116))]}function x(t){var e,i,n,a,o=t[0],r=t[1],s=t[2];return o<=8?a=(i=100*o/903.3)/100*7.787+16/116:(i=100*Math.pow((o+16)/116,3),a=Math.pow(i/100,1/3)),[e=e/95.047<=.008856?e=95.047*(r/500+a-16/116)/7.787:95.047*Math.pow(r/500+a,3),i,n=n/108.883<=.008859?n=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3)]}function y(t){var e,i=t[0],n=t[1],a=t[2];return(e=360*Math.atan2(a,n)/2/Math.PI)<0&&(e+=360),[i,Math.sqrt(n*n+a*a),e]}function k(t){return m(x(t))}function M(t){var e,i=t[0],n=t[1];return e=t[2]/360*2*Math.PI,[i,n*Math.cos(e),n*Math.sin(e)]}function w(t){return S[t]}e.exports={rgb2hsl:n,rgb2hsv:a,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:function(t){return y(d(t))},hsl2rgb:c,hsl2hsv:function(t){var e=t[0],i=t[1]/100,n=t[2]/100;if(0===n)return[0,0,0];return[e,100*(2*(i*=(n*=2)<=1?n:2-n)/(n+i)),100*((n+i)/2)]},hsl2hwb:function(t){return o(c(t))},hsl2cmyk:function(t){return s(c(t))},hsl2keyword:function(t){return l(c(t))},hsv2rgb:h,hsv2hsl:function(t){var e,i,n=t[0],a=t[1]/100,o=t[2]/100;return e=a*o,[n,100*(e=(e/=(i=(2-a)*o)<=1?i:2-i)||0),100*(i/=2)]},hsv2hwb:function(t){return o(h(t))},hsv2cmyk:function(t){return s(h(t))},hsv2keyword:function(t){return l(h(t))},hwb2rgb:f,hwb2hsl:function(t){return n(f(t))},hwb2hsv:function(t){return a(f(t))},hwb2cmyk:function(t){return s(f(t))},hwb2keyword:function(t){return l(f(t))},cmyk2rgb:p,cmyk2hsl:function(t){return n(p(t))},cmyk2hsv:function(t){return a(p(t))},cmyk2hwb:function(t){return o(p(t))},cmyk2keyword:function(t){return l(p(t))},keyword2rgb:w,keyword2hsl:function(t){return n(w(t))},keyword2hsv:function(t){return a(w(t))},keyword2hwb:function(t){return o(w(t))},keyword2cmyk:function(t){return s(w(t))},keyword2lab:function(t){return d(w(t))},keyword2xyz:function(t){return u(w(t))},xyz2rgb:m,xyz2lab:v,xyz2lch:function(t){return y(v(t))},lab2xyz:x,lab2rgb:k,lab2lch:y,lch2lab:M,lch2xyz:function(t){return x(M(t))},lch2rgb:function(t){return k(M(t))}};var S={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},C={};for(var _ in S)C[JSON.stringify(S[_])]=_},{}],5:[function(t,e,i){var n=t(4),a=function(){return new u};for(var o in n){a[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),n[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),s=r[1],l=r[2];(a[s]=a[s]||{})[l]=a[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var i=n[t](e);if("string"==typeof i||void 0===i)return i;for(var a=0;a<i.length;a++)i[a]=Math.round(i[a]);return i}}(o)}var u=function(){this.convs={}};u.prototype.routeSpace=function(t,e){var i=e[0];return void 0===i?this.getValues(t):("number"==typeof i&&(i=Array.prototype.slice.call(e)),this.setValues(t,i))},u.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},u.prototype.getValues=function(t){var e=this.convs[t];if(!e){var i=this.space,n=this.convs[i];e=a[i][t](n),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){u.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=a},{4:4}],6:[function(t,e,i){"use strict";e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],7:[function(t,e,i){var n=t(29)();n.helpers=t(45),t(27)(n),n.defaults=t(25),n.Element=t(26),n.elements=t(40),n.Interaction=t(28),n.layouts=t(30),n.platform=t(48),n.plugins=t(31),n.Ticks=t(34),t(22)(n),t(23)(n),t(24)(n),t(33)(n),t(32)(n),t(35)(n),t(55)(n),t(53)(n),t(54)(n),t(56)(n),t(57)(n),t(58)(n),t(15)(n),t(16)(n),t(17)(n),t(18)(n),t(19)(n),t(20)(n),t(21)(n),t(8)(n),t(9)(n),t(10)(n),t(11)(n),t(12)(n),t(13)(n),t(14)(n);var a=t(49);for(var o in a)a.hasOwnProperty(o)&&n.plugins.register(a[o]);n.platform.initialize(),e.exports=n,"undefined"!=typeof window&&(window.Chart=n),n.Legend=a.legend._element,n.Title=a.title._element,n.pluginService=n.plugins,n.PluginBase=n.Element.extend({}),n.canvasHelpers=n.helpers.canvas,n.layoutService=n.layouts},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,40:40,45:45,48:48,49:49,53:53,54:54,55:55,56:56,57:57,58:58,8:8,9:9}],8:[function(t,e,i){"use strict";e.exports=function(t){t.Bar=function(e,i){return i.type="bar",new t(e,i)}}},{}],9:[function(t,e,i){"use strict";e.exports=function(t){t.Bubble=function(e,i){return i.type="bubble",new t(e,i)}}},{}],10:[function(t,e,i){"use strict";e.exports=function(t){t.Doughnut=function(e,i){return i.type="doughnut",new t(e,i)}}},{}],11:[function(t,e,i){"use strict";e.exports=function(t){t.Line=function(e,i){return i.type="line",new t(e,i)}}},{}],12:[function(t,e,i){"use strict";e.exports=function(t){t.PolarArea=function(e,i){return i.type="polarArea",new t(e,i)}}},{}],13:[function(t,e,i){"use strict";e.exports=function(t){t.Radar=function(e,i){return i.type="radar",new t(e,i)}}},{}],14:[function(t,e,i){"use strict";e.exports=function(t){t.Scatter=function(e,i){return i.type="scatter",new t(e,i)}}},{}],15:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),n._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var i="";return t.length>0&&(t[0].yLabel?i=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(i=e.labels[t[0].index])),i},label:function(t,e){return(e.datasets[t.datasetIndex].label||"")+": "+t.xLabel}},mode:"index",axis:"y"}}),e.exports=function(t){t.controllers.bar=t.DatasetController.extend({dataElementType:a.Rectangle,initialize:function(){var e;t.DatasetController.prototype.initialize.apply(this,arguments),(e=this.getMeta()).stack=this.getDataset().stack,e.bar=!0},update:function(t){var e,i,n=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,i=n.length;e<i;++e)this.updateElement(n[e],e,t)},updateElement:function(t,e,i){var n=this,a=n.chart,r=n.getMeta(),s=n.getDataset(),l=t.custom||{},u=a.options.elements.rectangle;t._xScale=n.getScaleForId(r.xAxisID),t._yScale=n.getScaleForId(r.yAxisID),t._datasetIndex=n.index,t._index=e,t._model={datasetLabel:s.label,label:a.data.labels[e],borderSkipped:l.borderSkipped?l.borderSkipped:u.borderSkipped,backgroundColor:l.backgroundColor?l.backgroundColor:o.valueAtIndexOrDefault(s.backgroundColor,e,u.backgroundColor),borderColor:l.borderColor?l.borderColor:o.valueAtIndexOrDefault(s.borderColor,e,u.borderColor),borderWidth:l.borderWidth?l.borderWidth:o.valueAtIndexOrDefault(s.borderWidth,e,u.borderWidth)},n.updateElementGeometry(t,e,i),t.pivot()},updateElementGeometry:function(t,e,i){var n=this,a=t._model,o=n.getValueScale(),r=o.getBasePixel(),s=o.isHorizontal(),l=n._ruler||n.getRuler(),u=n.calculateBarValuePixels(n.index,e),d=n.calculateBarIndexPixels(n.index,e,l);a.horizontal=s,a.base=i?r:u.base,a.x=s?i?r:u.head:d.center,a.y=s?d.center:i?r:u.head,a.height=s?d.size:void 0,a.width=s?void 0:d.size},getValueScaleId:function(){return this.getMeta().yAxisID},getIndexScaleId:function(){return this.getMeta().xAxisID},getValueScale:function(){return this.getScaleForId(this.getValueScaleId())},getIndexScale:function(){return this.getScaleForId(this.getIndexScaleId())},_getStacks:function(t){var e,i,n=this.chart,a=this.getIndexScale().options.stacked,o=void 0===t?n.data.datasets.length:t+1,r=[];for(e=0;e<o;++e)(i=n.getDatasetMeta(e)).bar&&n.isDatasetVisible(e)&&(!1===a||!0===a&&-1===r.indexOf(i.stack)||void 0===a&&(void 0===i.stack||-1===r.indexOf(i.stack)))&&r.push(i.stack);return r},getStackCount:function(){return this._getStacks().length},getStackIndex:function(t,e){var i=this._getStacks(t),n=void 0!==e?i.indexOf(e):-1;return-1===n?i.length-1:n},getRuler:function(){var t,e,i=this.getIndexScale(),n=this.getStackCount(),a=this.index,r=i.isHorizontal(),s=r?i.left:i.top,l=s+(r?i.width:i.height),u=[];for(t=0,e=this.getMeta().data.length;t<e;++t)u.push(i.getPixelForValue(null,t,a));return{min:o.isNullOrUndef(i.options.barThickness)?function(t,e){var i,n,a,o,r=t.isHorizontal()?t.width:t.height,s=t.getTicks();for(a=1,o=e.length;a<o;++a)r=Math.min(r,e[a]-e[a-1]);for(a=0,o=s.length;a<o;++a)n=t.getPixelForTick(a),r=a>0?Math.min(r,n-i):r,i=n;return r}(i,u):-1,pixels:u,start:s,end:l,stackCount:n,scale:i}},calculateBarValuePixels:function(t,e){var i,n,a,o,r,s,l=this.chart,u=this.getMeta(),d=this.getValueScale(),c=l.data.datasets,h=d.getRightValue(c[t].data[e]),f=d.options.stacked,g=u.stack,p=0;if(f||void 0===f&&void 0!==g)for(i=0;i<t;++i)(n=l.getDatasetMeta(i)).bar&&n.stack===g&&n.controller.getValueScaleId()===d.id&&l.isDatasetVisible(i)&&(a=d.getRightValue(c[i].data[e]),(h<0&&a<0||h>=0&&a>0)&&(p+=a));return o=d.getPixelForValue(p),{size:s=((r=d.getPixelForValue(p+h))-o)/2,base:o,head:r,center:r+s/2}},calculateBarIndexPixels:function(t,e,i){var n,a,r,s,l,u,d,c,h,f,g,p,m,v,b,x,y,k=i.scale.options,M="flex"===k.barThickness?(h=e,g=k,m=(f=i).pixels,v=m[h],b=h>0?m[h-1]:null,x=h<m.length-1?m[h+1]:null,y=g.categoryPercentage,null===b&&(b=v-(null===x?f.end-v:x-v)),null===x&&(x=v+v-b),p=v-(v-b)/2*y,{chunk:(x-b)/2*y/f.stackCount,ratio:g.barPercentage,start:p}):(n=e,a=i,u=(r=k).barThickness,d=a.stackCount,c=a.pixels[n],o.isNullOrUndef(u)?(s=a.min*r.categoryPercentage,l=r.barPercentage):(s=u*d,l=1),{chunk:s/d,ratio:l,start:c-s/2}),w=this.getStackIndex(t,this.getMeta().stack),S=M.start+M.chunk*w+M.chunk/2,C=Math.min(o.valueOrDefault(k.maxBarThickness,1/0),M.chunk*M.ratio);return{base:S-C/2,head:S+C/2,center:S,size:C}},draw:function(){var t=this.chart,e=this.getValueScale(),i=this.getMeta().data,n=this.getDataset(),a=i.length,r=0;for(o.canvas.clipArea(t.ctx,t.chartArea);r<a;++r)isNaN(e.getRightValue(n.data[r]))||i[r].draw();o.canvas.unclipArea(t.ctx)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},a=t._model;a.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:o.valueAtIndexOrDefault(e.hoverBackgroundColor,i,o.getHoverColor(a.backgroundColor)),a.borderColor=n.hoverBorderColor?n.hoverBorderColor:o.valueAtIndexOrDefault(e.hoverBorderColor,i,o.getHoverColor(a.borderColor)),a.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:o.valueAtIndexOrDefault(e.hoverBorderWidth,i,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},a=t._model,r=this.chart.options.elements.rectangle;a.backgroundColor=n.backgroundColor?n.backgroundColor:o.valueAtIndexOrDefault(e.backgroundColor,i,r.backgroundColor),a.borderColor=n.borderColor?n.borderColor:o.valueAtIndexOrDefault(e.borderColor,i,r.borderColor),a.borderWidth=n.borderWidth?n.borderWidth:o.valueAtIndexOrDefault(e.borderWidth,i,r.borderWidth)}}),t.controllers.horizontalBar=t.controllers.bar.extend({getValueScaleId:function(){return this.getMeta().xAxisID},getIndexScaleId:function(){return this.getMeta().yAxisID}})}},{25:25,40:40,45:45}],16:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("bubble",{hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var i=e.datasets[t.datasetIndex].label||"",n=e.datasets[t.datasetIndex].data[t.index];return i+": ("+t.xLabel+", "+t.yLabel+", "+n.r+")"}}}}),e.exports=function(t){t.controllers.bubble=t.DatasetController.extend({dataElementType:a.Point,update:function(t){var e=this,i=e.getMeta().data;o.each(i,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){var n=this,a=n.getMeta(),o=t.custom||{},r=n.getScaleForId(a.xAxisID),s=n.getScaleForId(a.yAxisID),l=n._resolveElementOptions(t,e),u=n.getDataset().data[e],d=n.index,c=i?r.getPixelForDecimal(.5):r.getPixelForValue("object"==typeof u?u:NaN,e,d),h=i?s.getBasePixel():s.getPixelForValue(u,e,d);t._xScale=r,t._yScale=s,t._options=l,t._datasetIndex=d,t._index=e,t._model={backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,hitRadius:l.hitRadius,pointStyle:l.pointStyle,radius:i?0:l.radius,skip:o.skip||isNaN(c)||isNaN(h),x:c,y:h},t.pivot()},setHoverStyle:function(t){var e=t._model,i=t._options;e.backgroundColor=o.valueOrDefault(i.hoverBackgroundColor,o.getHoverColor(i.backgroundColor)),e.borderColor=o.valueOrDefault(i.hoverBorderColor,o.getHoverColor(i.borderColor)),e.borderWidth=o.valueOrDefault(i.hoverBorderWidth,i.borderWidth),e.radius=i.radius+i.hoverRadius},removeHoverStyle:function(t){var e=t._model,i=t._options;e.backgroundColor=i.backgroundColor,e.borderColor=i.borderColor,e.borderWidth=i.borderWidth,e.radius=i.radius},_resolveElementOptions:function(t,e){var i,n,a,r=this.chart,s=r.data.datasets[this.index],l=t.custom||{},u=r.options.elements.point,d=o.options.resolve,c=s.data[e],h={},f={chart:r,dataIndex:e,dataset:s,datasetIndex:this.index},g=["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle"];for(i=0,n=g.length;i<n;++i)h[a=g[i]]=d([l[a],s[a],u[a]],f,e);return h.radius=d([l.radius,c?c.r:void 0,s.radius,u.radius],f,e),h}})}},{25:25,40:40,45:45}],17:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o<n[0].data.length;++o)e.push('<li><span style="background-color:'+n[0].backgroundColor[o]+'"></span>'),a[o]&&e.push(a[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),r=e.datasets[0],s=a.data[n],l=s&&s.custom||{},u=o.valueAtIndexOrDefault,d=t.options.elements.arc;return{text:i,fillStyle:l.backgroundColor?l.backgroundColor:u(r.backgroundColor,n,d.backgroundColor),strokeStyle:l.borderColor?l.borderColor:u(r.borderColor,n,d.borderColor),lineWidth:l.borderWidth?l.borderWidth:u(r.borderWidth,n,d.borderWidth),hidden:isNaN(r.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i<n;++i)(a=r.getDatasetMeta(i)).data[o]&&(a.data[o].hidden=!a.data[o].hidden);r.update()}},cutoutPercentage:50,rotation:-.5*Math.PI,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var i=e.labels[t.index],n=": "+e.datasets[t.datasetIndex].data[t.index];return o.isArray(i)?(i=i.slice())[0]+=n:i+=n,i}}}}),n._set("pie",o.clone(n.doughnut)),n._set("pie",{cutoutPercentage:0}),e.exports=function(t){t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:a.Arc,linkScales:o.noop,getRingIndex:function(t){for(var e=0,i=0;i<t;++i)this.chart.isDatasetVisible(i)&&++e;return e},update:function(t){var e=this,i=e.chart,n=i.chartArea,a=i.options,r=a.elements.arc,s=n.right-n.left-r.borderWidth,l=n.bottom-n.top-r.borderWidth,u=Math.min(s,l),d={x:0,y:0},c=e.getMeta(),h=a.cutoutPercentage,f=a.circumference;if(f<2*Math.PI){var g=a.rotation%(2*Math.PI),p=(g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0))+f,m=Math.cos(g),v=Math.sin(g),b=Math.cos(p),x=Math.sin(p),y=g<=0&&p>=0||g<=2*Math.PI&&2*Math.PI<=p,k=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,M=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,w=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,S=h/100,C=M?-1:Math.min(m*(m<0?1:S),b*(b<0?1:S)),_=w?-1:Math.min(v*(v<0?1:S),x*(x<0?1:S)),D=y?1:Math.max(m*(m>0?1:S),b*(b>0?1:S)),I=k?1:Math.max(v*(v>0?1:S),x*(x>0?1:S)),P=.5*(D-C),A=.5*(I-_);u=Math.min(s/P,l/A),d={x:-.5*(D+C),y:-.5*(I+_)}}i.borderWidth=e.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:0,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=e.calculateTotal(),e.outerRadius=i.outerRadius-i.radiusLength*e.getRingIndex(e.index),e.innerRadius=Math.max(e.outerRadius-i.radiusLength,0),o.each(c.data,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){var n=this,a=n.chart,r=a.chartArea,s=a.options,l=s.animation,u=(r.left+r.right)/2,d=(r.top+r.bottom)/2,c=s.rotation,h=s.rotation,f=n.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[e])*(s.circumference/(2*Math.PI)),p=i&&l.animateScale?0:n.innerRadius,m=i&&l.animateScale?0:n.outerRadius,v=o.valueAtIndexOrDefault;o.extend(t,{_datasetIndex:n.index,_index:e,_model:{x:u+a.offsetX,y:d+a.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:v(f.label,e,a.data.labels[e])}});var b=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(b.startAngle=0===e?s.rotation:n.getMeta().data[e-1]._model.endAngle,b.endAngle=b.startAngle+b.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,e=this.getDataset(),i=this.getMeta(),n=0;return o.each(i.data,function(i,a){t=e.data[a],isNaN(t)||i.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){for(var e,i,n=0,a=this.index,o=t.length,r=0;r<o;r++)e=t[r]._model?t[r]._model.borderWidth:0,n=(i=t[r]._chart?t[r]._chart.config.data.datasets[a].hoverBorderWidth:0)>(n=e>n?e:n)?i:n;return n}})}},{25:25,40:40,45:45}],18:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}}),e.exports=function(t){function e(t,e){return o.valueOrDefault(t.showLine,e.showLines)}t.controllers.line=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,update:function(t){var i,n,a,r=this,s=r.getMeta(),l=s.dataset,u=s.data||[],d=r.chart.options,c=d.elements.line,h=r.getScaleForId(s.yAxisID),f=r.getDataset(),g=e(f,d);for(g&&(a=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=r.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:a.tension?a.tension:o.valueOrDefault(f.lineTension,c.tension),backgroundColor:a.backgroundColor?a.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:a.borderWidth?a.borderWidth:f.borderWidth||c.borderWidth,borderColor:a.borderColor?a.borderColor:f.borderColor||c.borderColor,borderCapStyle:a.borderCapStyle?a.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:a.borderDash?a.borderDash:f.borderDash||c.borderDash,borderDashOffset:a.borderDashOffset?a.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:a.borderJoinStyle?a.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:a.fill?a.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:a.steppedLine?a.steppedLine:o.valueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:a.cubicInterpolationMode?a.cubicInterpolationMode:o.valueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode)},l.pivot()),i=0,n=u.length;i<n;++i)r.updateElement(u[i],i,t);for(g&&0!==l._model.tension&&r.updateBezierControlPoints(),i=0,n=u.length;i<n;++i)u[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,n=this.getDataset(),a=t.custom||{};return a.backgroundColor?i=a.backgroundColor:n.pointBackgroundColor?i=o.valueAtIndexOrDefault(n.pointBackgroundColor,e,i):n.backgroundColor&&(i=n.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,n=this.getDataset(),a=t.custom||{};return a.borderColor?i=a.borderColor:n.pointBorderColor?i=o.valueAtIndexOrDefault(n.pointBorderColor,e,i):n.borderColor&&(i=n.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,n=this.getDataset(),a=t.custom||{};return isNaN(a.borderWidth)?!isNaN(n.pointBorderWidth)||o.isArray(n.pointBorderWidth)?i=o.valueAtIndexOrDefault(n.pointBorderWidth,e,i):isNaN(n.borderWidth)||(i=n.borderWidth):i=a.borderWidth,i},updateElement:function(t,e,i){var n,a,r=this,s=r.getMeta(),l=t.custom||{},u=r.getDataset(),d=r.index,c=u.data[e],h=r.getScaleForId(s.yAxisID),f=r.getScaleForId(s.xAxisID),g=r.chart.options.elements.point;void 0!==u.radius&&void 0===u.pointRadius&&(u.pointRadius=u.radius),void 0!==u.hitRadius&&void 0===u.pointHitRadius&&(u.pointHitRadius=u.hitRadius),n=f.getPixelForValue("object"==typeof c?c:NaN,e,d),a=i?h.getBasePixel():r.calculatePointY(c,e,d),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:n,y:a,skip:l.skip||isNaN(n)||isNaN(a),radius:l.radius||o.valueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:l.pointStyle||o.valueAtIndexOrDefault(u.pointStyle,e,g.pointStyle),backgroundColor:r.getPointBackgroundColor(t,e),borderColor:r.getPointBorderColor(t,e),borderWidth:r.getPointBorderWidth(t,e),tension:s.dataset._model?s.dataset._model.tension:0,steppedLine:!!s.dataset._model&&s.dataset._model.steppedLine,hitRadius:l.hitRadius||o.valueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,i){var n,a,o,r=this.chart,s=this.getMeta(),l=this.getScaleForId(s.yAxisID),u=0,d=0;if(l.options.stacked){for(n=0;n<i;n++)if(a=r.data.datasets[n],"line"===(o=r.getDatasetMeta(n)).type&&o.yAxisID===l.id&&r.isDatasetVisible(n)){var c=Number(l.getRightValue(a.data[e]));c<0?d+=c||0:u+=c||0}var h=Number(l.getRightValue(t));return h<0?l.getPixelForValue(d+h):l.getPixelForValue(u+h)}return l.getPixelForValue(t)},updateBezierControlPoints:function(){var t,e,i,n,a=this.getMeta(),r=this.chart.chartArea,s=a.data||[];function l(t,e,i){return Math.max(Math.min(t,i),e)}if(a.dataset._model.spanGaps&&(s=s.filter(function(t){return!t._model.skip})),"monotone"===a.dataset._model.cubicInterpolationMode)o.splineCurveMonotone(s);else for(t=0,e=s.length;t<e;++t)i=s[t]._model,n=o.splineCurve(o.previousItem(s,t)._model,i,o.nextItem(s,t)._model,a.dataset._model.tension),i.controlPointPreviousX=n.previous.x,i.controlPointPreviousY=n.previous.y,i.controlPointNextX=n.next.x,i.controlPointNextY=n.next.y;if(this.chart.options.elements.line.capBezierPoints)for(t=0,e=s.length;t<e;++t)(i=s[t]._model).controlPointPreviousX=l(i.controlPointPreviousX,r.left,r.right),i.controlPointPreviousY=l(i.controlPointPreviousY,r.top,r.bottom),i.controlPointNextX=l(i.controlPointNextX,r.left,r.right),i.controlPointNextY=l(i.controlPointNextY,r.top,r.bottom)},draw:function(){var t=this.chart,i=this.getMeta(),n=i.data||[],a=t.chartArea,r=n.length,s=0;for(o.canvas.clipArea(t.ctx,a),e(this.getDataset(),t.options)&&i.dataset.draw(),o.canvas.unclipArea(t.ctx);s<r;++s)n[s].draw(a)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},a=t._model;a.radius=n.hoverRadius||o.valueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),a.backgroundColor=n.hoverBackgroundColor||o.valueAtIndexOrDefault(e.pointHoverBackgroundColor,i,o.getHoverColor(a.backgroundColor)),a.borderColor=n.hoverBorderColor||o.valueAtIndexOrDefault(e.pointHoverBorderColor,i,o.getHoverColor(a.borderColor)),a.borderWidth=n.hoverBorderWidth||o.valueAtIndexOrDefault(e.pointHoverBorderWidth,i,a.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],n=t._index,a=t.custom||{},r=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),r.radius=a.radius||o.valueAtIndexOrDefault(i.pointRadius,n,e.chart.options.elements.point.radius),r.backgroundColor=e.getPointBackgroundColor(t,n),r.borderColor=e.getPointBorderColor(t,n),r.borderWidth=e.getPointBorderWidth(t,n)}})}},{25:25,40:40,45:45}],19:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("polarArea",{scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o<n[0].data.length;++o)e.push('<li><span style="background-color:'+n[0].backgroundColor[o]+'"></span>'),a[o]&&e.push(a[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),r=e.datasets[0],s=a.data[n].custom||{},l=o.valueAtIndexOrDefault,u=t.options.elements.arc;return{text:i,fillStyle:s.backgroundColor?s.backgroundColor:l(r.backgroundColor,n,u.backgroundColor),strokeStyle:s.borderColor?s.borderColor:l(r.borderColor,n,u.borderColor),lineWidth:s.borderWidth?s.borderWidth:l(r.borderWidth,n,u.borderWidth),hidden:isNaN(r.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i<n;++i)(a=r.getDatasetMeta(i)).data[o].hidden=!a.data[o].hidden;r.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}}),e.exports=function(t){t.controllers.polarArea=t.DatasetController.extend({dataElementType:a.Arc,linkScales:o.noop,update:function(t){var e=this,i=e.chart,n=i.chartArea,a=e.getMeta(),r=i.options,s=r.elements.arc,l=Math.min(n.right-n.left,n.bottom-n.top);i.outerRadius=Math.max((l-s.borderWidth/2)/2,0),i.innerRadius=Math.max(r.cutoutPercentage?i.outerRadius/100*r.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),e.outerRadius=i.outerRadius-i.radiusLength*e.index,e.innerRadius=e.outerRadius-i.radiusLength,a.count=e.countVisibleElements(),o.each(a.data,function(i,n){e.updateElement(i,n,t)})},updateElement:function(t,e,i){for(var n=this,a=n.chart,r=n.getDataset(),s=a.options,l=s.animation,u=a.scale,d=a.data.labels,c=n.calculateCircumference(r.data[e]),h=u.xCenter,f=u.yCenter,g=0,p=n.getMeta(),m=0;m<e;++m)isNaN(r.data[m])||p.data[m].hidden||++g;var v=s.startAngle,b=t.hidden?0:u.getDistanceFromCenterForValue(r.data[e]),x=v+c*g,y=x+(t.hidden?0:c),k=l.animateScale?0:u.getDistanceFromCenterForValue(r.data[e]);o.extend(t,{_datasetIndex:n.index,_index:e,_scale:u,_model:{x:h,y:f,innerRadius:0,outerRadius:i?k:b,startAngle:i&&l.animateRotate?v:x,endAngle:i&&l.animateRotate?v:y,label:o.valueAtIndexOrDefault(d,e,d[e])}}),n.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),e=this.getMeta(),i=0;return o.each(e.data,function(e,n){isNaN(t.data[n])||e.hidden||i++}),i},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{25:25,40:40,45:45}],20:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("radar",{scale:{type:"radialLinear"},elements:{line:{tension:0}}}),e.exports=function(t){t.controllers.radar=t.DatasetController.extend({datasetElementType:a.Line,dataElementType:a.Point,linkScales:o.noop,update:function(t){var e=this,i=e.getMeta(),n=i.dataset,a=i.data,r=n.custom||{},s=e.getDataset(),l=e.chart.options.elements.line,u=e.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),o.extend(i.dataset,{_datasetIndex:e.index,_scale:u,_children:a,_loop:!0,_model:{tension:r.tension?r.tension:o.valueOrDefault(s.lineTension,l.tension),backgroundColor:r.backgroundColor?r.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:s.borderWidth||l.borderWidth,borderColor:r.borderColor?r.borderColor:s.borderColor||l.borderColor,fill:r.fill?r.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:r.borderDash?r.borderDash:s.borderDash||l.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle}}),i.dataset.pivot(),o.each(a,function(i,n){e.updateElement(i,n,t)},e),e.updateBezierControlPoints()},updateElement:function(t,e,i){var n=this,a=t.custom||{},r=n.getDataset(),s=n.chart.scale,l=n.chart.options.elements.point,u=s.getPointPositionForValue(e,r.data[e]);void 0!==r.radius&&void 0===r.pointRadius&&(r.pointRadius=r.radius),void 0!==r.hitRadius&&void 0===r.pointHitRadius&&(r.pointHitRadius=r.hitRadius),o.extend(t,{_datasetIndex:n.index,_index:e,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:a.tension?a.tension:o.valueOrDefault(r.lineTension,n.chart.options.elements.line.tension),radius:a.radius?a.radius:o.valueAtIndexOrDefault(r.pointRadius,e,l.radius),backgroundColor:a.backgroundColor?a.backgroundColor:o.valueAtIndexOrDefault(r.pointBackgroundColor,e,l.backgroundColor),borderColor:a.borderColor?a.borderColor:o.valueAtIndexOrDefault(r.pointBorderColor,e,l.borderColor),borderWidth:a.borderWidth?a.borderWidth:o.valueAtIndexOrDefault(r.pointBorderWidth,e,l.borderWidth),pointStyle:a.pointStyle?a.pointStyle:o.valueAtIndexOrDefault(r.pointStyle,e,l.pointStyle),hitRadius:a.hitRadius?a.hitRadius:o.valueAtIndexOrDefault(r.pointHitRadius,e,l.hitRadius)}}),t._model.skip=a.skip?a.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,e=this.getMeta();o.each(e.data,function(i,n){var a=i._model,r=o.splineCurve(o.previousItem(e.data,n,!0)._model,a,o.nextItem(e.data,n,!0)._model,a.tension);a.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),a.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),a.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),a.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,a=t._model;a.radius=i.hoverRadius?i.hoverRadius:o.valueAtIndexOrDefault(e.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),a.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:o.valueAtIndexOrDefault(e.pointHoverBackgroundColor,n,o.getHoverColor(a.backgroundColor)),a.borderColor=i.hoverBorderColor?i.hoverBorderColor:o.valueAtIndexOrDefault(e.pointHoverBorderColor,n,o.getHoverColor(a.borderColor)),a.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:o.valueAtIndexOrDefault(e.pointHoverBorderWidth,n,a.borderWidth)},removeHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,a=t._model,r=this.chart.options.elements.point;a.radius=i.radius?i.radius:o.valueAtIndexOrDefault(e.pointRadius,n,r.radius),a.backgroundColor=i.backgroundColor?i.backgroundColor:o.valueAtIndexOrDefault(e.pointBackgroundColor,n,r.backgroundColor),a.borderColor=i.borderColor?i.borderColor:o.valueAtIndexOrDefault(e.pointBorderColor,n,r.borderColor),a.borderWidth=i.borderWidth?i.borderWidth:o.valueAtIndexOrDefault(e.pointBorderWidth,n,r.borderWidth)}})}},{25:25,40:40,45:45}],21:[function(t,e,i){"use strict";t(25)._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},showLines:!1,tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),e.exports=function(t){t.controllers.scatter=t.controllers.line}},{25:25}],22:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:o.noop,onComplete:o.noop}}),e.exports=function(t){t.Animation=a.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,i,n){var a,o,r=this.animations;for(e.chart=t,n||(t.animating=!0),a=0,o=r.length;a<o;++a)if(r[a].chart===t)return void(r[a]=e);r.push(e),1===r.length&&this.requestAnimationFrame()},cancelAnimation:function(t){var e=o.findIndex(this.animations,function(e){return e.chart===t});-1!==e&&(this.animations.splice(e,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=o.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),i=0;t.dropFrames>1&&(i=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1),t.advance(1+i);var n=Date.now();t.dropFrames+=(n-e)/t.frameDuration,t.animations.length>0&&t.requestAnimationFrame()},advance:function(t){for(var e,i,n=this.animations,a=0;a<n.length;)i=(e=n[a]).chart,e.currentStep=(e.currentStep||0)+t,e.currentStep=Math.min(e.currentStep,e.numSteps),o.callback(e.render,[i,e],i),o.callback(e.onAnimationProgress,[e],i),e.currentStep>=e.numSteps?(o.callback(e.onAnimationComplete,[e],i),i.animating=!1,n.splice(a,1)):++a}},Object.defineProperty(t.Animation.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(t.Animation.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}})}},{25:25,26:26,45:45}],23:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(28),r=t(30),s=t(48),l=t(31);e.exports=function(t){function e(t){return"top"===t||"bottom"===t}t.types={},t.instances={},t.controllers={},a.extend(t.prototype,{construct:function(e,i){var o,r,l=this;(r=(o=(o=i)||{}).data=o.data||{}).datasets=r.datasets||[],r.labels=r.labels||[],o.options=a.configMerge(n.global,n[o.type],o.options||{}),i=o;var u=s.acquireContext(e,i),d=u&&u.canvas,c=d&&d.height,h=d&&d.width;l.id=a.uid(),l.ctx=u,l.canvas=d,l.config=i,l.width=h,l.height=c,l.aspectRatio=c?h/c:null,l.options=i.options,l._bufferedRender=!1,l.chart=l,l.controller=l,t.instances[l.id]=l,Object.defineProperty(l,"data",{get:function(){return l.config.data},set:function(t){l.config.data=t}}),u&&d?(l.initialize(),l.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return l.notify(t,"beforeInit"),a.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.initToolTip(),l.notify(t,"afterInit"),t},clear:function(){return a.canvas.clear(this),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,i=e.options,n=e.canvas,o=i.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(a.getMaximumWidth(n))),s=Math.max(0,Math.floor(o?r/o:a.getMaximumHeight(n)));if((e.width!==r||e.height!==s)&&(n.width=e.width=r,n.height=e.height=s,n.style.width=r+"px",n.style.height=s+"px",a.retinaScale(e,i.devicePixelRatio),!t)){var u={width:r,height:s};l.notify(e,"resize",[u]),e.options.onResize&&e.options.onResize(e,u),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},i=t.scale;a.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),a.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildOrUpdateScales:function(){var i=this,n=i.options,o=i.scales||{},r=[],s=Object.keys(o).reduce(function(t,e){return t[e]=!1,t},{});n.scales&&(r=r.concat((n.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(n.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),n.scale&&r.push({options:n.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),a.each(r,function(n){var r=n.options,l=r.id,u=a.valueOrDefault(r.type,n.dtype);e(r.position)!==e(n.dposition)&&(r.position=n.dposition),s[l]=!0;var d=null;if(l in o&&o[l].type===u)(d=o[l]).options=r,d.ctx=i.ctx,d.chart=i;else{var c=t.scaleService.getScaleConstructor(u);if(!c)return;d=new c({id:l,type:u,options:r,ctx:i.ctx,chart:i}),o[d.id]=d}d.mergeTicksOptions(),n.isDefault&&(i.scale=d)}),a.each(s,function(t,e){t||delete o[e]}),i.scales=o,t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,i=[],n=[];return a.each(e.data.datasets,function(a,o){var r=e.getDatasetMeta(o),s=a.type||e.config.type;if(r.type&&r.type!==s&&(e.destroyDatasetMeta(o),r=e.getDatasetMeta(o)),r.type=s,i.push(r.type),r.controller)r.controller.updateIndex(o),r.controller.linkScales();else{var l=t.controllers[r.type];if(void 0===l)throw new Error('"'+r.type+'" is not a chart type.');r.controller=new l(e,o),n.push(r.controller)}},e),n},resetElements:function(){var t=this;a.each(t.data.datasets,function(e,i){t.getDatasetMeta(i).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(e){var i,n,o=this;if(e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]}),n=(i=o).options,a.each(i.scales,function(t){r.removeBox(i,t)}),n=a.configMerge(t.defaults.global,t.defaults[i.config.type],n),i.options=i.config.options=n,i.ensureScalesHaveIDs(),i.buildOrUpdateScales(),i.tooltip._options=n.tooltips,i.tooltip.initialize(),l._invalidate(o),!1!==l.notify(o,"beforeUpdate")){o.tooltip._data=o.data;var s=o.buildOrUpdateControllers();a.each(o.data.datasets,function(t,e){o.getDatasetMeta(e).controller.buildOrUpdateElements()},o),o.updateLayout(),o.options.animation&&o.options.animation.duration&&a.each(s,function(t){t.reset()}),o.updateDatasets(),o.tooltip.initialize(),o.lastActive=[],l.notify(o,"afterUpdate"),o._bufferedRender?o._bufferedRequest={duration:e.duration,easing:e.easing,lazy:e.lazy}:o.render(e)}},updateLayout:function(){!1!==l.notify(this,"beforeLayout")&&(r.update(this,this.width,this.height),l.notify(this,"afterScaleUpdate"),l.notify(this,"afterLayout"))},updateDatasets:function(){if(!1!==l.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t<e;++t)this.updateDataset(t);l.notify(this,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this.getDatasetMeta(t),i={meta:e,index:t};!1!==l.notify(this,"beforeDatasetUpdate",[i])&&(e.controller.update(),l.notify(this,"afterDatasetUpdate",[i]))},render:function(e){var i=this;e&&"object"==typeof e||(e={duration:e,lazy:arguments[1]});var n=e.duration,o=e.lazy;if(!1!==l.notify(i,"beforeRender")){var r=i.options.animation,s=function(t){l.notify(i,"afterRender"),a.callback(r&&r.onComplete,[t],i)};if(r&&(void 0!==n&&0!==n||void 0===n&&0!==r.duration)){var u=new t.Animation({numSteps:(n||r.duration)/16.66,easing:e.easing||r.easing,render:function(t,e){var i=a.easing.effects[e.easing],n=e.currentStep,o=n/e.numSteps;t.draw(i(o),o,n)},onAnimationProgress:r.onProgress,onAnimationComplete:s});t.animationService.addAnimation(i,u,n,o)}else i.draw(),s(new t.Animation({numSteps:0,chart:i}));return i}},draw:function(t){var e=this;e.clear(),a.isNullOrUndef(t)&&(t=1),e.transition(t),!1!==l.notify(e,"beforeDraw",[t])&&(a.each(e.boxes,function(t){t.draw(e.chartArea)},e),e.scale&&e.scale.draw(),e.drawDatasets(t),e._drawTooltip(t),l.notify(e,"afterDraw",[t]))},transition:function(t){for(var e=0,i=(this.data.datasets||[]).length;e<i;++e)this.isDatasetVisible(e)&&this.getDatasetMeta(e).controller.transition(t);this.tooltip.transition(t)},drawDatasets:function(t){var e=this;if(!1!==l.notify(e,"beforeDatasetsDraw",[t])){for(var i=(e.data.datasets||[]).length-1;i>=0;--i)e.isDatasetVisible(i)&&e.drawDataset(i,t);l.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var i=this.getDatasetMeta(t),n={meta:i,index:t,easingValue:e};!1!==l.notify(this,"beforeDatasetDraw",[n])&&(i.controller.draw(e),l.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,i={tooltip:e,easingValue:t};!1!==l.notify(this,"beforeTooltipDraw",[i])&&(e.draw(),l.notify(this,"afterTooltipDraw",[i]))},getElementAtEvent:function(t){return o.modes.single(this,t)},getElementsAtEvent:function(t){return o.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return o.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,i){var n=o.modes[e];return"function"==typeof n?n(this,t,i):[]},getDatasetAtEvent:function(t){return o.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var i=e._meta[this.id];return i||(i=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,i=this.data.datasets.length;e<i;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroyDatasetMeta:function(t){var e=this.id,i=this.data.datasets[t],n=i._meta&&i._meta[e];n&&(n.controller.destroy(),delete i._meta[e])},destroy:function(){var e,i,n=this,o=n.canvas;for(n.stop(),e=0,i=n.data.datasets.length;e<i;++e)n.destroyDatasetMeta(e);o&&(n.unbindEvents(),a.canvas.clear(n),s.releaseContext(n.ctx),n.canvas=null,n.ctx=null),l.notify(n,"destroy"),delete t.instances[n.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e)},bindEvents:function(){var t=this,e=t._listeners={},i=function(){t.eventHandler.apply(t,arguments)};a.each(t.options.events,function(n){s.addEventListener(t,n,i),e[n]=i}),t.options.responsive&&(i=function(){t.resize()},s.addEventListener(t,"resize",i),e.resize=i)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,a.each(e,function(e,i){s.removeEventListener(t,i,e)}))},updateHoverStyle:function(t,e,i){var n,a,o,r=i?"setHoverStyle":"removeHoverStyle";for(a=0,o=t.length;a<o;++a)(n=t[a])&&this.getDatasetMeta(n._datasetIndex).controller[r](n)},eventHandler:function(t){var e=this,i=e.tooltip;if(!1!==l.notify(e,"beforeEvent",[t])){e._bufferedRender=!0,e._bufferedRequest=null;var n=e.handleEvent(t);i&&(n=i._start?i.handleEvent(t):n|i.handleEvent(t)),l.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a):n&&!e.animating&&(e.stop(),e.render(e.options.hover.animationDuration,!0)),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e,i=this,n=i.options||{},o=n.hover;return i.lastActive=i.lastActive||[],"mouseout"===t.type?i.active=[]:i.active=i.getElementsAtEventForMode(t,o.mode,o),a.callback(n.onHover||n.hover.onHover,[t.native,i.active],i),"mouseup"!==t.type&&"click"!==t.type||n.onClick&&n.onClick.call(i,t.native,i.active),i.lastActive.length&&i.updateHoverStyle(i.lastActive,o.mode,!1),i.active.length&&o.mode&&i.updateHoverStyle(i.active,o.mode,!0),e=!a.arrayEquals(i.active,i.lastActive),i.lastActive=i.active,e}}),t.Controller=t}},{25:25,28:28,30:30,31:31,45:45,48:48}],24:[function(t,e,i){"use strict";var n=t(45);e.exports=function(t){var e=["push","pop","shift","splice","unshift"];function i(t,i){var n=t._chartjs;if(n){var a=n.listeners,o=a.indexOf(i);-1!==o&&a.splice(o,1),a.length>0||(e.forEach(function(e){delete t[e]}),delete t._chartjs)}}t.DatasetController=function(t,e){this.initialize(t,e)},n.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){this.chart=t,this.index=e,this.linkScales(),this.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),i=t.getDataset();null!==e.xAxisID&&e.xAxisID in t.chart.scales||(e.xAxisID=i.xAxisID||t.chart.options.scales.xAxes[0].id),null!==e.yAxisID&&e.yAxisID in t.chart.scales||(e.yAxisID=i.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&i(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,i=this.getMeta(),n=this.getDataset().data||[],a=i.data;for(t=0,e=n.length;t<e;++t)a[t]=a[t]||this.createMetaData(t);i.dataset=i.dataset||this.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t,a,o=this,r=o.getDataset(),s=r.data||(r.data=[]);o._data!==s&&(o._data&&i(o._data,o),a=o,(t=s)._chartjs?t._chartjs.listeners.push(a):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[a]}}),e.forEach(function(e){var i="onData"+e.charAt(0).toUpperCase()+e.slice(1),a=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),o=a.apply(this,e);return n.each(t._chartjs.listeners,function(t){"function"==typeof t[i]&&t[i].apply(t,e)}),o}})})),o._data=s),o.resyncElements()},update:n.noop,transition:function(t){for(var e=this.getMeta(),i=e.data||[],n=i.length,a=0;a<n;++a)i[a].transition(t);e.dataset&&e.dataset.transition(t)},draw:function(){var t=this.getMeta(),e=t.data||[],i=e.length,n=0;for(t.dataset&&t.dataset.draw();n<i;++n)e[n].draw()},removeHoverStyle:function(t,e){var i=this.chart.data.datasets[t._datasetIndex],a=t._index,o=t.custom||{},r=n.valueAtIndexOrDefault,s=t._model;s.backgroundColor=o.backgroundColor?o.backgroundColor:r(i.backgroundColor,a,e.backgroundColor),s.borderColor=o.borderColor?o.borderColor:r(i.borderColor,a,e.borderColor),s.borderWidth=o.borderWidth?o.borderWidth:r(i.borderWidth,a,e.borderWidth)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,a=t.custom||{},o=n.valueAtIndexOrDefault,r=n.getHoverColor,s=t._model;s.backgroundColor=a.hoverBackgroundColor?a.hoverBackgroundColor:o(e.hoverBackgroundColor,i,r(s.backgroundColor)),s.borderColor=a.hoverBorderColor?a.hoverBorderColor:o(e.hoverBorderColor,i,r(s.borderColor)),s.borderWidth=a.hoverBorderWidth?a.hoverBorderWidth:o(e.hoverBorderWidth,i,s.borderWidth)},resyncElements:function(){var t=this.getMeta(),e=this.getDataset().data,i=t.data.length,n=e.length;n<i?t.data.splice(n,i-n):n>i&&this.insertElements(i,n-i)},insertElements:function(t,e){for(var i=0;i<e;++i)this.addElementAndReset(t+i)},onDataPush:function(){this.insertElements(this.getDataset().data.length-1,arguments.length)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),t.DatasetController.extend=n.inherits}},{45:45}],25:[function(t,e,i){"use strict";var n=t(45);e.exports={_set:function(t,e){return n.merge(this[t]||(this[t]={}),e)}}},{45:45}],26:[function(t,e,i){"use strict";var n=t(3),a=t(45);var o=function(t){a.extend(this,t),this.initialize.apply(this,arguments)};a.extend(o.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=a.clone(t._model)),t._start={},t},transition:function(t){var e=this,i=e._model,a=e._start,o=e._view;return i&&1!==t?(o||(o=e._view={}),a||(a=e._start={}),function(t,e,i,a){var o,r,s,l,u,d,c,h,f,g=Object.keys(i);for(o=0,r=g.length;o<r;++o)if(d=i[s=g[o]],e.hasOwnProperty(s)||(e[s]=d),(l=e[s])!==d&&"_"!==s[0]){if(t.hasOwnProperty(s)||(t[s]=l),(c=typeof d)==typeof(u=t[s]))if("string"===c){if((h=n(u)).valid&&(f=n(d)).valid){e[s]=f.mix(h,a).rgbString();continue}}else if("number"===c&&isFinite(u)&&isFinite(d)){e[s]=u+(d-u)*a;continue}e[s]=d}}(a,o,i,t),e):(e._view=i,e._start=null,e)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return a.isNumber(this._model.x)&&a.isNumber(this._model.y)}}),o.extend=a.inherits,e.exports=o},{3:3,45:45}],27:[function(t,e,i){"use strict";var n=t(3),a=t(25),o=t(45);e.exports=function(t){function e(t,e,i){var n;return"string"==typeof t?(n=parseInt(t,10),-1!==t.indexOf("%")&&(n=n/100*e.parentNode[i])):n=t,n}function i(t){return null!=t&&"none"!==t}function r(t,n,a){var o=document.defaultView,r=t.parentNode,s=o.getComputedStyle(t)[n],l=o.getComputedStyle(r)[n],u=i(s),d=i(l),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(s,t,a):c,d?e(l,r,a):c):"none"}o.configMerge=function(){return o.merge(o.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(e,i,n,a){var r=i[e]||{},s=n[e];"scales"===e?i[e]=o.scaleMerge(r,s):"scale"===e?i[e]=o.merge(r,[t.scaleService.getScaleDefaults(s.type),s]):o._merger(e,i,n,a)}})},o.scaleMerge=function(){return o.merge(o.clone(arguments[0]),[].slice.call(arguments,1),{merger:function(e,i,n,a){if("xAxes"===e||"yAxes"===e){var r,s,l,u=n[e].length;for(i[e]||(i[e]=[]),r=0;r<u;++r)l=n[e][r],s=o.valueOrDefault(l.type,"xAxes"===e?"category":"linear"),r>=i[e].length&&i[e].push({}),!i[e][r].type||l.type&&l.type!==i[e][r].type?o.merge(i[e][r],[t.scaleService.getScaleDefaults(s),l]):o.merge(i[e][r],l)}else o._merger(e,i,n,a)}})},o.where=function(t,e){if(o.isArray(t)&&Array.prototype.filter)return t.filter(e);var i=[];return o.each(t,function(t){e(t)&&i.push(t)}),i},o.findIndex=Array.prototype.findIndex?function(t,e,i){return t.findIndex(e,i)}:function(t,e,i){i=void 0===i?t:i;for(var n=0,a=t.length;n<a;++n)if(e.call(i,t[n],n,t))return n;return-1},o.findNextWhere=function(t,e,i){o.isNullOrUndef(i)&&(i=-1);for(var n=i+1;n<t.length;n++){var a=t[n];if(e(a))return a}},o.findPreviousWhere=function(t,e,i){o.isNullOrUndef(i)&&(i=t.length);for(var n=i-1;n>=0;n--){var a=t[n];if(e(a))return a}},o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,i){return Math.abs(t-e)<i},o.almostWhole=function(t,e){var i=Math.round(t);return i-e<t&&i+e>t},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){var e=Math.log(t)*Math.LOG10E,i=Math.round(e);return t===Math.pow(10,i)?i:e},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var i=e.x-t.x,n=e.y-t.y,a=Math.sqrt(i*i+n*n),o=Math.atan2(n,i);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:a}},o.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},o.aliasPixel=function(t){return t%2==0?0:.5},o.splineCurve=function(t,e,i,n){var a=t.skip?e:t,o=e,r=i.skip?e:i,s=Math.sqrt(Math.pow(o.x-a.x,2)+Math.pow(o.y-a.y,2)),l=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),u=s/(s+l),d=l/(s+l),c=n*(u=isNaN(u)?0:u),h=n*(d=isNaN(d)?0:d);return{previous:{x:o.x-c*(r.x-a.x),y:o.y-c*(r.y-a.y)},next:{x:o.x+h*(r.x-a.x),y:o.y+h*(r.y-a.y)}}},o.EPSILON=Number.EPSILON||1e-14,o.splineCurveMonotone=function(t){var e,i,n,a,r,s,l,u,d,c=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),h=c.length;for(e=0;e<h;++e)if(!(n=c[e]).model.skip){if(i=e>0?c[e-1]:null,(a=e<h-1?c[e+1]:null)&&!a.model.skip){var f=a.model.x-n.model.x;n.deltaK=0!==f?(a.model.y-n.model.y)/f:0}!i||i.model.skip?n.mK=n.deltaK:!a||a.model.skip?n.mK=i.deltaK:this.sign(i.deltaK)!==this.sign(n.deltaK)?n.mK=0:n.mK=(i.deltaK+n.deltaK)/2}for(e=0;e<h-1;++e)n=c[e],a=c[e+1],n.model.skip||a.model.skip||(o.almostEquals(n.deltaK,0,this.EPSILON)?n.mK=a.mK=0:(r=n.mK/n.deltaK,s=a.mK/n.deltaK,(u=Math.pow(r,2)+Math.pow(s,2))<=9||(l=3/Math.sqrt(u),n.mK=r*l*n.deltaK,a.mK=s*l*n.deltaK)));for(e=0;e<h;++e)(n=c[e]).model.skip||(i=e>0?c[e-1]:null,a=e<h-1?c[e+1]:null,i&&!i.model.skip&&(d=(n.model.x-i.model.x)/3,n.model.controlPointPreviousX=n.model.x-d,n.model.controlPointPreviousY=n.model.y-d*n.mK),a&&!a.model.skip&&(d=(a.model.x-n.model.x)/3,n.model.controlPointNextX=n.model.x+d,n.model.controlPointNextY=n.model.y+d*n.mK))},o.nextItem=function(t,e,i){return i?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,i){return i?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},o.niceNum=function(t,e){var i=Math.floor(o.log10(t)),n=t/Math.pow(10,i);return(e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10)*Math.pow(10,i)},o.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},o.getRelativePosition=function(t,e){var i,n,a=t.originalEvent||t,r=t.currentTarget||t.srcElement,s=r.getBoundingClientRect(),l=a.touches;l&&l.length>0?(i=l[0].clientX,n=l[0].clientY):(i=a.clientX,n=a.clientY);var u=parseFloat(o.getStyle(r,"padding-left")),d=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return{x:i=Math.round((i-s.left-u)/f*r.width/e.currentDevicePixelRatio),y:n=Math.round((n-s.top-d)/g*r.height/e.currentDevicePixelRatio)}},o.getConstraintWidth=function(t){return r(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return r(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode;if(!e)return t.clientWidth;var i=parseInt(o.getStyle(e,"padding-left"),10),n=parseInt(o.getStyle(e,"padding-right"),10),a=e.clientWidth-i-n,r=o.getConstraintWidth(t);return isNaN(r)?a:Math.min(a,r)},o.getMaximumHeight=function(t){var e=t.parentNode;if(!e)return t.clientHeight;var i=parseInt(o.getStyle(e,"padding-top"),10),n=parseInt(o.getStyle(e,"padding-bottom"),10),a=e.clientHeight-i-n,r=o.getConstraintHeight(t);return isNaN(r)?a:Math.min(a,r)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t,e){var i=t.currentDevicePixelRatio=e||window.devicePixelRatio||1;if(1!==i){var n=t.canvas,a=t.height,o=t.width;n.height=a*i,n.width=o*i,t.ctx.scale(i,i),n.style.height||n.style.width||(n.style.height=a+"px",n.style.width=o+"px")}},o.fontString=function(t,e,i){return e+" "+t+"px "+i},o.longestText=function(t,e,i,n){var a=(n=n||{}).data=n.data||{},r=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(a=n.data={},r=n.garbageCollect=[],n.font=e),t.font=e;var s=0;o.each(i,function(e){null!=e&&!0!==o.isArray(e)?s=o.measureText(t,a,r,s,e):o.isArray(e)&&o.each(e,function(e){null==e||o.isArray(e)||(s=o.measureText(t,a,r,s,e))})});var l=r.length/2;if(l>i.length){for(var u=0;u<l;u++)delete a[r[u]];r.splice(0,l)}return s},o.measureText=function(t,e,i,n,a){var o=e[a];return o||(o=e[a]=t.measureText(a).width,i.push(a)),o>n&&(n=o),n},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.color=n?function(t){return t instanceof CanvasGradient&&(t=a.global.defaultColor),n(t)}:function(t){return console.error("Color.js not found!"),t},o.getHoverColor=function(t){return t instanceof CanvasPattern?t:o.color(t).saturate(.5).darken(.1).rgbString()}}},{25:25,3:3,45:45}],28:[function(t,e,i){"use strict";var n=t(45);function a(t,e){return t.native?{x:t.x,y:t.y}:n.getRelativePosition(t,e)}function o(t,e){var i,n,a,o,r;for(n=0,o=t.data.datasets.length;n<o;++n)if(t.isDatasetVisible(n))for(a=0,r=(i=t.getDatasetMeta(n)).data.length;a<r;++a){var s=i.data[a];s._view.skip||e(s)}}function r(t,e){var i=[];return o(t,function(t){t.inRange(e.x,e.y)&&i.push(t)}),i}function s(t,e,i,n){var a=Number.POSITIVE_INFINITY,r=[];return o(t,function(t){if(!i||t.inRange(e.x,e.y)){var o=t.getCenterPoint(),s=n(e,o);s<a?(r=[t],a=s):s===a&&r.push(t)}}),r}function l(t){var e=-1!==t.indexOf("x"),i=-1!==t.indexOf("y");return function(t,n){var a=e?Math.abs(t.x-n.x):0,o=i?Math.abs(t.y-n.y):0;return Math.sqrt(Math.pow(a,2)+Math.pow(o,2))}}function u(t,e,i){var n=a(e,t);i.axis=i.axis||"x";var o=l(i.axis),u=i.intersect?r(t,n):s(t,n,!1,o),d=[];return u.length?(t.data.datasets.forEach(function(e,i){if(t.isDatasetVisible(i)){var n=t.getDatasetMeta(i).data[u[0]._index];n&&!n._view.skip&&d.push(n)}}),d):[]}e.exports={modes:{single:function(t,e){var i=a(e,t),n=[];return o(t,function(t){if(t.inRange(i.x,i.y))return n.push(t),n}),n.slice(0,1)},label:u,index:u,dataset:function(t,e,i){var n=a(e,t);i.axis=i.axis||"xy";var o=l(i.axis),u=i.intersect?r(t,n):s(t,n,!1,o);return u.length>0&&(u=t.getDatasetMeta(u[0]._datasetIndex).data),u},"x-axis":function(t,e){return u(t,e,{intersect:!1})},point:function(t,e){return r(t,a(e,t))},nearest:function(t,e,i){var n=a(e,t);i.axis=i.axis||"xy";var o=l(i.axis),r=s(t,n,i.intersect,o);return r.length>1&&r.sort(function(t,e){var i=t.getArea()-e.getArea();return 0===i&&(i=t._datasetIndex-e._datasetIndex),i}),r.slice(0,1)},x:function(t,e,i){var n=a(e,t),r=[],s=!1;return o(t,function(t){t.inXRange(n.x)&&r.push(t),t.inRange(n.x,n.y)&&(s=!0)}),i.intersect&&!s&&(r=[]),r},y:function(t,e,i){var n=a(e,t),r=[],s=!1;return o(t,function(t){t.inYRange(n.y)&&r.push(t),t.inRange(n.x,n.y)&&(s=!0)}),i.intersect&&!s&&(r=[]),r}}}},{45:45}],29:[function(t,e,i){"use strict";t(25)._set("global",{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},layout:{padding:{top:0,right:0,bottom:0,left:0}}}),e.exports=function(){var t=function(t,e){return this.construct(t,e),this};return t.Chart=t,t}},{25:25}],30:[function(t,e,i){"use strict";var n=t(45);function a(t,e){return n.where(t,function(t){return t.position===e})}function o(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,i){var n=e?i:t,a=e?t:i;return n.weight===a.weight?n._tmpIndex_-a._tmpIndex_:n.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}e.exports={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure:function(t,e,i){for(var n,a=["fullWidth","position","weight"],o=a.length,r=0;r<o;++r)n=a[r],i.hasOwnProperty(n)&&(e[n]=i[n])},update:function(t,e,i){if(t){var r=t.options.layout||{},s=n.options.toPadding(r.padding),l=s.left,u=s.right,d=s.top,c=s.bottom,h=a(t.boxes,"left"),f=a(t.boxes,"right"),g=a(t.boxes,"top"),p=a(t.boxes,"bottom"),m=a(t.boxes,"chartArea");o(h,!0),o(f,!1),o(g,!0),o(p,!1);var v=e-l-u,b=i-d-c,x=b/2,y=(e-v/2)/(h.length+f.length),k=(i-x)/(g.length+p.length),M=v,w=b,S=[];n.each(h.concat(f,g,p),function(t){var e,i=t.isHorizontal();i?(e=t.update(t.fullWidth?v:M,k),w-=e.height):(e=t.update(y,w),M-=e.width),S.push({horizontal:i,minSize:e,box:t})});var C=0,_=0,D=0,I=0;n.each(g.concat(p),function(t){if(t.getPadding){var e=t.getPadding();C=Math.max(C,e.left),_=Math.max(_,e.right)}}),n.each(h.concat(f),function(t){if(t.getPadding){var e=t.getPadding();D=Math.max(D,e.top),I=Math.max(I,e.bottom)}});var P=l,A=u,T=d,F=c;n.each(h.concat(f),N),n.each(h,function(t){P+=t.width}),n.each(f,function(t){A+=t.width}),n.each(g.concat(p),N),n.each(g,function(t){T+=t.height}),n.each(p,function(t){F+=t.height}),n.each(h.concat(f),function(t){var e=n.findNextWhere(S,function(e){return e.box===t}),i={left:0,right:0,top:T,bottom:F};e&&t.update(e.minSize.width,w,i)}),P=l,A=u,T=d,F=c,n.each(h,function(t){P+=t.width}),n.each(f,function(t){A+=t.width}),n.each(g,function(t){T+=t.height}),n.each(p,function(t){F+=t.height});var O=Math.max(C-P,0);P+=O,A+=Math.max(_-A,0);var R=Math.max(D-T,0);T+=R,F+=Math.max(I-F,0);var L=i-T-F,z=e-P-A;z===M&&L===w||(n.each(h,function(t){t.height=L}),n.each(f,function(t){t.height=L}),n.each(g,function(t){t.fullWidth||(t.width=z)}),n.each(p,function(t){t.fullWidth||(t.width=z)}),w=L,M=z);var B=l+O,W=d+R;n.each(h.concat(g),V),B+=M,W+=w,n.each(f,V),n.each(p,V),t.chartArea={left:P,top:T,right:P+M,bottom:T+w},n.each(m,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(M,w)})}function N(t){var e=n.findNextWhere(S,function(e){return e.box===t});if(e)if(t.isHorizontal()){var i={left:Math.max(P,C),right:Math.max(A,_),top:0,bottom:0};t.update(t.fullWidth?v:M,b/2,i)}else t.update(e.minSize.width,w)}function V(t){t.isHorizontal()?(t.left=t.fullWidth?l:P,t.right=t.fullWidth?e-u:P+M,t.top=W,t.bottom=W+t.height,W=t.bottom):(t.left=B,t.right=B+t.width,t.top=T,t.bottom=T+w,B=t.right)}}}},{45:45}],31:[function(t,e,i){"use strict";var n=t(25),a=t(45);n._set("global",{plugins:{}}),e.exports={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){-1===e.indexOf(t)&&e.push(t)}),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var i=e.indexOf(t);-1!==i&&e.splice(i,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e,i){var n,a,o,r,s,l=this.descriptors(t),u=l.length;for(n=0;n<u;++n)if("function"==typeof(s=(o=(a=l[n]).plugin)[e])&&((r=[t].concat(i||[])).push(a.options),!1===s.apply(o,r)))return!1;return!0},descriptors:function(t){var e=t.$plugins||(t.$plugins={});if(e.id===this._cacheId)return e.descriptors;var i=[],o=[],r=t&&t.config||{},s=r.options&&r.options.plugins||{};return this._plugins.concat(r.plugins||[]).forEach(function(t){if(-1===i.indexOf(t)){var e=t.id,r=s[e];!1!==r&&(!0===r&&(r=a.clone(n.global.plugins[e])),i.push(t),o.push({plugin:t,options:r||{}}))}}),e.descriptors=o,e.id=this._cacheId,o},_invalidate:function(t){delete t.$plugins}}},{25:25,45:45}],32:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=t(34);function s(t){var e,i,n=[];for(e=0,i=t.length;e<i;++e)n.push(t[e].label);return n}function l(t,e,i){var n=t.getPixelForTick(e);return i&&(n-=0===e?(t.getPixelForTick(1)-n)/2:(n-t.getPixelForTick(e-1))/2),n}n._set("scale",{display:!0,position:"left",offset:!1,gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{display:!1,labelString:"",lineHeight:1.2,padding:{top:4,bottom:4}},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:r.formatters.values,minor:{},major:{}}}),e.exports=function(t){function e(t,e,i){return o.isArray(e)?o.longestText(t,i,e):t.measureText(e).width}function i(t){var e=o.valueOrDefault,i=n.global,a=e(t.fontSize,i.defaultFontSize),r=e(t.fontStyle,i.defaultFontStyle),s=e(t.fontFamily,i.defaultFontFamily);return{size:a,style:r,family:s,font:o.fontString(a,r,s)}}function r(t){return o.options.toLineHeight(o.valueOrDefault(t.lineHeight,1.2),o.valueOrDefault(t.fontSize,n.global.defaultFontSize))}t.Scale=a.extend({getPadding:function(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}},getTicks:function(){return this._ticks},mergeTicksOptions:function(){var t=this.options.ticks;for(var e in!1===t.minor&&(t.minor={display:!1}),!1===t.major&&(t.major={display:!1}),t)"major"!==e&&"minor"!==e&&(void 0===t.minor[e]&&(t.minor[e]=t[e]),void 0===t.major[e]&&(t.major[e]=t[e]))},beforeUpdate:function(){o.callback(this.options.beforeUpdate,[this])},update:function(t,e,i){var n,a,r,s,l,u,d=this;for(d.beforeUpdate(),d.maxWidth=t,d.maxHeight=e,d.margins=o.extend({left:0,right:0,top:0,bottom:0},i),d.longestTextCache=d.longestTextCache||{},d.beforeSetDimensions(),d.setDimensions(),d.afterSetDimensions(),d.beforeDataLimits(),d.determineDataLimits(),d.afterDataLimits(),d.beforeBuildTicks(),l=d.buildTicks()||[],d.afterBuildTicks(),d.beforeTickToLabelConversion(),r=d.convertTicksToLabels(l)||d.ticks,d.afterTickToLabelConversion(),d.ticks=r,n=0,a=r.length;n<a;++n)s=r[n],(u=l[n])?u.label=s:l.push(u={label:s,major:!1});return d._ticks=l,d.beforeCalculateTickRotation(),d.calculateTickRotation(),d.afterCalculateTickRotation(),d.beforeFit(),d.fit(),d.afterFit(),d.afterUpdate(),d.minSize},afterUpdate:function(){o.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){o.callback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){o.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){o.callback(this.options.beforeDataLimits,[this])},determineDataLimits:o.noop,afterDataLimits:function(){o.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){o.callback(this.options.beforeBuildTicks,[this])},buildTicks:o.noop,afterBuildTicks:function(){o.callback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){o.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this.options.ticks;this.ticks=this.ticks.map(t.userCallback||t.callback,this)},afterTickToLabelConversion:function(){o.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){o.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t=this,e=t.ctx,n=t.options.ticks,a=s(t._ticks),r=i(n);e.font=r.font;var l=n.minRotation||0;if(a.length&&t.options.display&&t.isHorizontal())for(var u,d=o.longestText(e,r.font,a,t.longestTextCache),c=d,h=t.getPixelForTick(1)-t.getPixelForTick(0)-6;c>h&&l<n.maxRotation;){var f=o.toRadians(l);if(u=Math.cos(f),Math.sin(f)*d>t.maxHeight){l--;break}l++,c=u*d}t.labelRotation=l},afterCalculateTickRotation:function(){o.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){o.callback(this.options.beforeFit,[this])},fit:function(){var t=this,n=t.minSize={width:0,height:0},a=s(t._ticks),l=t.options,u=l.ticks,d=l.scaleLabel,c=l.gridLines,h=l.display,f=t.isHorizontal(),g=i(u),p=l.gridLines.tickMarkLength;if(n.width=f?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:h&&c.drawTicks?p:0,n.height=f?h&&c.drawTicks?p:0:t.maxHeight,d.display&&h){var m=r(d)+o.options.toPadding(d.padding).height;f?n.height+=m:n.width+=m}if(u.display&&h){var v=o.longestText(t.ctx,g.font,a,t.longestTextCache),b=o.numberOfLabelLines(a),x=.5*g.size,y=t.options.ticks.padding;if(f){t.longestLabelWidth=v;var k=o.toRadians(t.labelRotation),M=Math.cos(k),w=Math.sin(k)*v+g.size*b+x*(b-1)+x;n.height=Math.min(t.maxHeight,n.height+w+y),t.ctx.font=g.font;var S=e(t.ctx,a[0],g.font),C=e(t.ctx,a[a.length-1],g.font);0!==t.labelRotation?(t.paddingLeft="bottom"===l.position?M*S+3:M*x+3,t.paddingRight="bottom"===l.position?M*x+3:M*C+3):(t.paddingLeft=S/2+3,t.paddingRight=C/2+3)}else u.mirror?v=0:v+=y+x,n.width=Math.min(t.maxWidth,n.width+v),t.paddingTop=g.size/2,t.paddingBottom=g.size/2}t.handleMargins(),t.width=n.width,t.height=n.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){o.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(o.isNullOrUndef(t))return NaN;if("number"==typeof t&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},getLabelForIndex:o.noop,getPixelForValue:o.noop,getValueForPixel:o.noop,getPixelForTick:function(t){var e=this,i=e.options.offset;if(e.isHorizontal()){var n=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(i?0:1),1),a=n*t+e.paddingLeft;i&&(a+=n/2);var o=e.left+Math.round(a);return o+=e.isFullWidth()?e.margins.left:0}var r=e.height-(e.paddingTop+e.paddingBottom);return e.top+t*(r/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var i=(e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,i,n,a,r=this,s=r.isHorizontal(),l=r.options.ticks.minor,u=t.length,d=o.toRadians(r.labelRotation),c=Math.cos(d),h=r.longestLabelWidth*c,f=[];for(l.maxTicksLimit&&(a=l.maxTicksLimit),s&&(e=!1,(h+l.autoSkipPadding)*u>r.width-(r.paddingLeft+r.paddingRight)&&(e=1+Math.floor((h+l.autoSkipPadding)*u/(r.width-(r.paddingLeft+r.paddingRight)))),a&&u>a&&(e=Math.max(e,Math.floor(u/a)))),i=0;i<u;i++)n=t[i],(e>1&&i%e>0||i%e==0&&i+e>=u)&&i!==u-1&&delete n.label,f.push(n);return f},draw:function(t){var e=this,a=e.options;if(a.display){var s=e.ctx,u=n.global,d=a.ticks.minor,c=a.ticks.major||d,h=a.gridLines,f=a.scaleLabel,g=0!==e.labelRotation,p=e.isHorizontal(),m=d.autoSkip?e._autoSkip(e.getTicks()):e.getTicks(),v=o.valueOrDefault(d.fontColor,u.defaultFontColor),b=i(d),x=o.valueOrDefault(c.fontColor,u.defaultFontColor),y=i(c),k=h.drawTicks?h.tickMarkLength:0,M=o.valueOrDefault(f.fontColor,u.defaultFontColor),w=i(f),S=o.options.toPadding(f.padding),C=o.toRadians(e.labelRotation),_=[],D=e.options.gridLines.lineWidth,I="right"===a.position?e.right:e.right-D-k,P="right"===a.position?e.right+k:e.right,A="bottom"===a.position?e.top+D:e.bottom-k-D,T="bottom"===a.position?e.top+D+k:e.bottom+D;if(o.each(m,function(i,n){if(!o.isNullOrUndef(i.label)){var r,s,c,f,v,b,x,y,M,w,S,F,O,R,L=i.label;n===e.zeroLineIndex&&a.offset===h.offsetGridLines?(r=h.zeroLineWidth,s=h.zeroLineColor,c=h.zeroLineBorderDash,f=h.zeroLineBorderDashOffset):(r=o.valueAtIndexOrDefault(h.lineWidth,n),s=o.valueAtIndexOrDefault(h.color,n),c=o.valueOrDefault(h.borderDash,u.borderDash),f=o.valueOrDefault(h.borderDashOffset,u.borderDashOffset));var z="middle",B="middle",W=d.padding;if(p){var N=k+W;"bottom"===a.position?(B=g?"middle":"top",z=g?"right":"center",R=e.top+N):(B=g?"middle":"bottom",z=g?"left":"center",R=e.bottom-N);var V=l(e,n,h.offsetGridLines&&m.length>1);V<e.left&&(s="rgba(0,0,0,0)"),V+=o.aliasPixel(r),O=e.getPixelForTick(n)+d.labelOffset,v=x=M=S=V,b=A,y=T,w=t.top,F=t.bottom+D}else{var E,H="left"===a.position;d.mirror?(z=H?"left":"right",E=W):(z=H?"right":"left",E=k+W),O=H?e.right-E:e.left+E;var j=l(e,n,h.offsetGridLines&&m.length>1);j<e.top&&(s="rgba(0,0,0,0)"),j+=o.aliasPixel(r),R=e.getPixelForTick(n)+d.labelOffset,v=I,x=P,M=t.left,S=t.right+D,b=y=w=F=j}_.push({tx1:v,ty1:b,tx2:x,ty2:y,x1:M,y1:w,x2:S,y2:F,labelX:O,labelY:R,glWidth:r,glColor:s,glBorderDash:c,glBorderDashOffset:f,rotation:-1*C,label:L,major:i.major,textBaseline:B,textAlign:z})}}),o.each(_,function(t){if(h.display&&(s.save(),s.lineWidth=t.glWidth,s.strokeStyle=t.glColor,s.setLineDash&&(s.setLineDash(t.glBorderDash),s.lineDashOffset=t.glBorderDashOffset),s.beginPath(),h.drawTicks&&(s.moveTo(t.tx1,t.ty1),s.lineTo(t.tx2,t.ty2)),h.drawOnChartArea&&(s.moveTo(t.x1,t.y1),s.lineTo(t.x2,t.y2)),s.stroke(),s.restore()),d.display){s.save(),s.translate(t.labelX,t.labelY),s.rotate(t.rotation),s.font=t.major?y.font:b.font,s.fillStyle=t.major?x:v,s.textBaseline=t.textBaseline,s.textAlign=t.textAlign;var i=t.label;if(o.isArray(i))for(var n=i.length,a=1.5*b.size,r=e.isHorizontal()?0:-a*(n-1)/2,l=0;l<n;++l)s.fillText(""+i[l],0,r),r+=a;else s.fillText(i,0,0);s.restore()}}),f.display){var F,O,R=0,L=r(f)/2;if(p)F=e.left+(e.right-e.left)/2,O="bottom"===a.position?e.bottom-L-S.bottom:e.top+L+S.top;else{var z="left"===a.position;F=z?e.left+L+S.top:e.right-L-S.top,O=e.top+(e.bottom-e.top)/2,R=z?-.5*Math.PI:.5*Math.PI}s.save(),s.translate(F,O),s.rotate(R),s.textAlign="center",s.textBaseline="middle",s.fillStyle=M,s.font=w.font,s.fillText(f.labelString,0,0),s.restore()}if(h.drawBorder){s.lineWidth=o.valueAtIndexOrDefault(h.lineWidth,0),s.strokeStyle=o.valueAtIndexOrDefault(h.color,0);var B=e.left,W=e.right+D,N=e.top,V=e.bottom+D,E=o.aliasPixel(s.lineWidth);p?(N=V="top"===a.position?e.bottom:e.top,N+=E,V+=E):(B=W="left"===a.position?e.right:e.left,B+=E,W+=E),s.beginPath(),s.moveTo(B,N),s.lineTo(W,V),s.stroke()}}}})}},{25:25,26:26,34:34,45:45}],33:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(30);e.exports=function(t){t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,e,i){this.constructors[t]=e,this.defaults[t]=a.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?a.merge({},[n.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){this.defaults.hasOwnProperty(t)&&(this.defaults[t]=a.extend(this.defaults[t],e))},addScalesToLayout:function(t){a.each(t.scales,function(e){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,o.addBox(t,e)})}}}},{25:25,30:30,45:45}],34:[function(t,e,i){"use strict";var n=t(45);e.exports={formatters:{values:function(t){return n.isArray(t)?t:""+t},linear:function(t,e,i){var a=i.length>3?i[2]-i[1]:i[1]-i[0];Math.abs(a)>1&&t!==Math.floor(t)&&(a=t-Math.floor(t));var o=n.log10(Math.abs(a)),r="";if(0!==t){var s=-1*Math.floor(o);s=Math.max(Math.min(s,20),0),r=t.toFixed(s)}else r="0";return r},logarithmic:function(t,e,i){var a=t/Math.pow(10,Math.floor(n.log10(t)));return 0===t?"0":1===a||2===a||5===a||0===e||e===i.length-1?t.toExponential():""}}}},{45:45}],35:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:o.noop,title:function(t,e){var i="",n=e.labels,a=n?n.length:0;if(t.length>0){var o=t[0];o.xLabel?i=o.xLabel:a>0&&o.index<a&&(i=n[o.index])}return i},afterTitle:o.noop,beforeBody:o.noop,beforeLabel:o.noop,label:function(t,e){var i=e.datasets[t.datasetIndex].label||"";return i&&(i+=": "),i+=t.yLabel},labelColor:function(t,e){var i=e.getDatasetMeta(t.datasetIndex).data[t.index]._view;return{borderColor:i.borderColor,backgroundColor:i.backgroundColor}},labelTextColor:function(){return this._options.bodyFontColor},afterLabel:o.noop,afterBody:o.noop,beforeFooter:o.noop,footer:o.noop,afterFooter:o.noop}}}),e.exports=function(t){function e(t,e){var i=o.color(t);return i.alpha(e*i.alpha()).rgbaString()}function i(t,e){return e&&(o.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function r(t){var e=n.global,i=o.valueOrDefault;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,bodyFontColor:t.bodyFontColor,_bodyFontFamily:i(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:i(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:i(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:i(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:i(t.titleFontStyle,e.defaultFontStyle),titleFontSize:i(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:i(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:i(t.footerFontStyle,e.defaultFontStyle),footerFontSize:i(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}t.Tooltip=a.extend({initialize:function(){this._model=r(this._options),this._lastActive=[]},getTitle:function(){var t=this._options.callbacks,e=t.beforeTitle.apply(this,arguments),n=t.title.apply(this,arguments),a=t.afterTitle.apply(this,arguments),o=[];return o=i(o=i(o=i(o,e),n),a)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return o.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,e){var n=this,a=n._options.callbacks,r=[];return o.each(t,function(t){var o={before:[],lines:[],after:[]};i(o.before,a.beforeLabel.call(n,t,e)),i(o.lines,a.label.call(n,t,e)),i(o.after,a.afterLabel.call(n,t,e)),r.push(o)}),r},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return o.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this._options.callbacks,e=t.beforeFooter.apply(this,arguments),n=t.footer.apply(this,arguments),a=t.afterFooter.apply(this,arguments),o=[];return o=i(o=i(o=i(o,e),n),a)},update:function(e){var i,n,a,s,l,u,d,c,h,f,g,p,m,v,b,x,y,k,M,w,S=this,C=S._options,_=S._model,D=S._model=r(C),I=S._active,P=S._data,A={xAlign:_.xAlign,yAlign:_.yAlign},T={x:_.x,y:_.y},F={width:_.width,height:_.height},O={x:_.caretX,y:_.caretY};if(I.length){D.opacity=1;var R=[],L=[];O=t.Tooltip.positioners[C.position].call(S,I,S._eventPosition);var z=[];for(i=0,n=I.length;i<n;++i)z.push((x=I[i],y=void 0,k=void 0,void 0,void 0,y=x._xScale,k=x._yScale||x._scale,M=x._index,w=x._datasetIndex,{xLabel:y?y.getLabelForIndex(M,w):"",yLabel:k?k.getLabelForIndex(M,w):"",index:M,datasetIndex:w,x:x._model.x,y:x._model.y}));C.filter&&(z=z.filter(function(t){return C.filter(t,P)})),C.itemSort&&(z=z.sort(function(t,e){return C.itemSort(t,e,P)})),o.each(z,function(t){R.push(C.callbacks.labelColor.call(S,t,S._chart)),L.push(C.callbacks.labelTextColor.call(S,t,S._chart))}),D.title=S.getTitle(z,P),D.beforeBody=S.getBeforeBody(z,P),D.body=S.getBody(z,P),D.afterBody=S.getAfterBody(z,P),D.footer=S.getFooter(z,P),D.x=Math.round(O.x),D.y=Math.round(O.y),D.caretPadding=C.caretPadding,D.labelColors=R,D.labelTextColors=L,D.dataPoints=z,A=function(t,e){var i,n,a,o,r,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",c="center";s.y<e.height?c="top":s.y>l.height-e.height&&(c="bottom");var h=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===c?(i=function(t){return t<=h},n=function(t){return t>h}):(i=function(t){return t<=e.width/2},n=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},o=function(t){return t-e.width-s.caretSize-s.caretPadding<0},r=function(t){return t<=f?"top":"bottom"},i(s.x)?(d="left",a(s.x)&&(d="center",c=r(s.y))):n(s.x)&&(d="right",o(s.x)&&(d="center",c=r(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:c}}(this,F=function(t,e){var i=t._chart.ctx,n=2*e.yPadding,a=0,r=e.body,s=r.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);s+=e.beforeBody.length+e.afterBody.length;var l=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;n+=l*d,n+=l?(l-1)*e.titleSpacing:0,n+=l?e.titleMarginBottom:0,n+=s*c,n+=s?(s-1)*e.bodySpacing:0,n+=u?e.footerMarginTop:0,n+=u*h,n+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){a=Math.max(a,i.measureText(t).width+f)};return i.font=o.fontString(d,e._titleFontStyle,e._titleFontFamily),o.each(e.title,g),i.font=o.fontString(c,e._bodyFontStyle,e._bodyFontFamily),o.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,o.each(r,function(t){o.each(t.before,g),o.each(t.lines,g),o.each(t.after,g)}),f=0,i.font=o.fontString(h,e._footerFontStyle,e._footerFontFamily),o.each(e.footer,g),{width:a+=2*e.xPadding,height:n}}(this,D)),a=D,s=F,l=A,u=S._chart,d=a.x,c=a.y,h=a.caretSize,f=a.caretPadding,g=a.cornerRadius,p=l.xAlign,m=l.yAlign,v=h+f,b=g+f,"right"===p?d-=s.width:"center"===p&&((d-=s.width/2)+s.width>u.width&&(d=u.width-s.width),d<0&&(d=0)),"top"===m?c+=v:c-="bottom"===m?s.height+v:s.height/2,"center"===m?"left"===p?d+=v:"right"===p&&(d-=v):"left"===p?d-=b:"right"===p&&(d+=b),T={x:d,y:c}}else D.opacity=0;return D.xAlign=A.xAlign,D.yAlign=A.yAlign,D.x=T.x,D.y=T.y,D.width=F.width,D.height=F.height,D.caretX=O.x,D.caretY=O.y,S._model=D,e&&C.custom&&C.custom.call(S,D),S},drawCaret:function(t,e){var i=this._chart.ctx,n=this._view,a=this.getCaretPosition(t,e,n);i.lineTo(a.x1,a.y1),i.lineTo(a.x2,a.y2),i.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,i){var n,a,o,r,s,l,u=i.caretSize,d=i.cornerRadius,c=i.xAlign,h=i.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===h)s=g+m/2,"left"===c?(a=(n=f)-u,o=n,r=s+u,l=s-u):(a=(n=f+p)+u,o=n,r=s-u,l=s+u);else if("left"===c?(n=(a=f+d+u)-u,o=a+u):"right"===c?(n=(a=f+p-d-u)-u,o=a+u):(n=(a=i.caretX)-u,o=a+u),"top"===h)s=(r=g)-u,l=r;else{s=(r=g+m)+u,l=r;var v=o;o=n,n=v}return{x1:n,x2:a,x3:o,y1:r,y2:s,y3:l}},drawTitle:function(t,i,n,a){var r=i.title;if(r.length){n.textAlign=i._titleAlign,n.textBaseline="top";var s,l,u=i.titleFontSize,d=i.titleSpacing;for(n.fillStyle=e(i.titleFontColor,a),n.font=o.fontString(u,i._titleFontStyle,i._titleFontFamily),s=0,l=r.length;s<l;++s)n.fillText(r[s],t.x,t.y),t.y+=u+d,s+1===r.length&&(t.y+=i.titleMarginBottom-d)}},drawBody:function(t,i,n,a){var r=i.bodyFontSize,s=i.bodySpacing,l=i.body;n.textAlign=i._bodyAlign,n.textBaseline="top",n.font=o.fontString(r,i._bodyFontStyle,i._bodyFontFamily);var u=0,d=function(e){n.fillText(e,t.x+u,t.y),t.y+=r+s};n.fillStyle=e(i.bodyFontColor,a),o.each(i.beforeBody,d);var c=i.displayColors;u=c?r+2:0,o.each(l,function(s,l){var u=e(i.labelTextColors[l],a);n.fillStyle=u,o.each(s.before,d),o.each(s.lines,function(o){c&&(n.fillStyle=e(i.legendColorBackground,a),n.fillRect(t.x,t.y,r,r),n.lineWidth=1,n.strokeStyle=e(i.labelColors[l].borderColor,a),n.strokeRect(t.x,t.y,r,r),n.fillStyle=e(i.labelColors[l].backgroundColor,a),n.fillRect(t.x+1,t.y+1,r-2,r-2),n.fillStyle=u),d(o)}),o.each(s.after,d)}),u=0,o.each(i.afterBody,d),t.y-=s},drawFooter:function(t,i,n,a){var r=i.footer;r.length&&(t.y+=i.footerMarginTop,n.textAlign=i._footerAlign,n.textBaseline="top",n.fillStyle=e(i.footerFontColor,a),n.font=o.fontString(i.footerFontSize,i._footerFontStyle,i._footerFontFamily),o.each(r,function(e){n.fillText(e,t.x,t.y),t.y+=i.footerFontSize+i.footerSpacing}))},drawBackground:function(t,i,n,a,o){n.fillStyle=e(i.backgroundColor,o),n.strokeStyle=e(i.borderColor,o),n.lineWidth=i.borderWidth;var r=i.xAlign,s=i.yAlign,l=t.x,u=t.y,d=a.width,c=a.height,h=i.cornerRadius;n.beginPath(),n.moveTo(l+h,u),"top"===s&&this.drawCaret(t,a),n.lineTo(l+d-h,u),n.quadraticCurveTo(l+d,u,l+d,u+h),"center"===s&&"right"===r&&this.drawCaret(t,a),n.lineTo(l+d,u+c-h),n.quadraticCurveTo(l+d,u+c,l+d-h,u+c),"bottom"===s&&this.drawCaret(t,a),n.lineTo(l+h,u+c),n.quadraticCurveTo(l,u+c,l,u+c-h),"center"===s&&"left"===r&&this.drawCaret(t,a),n.lineTo(l,u+h),n.quadraticCurveTo(l,u,l+h,u),n.closePath(),n.fill(),i.borderWidth>0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var i={width:e.width,height:e.height},n={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,o=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&o&&(this.drawBackground(n,e,t,i,a),n.x+=e.xPadding,n.y+=e.yPadding,this.drawTitle(n,e,t,a),this.drawBody(n,e,t,a),this.drawFooter(n,e,t,a))}},handleEvent:function(t){var e,i=this,n=i._options;return i._lastActive=i._lastActive||[],"mouseout"===t.type?i._active=[]:i._active=i._chart.getElementsAtEventForMode(t,n.mode,n),(e=!o.arrayEquals(i._active,i._lastActive))&&(i._lastActive=i._active,(n.enabled||n.custom)&&(i._eventPosition={x:t.x,y:t.y},i.update(!0),i.pivot())),e}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,i,n=0,a=0,o=0;for(e=0,i=t.length;e<i;++e){var r=t[e];if(r&&r.hasValue()){var s=r.tooltipPosition();n+=s.x,a+=s.y,++o}}return{x:Math.round(n/o),y:Math.round(a/o)}},nearest:function(t,e){var i,n,a,r=e.x,s=e.y,l=Number.POSITIVE_INFINITY;for(i=0,n=t.length;i<n;++i){var u=t[i];if(u&&u.hasValue()){var d=u.getCenterPoint(),c=o.distanceBetweenPoints(e,d);c<l&&(l=c,a=u)}}if(a){var h=a.tooltipPosition();r=h.x,s=h.y}return{x:r,y:s}}}}},{25:25,26:26,45:45}],36:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45);n._set("global",{elements:{arc:{backgroundColor:n.global.defaultColor,borderColor:"#fff",borderWidth:2}}}),e.exports=a.extend({inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2)},inRange:function(t,e){var i=this._view;if(i){for(var n=o.getAngleFromPoint(i,{x:t,y:e}),a=n.angle,r=n.distance,s=i.startAngle,l=i.endAngle;l<s;)l+=2*Math.PI;for(;a>l;)a-=2*Math.PI;for(;a<s;)a+=2*Math.PI;var u=a>=s&&a<=l,d=r>=i.innerRadius&&r<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,i=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,i=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},draw:function(){var t=this._chart.ctx,e=this._view,i=e.startAngle,n=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,i,n),t.arc(e.x,e.y,e.innerRadius,n,i,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})},{25:25,26:26,45:45}],37:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=n.global;n._set("global",{elements:{line:{tension:.4,backgroundColor:r.defaultColor,borderWidth:3,borderColor:r.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}}),e.exports=a.extend({draw:function(){var t,e,i,n,a=this._view,s=this._chart.ctx,l=a.spanGaps,u=this._children.slice(),d=r.elements.line,c=-1;for(this._loop&&u.length&&u.push(u[0]),s.save(),s.lineCap=a.borderCapStyle||d.borderCapStyle,s.setLineDash&&s.setLineDash(a.borderDash||d.borderDash),s.lineDashOffset=a.borderDashOffset||d.borderDashOffset,s.lineJoin=a.borderJoinStyle||d.borderJoinStyle,s.lineWidth=a.borderWidth||d.borderWidth,s.strokeStyle=a.borderColor||r.defaultColor,s.beginPath(),c=-1,t=0;t<u.length;++t)e=u[t],i=o.previousItem(u,t),n=e._view,0===t?n.skip||(s.moveTo(n.x,n.y),c=t):(i=-1===c?i:u[c],n.skip||(c!==t-1&&!l||-1===c?s.moveTo(n.x,n.y):o.canvas.lineTo(s,i._view,e._view),c=t));s.stroke(),s.restore()}})},{25:25,26:26,45:45}],38:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=n.global.defaultColor;function s(t){var e=this._view;return!!e&&Math.abs(t-e.x)<e.radius+e.hitRadius}n._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:r,borderColor:r,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}}),e.exports=a.extend({inRange:function(t,e){var i=this._view;return!!i&&Math.pow(t-i.x,2)+Math.pow(e-i.y,2)<Math.pow(i.hitRadius+i.radius,2)},inLabelRange:s,inXRange:s,inYRange:function(t){var e=this._view;return!!e&&Math.abs(t-e.y)<e.radius+e.hitRadius},getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(t){var e=this._view,i=this._model,a=this._chart.ctx,s=e.pointStyle,l=e.radius,u=e.x,d=e.y,c=o.color,h=0;e.skip||(a.strokeStyle=e.borderColor||r,a.lineWidth=o.valueOrDefault(e.borderWidth,n.global.elements.point.borderWidth),a.fillStyle=e.backgroundColor||r,void 0!==t&&(i.x<t.left||1.01*t.right<i.x||i.y<t.top||1.01*t.bottom<i.y)&&(i.x<t.left?h=(u-i.x)/(t.left-i.x):1.01*t.right<i.x?h=(i.x-u)/(i.x-t.right):i.y<t.top?h=(d-i.y)/(t.top-i.y):1.01*t.bottom<i.y&&(h=(i.y-d)/(i.y-t.bottom)),h=Math.round(100*h)/100,a.strokeStyle=c(a.strokeStyle).alpha(h).rgbString(),a.fillStyle=c(a.fillStyle).alpha(h).rgbString()),o.canvas.drawPoint(a,s,l,u,d))}})},{25:25,26:26,45:45}],39:[function(t,e,i){"use strict";var n=t(25),a=t(26);function o(t){return void 0!==t._view.width}function r(t){var e,i,n,a,r=t._view;if(o(t)){var s=r.width/2;e=r.x-s,i=r.x+s,n=Math.min(r.y,r.base),a=Math.max(r.y,r.base)}else{var l=r.height/2;e=Math.min(r.x,r.base),i=Math.max(r.x,r.base),n=r.y-l,a=r.y+l}return{left:e,top:n,right:i,bottom:a}}n._set("global",{elements:{rectangle:{backgroundColor:n.global.defaultColor,borderColor:n.global.defaultColor,borderSkipped:"bottom",borderWidth:0}}}),e.exports=a.extend({draw:function(){var t,e,i,n,a,o,r,s=this._chart.ctx,l=this._view,u=l.borderWidth;if(l.horizontal?(t=l.base,e=l.x,i=l.y-l.height/2,n=l.y+l.height/2,a=e>t?1:-1,o=1,r=l.borderSkipped||"left"):(t=l.x-l.width/2,e=l.x+l.width/2,i=l.y,a=1,o=(n=l.base)>i?1:-1,r=l.borderSkipped||"bottom"),u){var d=Math.min(Math.abs(t-e),Math.abs(i-n)),c=(u=u>d?d:u)/2,h=t+("left"!==r?c*a:0),f=e+("right"!==r?-c*a:0),g=i+("top"!==r?c*o:0),p=n+("bottom"!==r?-c*o:0);h!==f&&(i=g,n=p),g!==p&&(t=h,e=f)}s.beginPath(),s.fillStyle=l.backgroundColor,s.strokeStyle=l.borderColor,s.lineWidth=u;var m=[[t,n],[t,i],[e,i],[e,n]],v=["bottom","left","top","right"].indexOf(r,0);function b(t){return m[(v+t)%4]}-1===v&&(v=0);var x=b(0);s.moveTo(x[0],x[1]);for(var y=1;y<4;y++)x=b(y),s.lineTo(x[0],x[1]);s.fill(),u&&s.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var n=r(this);i=t>=n.left&&t<=n.right&&e>=n.top&&e<=n.bottom}return i},inLabelRange:function(t,e){if(!this._view)return!1;var i=r(this);return o(this)?t>=i.left&&t<=i.right:e>=i.top&&e<=i.bottom},inXRange:function(t){var e=r(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=r(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,e,i=this._view;return o(this)?(t=i.x,e=(i.y+i.base)/2):(t=(i.x+i.base)/2,e=i.y),{x:t,y:e}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})},{25:25,26:26}],40:[function(t,e,i){"use strict";e.exports={},e.exports.Arc=t(36),e.exports.Line=t(37),e.exports.Point=t(38),e.exports.Rectangle=t(39)},{36:36,37:37,38:38,39:39}],41:[function(t,e,i){"use strict";var n=t(42);i=e.exports={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,i,n,a,o){if(o){var r=Math.min(o,n/2),s=Math.min(o,a/2);t.moveTo(e+r,i),t.lineTo(e+n-r,i),t.quadraticCurveTo(e+n,i,e+n,i+s),t.lineTo(e+n,i+a-s),t.quadraticCurveTo(e+n,i+a,e+n-r,i+a),t.lineTo(e+r,i+a),t.quadraticCurveTo(e,i+a,e,i+a-s),t.lineTo(e,i+s),t.quadraticCurveTo(e,i,e+r,i)}else t.rect(e,i,n,a)},drawPoint:function(t,e,i,n,a){var o,r,s,l,u,d;if(!e||"object"!=typeof e||"[object HTMLImageElement]"!==(o=e.toString())&&"[object HTMLCanvasElement]"!==o){if(!(isNaN(i)||i<=0)){switch(e){default:t.beginPath(),t.arc(n,a,i,0,2*Math.PI),t.closePath(),t.fill();break;case"triangle":t.beginPath(),u=(r=3*i/Math.sqrt(3))*Math.sqrt(3)/2,t.moveTo(n-r/2,a+u/3),t.lineTo(n+r/2,a+u/3),t.lineTo(n,a-2*u/3),t.closePath(),t.fill();break;case"rect":d=1/Math.SQRT2*i,t.beginPath(),t.fillRect(n-d,a-d,2*d,2*d),t.strokeRect(n-d,a-d,2*d,2*d);break;case"rectRounded":var c=i/Math.SQRT2,h=n-c,f=a-c,g=Math.SQRT2*i;t.beginPath(),this.roundedRect(t,h,f,g,g,i/2),t.closePath(),t.fill();break;case"rectRot":d=1/Math.SQRT2*i,t.beginPath(),t.moveTo(n-d,a),t.lineTo(n,a+d),t.lineTo(n+d,a),t.lineTo(n,a-d),t.closePath(),t.fill();break;case"cross":t.beginPath(),t.moveTo(n,a+i),t.lineTo(n,a-i),t.moveTo(n-i,a),t.lineTo(n+i,a),t.closePath();break;case"crossRot":t.beginPath(),s=Math.cos(Math.PI/4)*i,l=Math.sin(Math.PI/4)*i,t.moveTo(n-s,a-l),t.lineTo(n+s,a+l),t.moveTo(n-s,a+l),t.lineTo(n+s,a-l),t.closePath();break;case"star":t.beginPath(),t.moveTo(n,a+i),t.lineTo(n,a-i),t.moveTo(n-i,a),t.lineTo(n+i,a),s=Math.cos(Math.PI/4)*i,l=Math.sin(Math.PI/4)*i,t.moveTo(n-s,a-l),t.lineTo(n+s,a+l),t.moveTo(n-s,a+l),t.lineTo(n+s,a-l),t.closePath();break;case"line":t.beginPath(),t.moveTo(n-i,a),t.lineTo(n+i,a),t.closePath();break;case"dash":t.beginPath(),t.moveTo(n,a),t.lineTo(n+i,a),t.closePath()}t.stroke()}}else t.drawImage(e,n-e.width/2,a-e.height/2,e.width,e.height)},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,i,n){if(i.steppedLine)return"after"===i.steppedLine&&!n||"after"!==i.steppedLine&&n?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y),void t.lineTo(i.x,i.y);i.tension?t.bezierCurveTo(n?e.controlPointPreviousX:e.controlPointNextX,n?e.controlPointPreviousY:e.controlPointNextY,n?i.controlPointNextX:i.controlPointPreviousX,n?i.controlPointNextY:i.controlPointPreviousY,i.x,i.y):t.lineTo(i.x,i.y)}};n.clear=i.clear,n.drawRoundedRectangle=function(t){t.beginPath(),i.roundedRect.apply(i,arguments),t.closePath()}},{42:42}],42:[function(t,e,i){"use strict";var n,a={noop:function(){},uid:(n=0,function(){return n++}),isNullOrUndef:function(t){return null==t},isArray:Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,i){return a.valueOrDefault(a.isArray(t)?t[e]:t,i)},callback:function(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)},each:function(t,e,i,n){var o,r,s;if(a.isArray(t))if(r=t.length,n)for(o=r-1;o>=0;o--)e.call(i,t[o],o);else for(o=0;o<r;o++)e.call(i,t[o],o);else if(a.isObject(t))for(r=(s=Object.keys(t)).length,o=0;o<r;o++)e.call(i,t[s[o]],s[o])},arrayEquals:function(t,e){var i,n,o,r;if(!t||!e||t.length!==e.length)return!1;for(i=0,n=t.length;i<n;++i)if(o=t[i],r=e[i],o instanceof Array&&r instanceof Array){if(!a.arrayEquals(o,r))return!1}else if(o!==r)return!1;return!0},clone:function(t){if(a.isArray(t))return t.map(a.clone);if(a.isObject(t)){for(var e={},i=Object.keys(t),n=i.length,o=0;o<n;++o)e[i[o]]=a.clone(t[i[o]]);return e}return t},_merger:function(t,e,i,n){var o=e[t],r=i[t];a.isObject(o)&&a.isObject(r)?a.merge(o,r,n):e[t]=a.clone(r)},_mergerIf:function(t,e,i){var n=e[t],o=i[t];a.isObject(n)&&a.isObject(o)?a.mergeIf(n,o):e.hasOwnProperty(t)||(e[t]=a.clone(o))},merge:function(t,e,i){var n,o,r,s,l,u=a.isArray(e)?e:[e],d=u.length;if(!a.isObject(t))return t;for(n=(i=i||{}).merger||a._merger,o=0;o<d;++o)if(e=u[o],a.isObject(e))for(l=0,s=(r=Object.keys(e)).length;l<s;++l)n(r[l],t,e,i);return t},mergeIf:function(t,e){return a.merge(t,e,{merger:a._mergerIf})},extend:function(t){for(var e=function(e,i){t[i]=e},i=1,n=arguments.length;i<n;++i)a.each(arguments[i],e);return t},inherits:function(t){var e=this,i=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},n=function(){this.constructor=i};return n.prototype=e.prototype,i.prototype=new n,i.extend=a.inherits,t&&a.extend(i.prototype,t),i.__super__=e.prototype,i}};e.exports=a,a.callCallback=a.callback,a.indexOf=function(t,e,i){return Array.prototype.indexOf.call(t,e,i)},a.getValueOrDefault=a.valueOrDefault,a.getValueAtIndexOrDefault=a.valueAtIndexOrDefault},{}],43:[function(t,e,i){"use strict";var n=t(42),a={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return(t-=1)*t*t+1},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-((t-=1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return(t-=1)*t*t*t*t+1},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return 1-Math.cos(t*(Math.PI/2))},easeOutSine:function(t){return Math.sin(t*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t)-1)},easeInExpo:function(t){return 0===t?0:Math.pow(2,10*(t-1))},easeOutExpo:function(t){return 1===t?1:1-Math.pow(2,-10*t)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*--t))},easeInCirc:function(t){return t>=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),-n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i))},easeOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),n*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/i)+1)},easeInOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:2==(t/=.5)?1:(i||(i=.45),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),t<1?n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*-.5:n*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*.5+1)},easeInBack:function(t){return t*t*(2.70158*t-1.70158)},easeOutBack:function(t){return(t-=1)*t*(2.70158*t+1.70158)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-a.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*a.easeInBounce(2*t):.5*a.easeOutBounce(2*t-1)+.5}};e.exports={effects:a},n.easingEffects=a},{42:42}],44:[function(t,e,i){"use strict";var n=t(42);e.exports={toLineHeight:function(t,e){var i=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,i,a,o;return n.isObject(t)?(e=+t.top||0,i=+t.right||0,a=+t.bottom||0,o=+t.left||0):e=i=a=o=+t||0,{top:e,right:i,bottom:a,left:o,height:e+a,width:o+i}},resolve:function(t,e,i){var a,o,r;for(a=0,o=t.length;a<o;++a)if(void 0!==(r=t[a])&&(void 0!==e&&"function"==typeof r&&(r=r(e)),void 0!==i&&n.isArray(r)&&(r=r[i]),void 0!==r))return r}}},{42:42}],45:[function(t,e,i){"use strict";e.exports=t(42),e.exports.easing=t(43),e.exports.canvas=t(41),e.exports.options=t(44)},{41:41,42:42,43:43,44:44}],46:[function(t,e,i){e.exports={acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}}},{}],47:[function(t,e,i){"use strict";var n=t(45),a="$chartjs",o="chartjs-",r=o+"render-monitor",s=o+"render-animation",l=["animationstart","webkitAnimationStart"],u={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function d(t,e){var i=n.getStyle(t,e),a=i&&i.match(/^(\d+)(\.\d+)?px$/);return a?Number(a[1]):void 0}var c=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function h(t,e,i){t.addEventListener(e,i,c)}function f(t,e,i){t.removeEventListener(e,i,c)}function g(t,e,i,n,a){return{type:t,chart:e,native:a||null,x:void 0!==i?i:null,y:void 0!==n?n:null}}function p(t,e,i){var u,d,c,f,p,m,v,b,x=t[a]||(t[a]={}),y=x.resizer=function(t){var e=document.createElement("div"),i=o+"size-monitor",n="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;";e.style.cssText=n,e.className=i,e.innerHTML='<div class="'+i+'-expand" style="'+n+'"><div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div></div><div class="'+i+'-shrink" style="'+n+'"><div style="position:absolute;width:200%;height:200%;left:0; top:0"></div></div>';var a=e.childNodes[0],r=e.childNodes[1];e._reset=function(){a.scrollLeft=1e6,a.scrollTop=1e6,r.scrollLeft=1e6,r.scrollTop=1e6};var s=function(){e._reset(),t()};return h(a,"scroll",s.bind(a,"expand")),h(r,"scroll",s.bind(r,"shrink")),e}((u=function(){if(x.resizer)return e(g("resize",i))},c=!1,f=[],function(){f=Array.prototype.slice.call(arguments),d=d||this,c||(c=!0,n.requestAnimFrame.call(window,function(){c=!1,u.apply(d,f)}))}));m=function(){if(x.resizer){var e=t.parentNode;e&&e!==y.parentNode&&e.insertBefore(y,e.firstChild),y._reset()}},v=(p=t)[a]||(p[a]={}),b=v.renderProxy=function(t){t.animationName===s&&m()},n.each(l,function(t){h(p,t,b)}),v.reflow=!!p.offsetParent,p.classList.add(r)}function m(t){var e,i,o,s=t[a]||{},u=s.resizer;delete s.resizer,i=(e=t)[a]||{},(o=i.renderProxy)&&(n.each(l,function(t){f(e,t,o)}),delete i.renderProxy),e.classList.remove(r),u&&u.parentNode&&u.parentNode.removeChild(u)}e.exports={_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,initialize:function(){var t,e,i,n="from{opacity:0.99}to{opacity:1}";e="@-webkit-keyframes "+s+"{"+n+"}@keyframes "+s+"{"+n+"}."+r+"{-webkit-animation:"+s+" 0.001s;animation:"+s+" 0.001s;}",i=(t=this)._style||document.createElement("style"),t._style||(t._style=i,e="/* Chart.js */\n"+e,i.setAttribute("type","text/css"),document.getElementsByTagName("head")[0].appendChild(i)),i.appendChild(document.createTextNode(e))},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){var i=t.style,n=t.getAttribute("height"),o=t.getAttribute("width");if(t[a]={initial:{height:n,width:o,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===o||""===o){var r=d(t,"width");void 0!==r&&(t.width=r)}if(null===n||""===n)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var s=d(t,"height");void 0!==r&&(t.height=s)}}(t,e),i):null},releaseContext:function(t){var e=t.canvas;if(e[a]){var i=e[a].initial;["height","width"].forEach(function(t){var a=i[t];n.isNullOrUndef(a)?e.removeAttribute(t):e.setAttribute(t,a)}),n.each(i.style||{},function(t,i){e.style[i]=t}),e.width=e.width,delete e[a]}},addEventListener:function(t,e,i){var o=t.canvas;if("resize"!==e){var r=i[a]||(i[a]={});h(o,e,(r.proxies||(r.proxies={}))[t.id+"_"+e]=function(e){var a,o,r,s;i((o=t,r=u[(a=e).type]||a.type,s=n.getRelativePosition(a,o),g(r,o,s.x,s.y,a)))})}else p(o,i,t)},removeEventListener:function(t,e,i){var n=t.canvas;if("resize"!==e){var o=((i[a]||{}).proxies||{})[t.id+"_"+e];o&&f(n,e,o)}else m(n)}},n.addEvent=h,n.removeEvent=f},{45:45}],48:[function(t,e,i){"use strict";var n=t(45),a=t(46),o=t(47),r=o._enabled?o:a;e.exports=n.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},r)},{45:45,46:46,47:47}],49:[function(t,e,i){"use strict";e.exports={},e.exports.filler=t(50),e.exports.legend=t(51),e.exports.title=t(52)},{50:50,51:51,52:52}],50:[function(t,e,i){"use strict";var n=t(25),a=t(40),o=t(45);n._set("global",{plugins:{filler:{propagate:!0}}});var r={dataset:function(t){var e=t.fill,i=t.chart,n=i.getDatasetMeta(e),a=n&&i.isDatasetVisible(e)&&n.dataset._children||[],o=a.length||0;return o?function(t,e){return e<o&&a[e]._view||null}:null},boundary:function(t){var e=t.boundary,i=e?e.x:null,n=e?e.y:null;return function(t){return{x:null===i?t.x:i,y:null===n?t.y:n}}}};function s(t,e,i){var n,a=t._model||{},o=a.fill;if(void 0===o&&(o=!!a.backgroundColor),!1===o||null===o)return!1;if(!0===o)return"origin";if(n=parseFloat(o,10),isFinite(n)&&Math.floor(n)===n)return"-"!==o[0]&&"+"!==o[0]||(n=e+n),!(n===e||n<0||n>=i)&&n;switch(o){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return o;default:return!1}}function l(t){var e,i=t.el._model||{},n=t.el._scale||{},a=t.fill,o=null;if(isFinite(a))return null;if("start"===a?o=void 0===i.scaleBottom?n.bottom:i.scaleBottom:"end"===a?o=void 0===i.scaleTop?n.top:i.scaleTop:void 0!==i.scaleZero?o=i.scaleZero:n.getBasePosition?o=n.getBasePosition():n.getBasePixel&&(o=n.getBasePixel()),null!=o){if(void 0!==o.x&&void 0!==o.y)return o;if("number"==typeof o&&isFinite(o))return{x:(e=n.isHorizontal())?o:null,y:e?null:o}}return null}function u(t,e,i){var n,a=t[e].fill,o=[e];if(!i)return a;for(;!1!==a&&-1===o.indexOf(a);){if(!isFinite(a))return a;if(!(n=t[a]))return!1;if(n.visible)return a;o.push(a),a=n.fill}return!1}function d(t){return t&&!t.skip}function c(t,e,i,n,a){var r;if(n&&a){for(t.moveTo(e[0].x,e[0].y),r=1;r<n;++r)o.canvas.lineTo(t,e[r-1],e[r]);for(t.lineTo(i[a-1].x,i[a-1].y),r=a-1;r>0;--r)o.canvas.lineTo(t,i[r],i[r-1],!0)}}e.exports={id:"filler",afterDatasetsUpdate:function(t,e){var i,n,o,d,c,h,f,g=(t.data.datasets||[]).length,p=e.propagate,m=[];for(n=0;n<g;++n)d=null,(o=(i=t.getDatasetMeta(n)).dataset)&&o._model&&o instanceof a.Line&&(d={visible:t.isDatasetVisible(n),fill:s(o,n,g),chart:t,el:o}),i.$filler=d,m.push(d);for(n=0;n<g;++n)(d=m[n])&&(d.fill=u(m,n,p),d.boundary=l(d),d.mapper=(void 0,f=void 0,h=(c=d).fill,f="dataset",!1===h?null:(isFinite(h)||(f="boundary"),r[f](c))))},beforeDatasetDraw:function(t,e){var i=e.meta.$filler;if(i){var a=t.ctx,r=i.el,s=r._view,l=r._children||[],u=i.mapper,h=s.backgroundColor||n.global.defaultColor;u&&h&&l.length&&(o.canvas.clipArea(a,t.chartArea),function(t,e,i,n,a,o){var r,s,l,u,h,f,g,p=e.length,m=n.spanGaps,v=[],b=[],x=0,y=0;for(t.beginPath(),r=0,s=p+!!o;r<s;++r)h=i(u=e[l=r%p]._view,l,n),f=d(u),g=d(h),f&&g?(x=v.push(u),y=b.push(h)):x&&y&&(m?(f&&v.push(u),g&&b.push(h)):(c(t,v,b,x,y),x=y=0,v=[],b=[]));c(t,v,b,x,y),t.closePath(),t.fillStyle=a,t.fill()}(a,l,u,s,h,r._loop),o.canvas.unclipArea(a))}}}},{25:25,40:40,45:45}],51:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=t(30),s=o.noop;function l(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}n._set("global",{legend:{display:!0,position:"top",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var i=e.datasetIndex,n=this.chart,a=n.getDatasetMeta(i);a.hidden=null===a.hidden?!n.data.datasets[i].hidden:null,n.update()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return o.isArray(e.datasets)?e.datasets.map(function(e,i){return{text:e.label,fillStyle:o.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(i),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:i}},this):[]}}},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var i=0;i<t.data.datasets.length;i++)e.push('<li><span style="background-color:'+t.data.datasets[i].backgroundColor+'"></span>'),t.data.datasets[i].label&&e.push(t.data.datasets[i].label),e.push("</li>");return e.push("</ul>"),e.join("")}});var u=a.extend({initialize:function(t){o.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:s,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:s,beforeSetDimensions:s,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:s,beforeBuildLabels:s,buildLabels:function(){var t=this,e=t.options.labels||{},i=o.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(i=i.filter(function(i){return e.filter(i,t.chart.data)})),t.options.reverse&&i.reverse(),t.legendItems=i},afterBuildLabels:s,beforeFit:s,fit:function(){var t=this,e=t.options,i=e.labels,a=e.display,r=t.ctx,s=n.global,u=o.valueOrDefault,d=u(i.fontSize,s.defaultFontSize),c=u(i.fontStyle,s.defaultFontStyle),h=u(i.fontFamily,s.defaultFontFamily),f=o.fontString(d,c,h),g=t.legendHitBoxes=[],p=t.minSize,m=t.isHorizontal();if(m?(p.width=t.maxWidth,p.height=a?10:0):(p.width=a?10:0,p.height=t.maxHeight),a)if(r.font=f,m){var v=t.lineWidths=[0],b=t.legendItems.length?d+i.padding:0;r.textAlign="left",r.textBaseline="top",o.each(t.legendItems,function(e,n){var a=l(i,d)+d/2+r.measureText(e.text).width;v[v.length-1]+a+i.padding>=t.width&&(b+=d+i.padding,v[v.length]=t.left),g[n]={left:0,top:0,width:a,height:d},v[v.length-1]+=a+i.padding}),p.height+=b}else{var x=i.padding,y=t.columnWidths=[],k=i.padding,M=0,w=0,S=d+x;o.each(t.legendItems,function(t,e){var n=l(i,d)+d/2+r.measureText(t.text).width;w+S>p.height&&(k+=M+i.padding,y.push(M),M=0,w=0),M=Math.max(M,n),w+=S,g[e]={left:0,top:0,width:n,height:d}}),k+=M,y.push(M),p.width+=k}t.width=p.width,t.height=p.height},afterFit:s,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,i=e.labels,a=n.global,r=a.elements.line,s=t.width,u=t.lineWidths;if(e.display){var d,c=t.ctx,h=o.valueOrDefault,f=h(i.fontColor,a.defaultFontColor),g=h(i.fontSize,a.defaultFontSize),p=h(i.fontStyle,a.defaultFontStyle),m=h(i.fontFamily,a.defaultFontFamily),v=o.fontString(g,p,m);c.textAlign="left",c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var b=l(i,g),x=t.legendHitBoxes,y=t.isHorizontal();d=y?{x:t.left+(s-u[0])/2,y:t.top+i.padding,line:0}:{x:t.left+i.padding,y:t.top+i.padding,line:0};var k=g+i.padding;o.each(t.legendItems,function(n,l){var f,p,m,v,M,w=c.measureText(n.text).width,S=b+g/2+w,C=d.x,_=d.y;y?C+S>=s&&(_=d.y+=k,d.line++,C=d.x=t.left+(s-u[d.line])/2):_+k>t.bottom&&(C=d.x=C+t.columnWidths[d.line]+i.padding,_=d.y=t.top+i.padding,d.line++),function(t,i,n){if(!(isNaN(b)||b<=0)){c.save(),c.fillStyle=h(n.fillStyle,a.defaultColor),c.lineCap=h(n.lineCap,r.borderCapStyle),c.lineDashOffset=h(n.lineDashOffset,r.borderDashOffset),c.lineJoin=h(n.lineJoin,r.borderJoinStyle),c.lineWidth=h(n.lineWidth,r.borderWidth),c.strokeStyle=h(n.strokeStyle,a.defaultColor);var s=0===h(n.lineWidth,r.borderWidth);if(c.setLineDash&&c.setLineDash(h(n.lineDash,r.borderDash)),e.labels&&e.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=t+u,f=i+u;o.canvas.drawPoint(c,n.pointStyle,l,d,f)}else s||c.strokeRect(t,i,b,g),c.fillRect(t,i,b,g);c.restore()}}(C,_,n),x[l].left=C,x[l].top=_,f=n,p=w,v=b+(m=g/2)+C,M=_+m,c.fillText(f.text,v,M),f.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(v,M),c.lineTo(v+p,M),c.stroke()),y?d.x+=S+i.padding:d.y+=k})}},handleEvent:function(t){var e=this,i=e.options,n="mouseup"===t.type?"click":t.type,a=!1;if("mousemove"===n){if(!i.onHover)return}else{if("click"!==n)return;if(!i.onClick)return}var o=t.x,r=t.y;if(o>=e.left&&o<=e.right&&r>=e.top&&r<=e.bottom)for(var s=e.legendHitBoxes,l=0;l<s.length;++l){var u=s[l];if(o>=u.left&&o<=u.left+u.width&&r>=u.top&&r<=u.top+u.height){if("click"===n){i.onClick.call(e,t.native,e.legendItems[l]),a=!0;break}if("mousemove"===n){i.onHover.call(e,t.native,e.legendItems[l]),a=!0;break}}}return a}});function d(t,e){var i=new u({ctx:t.ctx,options:e,chart:t});r.configure(t,i,e),r.addBox(t,i),t.legend=i}e.exports={id:"legend",_element:u,beforeInit:function(t){var e=t.options.legend;e&&d(t,e)},beforeUpdate:function(t){var e=t.options.legend,i=t.legend;e?(o.mergeIf(e,n.global.legend),i?(r.configure(t,i,e),i.options=e):d(t,e)):i&&(r.removeBox(t,i),delete t.legend)},afterEvent:function(t,e){var i=t.legend;i&&i.handleEvent(e)}}},{25:25,26:26,30:30,45:45}],52:[function(t,e,i){"use strict";var n=t(25),a=t(26),o=t(45),r=t(30),s=o.noop;n._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,lineHeight:1.2,padding:10,position:"top",text:"",weight:2e3}});var l=a.extend({initialize:function(t){o.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:s,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:s,beforeSetDimensions:s,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:s,beforeBuildLabels:s,buildLabels:s,afterBuildLabels:s,beforeFit:s,fit:function(){var t=this,e=o.valueOrDefault,i=t.options,a=i.display,r=e(i.fontSize,n.global.defaultFontSize),s=t.minSize,l=o.isArray(i.text)?i.text.length:1,u=o.options.toLineHeight(i.lineHeight,r),d=a?l*u+2*i.padding:0;t.isHorizontal()?(s.width=t.maxWidth,s.height=d):(s.width=d,s.height=t.maxHeight),t.width=s.width,t.height=s.height},afterFit:s,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,i=o.valueOrDefault,a=t.options,r=n.global;if(a.display){var s,l,u,d=i(a.fontSize,r.defaultFontSize),c=i(a.fontStyle,r.defaultFontStyle),h=i(a.fontFamily,r.defaultFontFamily),f=o.fontString(d,c,h),g=o.options.toLineHeight(a.lineHeight,d),p=g/2+a.padding,m=0,v=t.top,b=t.left,x=t.bottom,y=t.right;e.fillStyle=i(a.fontColor,r.defaultFontColor),e.font=f,t.isHorizontal()?(l=b+(y-b)/2,u=v+p,s=y-b):(l="left"===a.position?b+p:y-p,u=v+(x-v)/2,s=x-v,m=Math.PI*("left"===a.position?-.5:.5)),e.save(),e.translate(l,u),e.rotate(m),e.textAlign="center",e.textBaseline="middle";var k=a.text;if(o.isArray(k))for(var M=0,w=0;w<k.length;++w)e.fillText(k[w],0,M,s),M+=g;else e.fillText(k,0,0,s);e.restore()}}});function u(t,e){var i=new l({ctx:t.ctx,options:e,chart:t});r.configure(t,i,e),r.addBox(t,i),t.titleBlock=i}e.exports={id:"title",_element:l,beforeInit:function(t){var e=t.options.title;e&&u(t,e)},beforeUpdate:function(t){var e=t.options.title,i=t.titleBlock;e?(o.mergeIf(e,n.global.title),i?(r.configure(t,i,e),i.options=e):u(t,e)):i&&(r.removeBox(t,i),delete t.titleBlock)}}},{25:25,26:26,30:30,45:45}],53:[function(t,e,i){"use strict";e.exports=function(t){var e=t.Scale.extend({getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t,e=this,i=e.getLabels();e.minIndex=0,e.maxIndex=i.length-1,void 0!==e.options.ticks.min&&(t=i.indexOf(e.options.ticks.min),e.minIndex=-1!==t?t:e.minIndex),void 0!==e.options.ticks.max&&(t=i.indexOf(e.options.ticks.max),e.maxIndex=-1!==t?t:e.maxIndex),e.min=i[e.minIndex],e.max=i[e.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var i=this,n=i.chart.data,a=i.isHorizontal();return n.yLabels&&!a?i.getRightValue(n.datasets[e].data[t]):i.ticks[t-i.minIndex]},getPixelForValue:function(t,e){var i,n=this,a=n.options.offset,o=Math.max(n.maxIndex+1-n.minIndex-(a?0:1),1);if(null!=t&&(i=n.isHorizontal()?t.x:t.y),void 0!==i||void 0!==t&&isNaN(e)){t=i||t;var r=n.getLabels().indexOf(t);e=-1!==r?r:e}if(n.isHorizontal()){var s=n.width/o,l=s*(e-n.minIndex);return a&&(l+=s/2),n.left+Math.round(l)}var u=n.height/o,d=u*(e-n.minIndex);return a&&(d+=u/2),n.top+Math.round(d)},getPixelForTick:function(t){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null)},getValueForPixel:function(t){var e=this,i=e.options.offset,n=Math.max(e._ticks.length-(i?0:1),1),a=e.isHorizontal(),o=(a?e.width:e.height)/n;return t-=a?e.left:e.top,i&&(t-=o/2),(t<=0?0:Math.round(t/o))+e.minIndex},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",e,{position:"bottom"})}},{}],54:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(34);e.exports=function(t){var e={position:"left",ticks:{callback:o.formatters.linear}},i=t.LinearScaleBase.extend({determineDataLimits:function(){var t=this,e=t.options,i=t.chart,n=i.data.datasets,o=t.isHorizontal();function r(e){return o?e.xAxisID===t.id:e.yAxisID===t.id}t.min=null,t.max=null;var s=e.stacked;if(void 0===s&&a.each(n,function(t,e){if(!s){var n=i.getDatasetMeta(e);i.isDatasetVisible(e)&&r(n)&&void 0!==n.stack&&(s=!0)}}),e.stacked||s){var l={};a.each(n,function(n,o){var s=i.getDatasetMeta(o),u=[s.type,void 0===e.stacked&&void 0===s.stack?o:"",s.stack].join(".");void 0===l[u]&&(l[u]={positiveValues:[],negativeValues:[]});var d=l[u].positiveValues,c=l[u].negativeValues;i.isDatasetVisible(o)&&r(s)&&a.each(n.data,function(i,n){var a=+t.getRightValue(i);isNaN(a)||s.data[n].hidden||(d[n]=d[n]||0,c[n]=c[n]||0,e.relativePoints?d[n]=100:a<0?c[n]+=a:d[n]+=a)})}),a.each(l,function(e){var i=e.positiveValues.concat(e.negativeValues),n=a.min(i),o=a.max(i);t.min=null===t.min?n:Math.min(t.min,n),t.max=null===t.max?o:Math.max(t.max,o)})}else a.each(n,function(e,n){var o=i.getDatasetMeta(n);i.isDatasetVisible(n)&&r(o)&&a.each(e.data,function(e,i){var n=+t.getRightValue(e);isNaN(n)||o.data[i].hidden||(null===t.min?t.min=n:n<t.min&&(t.min=n),null===t.max?t.max=n:n>t.max&&(t.max=n))})});t.min=isFinite(t.min)&&!isNaN(t.min)?t.min:0,t.max=isFinite(t.max)&&!isNaN(t.max)?t.max:1,this.handleTickRangeOptions()},getTickLimit:function(){var t,e=this.options.ticks;if(this.isHorizontal())t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.width/50));else{var i=a.valueOrDefault(e.fontSize,n.global.defaultFontSize);t=Math.min(e.maxTicksLimit?e.maxTicksLimit:11,Math.ceil(this.height/(2*i)))}return t},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e=this,i=e.start,n=+e.getRightValue(t),a=e.end-i;return e.isHorizontal()?e.left+e.width/a*(n-i):e.bottom-e.height/a*(n-i)},getValueForPixel:function(t){var e=this,i=e.isHorizontal(),n=i?e.width:e.height,a=(i?t-e.left:e.bottom-t)/n;return e.start+(e.end-e.start)*a},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,e)}},{25:25,34:34,45:45}],55:[function(t,e,i){"use strict";var n=t(45);e.exports=function(t){var e=n.noop;t.LinearScaleBase=t.Scale.extend({getRightValue:function(e){return"string"==typeof e?+e:t.Scale.prototype.getRightValue.call(this,e)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var i=n.sign(t.min),a=n.sign(t.max);i<0&&a<0?t.max=0:i>0&&a>0&&(t.min=0)}var o=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),o!==r&&t.min>=t.max&&(o?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:e,handleDirectionalChanges:e,buildTicks:function(){var t=this,e=t.options.ticks,i=t.getTickLimit(),a={maxTicks:i=Math.max(2,i),min:e.min,max:e.max,stepSize:n.valueOrDefault(e.fixedStepSize,e.stepSize)},o=t.ticks=function(t,e){var i,a=[];if(t.stepSize&&t.stepSize>0)i=t.stepSize;else{var o=n.niceNum(e.max-e.min,!1);i=n.niceNum(o/(t.maxTicks-1),!0)}var r=Math.floor(e.min/i)*i,s=Math.ceil(e.max/i)*i;t.min&&t.max&&t.stepSize&&n.almostWhole((t.max-t.min)/t.stepSize,i/1e3)&&(r=t.min,s=t.max);var l=(s-r)/i;l=n.almostEquals(l,Math.round(l),i/1e3)?Math.round(l):Math.ceil(l);var u=1;i<1&&(u=Math.pow(10,i.toString().length-2),r=Math.round(r*u)/u,s=Math.round(s*u)/u),a.push(void 0!==t.min?t.min:r);for(var d=1;d<l;++d)a.push(Math.round((r+d*i)*u)/u);return a.push(void 0!==t.max?t.max:s),a}(a,t);t.handleDirectionalChanges(),t.max=n.max(o),t.min=n.min(o),e.reverse?(o.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{45:45}],56:[function(t,e,i){"use strict";var n=t(45),a=t(34);e.exports=function(t){var e={position:"left",ticks:{callback:a.formatters.logarithmic}},i=t.Scale.extend({determineDataLimits:function(){var t=this,e=t.options,i=t.chart,a=i.data.datasets,o=t.isHorizontal();function r(e){return o?e.xAxisID===t.id:e.yAxisID===t.id}t.min=null,t.max=null,t.minNotZero=null;var s=e.stacked;if(void 0===s&&n.each(a,function(t,e){if(!s){var n=i.getDatasetMeta(e);i.isDatasetVisible(e)&&r(n)&&void 0!==n.stack&&(s=!0)}}),e.stacked||s){var l={};n.each(a,function(a,o){var s=i.getDatasetMeta(o),u=[s.type,void 0===e.stacked&&void 0===s.stack?o:"",s.stack].join(".");i.isDatasetVisible(o)&&r(s)&&(void 0===l[u]&&(l[u]=[]),n.each(a.data,function(e,i){var n=l[u],a=+t.getRightValue(e);isNaN(a)||s.data[i].hidden||a<0||(n[i]=n[i]||0,n[i]+=a)}))}),n.each(l,function(e){if(e.length>0){var i=n.min(e),a=n.max(e);t.min=null===t.min?i:Math.min(t.min,i),t.max=null===t.max?a:Math.max(t.max,a)}})}else n.each(a,function(e,a){var o=i.getDatasetMeta(a);i.isDatasetVisible(a)&&r(o)&&n.each(e.data,function(e,i){var n=+t.getRightValue(e);isNaN(n)||o.data[i].hidden||n<0||(null===t.min?t.min=n:n<t.min&&(t.min=n),null===t.max?t.max=n:n>t.max&&(t.max=n),0!==n&&(null===t.minNotZero||n<t.minNotZero)&&(t.minNotZero=n))})});this.handleTickRangeOptions()},handleTickRangeOptions:function(){var t=this,e=t.options.ticks,i=n.valueOrDefault;t.min=i(e.min,t.min),t.max=i(e.max,t.max),t.min===t.max&&(0!==t.min&&null!==t.min?(t.min=Math.pow(10,Math.floor(n.log10(t.min))-1),t.max=Math.pow(10,Math.floor(n.log10(t.max))+1)):(t.min=1,t.max=10)),null===t.min&&(t.min=Math.pow(10,Math.floor(n.log10(t.max))-1)),null===t.max&&(t.max=0!==t.min?Math.pow(10,Math.floor(n.log10(t.min))+1):10),null===t.minNotZero&&(t.min>0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(n.log10(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,i=!t.isHorizontal(),a={min:e.min,max:e.max},o=t.ticks=function(t,e){var i,a,o=[],r=n.valueOrDefault,s=r(t.min,Math.pow(10,Math.floor(n.log10(e.min)))),l=Math.floor(n.log10(e.max)),u=Math.ceil(e.max/Math.pow(10,l));0===s?(i=Math.floor(n.log10(e.minNotZero)),a=Math.floor(e.minNotZero/Math.pow(10,i)),o.push(s),s=a*Math.pow(10,i)):(i=Math.floor(n.log10(s)),a=Math.floor(s/Math.pow(10,i)));for(var d=i<0?Math.pow(10,Math.abs(i)):1;o.push(s),10==++a&&(a=1,d=++i>=0?1:d),s=Math.round(a*Math.pow(10,i)*d)/d,i<l||i===l&&a<u;);var c=r(t.max,s);return o.push(c),o}(a,t);t.max=n.max(o),t.min=n.min(o),e.reverse?(i=!i,t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max),i&&o.reverse()},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){return this.getPixelForValue(this.tickValues[t])},_getFirstTickValue:function(t){var e=Math.floor(n.log10(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},getPixelForValue:function(e){var i,a,o,r,s,l=this,u=l.options.ticks.reverse,d=n.log10,c=l._getFirstTickValue(l.minNotZero),h=0;return e=+l.getRightValue(e),u?(o=l.end,r=l.start,s=-1):(o=l.start,r=l.end,s=1),l.isHorizontal()?(i=l.width,a=u?l.right:l.left):(i=l.height,s*=-1,a=u?l.top:l.bottom),e!==o&&(0===o&&(i-=h=n.getValueOrDefault(l.options.ticks.fontSize,t.defaults.global.defaultFontSize),o=c),0!==e&&(h+=i/(d(r)-d(o))*(d(e)-d(o))),a+=s*h),a},getValueForPixel:function(e){var i,a,o,r,s=this,l=s.options.ticks.reverse,u=n.log10,d=s._getFirstTickValue(s.minNotZero);if(l?(a=s.end,o=s.start):(a=s.start,o=s.end),s.isHorizontal()?(i=s.width,r=l?s.right-e:e-s.left):(i=s.height,r=l?e-s.top:s.bottom-e),r!==a){if(0===a){var c=n.getValueOrDefault(s.options.ticks.fontSize,t.defaults.global.defaultFontSize);r-=c,i-=c,a=d}r*=u(o)-u(a),r/=i,r=Math.pow(10,u(a)+r)}return r}});t.scaleService.registerScaleType("logarithmic",i,e)}},{34:34,45:45}],57:[function(t,e,i){"use strict";var n=t(25),a=t(45),o=t(34);e.exports=function(t){var e=n.global,i={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:o.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function r(t){var e=t.options;return e.angleLines.display||e.pointLabels.display?t.chart.data.labels.length:0}function s(t){var i=t.options.pointLabels,n=a.valueOrDefault(i.fontSize,e.defaultFontSize),o=a.valueOrDefault(i.fontStyle,e.defaultFontStyle),r=a.valueOrDefault(i.fontFamily,e.defaultFontFamily);return{size:n,style:o,family:r,font:a.fontString(n,o,r)}}function l(t,e,i,n,a){return t===n||t===a?{start:e-i/2,end:e+i/2}:t<n||t>a?{start:e-i-5,end:e}:{start:e,end:e+i+5}}function u(t,e,i,n){if(a.isArray(e))for(var o=i.y,r=1.5*n,s=0;s<e.length;++s)t.fillText(e[s],i.x,o),o+=r;else t.fillText(e,i.x,i.y)}function d(t){return a.isNumber(t)?t:0}var c=t.LinearScaleBase.extend({setDimensions:function(){var t=this,i=t.options,n=i.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var o=a.min([t.height,t.width]),r=a.valueOrDefault(n.fontSize,e.defaultFontSize);t.drawingArea=i.display?o/2-(r/2+n.backdropPaddingY):o/2},determineDataLimits:function(){var t=this,e=t.chart,i=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;a.each(e.data.datasets,function(o,r){if(e.isDatasetVisible(r)){var s=e.getDatasetMeta(r);a.each(o.data,function(e,a){var o=+t.getRightValue(e);isNaN(o)||s.data[a].hidden||(i=Math.min(o,i),n=Math.max(o,n))})}}),t.min=i===Number.POSITIVE_INFINITY?0:i,t.max=n===Number.NEGATIVE_INFINITY?0:n,t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,i=a.valueOrDefault(t.fontSize,e.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*i)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t,e;this.options.pointLabels.display?function(t){var e,i,n,o=s(t),u=Math.min(t.height/2,t.width/2),d={r:t.width,l:0,t:t.height,b:0},c={};t.ctx.font=o.font,t._pointLabelSizes=[];var h,f,g,p=r(t);for(e=0;e<p;e++){n=t.getPointPosition(e,u),h=t.ctx,f=o.size,g=t.pointLabels[e]||"",i=a.isArray(g)?{w:a.longestText(h,h.font,g),h:g.length*f+1.5*(g.length-1)*f}:{w:h.measureText(g).width,h:f},t._pointLabelSizes[e]=i;var m=t.getIndexAngle(e),v=a.toDegrees(m)%360,b=l(v,n.x,i.w,0,180),x=l(v,n.y,i.h,90,270);b.start<d.l&&(d.l=b.start,c.l=m),b.end>d.r&&(d.r=b.end,c.r=m),x.start<d.t&&(d.t=x.start,c.t=m),x.end>d.b&&(d.b=x.end,c.b=m)}t.setReductions(u,d,c)}(this):(t=this,e=Math.min(t.height/2,t.width/2),t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0))},setReductions:function(t,e,i){var n=e.l/Math.sin(i.l),a=Math.max(e.r-this.width,0)/Math.sin(i.r),o=-e.t/Math.cos(i.t),r=-Math.max(e.b-this.height,0)/Math.cos(i.b);n=d(n),a=d(a),o=d(o),r=d(r),this.drawingArea=Math.min(Math.round(t-(n+a)/2),Math.round(t-(o+r)/2)),this.setCenterPoint(n,a,o,r)},setCenterPoint:function(t,e,i,n){var a=this,o=a.width-e-a.drawingArea,r=t+a.drawingArea,s=i+a.drawingArea,l=a.height-n-a.drawingArea;a.xCenter=Math.round((r+o)/2+a.left),a.yCenter=Math.round((s+l)/2+a.top)},getIndexAngle:function(t){return t*(2*Math.PI/r(this))+(this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var i=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*i:(t-e.min)*i},getPointPosition:function(t,e){var i=this.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(i)*e)+this.xCenter,y:Math.round(Math.sin(i)*e)+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this.min,e=this.max;return this.getPointPositionForValue(0,this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0)},draw:function(){var t=this,i=t.options,n=i.gridLines,o=i.ticks,l=a.valueOrDefault;if(i.display){var d=t.ctx,c=this.getIndexAngle(0),h=l(o.fontSize,e.defaultFontSize),f=l(o.fontStyle,e.defaultFontStyle),g=l(o.fontFamily,e.defaultFontFamily),p=a.fontString(h,f,g);a.each(t.ticks,function(i,s){if(s>0||o.reverse){var u=t.getDistanceFromCenterForValue(t.ticksAsNumbers[s]);if(n.display&&0!==s&&function(t,e,i,n){var o=t.ctx;if(o.strokeStyle=a.valueAtIndexOrDefault(e.color,n-1),o.lineWidth=a.valueAtIndexOrDefault(e.lineWidth,n-1),t.options.gridLines.circular)o.beginPath(),o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),o.closePath(),o.stroke();else{var s=r(t);if(0===s)return;o.beginPath();var l=t.getPointPosition(0,i);o.moveTo(l.x,l.y);for(var u=1;u<s;u++)l=t.getPointPosition(u,i),o.lineTo(l.x,l.y);o.closePath(),o.stroke()}}(t,n,u,s),o.display){var f=l(o.fontColor,e.defaultFontColor);if(d.font=p,d.save(),d.translate(t.xCenter,t.yCenter),d.rotate(c),o.showLabelBackdrop){var g=d.measureText(i).width;d.fillStyle=o.backdropColor,d.fillRect(-g/2-o.backdropPaddingX,-u-h/2-o.backdropPaddingY,g+2*o.backdropPaddingX,h+2*o.backdropPaddingY)}d.textAlign="center",d.textBaseline="middle",d.fillStyle=f,d.fillText(i,0,-u),d.restore()}}}),(i.angleLines.display||i.pointLabels.display)&&function(t){var i=t.ctx,n=t.options,o=n.angleLines,l=n.pointLabels;i.lineWidth=o.lineWidth,i.strokeStyle=o.color;var d,c,h,f,g=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),p=s(t);i.textBaseline="top";for(var m=r(t)-1;m>=0;m--){if(o.display){var v=t.getPointPosition(m,g);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(v.x,v.y),i.stroke(),i.closePath()}if(l.display){var b=t.getPointPosition(m,g+5),x=a.valueAtIndexOrDefault(l.fontColor,m,e.defaultFontColor);i.font=p.font,i.fillStyle=x;var y=t.getIndexAngle(m),k=a.toDegrees(y);i.textAlign=0===(f=k)||180===f?"center":f<180?"left":"right",d=k,c=t._pointLabelSizes[m],h=b,90===d||270===d?h.y-=c.h/2:(d>270||d<90)&&(h.y-=c.h),u(i,t.pointLabels[m]||"",b,p.size)}}}(t)}}});t.scaleService.registerScaleType("radialLinear",c,i)}},{25:25,34:34,45:45}],58:[function(t,e,i){"use strict";var n=t(1);n="function"==typeof n?n:window.moment;var a=t(25),o=t(45),r=Number.MIN_SAFE_INTEGER||-9007199254740991,s=Number.MAX_SAFE_INTEGER||9007199254740991,l={millisecond:{common:!0,size:1,steps:[1,2,5,10,20,50,100,250,500]},second:{common:!0,size:1e3,steps:[1,2,5,10,30]},minute:{common:!0,size:6e4,steps:[1,2,5,10,30]},hour:{common:!0,size:36e5,steps:[1,2,3,6,12]},day:{common:!0,size:864e5,steps:[1,2,5]},week:{common:!1,size:6048e5,steps:[1,2,3,4]},month:{common:!0,size:2628e6,steps:[1,2,3]},quarter:{common:!1,size:7884e6,steps:[1,2,3,4]},year:{common:!0,size:3154e7}},u=Object.keys(l);function d(t,e){return t-e}function c(t){var e,i,n,a={},o=[];for(e=0,i=t.length;e<i;++e)a[n=t[e]]||(a[n]=!0,o.push(n));return o}function h(t,e,i,n){var a=function(t,e,i){for(var n,a,o,r=0,s=t.length-1;r>=0&&r<=s;){if(a=t[(n=r+s>>1)-1]||null,o=t[n],!a)return{lo:null,hi:o};if(o[e]<i)r=n+1;else{if(!(a[e]>i))return{lo:a,hi:o};s=n-1}}return{lo:o,hi:null}}(t,e,i),o=a.lo?a.hi?a.lo:t[t.length-2]:t[0],r=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=r[e]-o[e],l=s?(i-o[e])/s:0,u=(r[n]-o[n])*l;return o[n]+u}function f(t,e){var i=e.parser,a=e.parser||e.format;return"function"==typeof i?i(t):"string"==typeof t&&"string"==typeof a?n(t,a):(t instanceof n||(t=n(t)),t.isValid()?t:"function"==typeof a?a(t):t)}function g(t,e){if(o.isNullOrUndef(t))return null;var i=e.options.time,n=f(e.getRightValue(t),i);return n.isValid()?(i.round&&n.startOf(i.round),n.valueOf()):null}function p(t){for(var e=u.indexOf(t)+1,i=u.length;e<i;++e)if(l[u[e]].common)return u[e]}function m(t,e,i,a){var r,d=a.time,c=d.unit||function(t,e,i,n){var a,o,r,d=u.length;for(a=u.indexOf(t);a<d-1;++a)if(r=(o=l[u[a]]).steps?o.steps[o.steps.length-1]:s,o.common&&Math.ceil((i-e)/(r*o.size))<=n)return u[a];return u[d-1]}(d.minUnit,t,e,i),h=p(c),f=o.valueOrDefault(d.stepSize,d.unitStepSize),g="week"===c&&d.isoWeekday,m=a.ticks.major.enabled,v=l[c],b=n(t),x=n(e),y=[];for(f||(f=function(t,e,i,n){var a,o,r,s=e-t,u=l[i],d=u.size,c=u.steps;if(!c)return Math.ceil(s/(n*d));for(a=0,o=c.length;a<o&&(r=c[a],!(Math.ceil(s/(d*r))<=n));++a);return r}(t,e,c,i)),g&&(b=b.isoWeekday(g),x=x.isoWeekday(g)),b=b.startOf(g?"day":c),(x=x.startOf(g?"day":c))<e&&x.add(1,c),r=n(b),m&&h&&!g&&!d.round&&(r.startOf(h),r.add(~~((b-r)/(v.size*f))*f,c));r<x;r.add(f,c))y.push(+r);return y.push(+r),y}e.exports=function(t){var e=t.Scale.extend({initialize:function(){if(!n)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");this.mergeTicksOptions(),t.Scale.prototype.initialize.call(this)},update:function(){var e=this.options;return e.time&&e.time.format&&console.warn("options.time.format is deprecated and replaced by options.time.parser."),t.Scale.prototype.update.apply(this,arguments)},getRightValue:function(e){return e&&void 0!==e.t&&(e=e.t),t.Scale.prototype.getRightValue.call(this,e)},determineDataLimits:function(){var t,e,i,a,l,u,h=this,f=h.chart,p=h.options.time,m=p.unit||"day",v=s,b=r,x=[],y=[],k=[];for(t=0,i=f.data.labels.length;t<i;++t)k.push(g(f.data.labels[t],h));for(t=0,i=(f.data.datasets||[]).length;t<i;++t)if(f.isDatasetVisible(t))if(l=f.data.datasets[t].data,o.isObject(l[0]))for(y[t]=[],e=0,a=l.length;e<a;++e)u=g(l[e],h),x.push(u),y[t][e]=u;else x.push.apply(x,k),y[t]=k.slice(0);else y[t]=[];k.length&&(k=c(k).sort(d),v=Math.min(v,k[0]),b=Math.max(b,k[k.length-1])),x.length&&(x=c(x).sort(d),v=Math.min(v,x[0]),b=Math.max(b,x[x.length-1])),v=g(p.min,h)||v,b=g(p.max,h)||b,v=v===s?+n().startOf(m):v,b=b===r?+n().endOf(m)+1:b,h.min=Math.min(v,b),h.max=Math.max(v+1,b),h._horizontal=h.isHorizontal(),h._table=[],h._timestamps={data:x,datasets:y,labels:k}},buildTicks:function(){var t,e,i,a,o,r,s,d,c,v,b,x,y=this,k=y.min,M=y.max,w=y.options,S=w.time,C=[],_=[];switch(w.ticks.source){case"data":C=y._timestamps.data;break;case"labels":C=y._timestamps.labels;break;case"auto":default:C=m(k,M,y.getLabelCapacity(k),w)}for("ticks"===w.bounds&&C.length&&(k=C[0],M=C[C.length-1]),k=g(S.min,y)||k,M=g(S.max,y)||M,t=0,e=C.length;t<e;++t)(i=C[t])>=k&&i<=M&&_.push(i);return y.min=k,y.max=M,y._unit=S.unit||function(t,e,i,a){var o,r,s=n.duration(n(a).diff(n(i)));for(o=u.length-1;o>=u.indexOf(e);o--)if(r=u[o],l[r].common&&s.as(r)>=t.length)return r;return u[e?u.indexOf(e):0]}(_,S.minUnit,y.min,y.max),y._majorUnit=p(y._unit),y._table=function(t,e,i,n){if("linear"===n||!t.length)return[{time:e,pos:0},{time:i,pos:1}];var a,o,r,s,l,u=[],d=[e];for(a=0,o=t.length;a<o;++a)(s=t[a])>e&&s<i&&d.push(s);for(d.push(i),a=0,o=d.length;a<o;++a)l=d[a+1],r=d[a-1],s=d[a],void 0!==r&&void 0!==l&&Math.round((l+r)/2)===s||u.push({time:s,pos:a/(o-1)});return u}(y._timestamps.data,k,M,w.distribution),y._offsets=(a=y._table,o=_,r=k,s=M,b=0,x=0,(d=w).offset&&o.length&&(d.time.min||(c=o.length>1?o[1]:s,v=o[0],b=(h(a,"time",c,"pos")-h(a,"time",v,"pos"))/2),d.time.max||(c=o[o.length-1],v=o.length>1?o[o.length-2]:r,x=(h(a,"time",c,"pos")-h(a,"time",v,"pos"))/2)),{left:b,right:x}),y._labelFormat=function(t,e){var i,n,a,o=t.length;for(i=0;i<o;i++){if(0!==(n=f(t[i],e)).millisecond())return"MMM D, YYYY h:mm:ss.SSS a";0===n.second()&&0===n.minute()&&0===n.hour()||(a=!0)}return a?"MMM D, YYYY h:mm:ss a":"MMM D, YYYY"}(y._timestamps.data,S),function(t,e){var i,a,o,r,s=[];for(i=0,a=t.length;i<a;++i)o=t[i],r=!!e&&o===+n(o).startOf(e),s.push({value:o,major:r});return s}(_,y._majorUnit)},getLabelForIndex:function(t,e){var i=this.chart.data,n=this.options.time,a=i.labels&&t<i.labels.length?i.labels[t]:"",r=i.datasets[e].data[t];return o.isObject(r)&&(a=this.getRightValue(r)),n.tooltipFormat?f(a,n).format(n.tooltipFormat):"string"==typeof a?a:f(a,n).format(this._labelFormat)},tickFormatFunction:function(t,e,i,n){var a=this.options,r=t.valueOf(),s=a.time.displayFormats,l=s[this._unit],u=this._majorUnit,d=s[u],c=t.clone().startOf(u).valueOf(),h=a.ticks.major,f=h.enabled&&u&&d&&r===c,g=t.format(n||(f?d:l)),p=f?h:a.ticks.minor,m=o.valueOrDefault(p.callback,p.userCallback);return m?m(g,e,i):g},convertTicksToLabels:function(t){var e,i,a=[];for(e=0,i=t.length;e<i;++e)a.push(this.tickFormatFunction(n(t[e].value),e,t));return a},getPixelForOffset:function(t){var e=this,i=e._horizontal?e.width:e.height,n=e._horizontal?e.left:e.top,a=h(e._table,"time",t,"pos");return n+i*(e._offsets.left+a)/(e._offsets.left+1+e._offsets.right)},getPixelForValue:function(t,e,i){var n=null;if(void 0!==e&&void 0!==i&&(n=this._timestamps.datasets[i][e]),null===n&&(n=g(t,this)),null!==n)return this.getPixelForOffset(n)},getPixelForTick:function(t){var e=this.getTicks();return t>=0&&t<e.length?this.getPixelForOffset(e[t].value):null},getValueForPixel:function(t){var e=this,i=e._horizontal?e.width:e.height,a=e._horizontal?e.left:e.top,o=(i?(t-a)/i:0)*(e._offsets.left+1+e._offsets.left)-e._offsets.right,r=h(e._table,"pos",o,"time");return n(r)},getLabelWidth:function(t){var e=this.options.ticks,i=this.ctx.measureText(t).width,n=o.toRadians(e.maxRotation),r=Math.cos(n),s=Math.sin(n);return i*r+o.valueOrDefault(e.fontSize,a.global.defaultFontSize)*s},getLabelCapacity:function(t){var e=this,i=e.options.time.displayFormats.millisecond,a=e.tickFormatFunction(n(t),0,[],i),o=e.getLabelWidth(a),r=e.isHorizontal()?e.width:e.height,s=Math.floor(r/o);return s>0?s:1}});t.scaleService.registerScaleType("time",e,{position:"bottom",distribution:"linear",bounds:"data",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}})}},{1:1,25:25,45:45}]},{},[7])(7)}); diff --git a/web/js/bootstrap.js b/web/js/bootstrap.js deleted file mode 100644 index 1c88b71..0000000 --- a/web/js/bootstrap.js +++ /dev/null @@ -1,2317 +0,0 @@ -/*! - * Bootstrap v3.3.4 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -if (typeof jQuery === 'undefined') { - throw new Error('Bootstrap\'s JavaScript requires jQuery') -} - -+function ($) { - 'use strict'; - var version = $.fn.jquery.split(' ')[0].split('.') - if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { - throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') - } -}(jQuery); - -/* ======================================================================== - * Bootstrap: transition.js v3.3.4 - * http://getbootstrap.com/javascript/#transitions - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) - // ============================================================ - - function transitionEnd() { - var el = document.createElement('bootstrap') - - var transEndEventNames = { - WebkitTransition : 'webkitTransitionEnd', - MozTransition : 'transitionend', - OTransition : 'oTransitionEnd otransitionend', - transition : 'transitionend' - } - - for (var name in transEndEventNames) { - if (el.style[name] !== undefined) { - return { end: transEndEventNames[name] } - } - } - - return false // explicit for ie8 ( ._.) - } - - // http://blog.alexmaccaw.com/css-transitions - $.fn.emulateTransitionEnd = function (duration) { - var called = false - var $el = this - $(this).one('bsTransitionEnd', function () { called = true }) - var callback = function () { if (!called) $($el).trigger($.support.transition.end) } - setTimeout(callback, duration) - return this - } - - $(function () { - $.support.transition = transitionEnd() - - if (!$.support.transition) return - - $.event.special.bsTransitionEnd = { - bindType: $.support.transition.end, - delegateType: $.support.transition.end, - handle: function (e) { - if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) - } - } - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: alert.js v3.3.4 - * http://getbootstrap.com/javascript/#alerts - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // ALERT CLASS DEFINITION - // ====================== - - var dismiss = '[data-dismiss="alert"]' - var Alert = function (el) { - $(el).on('click', dismiss, this.close) - } - - Alert.VERSION = '3.3.4' - - Alert.TRANSITION_DURATION = 150 - - Alert.prototype.close = function (e) { - var $this = $(this) - var selector = $this.attr('data-target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - var $parent = $(selector) - - if (e) e.preventDefault() - - if (!$parent.length) { - $parent = $this.closest('.alert') - } - - $parent.trigger(e = $.Event('close.bs.alert')) - - if (e.isDefaultPrevented()) return - - $parent.removeClass('in') - - function removeElement() { - // detach from parent, fire event then clean up data - $parent.detach().trigger('closed.bs.alert').remove() - } - - $.support.transition && $parent.hasClass('fade') ? - $parent - .one('bsTransitionEnd', removeElement) - .emulateTransitionEnd(Alert.TRANSITION_DURATION) : - removeElement() - } - - - // ALERT PLUGIN DEFINITION - // ======================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.alert') - - if (!data) $this.data('bs.alert', (data = new Alert(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - var old = $.fn.alert - - $.fn.alert = Plugin - $.fn.alert.Constructor = Alert - - - // ALERT NO CONFLICT - // ================= - - $.fn.alert.noConflict = function () { - $.fn.alert = old - return this - } - - - // ALERT DATA-API - // ============== - - $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: button.js v3.3.4 - * http://getbootstrap.com/javascript/#buttons - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // BUTTON PUBLIC CLASS DEFINITION - // ============================== - - var Button = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Button.DEFAULTS, options) - this.isLoading = false - } - - Button.VERSION = '3.3.4' - - Button.DEFAULTS = { - loadingText: 'loading...' - } - - Button.prototype.setState = function (state) { - var d = 'disabled' - var $el = this.$element - var val = $el.is('input') ? 'val' : 'html' - var data = $el.data() - - state = state + 'Text' - - if (data.resetText == null) $el.data('resetText', $el[val]()) - - // push to event loop to allow forms to submit - setTimeout($.proxy(function () { - $el[val](data[state] == null ? this.options[state] : data[state]) - - if (state == 'loadingText') { - this.isLoading = true - $el.addClass(d).attr(d, d) - } else if (this.isLoading) { - this.isLoading = false - $el.removeClass(d).removeAttr(d) - } - }, this), 0) - } - - Button.prototype.toggle = function () { - var changed = true - var $parent = this.$element.closest('[data-toggle="buttons"]') - - if ($parent.length) { - var $input = this.$element.find('input') - if ($input.prop('type') == 'radio') { - if ($input.prop('checked') && this.$element.hasClass('active')) changed = false - else $parent.find('.active').removeClass('active') - } - if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') - } else { - this.$element.attr('aria-pressed', !this.$element.hasClass('active')) - } - - if (changed) this.$element.toggleClass('active') - } - - - // BUTTON PLUGIN DEFINITION - // ======================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.button') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.button', (data = new Button(this, options))) - - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - - var old = $.fn.button - - $.fn.button = Plugin - $.fn.button.Constructor = Button - - - // BUTTON NO CONFLICT - // ================== - - $.fn.button.noConflict = function () { - $.fn.button = old - return this - } - - - // BUTTON DATA-API - // =============== - - $(document) - .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - Plugin.call($btn, 'toggle') - e.preventDefault() - }) - .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { - $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: carousel.js v3.3.4 - * http://getbootstrap.com/javascript/#carousel - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // CAROUSEL CLASS DEFINITION - // ========================= - - var Carousel = function (element, options) { - this.$element = $(element) - this.$indicators = this.$element.find('.carousel-indicators') - this.options = options - this.paused = null - this.sliding = null - this.interval = null - this.$active = null - this.$items = null - - this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) - - this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element - .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) - .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) - } - - Carousel.VERSION = '3.3.4' - - Carousel.TRANSITION_DURATION = 600 - - Carousel.DEFAULTS = { - interval: 5000, - pause: 'hover', - wrap: true, - keyboard: true - } - - Carousel.prototype.keydown = function (e) { - if (/input|textarea/i.test(e.target.tagName)) return - switch (e.which) { - case 37: this.prev(); break - case 39: this.next(); break - default: return - } - - e.preventDefault() - } - - Carousel.prototype.cycle = function (e) { - e || (this.paused = false) - - this.interval && clearInterval(this.interval) - - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) - - return this - } - - Carousel.prototype.getItemIndex = function (item) { - this.$items = item.parent().children('.item') - return this.$items.index(item || this.$active) - } - - Carousel.prototype.getItemForDirection = function (direction, active) { - var activeIndex = this.getItemIndex(active) - var willWrap = (direction == 'prev' && activeIndex === 0) - || (direction == 'next' && activeIndex == (this.$items.length - 1)) - if (willWrap && !this.options.wrap) return active - var delta = direction == 'prev' ? -1 : 1 - var itemIndex = (activeIndex + delta) % this.$items.length - return this.$items.eq(itemIndex) - } - - Carousel.prototype.to = function (pos) { - var that = this - var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) - - if (pos > (this.$items.length - 1) || pos < 0) return - - if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" - if (activeIndex == pos) return this.pause().cycle() - - return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) - } - - Carousel.prototype.pause = function (e) { - e || (this.paused = true) - - if (this.$element.find('.next, .prev').length && $.support.transition) { - this.$element.trigger($.support.transition.end) - this.cycle(true) - } - - this.interval = clearInterval(this.interval) - - return this - } - - Carousel.prototype.next = function () { - if (this.sliding) return - return this.slide('next') - } - - Carousel.prototype.prev = function () { - if (this.sliding) return - return this.slide('prev') - } - - Carousel.prototype.slide = function (type, next) { - var $active = this.$element.find('.item.active') - var $next = next || this.getItemForDirection(type, $active) - var isCycling = this.interval - var direction = type == 'next' ? 'left' : 'right' - var that = this - - if ($next.hasClass('active')) return (this.sliding = false) - - var relatedTarget = $next[0] - var slideEvent = $.Event('slide.bs.carousel', { - relatedTarget: relatedTarget, - direction: direction - }) - this.$element.trigger(slideEvent) - if (slideEvent.isDefaultPrevented()) return - - this.sliding = true - - isCycling && this.pause() - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) - $nextIndicator && $nextIndicator.addClass('active') - } - - var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" - if ($.support.transition && this.$element.hasClass('slide')) { - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - $active - .one('bsTransitionEnd', function () { - $next.removeClass([type, direction].join(' ')).addClass('active') - $active.removeClass(['active', direction].join(' ')) - that.sliding = false - setTimeout(function () { - that.$element.trigger(slidEvent) - }, 0) - }) - .emulateTransitionEnd(Carousel.TRANSITION_DURATION) - } else { - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger(slidEvent) - } - - isCycling && this.cycle() - - return this - } - - - // CAROUSEL PLUGIN DEFINITION - // ========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.carousel') - var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) - var action = typeof option == 'string' ? option : options.slide - - if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) - if (typeof option == 'number') data.to(option) - else if (action) data[action]() - else if (options.interval) data.pause().cycle() - }) - } - - var old = $.fn.carousel - - $.fn.carousel = Plugin - $.fn.carousel.Constructor = Carousel - - - // CAROUSEL NO CONFLICT - // ==================== - - $.fn.carousel.noConflict = function () { - $.fn.carousel = old - return this - } - - - // CAROUSEL DATA-API - // ================= - - var clickHandler = function (e) { - var href - var $this = $(this) - var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 - if (!$target.hasClass('carousel')) return - var options = $.extend({}, $target.data(), $this.data()) - var slideIndex = $this.attr('data-slide-to') - if (slideIndex) options.interval = false - - Plugin.call($target, options) - - if (slideIndex) { - $target.data('bs.carousel').to(slideIndex) - } - - e.preventDefault() - } - - $(document) - .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) - .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) - - $(window).on('load', function () { - $('[data-ride="carousel"]').each(function () { - var $carousel = $(this) - Plugin.call($carousel, $carousel.data()) - }) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: collapse.js v3.3.4 - * http://getbootstrap.com/javascript/#collapse - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // COLLAPSE PUBLIC CLASS DEFINITION - // ================================ - - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, Collapse.DEFAULTS, options) - this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + - '[data-toggle="collapse"][data-target="#' + element.id + '"]') - this.transitioning = null - - if (this.options.parent) { - this.$parent = this.getParent() - } else { - this.addAriaAndCollapsedClass(this.$element, this.$trigger) - } - - if (this.options.toggle) this.toggle() - } - - Collapse.VERSION = '3.3.4' - - Collapse.TRANSITION_DURATION = 350 - - Collapse.DEFAULTS = { - toggle: true - } - - Collapse.prototype.dimension = function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - Collapse.prototype.show = function () { - if (this.transitioning || this.$element.hasClass('in')) return - - var activesData - var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') - - if (actives && actives.length) { - activesData = actives.data('bs.collapse') - if (activesData && activesData.transitioning) return - } - - var startEvent = $.Event('show.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - if (actives && actives.length) { - Plugin.call(actives, 'hide') - activesData || actives.data('bs.collapse', null) - } - - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - .addClass('collapsing')[dimension](0) - .attr('aria-expanded', true) - - this.$trigger - .removeClass('collapsed') - .attr('aria-expanded', true) - - this.transitioning = 1 - - var complete = function () { - this.$element - .removeClass('collapsing') - .addClass('collapse in')[dimension]('') - this.transitioning = 0 - this.$element - .trigger('shown.bs.collapse') - } - - if (!$.support.transition) return complete.call(this) - - var scrollSize = $.camelCase(['scroll', dimension].join('-')) - - this.$element - .one('bsTransitionEnd', $.proxy(complete, this)) - .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) - } - - Collapse.prototype.hide = function () { - if (this.transitioning || !this.$element.hasClass('in')) return - - var startEvent = $.Event('hide.bs.collapse') - this.$element.trigger(startEvent) - if (startEvent.isDefaultPrevented()) return - - var dimension = this.dimension() - - this.$element[dimension](this.$element[dimension]())[0].offsetHeight - - this.$element - .addClass('collapsing') - .removeClass('collapse in') - .attr('aria-expanded', false) - - this.$trigger - .addClass('collapsed') - .attr('aria-expanded', false) - - this.transitioning = 1 - - var complete = function () { - this.transitioning = 0 - this.$element - .removeClass('collapsing') - .addClass('collapse') - .trigger('hidden.bs.collapse') - } - - if (!$.support.transition) return complete.call(this) - - this.$element - [dimension](0) - .one('bsTransitionEnd', $.proxy(complete, this)) - .emulateTransitionEnd(Collapse.TRANSITION_DURATION) - } - - Collapse.prototype.toggle = function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } - - Collapse.prototype.getParent = function () { - return $(this.options.parent) - .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') - .each($.proxy(function (i, element) { - var $element = $(element) - this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) - }, this)) - .end() - } - - Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { - var isOpen = $element.hasClass('in') - - $element.attr('aria-expanded', isOpen) - $trigger - .toggleClass('collapsed', !isOpen) - .attr('aria-expanded', isOpen) - } - - function getTargetFromTrigger($trigger) { - var href - var target = $trigger.attr('data-target') - || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 - - return $(target) - } - - - // COLLAPSE PLUGIN DEFINITION - // ========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.collapse') - var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) - - if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false - if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.collapse - - $.fn.collapse = Plugin - $.fn.collapse.Constructor = Collapse - - - // COLLAPSE NO CONFLICT - // ==================== - - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } - - - // COLLAPSE DATA-API - // ================= - - $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { - var $this = $(this) - - if (!$this.attr('data-target')) e.preventDefault() - - var $target = getTargetFromTrigger($this) - var data = $target.data('bs.collapse') - var option = data ? 'toggle' : $this.data() - - Plugin.call($target, option) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: dropdown.js v3.3.4 - * http://getbootstrap.com/javascript/#dropdowns - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // DROPDOWN CLASS DEFINITION - // ========================= - - var backdrop = '.dropdown-backdrop' - var toggle = '[data-toggle="dropdown"]' - var Dropdown = function (element) { - $(element).on('click.bs.dropdown', this.toggle) - } - - Dropdown.VERSION = '3.3.4' - - Dropdown.prototype.toggle = function (e) { - var $this = $(this) - - if ($this.is('.disabled, :disabled')) return - - var $parent = getParent($this) - var isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { - // if mobile we use a backdrop because click events don't delegate - $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus) - } - - var relatedTarget = { relatedTarget: this } - $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) - - if (e.isDefaultPrevented()) return - - $this - .trigger('focus') - .attr('aria-expanded', 'true') - - $parent - .toggleClass('open') - .trigger('shown.bs.dropdown', relatedTarget) - } - - return false - } - - Dropdown.prototype.keydown = function (e) { - if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return - - var $this = $(this) - - e.preventDefault() - e.stopPropagation() - - if ($this.is('.disabled, :disabled')) return - - var $parent = getParent($this) - var isActive = $parent.hasClass('open') - - if ((!isActive && e.which != 27) || (isActive && e.which == 27)) { - if (e.which == 27) $parent.find(toggle).trigger('focus') - return $this.trigger('click') - } - - var desc = ' li:not(.disabled):visible a' - var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc) - - if (!$items.length) return - - var index = $items.index(e.target) - - if (e.which == 38 && index > 0) index-- // up - if (e.which == 40 && index < $items.length - 1) index++ // down - if (!~index) index = 0 - - $items.eq(index).trigger('focus') - } - - function clearMenus(e) { - if (e && e.which === 3) return - $(backdrop).remove() - $(toggle).each(function () { - var $this = $(this) - var $parent = getParent($this) - var relatedTarget = { relatedTarget: this } - - if (!$parent.hasClass('open')) return - - $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) - - if (e.isDefaultPrevented()) return - - $this.attr('aria-expanded', 'false') - $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) - }) - } - - function getParent($this) { - var selector = $this.attr('data-target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - var $parent = selector && $(selector) - - return $parent && $parent.length ? $parent : $this.parent() - } - - - // DROPDOWN PLUGIN DEFINITION - // ========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.dropdown') - - if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - var old = $.fn.dropdown - - $.fn.dropdown = Plugin - $.fn.dropdown.Constructor = Dropdown - - - // DROPDOWN NO CONFLICT - // ==================== - - $.fn.dropdown.noConflict = function () { - $.fn.dropdown = old - return this - } - - - // APPLY TO STANDARD DROPDOWN ELEMENTS - // =================================== - - $(document) - .on('click.bs.dropdown.data-api', clearMenus) - .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) - .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) - .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) - .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown) - .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: modal.js v3.3.4 - * http://getbootstrap.com/javascript/#modals - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // MODAL CLASS DEFINITION - // ====================== - - var Modal = function (element, options) { - this.options = options - this.$body = $(document.body) - this.$element = $(element) - this.$dialog = this.$element.find('.modal-dialog') - this.$backdrop = null - this.isShown = null - this.originalBodyPad = null - this.scrollbarWidth = 0 - this.ignoreBackdropClick = false - - if (this.options.remote) { - this.$element - .find('.modal-content') - .load(this.options.remote, $.proxy(function () { - this.$element.trigger('loaded.bs.modal') - }, this)) - } - } - - Modal.VERSION = '3.3.4' - - Modal.TRANSITION_DURATION = 300 - Modal.BACKDROP_TRANSITION_DURATION = 150 - - Modal.DEFAULTS = { - backdrop: true, - keyboard: true, - show: true - } - - Modal.prototype.toggle = function (_relatedTarget) { - return this.isShown ? this.hide() : this.show(_relatedTarget) - } - - Modal.prototype.show = function (_relatedTarget) { - var that = this - var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) - - this.$element.trigger(e) - - if (this.isShown || e.isDefaultPrevented()) return - - this.isShown = true - - this.checkScrollbar() - this.setScrollbar() - this.$body.addClass('modal-open') - - this.escape() - this.resize() - - this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) - - this.$dialog.on('mousedown.dismiss.bs.modal', function () { - that.$element.one('mouseup.dismiss.bs.modal', function (e) { - if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true - }) - }) - - this.backdrop(function () { - var transition = $.support.transition && that.$element.hasClass('fade') - - if (!that.$element.parent().length) { - that.$element.appendTo(that.$body) // don't move modals dom position - } - - that.$element - .show() - .scrollTop(0) - - that.adjustDialog() - - if (transition) { - that.$element[0].offsetWidth // force reflow - } - - that.$element - .addClass('in') - .attr('aria-hidden', false) - - that.enforceFocus() - - var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) - - transition ? - that.$dialog // wait for modal to slide in - .one('bsTransitionEnd', function () { - that.$element.trigger('focus').trigger(e) - }) - .emulateTransitionEnd(Modal.TRANSITION_DURATION) : - that.$element.trigger('focus').trigger(e) - }) - } - - Modal.prototype.hide = function (e) { - if (e) e.preventDefault() - - e = $.Event('hide.bs.modal') - - this.$element.trigger(e) - - if (!this.isShown || e.isDefaultPrevented()) return - - this.isShown = false - - this.escape() - this.resize() - - $(document).off('focusin.bs.modal') - - this.$element - .removeClass('in') - .attr('aria-hidden', true) - .off('click.dismiss.bs.modal') - .off('mouseup.dismiss.bs.modal') - - this.$dialog.off('mousedown.dismiss.bs.modal') - - $.support.transition && this.$element.hasClass('fade') ? - this.$element - .one('bsTransitionEnd', $.proxy(this.hideModal, this)) - .emulateTransitionEnd(Modal.TRANSITION_DURATION) : - this.hideModal() - } - - Modal.prototype.enforceFocus = function () { - $(document) - .off('focusin.bs.modal') // guard against infinite focus loop - .on('focusin.bs.modal', $.proxy(function (e) { - if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { - this.$element.trigger('focus') - } - }, this)) - } - - Modal.prototype.escape = function () { - if (this.isShown && this.options.keyboard) { - this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { - e.which == 27 && this.hide() - }, this)) - } else if (!this.isShown) { - this.$element.off('keydown.dismiss.bs.modal') - } - } - - Modal.prototype.resize = function () { - if (this.isShown) { - $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) - } else { - $(window).off('resize.bs.modal') - } - } - - Modal.prototype.hideModal = function () { - var that = this - this.$element.hide() - this.backdrop(function () { - that.$body.removeClass('modal-open') - that.resetAdjustments() - that.resetScrollbar() - that.$element.trigger('hidden.bs.modal') - }) - } - - Modal.prototype.removeBackdrop = function () { - this.$backdrop && this.$backdrop.remove() - this.$backdrop = null - } - - Modal.prototype.backdrop = function (callback) { - var that = this - var animate = this.$element.hasClass('fade') ? 'fade' : '' - - if (this.isShown && this.options.backdrop) { - var doAnimate = $.support.transition && animate - - this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />') - .appendTo(this.$body) - - this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { - if (this.ignoreBackdropClick) { - this.ignoreBackdropClick = false - return - } - if (e.target !== e.currentTarget) return - this.options.backdrop == 'static' - ? this.$element[0].focus() - : this.hide() - }, this)) - - if (doAnimate) this.$backdrop[0].offsetWidth // force reflow - - this.$backdrop.addClass('in') - - if (!callback) return - - doAnimate ? - this.$backdrop - .one('bsTransitionEnd', callback) - .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : - callback() - - } else if (!this.isShown && this.$backdrop) { - this.$backdrop.removeClass('in') - - var callbackRemove = function () { - that.removeBackdrop() - callback && callback() - } - $.support.transition && this.$element.hasClass('fade') ? - this.$backdrop - .one('bsTransitionEnd', callbackRemove) - .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : - callbackRemove() - - } else if (callback) { - callback() - } - } - - // these following methods are used to handle overflowing modals - - Modal.prototype.handleUpdate = function () { - this.adjustDialog() - } - - Modal.prototype.adjustDialog = function () { - var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight - - this.$element.css({ - paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', - paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' - }) - } - - Modal.prototype.resetAdjustments = function () { - this.$element.css({ - paddingLeft: '', - paddingRight: '' - }) - } - - Modal.prototype.checkScrollbar = function () { - var fullWindowWidth = window.innerWidth - if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 - var documentElementRect = document.documentElement.getBoundingClientRect() - fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) - } - this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth - this.scrollbarWidth = this.measureScrollbar() - } - - Modal.prototype.setScrollbar = function () { - var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) - this.originalBodyPad = document.body.style.paddingRight || '' - if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) - } - - Modal.prototype.resetScrollbar = function () { - this.$body.css('padding-right', this.originalBodyPad) - } - - Modal.prototype.measureScrollbar = function () { // thx walsh - var scrollDiv = document.createElement('div') - scrollDiv.className = 'modal-scrollbar-measure' - this.$body.append(scrollDiv) - var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth - this.$body[0].removeChild(scrollDiv) - return scrollbarWidth - } - - - // MODAL PLUGIN DEFINITION - // ======================= - - function Plugin(option, _relatedTarget) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.modal') - var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) - - if (!data) $this.data('bs.modal', (data = new Modal(this, options))) - if (typeof option == 'string') data[option](_relatedTarget) - else if (options.show) data.show(_relatedTarget) - }) - } - - var old = $.fn.modal - - $.fn.modal = Plugin - $.fn.modal.Constructor = Modal - - - // MODAL NO CONFLICT - // ================= - - $.fn.modal.noConflict = function () { - $.fn.modal = old - return this - } - - - // MODAL DATA-API - // ============== - - $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { - var $this = $(this) - var href = $this.attr('href') - var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 - var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) - - if ($this.is('a')) e.preventDefault() - - $target.one('show.bs.modal', function (showEvent) { - if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown - $target.one('hidden.bs.modal', function () { - $this.is(':visible') && $this.trigger('focus') - }) - }) - Plugin.call($target, option, this) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: tooltip.js v3.3.4 - * http://getbootstrap.com/javascript/#tooltip - * Inspired by the original jQuery.tipsy by Jason Frame - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // TOOLTIP PUBLIC CLASS DEFINITION - // =============================== - - var Tooltip = function (element, options) { - this.type = null - this.options = null - this.enabled = null - this.timeout = null - this.hoverState = null - this.$element = null - - this.init('tooltip', element, options) - } - - Tooltip.VERSION = '3.3.4' - - Tooltip.TRANSITION_DURATION = 150 - - Tooltip.DEFAULTS = { - animation: true, - placement: 'top', - selector: false, - template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', - trigger: 'hover focus', - title: '', - delay: 0, - html: false, - container: false, - viewport: { - selector: 'body', - padding: 0 - } - } - - Tooltip.prototype.init = function (type, element, options) { - this.enabled = true - this.type = type - this.$element = $(element) - this.options = this.getOptions(options) - this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) - - if (this.$element[0] instanceof document.constructor && !this.options.selector) { - throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') - } - - var triggers = this.options.trigger.split(' ') - - for (var i = triggers.length; i--;) { - var trigger = triggers[i] - - if (trigger == 'click') { - this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) - } else if (trigger != 'manual') { - var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' - var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' - - this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) - this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) - } - } - - this.options.selector ? - (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : - this.fixTitle() - } - - Tooltip.prototype.getDefaults = function () { - return Tooltip.DEFAULTS - } - - Tooltip.prototype.getOptions = function (options) { - options = $.extend({}, this.getDefaults(), this.$element.data(), options) - - if (options.delay && typeof options.delay == 'number') { - options.delay = { - show: options.delay, - hide: options.delay - } - } - - return options - } - - Tooltip.prototype.getDelegateOptions = function () { - var options = {} - var defaults = this.getDefaults() - - this._options && $.each(this._options, function (key, value) { - if (defaults[key] != value) options[key] = value - }) - - return options - } - - Tooltip.prototype.enter = function (obj) { - var self = obj instanceof this.constructor ? - obj : $(obj.currentTarget).data('bs.' + this.type) - - if (self && self.$tip && self.$tip.is(':visible')) { - self.hoverState = 'in' - return - } - - if (!self) { - self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) - $(obj.currentTarget).data('bs.' + this.type, self) - } - - clearTimeout(self.timeout) - - self.hoverState = 'in' - - if (!self.options.delay || !self.options.delay.show) return self.show() - - self.timeout = setTimeout(function () { - if (self.hoverState == 'in') self.show() - }, self.options.delay.show) - } - - Tooltip.prototype.leave = function (obj) { - var self = obj instanceof this.constructor ? - obj : $(obj.currentTarget).data('bs.' + this.type) - - if (!self) { - self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) - $(obj.currentTarget).data('bs.' + this.type, self) - } - - clearTimeout(self.timeout) - - self.hoverState = 'out' - - if (!self.options.delay || !self.options.delay.hide) return self.hide() - - self.timeout = setTimeout(function () { - if (self.hoverState == 'out') self.hide() - }, self.options.delay.hide) - } - - Tooltip.prototype.show = function () { - var e = $.Event('show.bs.' + this.type) - - if (this.hasContent() && this.enabled) { - this.$element.trigger(e) - - var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) - if (e.isDefaultPrevented() || !inDom) return - var that = this - - var $tip = this.tip() - - var tipId = this.getUID(this.type) - - this.setContent() - $tip.attr('id', tipId) - this.$element.attr('aria-describedby', tipId) - - if (this.options.animation) $tip.addClass('fade') - - var placement = typeof this.options.placement == 'function' ? - this.options.placement.call(this, $tip[0], this.$element[0]) : - this.options.placement - - var autoToken = /\s?auto?\s?/i - var autoPlace = autoToken.test(placement) - if (autoPlace) placement = placement.replace(autoToken, '') || 'top' - - $tip - .detach() - .css({ top: 0, left: 0, display: 'block' }) - .addClass(placement) - .data('bs.' + this.type, this) - - this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) - - var pos = this.getPosition() - var actualWidth = $tip[0].offsetWidth - var actualHeight = $tip[0].offsetHeight - - if (autoPlace) { - var orgPlacement = placement - var $container = this.options.container ? $(this.options.container) : this.$element.parent() - var containerDim = this.getPosition($container) - - placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' : - placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' : - placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' : - placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' : - placement - - $tip - .removeClass(orgPlacement) - .addClass(placement) - } - - var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) - - this.applyPlacement(calculatedOffset, placement) - - var complete = function () { - var prevHoverState = that.hoverState - that.$element.trigger('shown.bs.' + that.type) - that.hoverState = null - - if (prevHoverState == 'out') that.leave(that) - } - - $.support.transition && this.$tip.hasClass('fade') ? - $tip - .one('bsTransitionEnd', complete) - .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : - complete() - } - } - - Tooltip.prototype.applyPlacement = function (offset, placement) { - var $tip = this.tip() - var width = $tip[0].offsetWidth - var height = $tip[0].offsetHeight - - // manually read margins because getBoundingClientRect includes difference - var marginTop = parseInt($tip.css('margin-top'), 10) - var marginLeft = parseInt($tip.css('margin-left'), 10) - - // we must check for NaN for ie 8/9 - if (isNaN(marginTop)) marginTop = 0 - if (isNaN(marginLeft)) marginLeft = 0 - - offset.top = offset.top + marginTop - offset.left = offset.left + marginLeft - - // $.fn.offset doesn't round pixel values - // so we use setOffset directly with our own function B-0 - $.offset.setOffset($tip[0], $.extend({ - using: function (props) { - $tip.css({ - top: Math.round(props.top), - left: Math.round(props.left) - }) - } - }, offset), 0) - - $tip.addClass('in') - - // check to see if placing tip in new offset caused the tip to resize itself - var actualWidth = $tip[0].offsetWidth - var actualHeight = $tip[0].offsetHeight - - if (placement == 'top' && actualHeight != height) { - offset.top = offset.top + height - actualHeight - } - - var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) - - if (delta.left) offset.left += delta.left - else offset.top += delta.top - - var isVertical = /top|bottom/.test(placement) - var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight - var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' - - $tip.offset(offset) - this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) - } - - Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { - this.arrow() - .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') - .css(isVertical ? 'top' : 'left', '') - } - - Tooltip.prototype.setContent = function () { - var $tip = this.tip() - var title = this.getTitle() - - $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) - $tip.removeClass('fade in top bottom left right') - } - - Tooltip.prototype.hide = function (callback) { - var that = this - var $tip = $(this.$tip) - var e = $.Event('hide.bs.' + this.type) - - function complete() { - if (that.hoverState != 'in') $tip.detach() - that.$element - .removeAttr('aria-describedby') - .trigger('hidden.bs.' + that.type) - callback && callback() - } - - this.$element.trigger(e) - - if (e.isDefaultPrevented()) return - - $tip.removeClass('in') - - $.support.transition && $tip.hasClass('fade') ? - $tip - .one('bsTransitionEnd', complete) - .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : - complete() - - this.hoverState = null - - return this - } - - Tooltip.prototype.fixTitle = function () { - var $e = this.$element - if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') { - $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') - } - } - - Tooltip.prototype.hasContent = function () { - return this.getTitle() - } - - Tooltip.prototype.getPosition = function ($element) { - $element = $element || this.$element - - var el = $element[0] - var isBody = el.tagName == 'BODY' - - var elRect = el.getBoundingClientRect() - if (elRect.width == null) { - // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 - elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) - } - var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() - var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } - var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null - - return $.extend({}, elRect, scroll, outerDims, elOffset) - } - - Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { - return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : - placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : - placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : - /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } - - } - - Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { - var delta = { top: 0, left: 0 } - if (!this.$viewport) return delta - - var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 - var viewportDimensions = this.getPosition(this.$viewport) - - if (/right|left/.test(placement)) { - var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll - var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight - if (topEdgeOffset < viewportDimensions.top) { // top overflow - delta.top = viewportDimensions.top - topEdgeOffset - } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow - delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset - } - } else { - var leftEdgeOffset = pos.left - viewportPadding - var rightEdgeOffset = pos.left + viewportPadding + actualWidth - if (leftEdgeOffset < viewportDimensions.left) { // left overflow - delta.left = viewportDimensions.left - leftEdgeOffset - } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow - delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset - } - } - - return delta - } - - Tooltip.prototype.getTitle = function () { - var title - var $e = this.$element - var o = this.options - - title = $e.attr('data-original-title') - || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) - - return title - } - - Tooltip.prototype.getUID = function (prefix) { - do prefix += ~~(Math.random() * 1000000) - while (document.getElementById(prefix)) - return prefix - } - - Tooltip.prototype.tip = function () { - return (this.$tip = this.$tip || $(this.options.template)) - } - - Tooltip.prototype.arrow = function () { - return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) - } - - Tooltip.prototype.enable = function () { - this.enabled = true - } - - Tooltip.prototype.disable = function () { - this.enabled = false - } - - Tooltip.prototype.toggleEnabled = function () { - this.enabled = !this.enabled - } - - Tooltip.prototype.toggle = function (e) { - var self = this - if (e) { - self = $(e.currentTarget).data('bs.' + this.type) - if (!self) { - self = new this.constructor(e.currentTarget, this.getDelegateOptions()) - $(e.currentTarget).data('bs.' + this.type, self) - } - } - - self.tip().hasClass('in') ? self.leave(self) : self.enter(self) - } - - Tooltip.prototype.destroy = function () { - var that = this - clearTimeout(this.timeout) - this.hide(function () { - that.$element.off('.' + that.type).removeData('bs.' + that.type) - }) - } - - - // TOOLTIP PLUGIN DEFINITION - // ========================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.tooltip') - var options = typeof option == 'object' && option - - if (!data && /destroy|hide/.test(option)) return - if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.tooltip - - $.fn.tooltip = Plugin - $.fn.tooltip.Constructor = Tooltip - - - // TOOLTIP NO CONFLICT - // =================== - - $.fn.tooltip.noConflict = function () { - $.fn.tooltip = old - return this - } - -}(jQuery); - -/* ======================================================================== - * Bootstrap: popover.js v3.3.4 - * http://getbootstrap.com/javascript/#popovers - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // POPOVER PUBLIC CLASS DEFINITION - // =============================== - - var Popover = function (element, options) { - this.init('popover', element, options) - } - - if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') - - Popover.VERSION = '3.3.4' - - Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { - placement: 'right', - trigger: 'click', - content: '', - template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' - }) - - - // NOTE: POPOVER EXTENDS tooltip.js - // ================================ - - Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) - - Popover.prototype.constructor = Popover - - Popover.prototype.getDefaults = function () { - return Popover.DEFAULTS - } - - Popover.prototype.setContent = function () { - var $tip = this.tip() - var title = this.getTitle() - var content = this.getContent() - - $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) - $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events - this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' - ](content) - - $tip.removeClass('fade top bottom left right in') - - // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do - // this manually by checking the contents. - if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() - } - - Popover.prototype.hasContent = function () { - return this.getTitle() || this.getContent() - } - - Popover.prototype.getContent = function () { - var $e = this.$element - var o = this.options - - return $e.attr('data-content') - || (typeof o.content == 'function' ? - o.content.call($e[0]) : - o.content) - } - - Popover.prototype.arrow = function () { - return (this.$arrow = this.$arrow || this.tip().find('.arrow')) - } - - - // POPOVER PLUGIN DEFINITION - // ========================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.popover') - var options = typeof option == 'object' && option - - if (!data && /destroy|hide/.test(option)) return - if (!data) $this.data('bs.popover', (data = new Popover(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.popover - - $.fn.popover = Plugin - $.fn.popover.Constructor = Popover - - - // POPOVER NO CONFLICT - // =================== - - $.fn.popover.noConflict = function () { - $.fn.popover = old - return this - } - -}(jQuery); - -/* ======================================================================== - * Bootstrap: scrollspy.js v3.3.4 - * http://getbootstrap.com/javascript/#scrollspy - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // SCROLLSPY CLASS DEFINITION - // ========================== - - function ScrollSpy(element, options) { - this.$body = $(document.body) - this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) - this.options = $.extend({}, ScrollSpy.DEFAULTS, options) - this.selector = (this.options.target || '') + ' .nav li > a' - this.offsets = [] - this.targets = [] - this.activeTarget = null - this.scrollHeight = 0 - - this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) - this.refresh() - this.process() - } - - ScrollSpy.VERSION = '3.3.4' - - ScrollSpy.DEFAULTS = { - offset: 10 - } - - ScrollSpy.prototype.getScrollHeight = function () { - return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) - } - - ScrollSpy.prototype.refresh = function () { - var that = this - var offsetMethod = 'offset' - var offsetBase = 0 - - this.offsets = [] - this.targets = [] - this.scrollHeight = this.getScrollHeight() - - if (!$.isWindow(this.$scrollElement[0])) { - offsetMethod = 'position' - offsetBase = this.$scrollElement.scrollTop() - } - - this.$body - .find(this.selector) - .map(function () { - var $el = $(this) - var href = $el.data('target') || $el.attr('href') - var $href = /^#./.test(href) && $(href) - - return ($href - && $href.length - && $href.is(':visible') - && [[$href[offsetMethod]().top + offsetBase, href]]) || null - }) - .sort(function (a, b) { return a[0] - b[0] }) - .each(function () { - that.offsets.push(this[0]) - that.targets.push(this[1]) - }) - } - - ScrollSpy.prototype.process = function () { - var scrollTop = this.$scrollElement.scrollTop() + this.options.offset - var scrollHeight = this.getScrollHeight() - var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() - var offsets = this.offsets - var targets = this.targets - var activeTarget = this.activeTarget - var i - - if (this.scrollHeight != scrollHeight) { - this.refresh() - } - - if (scrollTop >= maxScroll) { - return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) - } - - if (activeTarget && scrollTop < offsets[0]) { - this.activeTarget = null - return this.clear() - } - - for (i = offsets.length; i--;) { - activeTarget != targets[i] - && scrollTop >= offsets[i] - && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) - && this.activate(targets[i]) - } - } - - ScrollSpy.prototype.activate = function (target) { - this.activeTarget = target - - this.clear() - - var selector = this.selector + - '[data-target="' + target + '"],' + - this.selector + '[href="' + target + '"]' - - var active = $(selector) - .parents('li') - .addClass('active') - - if (active.parent('.dropdown-menu').length) { - active = active - .closest('li.dropdown') - .addClass('active') - } - - active.trigger('activate.bs.scrollspy') - } - - ScrollSpy.prototype.clear = function () { - $(this.selector) - .parentsUntil(this.options.target, '.active') - .removeClass('active') - } - - - // SCROLLSPY PLUGIN DEFINITION - // =========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.scrollspy') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.scrollspy - - $.fn.scrollspy = Plugin - $.fn.scrollspy.Constructor = ScrollSpy - - - // SCROLLSPY NO CONFLICT - // ===================== - - $.fn.scrollspy.noConflict = function () { - $.fn.scrollspy = old - return this - } - - - // SCROLLSPY DATA-API - // ================== - - $(window).on('load.bs.scrollspy.data-api', function () { - $('[data-spy="scroll"]').each(function () { - var $spy = $(this) - Plugin.call($spy, $spy.data()) - }) - }) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: tab.js v3.3.4 - * http://getbootstrap.com/javascript/#tabs - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // TAB CLASS DEFINITION - // ==================== - - var Tab = function (element) { - this.element = $(element) - } - - Tab.VERSION = '3.3.4' - - Tab.TRANSITION_DURATION = 150 - - Tab.prototype.show = function () { - var $this = this.element - var $ul = $this.closest('ul:not(.dropdown-menu)') - var selector = $this.data('target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - if ($this.parent('li').hasClass('active')) return - - var $previous = $ul.find('.active:last a') - var hideEvent = $.Event('hide.bs.tab', { - relatedTarget: $this[0] - }) - var showEvent = $.Event('show.bs.tab', { - relatedTarget: $previous[0] - }) - - $previous.trigger(hideEvent) - $this.trigger(showEvent) - - if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return - - var $target = $(selector) - - this.activate($this.closest('li'), $ul) - this.activate($target, $target.parent(), function () { - $previous.trigger({ - type: 'hidden.bs.tab', - relatedTarget: $this[0] - }) - $this.trigger({ - type: 'shown.bs.tab', - relatedTarget: $previous[0] - }) - }) - } - - Tab.prototype.activate = function (element, container, callback) { - var $active = container.find('> .active') - var transition = callback - && $.support.transition - && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length) - - function next() { - $active - .removeClass('active') - .find('> .dropdown-menu > .active') - .removeClass('active') - .end() - .find('[data-toggle="tab"]') - .attr('aria-expanded', false) - - element - .addClass('active') - .find('[data-toggle="tab"]') - .attr('aria-expanded', true) - - if (transition) { - element[0].offsetWidth // reflow for transition - element.addClass('in') - } else { - element.removeClass('fade') - } - - if (element.parent('.dropdown-menu').length) { - element - .closest('li.dropdown') - .addClass('active') - .end() - .find('[data-toggle="tab"]') - .attr('aria-expanded', true) - } - - callback && callback() - } - - $active.length && transition ? - $active - .one('bsTransitionEnd', next) - .emulateTransitionEnd(Tab.TRANSITION_DURATION) : - next() - - $active.removeClass('in') - } - - - // TAB PLUGIN DEFINITION - // ===================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.tab') - - if (!data) $this.data('bs.tab', (data = new Tab(this))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.tab - - $.fn.tab = Plugin - $.fn.tab.Constructor = Tab - - - // TAB NO CONFLICT - // =============== - - $.fn.tab.noConflict = function () { - $.fn.tab = old - return this - } - - - // TAB DATA-API - // ============ - - var clickHandler = function (e) { - e.preventDefault() - Plugin.call($(this), 'show') - } - - $(document) - .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) - .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) - -}(jQuery); - -/* ======================================================================== - * Bootstrap: affix.js v3.3.4 - * http://getbootstrap.com/javascript/#affix - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // AFFIX CLASS DEFINITION - // ====================== - - var Affix = function (element, options) { - this.options = $.extend({}, Affix.DEFAULTS, options) - - this.$target = $(this.options.target) - .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) - .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) - - this.$element = $(element) - this.affixed = null - this.unpin = null - this.pinnedOffset = null - - this.checkPosition() - } - - Affix.VERSION = '3.3.4' - - Affix.RESET = 'affix affix-top affix-bottom' - - Affix.DEFAULTS = { - offset: 0, - target: window - } - - Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { - var scrollTop = this.$target.scrollTop() - var position = this.$element.offset() - var targetHeight = this.$target.height() - - if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false - - if (this.affixed == 'bottom') { - if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' - return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' - } - - var initializing = this.affixed == null - var colliderTop = initializing ? scrollTop : position.top - var colliderHeight = initializing ? targetHeight : height - - if (offsetTop != null && scrollTop <= offsetTop) return 'top' - if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' - - return false - } - - Affix.prototype.getPinnedOffset = function () { - if (this.pinnedOffset) return this.pinnedOffset - this.$element.removeClass(Affix.RESET).addClass('affix') - var scrollTop = this.$target.scrollTop() - var position = this.$element.offset() - return (this.pinnedOffset = position.top - scrollTop) - } - - Affix.prototype.checkPositionWithEventLoop = function () { - setTimeout($.proxy(this.checkPosition, this), 1) - } - - Affix.prototype.checkPosition = function () { - if (!this.$element.is(':visible')) return - - var height = this.$element.height() - var offset = this.options.offset - var offsetTop = offset.top - var offsetBottom = offset.bottom - var scrollHeight = $(document.body).height() - - if (typeof offset != 'object') offsetBottom = offsetTop = offset - if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) - if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) - - var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) - - if (this.affixed != affix) { - if (this.unpin != null) this.$element.css('top', '') - - var affixType = 'affix' + (affix ? '-' + affix : '') - var e = $.Event(affixType + '.bs.affix') - - this.$element.trigger(e) - - if (e.isDefaultPrevented()) return - - this.affixed = affix - this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null - - this.$element - .removeClass(Affix.RESET) - .addClass(affixType) - .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') - } - - if (affix == 'bottom') { - this.$element.offset({ - top: scrollHeight - height - offsetBottom - }) - } - } - - - // AFFIX PLUGIN DEFINITION - // ======================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.affix') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.affix', (data = new Affix(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.affix - - $.fn.affix = Plugin - $.fn.affix.Constructor = Affix - - - // AFFIX NO CONFLICT - // ================= - - $.fn.affix.noConflict = function () { - $.fn.affix = old - return this - } - - - // AFFIX DATA-API - // ============== - - $(window).on('load', function () { - $('[data-spy="affix"]').each(function () { - var $spy = $(this) - var data = $spy.data() - - data.offset = data.offset || {} - - if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom - if (data.offsetTop != null) data.offset.top = data.offsetTop - - Plugin.call($spy, data) - }) - }) - -}(jQuery); diff --git a/web/js/bootstrap.min.js b/web/js/bootstrap.min.js deleted file mode 100644 index c8f82e5..0000000 --- a/web/js/bootstrap.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.3.4 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.4",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.4",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.4",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.4",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport),this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(n).addClass(h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.4",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.4",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){ -var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.4",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a(document.body).height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file diff --git a/web/js/jquery.datetimepicker.full.js b/web/js/jquery.datetimepicker.full.js deleted file mode 100644 index 417037c..0000000 --- a/web/js/jquery.datetimepicker.full.js +++ /dev/null @@ -1,3073 +0,0 @@ -/*! - * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2015 - * @version 1.3.3 - * - * Date formatter utility library that allows formatting date/time variables or Date objects using PHP DateTime format. - * @see http://php.net/manual/en/function.date.php - * - * For more JQuery plugins visit http://plugins.krajee.com - * For more Yii related demos visit http://demos.krajee.com - */ -var DateFormatter; -(function () { - "use strict"; - - var _compare, _lpad, _extend, defaultSettings, DAY, HOUR; - DAY = 1000 * 60 * 60 * 24; - HOUR = 3600; - - _compare = function (str1, str2) { - return typeof(str1) === 'string' && typeof(str2) === 'string' && str1.toLowerCase() === str2.toLowerCase(); - }; - _lpad = function (value, length, char) { - var chr = char || '0', val = value.toString(); - return val.length < length ? _lpad(chr + val, length) : val; - }; - _extend = function (out) { - var i, obj; - out = out || {}; - for (i = 1; i < arguments.length; i++) { - obj = arguments[i]; - if (!obj) { - continue; - } - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - if (typeof obj[key] === 'object') { - _extend(out[key], obj[key]); - } else { - out[key] = obj[key]; - } - } - } - } - return out; - }; - defaultSettings = { - dateSettings: { - days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], - months: [ - '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'], - meridiem: ['AM', 'PM'], - ordinal: function (number) { - var n = number % 10, suffixes = {1: 'st', 2: 'nd', 3: 'rd'}; - return Math.floor(number % 100 / 10) === 1 || !suffixes[n] ? 'th' : suffixes[n]; - } - }, - separators: /[ \-+\/\.T:@]/g, - validParts: /[dDjlNSwzWFmMntLoYyaABgGhHisueTIOPZcrU]/g, - intParts: /[djwNzmnyYhHgGis]/g, - tzParts: /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, - tzClip: /[^-+\dA-Z]/g - }; - - DateFormatter = function (options) { - var self = this, config = _extend(defaultSettings, options); - self.dateSettings = config.dateSettings; - self.separators = config.separators; - self.validParts = config.validParts; - self.intParts = config.intParts; - self.tzParts = config.tzParts; - self.tzClip = config.tzClip; - }; - - DateFormatter.prototype = { - constructor: DateFormatter, - parseDate: function (vDate, vFormat) { - var self = this, vFormatParts, vDateParts, i, vDateFlag = false, vTimeFlag = false, vDatePart, iDatePart, - vSettings = self.dateSettings, vMonth, vMeriIndex, vMeriOffset, len, mer, - out = {date: null, year: null, month: null, day: null, hour: 0, min: 0, sec: 0}; - if (!vDate) { - return undefined; - } - if (vDate instanceof Date) { - return vDate; - } - if (typeof vDate === 'number') { - return new Date(vDate); - } - if (vFormat === 'U') { - i = parseInt(vDate); - return i ? new Date(i * 1000) : vDate; - } - if (typeof vDate !== 'string') { - return ''; - } - vFormatParts = vFormat.match(self.validParts); - if (!vFormatParts || vFormatParts.length === 0) { - throw new Error("Invalid date format definition."); - } - vDateParts = vDate.replace(self.separators, '\0').split('\0'); - for (i = 0; i < vDateParts.length; i++) { - vDatePart = vDateParts[i]; - iDatePart = parseInt(vDatePart); - switch (vFormatParts[i]) { - case 'y': - case 'Y': - len = vDatePart.length; - if (len === 2) { - out.year = parseInt((iDatePart < 70 ? '20' : '19') + vDatePart); - } else if (len === 4) { - out.year = iDatePart; - } - vDateFlag = true; - break; - case 'm': - case 'n': - case 'M': - case 'F': - if (isNaN(vDatePart)) { - vMonth = vSettings.monthsShort.indexOf(vDatePart); - if (vMonth > -1) { - out.month = vMonth + 1; - } - vMonth = vSettings.months.indexOf(vDatePart); - if (vMonth > -1) { - out.month = vMonth + 1; - } - } else { - if (iDatePart >= 1 && iDatePart <= 12) { - out.month = iDatePart; - } - } - vDateFlag = true; - break; - case 'd': - case 'j': - if (iDatePart >= 1 && iDatePart <= 31) { - out.day = iDatePart; - } - vDateFlag = true; - break; - case 'g': - case 'h': - vMeriIndex = (vFormatParts.indexOf('a') > -1) ? vFormatParts.indexOf('a') : - (vFormatParts.indexOf('A') > -1) ? vFormatParts.indexOf('A') : -1; - mer = vDateParts[vMeriIndex]; - if (vMeriIndex > -1) { - vMeriOffset = _compare(mer, vSettings.meridiem[0]) ? 0 : - (_compare(mer, vSettings.meridiem[1]) ? 12 : -1); - if (iDatePart >= 1 && iDatePart <= 12 && vMeriOffset > -1) { - out.hour = iDatePart + vMeriOffset - 1; - } else if (iDatePart >= 0 && iDatePart <= 23) { - out.hour = iDatePart; - } - } else if (iDatePart >= 0 && iDatePart <= 23) { - out.hour = iDatePart; - } - vTimeFlag = true; - break; - case 'G': - case 'H': - if (iDatePart >= 0 && iDatePart <= 23) { - out.hour = iDatePart; - } - vTimeFlag = true; - break; - case 'i': - if (iDatePart >= 0 && iDatePart <= 59) { - out.min = iDatePart; - } - vTimeFlag = true; - break; - case 's': - if (iDatePart >= 0 && iDatePart <= 59) { - out.sec = iDatePart; - } - vTimeFlag = true; - break; - } - } - if (vDateFlag === true && out.year && out.month && out.day) { - out.date = new Date(out.year, out.month - 1, out.day, out.hour, out.min, out.sec, 0); - } else { - if (vTimeFlag !== true) { - return false; - } - out.date = new Date(0, 0, 0, out.hour, out.min, out.sec, 0); - } - return out.date; - }, - guessDate: function (vDateStr, vFormat) { - if (typeof vDateStr !== 'string') { - return vDateStr; - } - var self = this, vParts = vDateStr.replace(self.separators, '\0').split('\0'), vPattern = /^[djmn]/g, - vFormatParts = vFormat.match(self.validParts), vDate = new Date(), vDigit = 0, vYear, i, iPart, iSec; - - if (!vPattern.test(vFormatParts[0])) { - return vDateStr; - } - - for (i = 0; i < vParts.length; i++) { - vDigit = 2; - iPart = vParts[i]; - iSec = parseInt(iPart.substr(0, 2)); - switch (i) { - case 0: - if (vFormatParts[0] === 'm' || vFormatParts[0] === 'n') { - vDate.setMonth(iSec - 1); - } else { - vDate.setDate(iSec); - } - break; - case 1: - if (vFormatParts[0] === 'm' || vFormatParts[0] === 'n') { - vDate.setDate(iSec); - } else { - vDate.setMonth(iSec - 1); - } - break; - case 2: - vYear = vDate.getFullYear(); - if (iPart.length < 4) { - vDate.setFullYear(parseInt(vYear.toString().substr(0, 4 - iPart.length) + iPart)); - vDigit = iPart.length; - } else { - vDate.setFullYear = parseInt(iPart.substr(0, 4)); - vDigit = 4; - } - break; - case 3: - vDate.setHours(iSec); - break; - case 4: - vDate.setMinutes(iSec); - break; - case 5: - vDate.setSeconds(iSec); - break; - } - if (iPart.substr(vDigit).length > 0) { - vParts.splice(i + 1, 0, iPart.substr(vDigit)); - } - } - return vDate; - }, - parseFormat: function (vChar, vDate) { - var self = this, vSettings = self.dateSettings, fmt, backspace = /\\?(.?)/gi, doFormat = function (t, s) { - return fmt[t] ? fmt[t]() : s; - }; - fmt = { - ///////// - // DAY // - ///////// - /** - * Day of month with leading 0: `01..31` - * @return {string} - */ - d: function () { - return _lpad(fmt.j(), 2); - }, - /** - * Shorthand day name: `Mon...Sun` - * @return {string} - */ - D: function () { - return vSettings.daysShort[fmt.w()]; - }, - /** - * Day of month: `1..31` - * @return {number} - */ - j: function () { - return vDate.getDate(); - }, - /** - * Full day name: `Monday...Sunday` - * @return {number} - */ - l: function () { - return vSettings.days[fmt.w()]; - }, - /** - * ISO-8601 day of week: `1[Mon]..7[Sun]` - * @return {number} - */ - N: function () { - return fmt.w() || 7; - }, - /** - * Day of week: `0[Sun]..6[Sat]` - * @return {number} - */ - w: function () { - return vDate.getDay(); - }, - /** - * Day of year: `0..365` - * @return {number} - */ - z: function () { - var a = new Date(fmt.Y(), fmt.n() - 1, fmt.j()), b = new Date(fmt.Y(), 0, 1); - return Math.round((a - b) / DAY); - }, - - ////////// - // WEEK // - ////////// - /** - * ISO-8601 week number - * @return {number} - */ - W: function () { - var a = new Date(fmt.Y(), fmt.n() - 1, fmt.j() - fmt.N() + 3), b = new Date(a.getFullYear(), 0, 4); - return _lpad(1 + Math.round((a - b) / DAY / 7), 2); - }, - - /////////// - // MONTH // - /////////// - /** - * Full month name: `January...December` - * @return {string} - */ - F: function () { - return vSettings.months[vDate.getMonth()]; - }, - /** - * Month w/leading 0: `01..12` - * @return {string} - */ - m: function () { - return _lpad(fmt.n(), 2); - }, - /** - * Shorthand month name; `Jan...Dec` - * @return {string} - */ - M: function () { - return vSettings.monthsShort[vDate.getMonth()]; - }, - /** - * Month: `1...12` - * @return {number} - */ - n: function () { - return vDate.getMonth() + 1; - }, - /** - * Days in month: `28...31` - * @return {number} - */ - t: function () { - return (new Date(fmt.Y(), fmt.n(), 0)).getDate(); - }, - - ////////// - // YEAR // - ////////// - /** - * Is leap year? `0 or 1` - * @return {number} - */ - L: function () { - var Y = fmt.Y(); - return (Y % 4 === 0 && Y % 100 !== 0 || Y % 400 === 0) ? 1 : 0; - }, - /** - * ISO-8601 year - * @return {number} - */ - o: function () { - var n = fmt.n(), W = fmt.W(), Y = fmt.Y(); - return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0); - }, - /** - * Full year: `e.g. 1980...2010` - * @return {number} - */ - Y: function () { - return vDate.getFullYear(); - }, - /** - * Last two digits of year: `00...99` - * @return {string} - */ - y: function () { - return fmt.Y().toString().slice(-2); - }, - - ////////// - // TIME // - ////////// - /** - * Meridian lower: `am or pm` - * @return {string} - */ - a: function () { - return fmt.A().toLowerCase(); - }, - /** - * Meridian upper: `AM or PM` - * @return {string} - */ - A: function () { - var n = fmt.G() < 12 ? 0 : 1; - return vSettings.meridiem[n]; - }, - /** - * Swatch Internet time: `000..999` - * @return {string} - */ - B: function () { - var H = vDate.getUTCHours() * HOUR, i = vDate.getUTCMinutes() * 60, s = vDate.getUTCSeconds(); - return _lpad(Math.floor((H + i + s + HOUR) / 86.4) % 1000, 3); - }, - /** - * 12-Hours: `1..12` - * @return {number} - */ - g: function () { - return fmt.G() % 12 || 12; - }, - /** - * 24-Hours: `0..23` - * @return {number} - */ - G: function () { - return vDate.getHours(); - }, - /** - * 12-Hours with leading 0: `01..12` - * @return {string} - */ - h: function () { - return _lpad(fmt.g(), 2); - }, - /** - * 24-Hours w/leading 0: `00..23` - * @return {string} - */ - H: function () { - return _lpad(fmt.G(), 2); - }, - /** - * Minutes w/leading 0: `00..59` - * @return {string} - */ - i: function () { - return _lpad(vDate.getMinutes(), 2); - }, - /** - * Seconds w/leading 0: `00..59` - * @return {string} - */ - s: function () { - return _lpad(vDate.getSeconds(), 2); - }, - /** - * Microseconds: `000000-999000` - * @return {string} - */ - u: function () { - return _lpad(vDate.getMilliseconds() * 1000, 6); - }, - - ////////////// - // TIMEZONE // - ////////////// - /** - * Timezone identifier: `e.g. Atlantic/Azores, ...` - * @return {string} - */ - e: function () { - var str = /\((.*)\)/.exec(String(vDate))[1]; - return str || 'Coordinated Universal Time'; - }, - /** - * Timezone abbreviation: `e.g. EST, MDT, ...` - * @return {string} - */ - T: function () { - var str = (String(vDate).match(self.tzParts) || [""]).pop().replace(self.tzClip, ""); - return str || 'UTC'; - }, - /** - * DST observed? `0 or 1` - * @return {number} - */ - I: function () { - var a = new Date(fmt.Y(), 0), c = Date.UTC(fmt.Y(), 0), - b = new Date(fmt.Y(), 6), d = Date.UTC(fmt.Y(), 6); - return ((a - c) !== (b - d)) ? 1 : 0; - }, - /** - * Difference to GMT in hour format: `e.g. +0200` - * @return {string} - */ - O: function () { - var tzo = vDate.getTimezoneOffset(), a = Math.abs(tzo); - return (tzo > 0 ? '-' : '+') + _lpad(Math.floor(a / 60) * 100 + a % 60, 4); - }, - /** - * Difference to GMT with colon: `e.g. +02:00` - * @return {string} - */ - P: function () { - var O = fmt.O(); - return (O.substr(0, 3) + ':' + O.substr(3, 2)); - }, - /** - * Timezone offset in seconds: `-43200...50400` - * @return {number} - */ - Z: function () { - return -vDate.getTimezoneOffset() * 60; - }, - - //////////////////// - // FULL DATE TIME // - //////////////////// - /** - * ISO-8601 date - * @return {string} - */ - c: function () { - return 'Y-m-d\\TH:i:s'.replace(backspace, doFormat); - }, - /** - * RFC 2822 date - * @return {string} - */ - r: function () { - return 'D, d M Y H:i:s O'.replace(backspace, doFormat); - }, - /** - * Seconds since UNIX epoch - * @return {number} - */ - U: function () { - return vDate.getTime() / 1000 || 0; - } - }; - return doFormat(vChar, vChar); - }, - formatDate: function (vDate, vFormat) { - var self = this, i, n, len, str, vChar, vDateStr = ''; - if (typeof vDate === 'string') { - vDate = self.parseDate(vDate, vFormat); - if (vDate === false) { - return false; - } - } - if (vDate instanceof Date) { - len = vFormat.length; - for (i = 0; i < len; i++) { - vChar = vFormat.charAt(i); - if (vChar === 'S') { - continue; - } - str = self.parseFormat(vChar, vDate); - if (i !== (len - 1) && self.intParts.test(vChar) && vFormat.charAt(i + 1) === 'S') { - n = parseInt(str); - str += self.dateSettings.ordinal(n); - } - vDateStr += str; - } - return vDateStr; - } - return ''; - } - }; -})();/** - * @preserve jQuery DateTimePicker plugin v2.5.1 - * @homepage http://xdsoft.net/jqplugins/datetimepicker/ - * @author Chupurnov Valeriy (<chupurnov@gmail.com>) - */ -/*global DateFormatter, document,window,jQuery,setTimeout,clearTimeout,HighlightedDate,getCurrentValue*/ -;(function (factory) { - if ( typeof define === 'function' && define.amd ) { - // AMD. Register as an anonymous module. - define(['jquery', 'jquery-mousewheel'], factory); - } else if (typeof exports === 'object') { - // Node/CommonJS style for Browserify - module.exports = factory; - } else { - // Browser globals - factory(jQuery); - } -}(function ($) { - 'use strict'; - var default_options = { - i18n: { - ar: { // Arabic - months: [ - "كانون الثاني", "شباط", "آذار", "نيسان", "مايو", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول" - ], - dayOfWeekShort: [ - "ن", "ث", "ع", "خ", "ج", "س", "ح" - ], - dayOfWeek: ["الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"] - }, - ro: { // Romanian - months: [ - "Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie" - ], - dayOfWeekShort: [ - "Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sâ" - ], - dayOfWeek: ["Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă"] - }, - id: { // Indonesian - months: [ - "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember" - ], - dayOfWeekShort: [ - "Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab" - ], - dayOfWeek: ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"] - }, - is: { // Icelandic - months: [ - "Janúar", "Febrúar", "Mars", "Apríl", "Maí", "Júní", "Júlí", "Ágúst", "September", "Október", "Nóvember", "Desember" - ], - dayOfWeekShort: [ - "Sun", "Mán", "Þrið", "Mið", "Fim", "Fös", "Lau" - ], - dayOfWeek: ["Sunnudagur", "Mánudagur", "Þriðjudagur", "Miðvikudagur", "Fimmtudagur", "Föstudagur", "Laugardagur"] - }, - bg: { // Bulgarian - months: [ - "Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември" - ], - dayOfWeekShort: [ - "Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб" - ], - dayOfWeek: ["Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота"] - }, - fa: { // Persian/Farsi - months: [ - 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند' - ], - dayOfWeekShort: [ - 'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه' - ], - dayOfWeek: ["یکشنبه", "دوشنبه", "سهشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه", "یکشنبه"] - }, - ru: { // Russian - months: [ - 'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь' - ], - dayOfWeekShort: [ - "Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб" - ], - dayOfWeek: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"] - }, - uk: { // Ukrainian - months: [ - 'Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень' - ], - dayOfWeekShort: [ - "Ндл", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Сбт" - ], - dayOfWeek: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П'ятниця", "Субота"] - }, - en: { // English - months: [ - "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" - ], - dayOfWeekShort: [ - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - ], - dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] - }, - el: { // Ελληνικά - months: [ - "Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος" - ], - dayOfWeekShort: [ - "Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ" - ], - dayOfWeek: ["Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο"] - }, - de: { // German - months: [ - 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember' - ], - dayOfWeekShort: [ - "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" - ], - dayOfWeek: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"] - }, - nl: { // Dutch - months: [ - "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december" - ], - dayOfWeekShort: [ - "zo", "ma", "di", "wo", "do", "vr", "za" - ], - dayOfWeek: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"] - }, - tr: { // Turkish - months: [ - "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık" - ], - dayOfWeekShort: [ - "Paz", "Pts", "Sal", "Çar", "Per", "Cum", "Cts" - ], - dayOfWeek: ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi"] - }, - fr: { //French - months: [ - "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre" - ], - dayOfWeekShort: [ - "Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam" - ], - dayOfWeek: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"] - }, - es: { // Spanish - months: [ - "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" - ], - dayOfWeekShort: [ - "Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb" - ], - dayOfWeek: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"] - }, - th: { // Thai - months: [ - 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม' - ], - dayOfWeekShort: [ - 'อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.' - ], - dayOfWeek: ["อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"] - }, - pl: { // Polish - months: [ - "styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień" - ], - dayOfWeekShort: [ - "nd", "pn", "wt", "śr", "cz", "pt", "sb" - ], - dayOfWeek: ["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"] - }, - pt: { // Portuguese - months: [ - "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" - ], - dayOfWeekShort: [ - "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab" - ], - dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"] - }, - ch: { // Simplified Chinese - months: [ - "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" - ], - dayOfWeekShort: [ - "日", "一", "二", "三", "四", "五", "六" - ] - }, - se: { // Swedish - months: [ - "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December" - ], - dayOfWeekShort: [ - "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör" - ] - }, - kr: { // Korean - months: [ - "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월" - ], - dayOfWeekShort: [ - "일", "월", "화", "수", "목", "금", "토" - ], - dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"] - }, - it: { // Italian - months: [ - "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre" - ], - dayOfWeekShort: [ - "Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab" - ], - dayOfWeek: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"] - }, - da: { // Dansk - months: [ - "January", "Februar", "Marts", "April", "Maj", "Juni", "July", "August", "September", "Oktober", "November", "December" - ], - dayOfWeekShort: [ - "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør" - ], - dayOfWeek: ["søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag"] - }, - no: { // Norwegian - months: [ - "Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember" - ], - dayOfWeekShort: [ - "Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør" - ], - dayOfWeek: ['Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag'] - }, - ja: { // Japanese - months: [ - "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月" - ], - dayOfWeekShort: [ - "日", "月", "火", "水", "木", "金", "土" - ], - dayOfWeek: ["日曜", "月曜", "火曜", "水曜", "木曜", "金曜", "土曜"] - }, - vi: { // Vietnamese - months: [ - "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12" - ], - dayOfWeekShort: [ - "CN", "T2", "T3", "T4", "T5", "T6", "T7" - ], - dayOfWeek: ["Chủ nhật", "Thứ hai", "Thứ ba", "Thứ tư", "Thứ năm", "Thứ sáu", "Thứ bảy"] - }, - sl: { // Slovenščina - months: [ - "Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December" - ], - dayOfWeekShort: [ - "Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob" - ], - dayOfWeek: ["Nedelja", "Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota"] - }, - cs: { // Čeština - months: [ - "Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec" - ], - dayOfWeekShort: [ - "Ne", "Po", "Út", "St", "Čt", "Pá", "So" - ] - }, - hu: { // Hungarian - months: [ - "Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December" - ], - dayOfWeekShort: [ - "Va", "Hé", "Ke", "Sze", "Cs", "Pé", "Szo" - ], - dayOfWeek: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"] - }, - az: { //Azerbaijanian (Azeri) - months: [ - "Yanvar", "Fevral", "Mart", "Aprel", "May", "Iyun", "Iyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr" - ], - dayOfWeekShort: [ - "B", "Be", "Ça", "Ç", "Ca", "C", "Ş" - ], - dayOfWeek: ["Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı", "Cümə", "Şənbə"] - }, - bs: { //Bosanski - months: [ - "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar" - ], - dayOfWeekShort: [ - "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub" - ], - dayOfWeek: ["Nedjelja","Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"] - }, - ca: { //Català - months: [ - "Gener", "Febrer", "Març", "Abril", "Maig", "Juny", "Juliol", "Agost", "Setembre", "Octubre", "Novembre", "Desembre" - ], - dayOfWeekShort: [ - "Dg", "Dl", "Dt", "Dc", "Dj", "Dv", "Ds" - ], - dayOfWeek: ["Diumenge", "Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte"] - }, - 'en-GB': { //English (British) - months: [ - "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" - ], - dayOfWeekShort: [ - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - ], - dayOfWeek: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] - }, - et: { //"Eesti" - months: [ - "Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember" - ], - dayOfWeekShort: [ - "P", "E", "T", "K", "N", "R", "L" - ], - dayOfWeek: ["Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev"] - }, - eu: { //Euskara - months: [ - "Urtarrila", "Otsaila", "Martxoa", "Apirila", "Maiatza", "Ekaina", "Uztaila", "Abuztua", "Iraila", "Urria", "Azaroa", "Abendua" - ], - dayOfWeekShort: [ - "Ig.", "Al.", "Ar.", "Az.", "Og.", "Or.", "La." - ], - dayOfWeek: ['Igandea', 'Astelehena', 'Asteartea', 'Asteazkena', 'Osteguna', 'Ostirala', 'Larunbata'] - }, - fi: { //Finnish (Suomi) - months: [ - "Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu" - ], - dayOfWeekShort: [ - "Su", "Ma", "Ti", "Ke", "To", "Pe", "La" - ], - dayOfWeek: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"] - }, - gl: { //Galego - months: [ - "Xan", "Feb", "Maz", "Abr", "Mai", "Xun", "Xul", "Ago", "Set", "Out", "Nov", "Dec" - ], - dayOfWeekShort: [ - "Dom", "Lun", "Mar", "Mer", "Xov", "Ven", "Sab" - ], - dayOfWeek: ["Domingo", "Luns", "Martes", "Mércores", "Xoves", "Venres", "Sábado"] - }, - hr: { //Hrvatski - months: [ - "Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac" - ], - dayOfWeekShort: [ - "Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub" - ], - dayOfWeek: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"] - }, - ko: { //Korean (한국어) - months: [ - "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월" - ], - dayOfWeekShort: [ - "일", "월", "화", "수", "목", "금", "토" - ], - dayOfWeek: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"] - }, - lt: { //Lithuanian (lietuvių) - months: [ - "Sausio", "Vasario", "Kovo", "Balandžio", "Gegužės", "Birželio", "Liepos", "Rugpjūčio", "Rugsėjo", "Spalio", "Lapkričio", "Gruodžio" - ], - dayOfWeekShort: [ - "Sek", "Pir", "Ant", "Tre", "Ket", "Pen", "Šeš" - ], - dayOfWeek: ["Sekmadienis", "Pirmadienis", "Antradienis", "Trečiadienis", "Ketvirtadienis", "Penktadienis", "Šeštadienis"] - }, - lv: { //Latvian (Latviešu) - months: [ - "Janvāris", "Februāris", "Marts", "Aprīlis ", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris" - ], - dayOfWeekShort: [ - "Sv", "Pr", "Ot", "Tr", "Ct", "Pk", "St" - ], - dayOfWeek: ["Svētdiena", "Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena"] - }, - mk: { //Macedonian (Македонски) - months: [ - "јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември" - ], - dayOfWeekShort: [ - "нед", "пон", "вто", "сре", "чет", "пет", "саб" - ], - dayOfWeek: ["Недела", "Понеделник", "Вторник", "Среда", "Четврток", "Петок", "Сабота"] - }, - mn: { //Mongolian (Монгол) - months: [ - "1-р сар", "2-р сар", "3-р сар", "4-р сар", "5-р сар", "6-р сар", "7-р сар", "8-р сар", "9-р сар", "10-р сар", "11-р сар", "12-р сар" - ], - dayOfWeekShort: [ - "Дав", "Мяг", "Лха", "Пүр", "Бсн", "Бям", "Ням" - ], - dayOfWeek: ["Даваа", "Мягмар", "Лхагва", "Пүрэв", "Баасан", "Бямба", "Ням"] - }, - 'pt-BR': { //Português(Brasil) - months: [ - "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" - ], - dayOfWeekShort: [ - "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb" - ], - dayOfWeek: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"] - }, - sk: { //Slovenčina - months: [ - "Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Október", "November", "December" - ], - dayOfWeekShort: [ - "Ne", "Po", "Ut", "St", "Št", "Pi", "So" - ], - dayOfWeek: ["Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota"] - }, - sq: { //Albanian (Shqip) - months: [ - "Janar", "Shkurt", "Mars", "Prill", "Maj", "Qershor", "Korrik", "Gusht", "Shtator", "Tetor", "Nëntor", "Dhjetor" - ], - dayOfWeekShort: [ - "Die", "Hën", "Mar", "Mër", "Enj", "Pre", "Shtu" - ], - dayOfWeek: ["E Diel", "E Hënë", "E Martē", "E Mërkurë", "E Enjte", "E Premte", "E Shtunë"] - }, - 'sr-YU': { //Serbian (Srpski) - months: [ - "Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar" - ], - dayOfWeekShort: [ - "Ned", "Pon", "Uto", "Sre", "čet", "Pet", "Sub" - ], - dayOfWeek: ["Nedelja","Ponedeljak", "Utorak", "Sreda", "Četvrtak", "Petak", "Subota"] - }, - sr: { //Serbian Cyrillic (Српски) - months: [ - "јануар", "фебруар", "март", "април", "мај", "јун", "јул", "август", "септембар", "октобар", "новембар", "децембар" - ], - dayOfWeekShort: [ - "нед", "пон", "уто", "сре", "чет", "пет", "суб" - ], - dayOfWeek: ["Недеља","Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота"] - }, - sv: { //Svenska - months: [ - "Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December" - ], - dayOfWeekShort: [ - "Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör" - ], - dayOfWeek: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"] - }, - 'zh-TW': { //Traditional Chinese (繁體中文) - months: [ - "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" - ], - dayOfWeekShort: [ - "日", "一", "二", "三", "四", "五", "六" - ], - dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"] - }, - zh: { //Simplified Chinese (简体中文) - months: [ - "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" - ], - dayOfWeekShort: [ - "日", "一", "二", "三", "四", "五", "六" - ], - dayOfWeek: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"] - }, - he: { //Hebrew (עברית) - months: [ - 'ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר' - ], - dayOfWeekShort: [ - 'א\'', 'ב\'', 'ג\'', 'ד\'', 'ה\'', 'ו\'', 'שבת' - ], - dayOfWeek: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ראשון"] - }, - hy: { // Armenian - months: [ - "Հունվար", "Փետրվար", "Մարտ", "Ապրիլ", "Մայիս", "Հունիս", "Հուլիս", "Օգոստոս", "Սեպտեմբեր", "Հոկտեմբեր", "Նոյեմբեր", "Դեկտեմբեր" - ], - dayOfWeekShort: [ - "Կի", "Երկ", "Երք", "Չոր", "Հնգ", "Ուրբ", "Շբթ" - ], - dayOfWeek: ["Կիրակի", "Երկուշաբթի", "Երեքշաբթի", "Չորեքշաբթի", "Հինգշաբթի", "Ուրբաթ", "Շաբաթ"] - }, - kg: { // Kyrgyz - months: [ - 'Үчтүн айы', 'Бирдин айы', 'Жалган Куран', 'Чын Куран', 'Бугу', 'Кулжа', 'Теке', 'Баш Оона', 'Аяк Оона', 'Тогуздун айы', 'Жетинин айы', 'Бештин айы' - ], - dayOfWeekShort: [ - "Жек", "Дүй", "Шей", "Шар", "Бей", "Жум", "Ише" - ], - dayOfWeek: [ - "Жекшемб", "Дүйшөмб", "Шейшемб", "Шаршемб", "Бейшемби", "Жума", "Ишенб" - ] - }, - rm: { // Romansh - months: [ - "Schaner", "Favrer", "Mars", "Avrigl", "Matg", "Zercladur", "Fanadur", "Avust", "Settember", "October", "November", "December" - ], - dayOfWeekShort: [ - "Du", "Gli", "Ma", "Me", "Gie", "Ve", "So" - ], - dayOfWeek: [ - "Dumengia", "Glindesdi", "Mardi", "Mesemna", "Gievgia", "Venderdi", "Sonda" - ] - }, - }, - value: '', - rtl: false, - - format: 'Y/m/d H:i', - formatTime: 'H:i', - formatDate: 'Y/m/d', - - startDate: false, // new Date(), '1986/12/08', '-1970/01/05','-1970/01/05', - step: 60, - monthChangeSpinner: true, - - closeOnDateSelect: false, - closeOnTimeSelect: true, - closeOnWithoutClick: true, - closeOnInputClick: true, - - timepicker: true, - datepicker: true, - weeks: false, - - defaultTime: false, // use formatTime format (ex. '10:00' for formatTime: 'H:i') - defaultDate: false, // use formatDate format (ex new Date() or '1986/12/08' or '-1970/01/05' or '-1970/01/05') - - minDate: false, - maxDate: false, - minTime: false, - maxTime: false, - disabledMinTime: false, - disabledMaxTime: false, - - allowTimes: [], - opened: false, - initTime: true, - inline: false, - theme: '', - - onSelectDate: function () {}, - onSelectTime: function () {}, - onChangeMonth: function () {}, - onGetWeekOfYear: function () {}, - onChangeYear: function () {}, - onChangeDateTime: function () {}, - onShow: function () {}, - onClose: function () {}, - onGenerate: function () {}, - - withoutCopyright: true, - inverseButton: false, - hours12: false, - next: 'xdsoft_next', - prev : 'xdsoft_prev', - dayOfWeekStart: 0, - parentID: 'body', - timeHeightInTimePicker: 25, - timepickerScrollbar: true, - todayButton: true, - prevButton: true, - nextButton: true, - defaultSelect: true, - - scrollMonth: true, - scrollTime: true, - scrollInput: true, - - lazyInit: false, - mask: false, - validateOnBlur: true, - allowBlank: true, - yearStart: 1950, - yearEnd: 2050, - monthStart: 0, - monthEnd: 11, - style: '', - id: '', - fixed: false, - roundTime: 'round', // ceil, floor - className: '', - weekends: [], - highlightedDates: [], - highlightedPeriods: [], - allowDates : [], - allowDateRe : null, - disabledDates : [], - disabledWeekDays: [], - yearOffset: 0, - beforeShowDay: null, - - enterLikeTab: true, - showApplyButton: false - }; - - var dateHelper = null, - globalLocaleDefault = 'en', - globalLocale = 'en'; - - var dateFormatterOptionsDefault = { - meridiem: ['AM', 'PM'] - }; - - var initDateFormatter = function(){ - var locale = default_options.i18n[globalLocale], - opts = { - days: locale.dayOfWeek, - daysShort: locale.dayOfWeekShort, - months: locale.months, - monthsShort: $.map(locale.months, function(n){ return n.substring(0, 3) }), - }; - - dateHelper = new DateFormatter({ - dateSettings: $.extend({}, dateFormatterOptionsDefault, opts) - }); - }; - - // for locale settings - $.datetimepicker = { - setLocale: function(locale){ - var newLocale = default_options.i18n[locale]?locale:globalLocaleDefault; - if(globalLocale != newLocale){ - globalLocale = newLocale; - // reinit date formatter - initDateFormatter(); - } - }, - RFC_2822: 'D, d M Y H:i:s O', - ATOM: 'Y-m-d\TH:i:sP', - ISO_8601: 'Y-m-d\TH:i:sO', - RFC_822: 'D, d M y H:i:s O', - RFC_850: 'l, d-M-y H:i:s T', - RFC_1036: 'D, d M y H:i:s O', - RFC_1123: 'D, d M Y H:i:s O', - RSS: 'D, d M Y H:i:s O', - W3C: 'Y-m-d\TH:i:sP' - }; - - // first init date formatter - initDateFormatter(); - - // fix for ie8 - if (!window.getComputedStyle) { - window.getComputedStyle = function (el, pseudo) { - this.el = el; - this.getPropertyValue = function (prop) { - var re = /(\-([a-z]){1})/g; - if (prop === 'float') { - prop = 'styleFloat'; - } - if (re.test(prop)) { - prop = prop.replace(re, function (a, b, c) { - return c.toUpperCase(); - }); - } - return el.currentStyle[prop] || null; - }; - return this; - }; - } - if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function (obj, start) { - var i, j; - for (i = (start || 0), j = this.length; i < j; i += 1) { - if (this[i] === obj) { return i; } - } - return -1; - }; - } - Date.prototype.countDaysInMonth = function () { - return new Date(this.getFullYear(), this.getMonth() + 1, 0).getDate(); - }; - $.fn.xdsoftScroller = function (percent) { - return this.each(function () { - var timeboxparent = $(this), - pointerEventToXY = function (e) { - var out = {x: 0, y: 0}, - touch; - if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') { - touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; - out.x = touch.clientX; - out.y = touch.clientY; - } else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'mousemove' || e.type === 'mouseover' || e.type === 'mouseout' || e.type === 'mouseenter' || e.type === 'mouseleave') { - out.x = e.clientX; - out.y = e.clientY; - } - return out; - }, - move = 0, - timebox, - parentHeight, - height, - scrollbar, - scroller, - maximumOffset = 100, - start = false, - startY = 0, - startTop = 0, - h1 = 0, - touchStart = false, - startTopScroll = 0, - calcOffset = function () {}; - if (percent === 'hide') { - timeboxparent.find('.xdsoft_scrollbar').hide(); - return; - } - if (!$(this).hasClass('xdsoft_scroller_box')) { - timebox = timeboxparent.children().eq(0); - parentHeight = timeboxparent[0].clientHeight; - height = timebox[0].offsetHeight; - scrollbar = $('<div class="xdsoft_scrollbar"></div>'); - scroller = $('<div class="xdsoft_scroller"></div>'); - scrollbar.append(scroller); - - timeboxparent.addClass('xdsoft_scroller_box').append(scrollbar); - calcOffset = function calcOffset(event) { - var offset = pointerEventToXY(event).y - startY + startTopScroll; - if (offset < 0) { - offset = 0; - } - if (offset + scroller[0].offsetHeight > h1) { - offset = h1 - scroller[0].offsetHeight; - } - timeboxparent.trigger('scroll_element.xdsoft_scroller', [maximumOffset ? offset / maximumOffset : 0]); - }; - - scroller - .on('touchstart.xdsoft_scroller mousedown.xdsoft_scroller', function (event) { - if (!parentHeight) { - timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]); - } - - startY = pointerEventToXY(event).y; - startTopScroll = parseInt(scroller.css('margin-top'), 10); - h1 = scrollbar[0].offsetHeight; - - if (event.type === 'mousedown' || event.type === 'touchstart') { - if (document) { - $(document.body).addClass('xdsoft_noselect'); - } - $([document.body, window]).on('touchend mouseup.xdsoft_scroller', function arguments_callee() { - $([document.body, window]).off('touchend mouseup.xdsoft_scroller', arguments_callee) - .off('mousemove.xdsoft_scroller', calcOffset) - .removeClass('xdsoft_noselect'); - }); - $(document.body).on('mousemove.xdsoft_scroller', calcOffset); - } else { - touchStart = true; - event.stopPropagation(); - event.preventDefault(); - } - }) - .on('touchmove', function (event) { - if (touchStart) { - event.preventDefault(); - calcOffset(event); - } - }) - .on('touchend touchcancel', function (event) { - touchStart = false; - startTopScroll = 0; - }); - - timeboxparent - .on('scroll_element.xdsoft_scroller', function (event, percentage) { - if (!parentHeight) { - timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percentage, true]); - } - percentage = percentage > 1 ? 1 : (percentage < 0 || isNaN(percentage)) ? 0 : percentage; - - scroller.css('margin-top', maximumOffset * percentage); - - setTimeout(function () { - timebox.css('marginTop', -parseInt((timebox[0].offsetHeight - parentHeight) * percentage, 10)); - }, 10); - }) - .on('resize_scroll.xdsoft_scroller', function (event, percentage, noTriggerScroll) { - var percent, sh; - parentHeight = timeboxparent[0].clientHeight; - height = timebox[0].offsetHeight; - percent = parentHeight / height; - sh = percent * scrollbar[0].offsetHeight; - if (percent > 1) { - scroller.hide(); - } else { - scroller.show(); - scroller.css('height', parseInt(sh > 10 ? sh : 10, 10)); - maximumOffset = scrollbar[0].offsetHeight - scroller[0].offsetHeight; - if (noTriggerScroll !== true) { - timeboxparent.trigger('scroll_element.xdsoft_scroller', [percentage || Math.abs(parseInt(timebox.css('marginTop'), 10)) / (height - parentHeight)]); - } - } - }); - - timeboxparent.on('mousewheel', function (event) { - var top = Math.abs(parseInt(timebox.css('marginTop'), 10)); - - top = top - (event.deltaY * 20); - if (top < 0) { - top = 0; - } - - timeboxparent.trigger('scroll_element.xdsoft_scroller', [top / (height - parentHeight)]); - event.stopPropagation(); - return false; - }); - - timeboxparent.on('touchstart', function (event) { - start = pointerEventToXY(event); - startTop = Math.abs(parseInt(timebox.css('marginTop'), 10)); - }); - - timeboxparent.on('touchmove', function (event) { - if (start) { - event.preventDefault(); - var coord = pointerEventToXY(event); - timeboxparent.trigger('scroll_element.xdsoft_scroller', [(startTop - (coord.y - start.y)) / (height - parentHeight)]); - } - }); - - timeboxparent.on('touchend touchcancel', function (event) { - start = false; - startTop = 0; - }); - } - timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]); - }); - }; - - $.fn.datetimepicker = function (opt, opt2) { - var result = this, - KEY0 = 48, - KEY9 = 57, - _KEY0 = 96, - _KEY9 = 105, - CTRLKEY = 17, - DEL = 46, - ENTER = 13, - ESC = 27, - BACKSPACE = 8, - ARROWLEFT = 37, - ARROWUP = 38, - ARROWRIGHT = 39, - ARROWDOWN = 40, - TAB = 9, - F5 = 116, - AKEY = 65, - CKEY = 67, - VKEY = 86, - ZKEY = 90, - YKEY = 89, - ctrlDown = false, - options = ($.isPlainObject(opt) || !opt) ? $.extend(true, {}, default_options, opt) : $.extend(true, {}, default_options), - - lazyInitTimer = 0, - createDateTimePicker, - destroyDateTimePicker, - - lazyInit = function (input) { - input - .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function initOnActionCallback(event) { - if (input.is(':disabled') || input.data('xdsoft_datetimepicker')) { - return; - } - clearTimeout(lazyInitTimer); - lazyInitTimer = setTimeout(function () { - - if (!input.data('xdsoft_datetimepicker')) { - createDateTimePicker(input); - } - input - .off('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', initOnActionCallback) - .trigger('open.xdsoft'); - }, 100); - }); - }; - - createDateTimePicker = function (input) { - var datetimepicker = $('<div class="xdsoft_datetimepicker xdsoft_noselect"></div>'), - xdsoft_copyright = $('<div class="xdsoft_copyright"><a target="_blank" href="http://xdsoft.net/jqplugins/datetimepicker/">xdsoft.net</a></div>'), - datepicker = $('<div class="xdsoft_datepicker active"></div>'), - mounth_picker = $('<div class="xdsoft_mounthpicker"><button type="button" class="xdsoft_prev"></button><button type="button" class="xdsoft_today_button"></button>' + - '<div class="xdsoft_label xdsoft_month"><span></span><i></i></div>' + - '<div class="xdsoft_label xdsoft_year"><span></span><i></i></div>' + - '<button type="button" class="xdsoft_next"></button></div>'), - calendar = $('<div class="xdsoft_calendar"></div>'), - timepicker = $('<div class="xdsoft_timepicker active"><button type="button" class="xdsoft_prev"></button><div class="xdsoft_time_box"></div><button type="button" class="xdsoft_next"></button></div>'), - timeboxparent = timepicker.find('.xdsoft_time_box').eq(0), - timebox = $('<div class="xdsoft_time_variant"></div>'), - applyButton = $('<button type="button" class="xdsoft_save_selected blue-gradient-button">Save Selected</button>'), - - monthselect = $('<div class="xdsoft_select xdsoft_monthselect"><div></div></div>'), - yearselect = $('<div class="xdsoft_select xdsoft_yearselect"><div></div></div>'), - triggerAfterOpen = false, - XDSoft_datetime, - - xchangeTimer, - timerclick, - current_time_index, - setPos, - timer = 0, - timer1 = 0, - _xdsoft_datetime; - - if (options.id) { - datetimepicker.attr('id', options.id); - } - if (options.style) { - datetimepicker.attr('style', options.style); - } - if (options.weeks) { - datetimepicker.addClass('xdsoft_showweeks'); - } - if (options.rtl) { - datetimepicker.addClass('xdsoft_rtl'); - } - - datetimepicker.addClass('xdsoft_' + options.theme); - datetimepicker.addClass(options.className); - - mounth_picker - .find('.xdsoft_month span') - .after(monthselect); - mounth_picker - .find('.xdsoft_year span') - .after(yearselect); - - mounth_picker - .find('.xdsoft_month,.xdsoft_year') - .on('touchstart mousedown.xdsoft', function (event) { - var select = $(this).find('.xdsoft_select').eq(0), - val = 0, - top = 0, - visible = select.is(':visible'), - items, - i; - - mounth_picker - .find('.xdsoft_select') - .hide(); - if (_xdsoft_datetime.currentTime) { - val = _xdsoft_datetime.currentTime[$(this).hasClass('xdsoft_month') ? 'getMonth' : 'getFullYear'](); - } - - select[visible ? 'hide' : 'show'](); - for (items = select.find('div.xdsoft_option'), i = 0; i < items.length; i += 1) { - if (items.eq(i).data('value') === val) { - break; - } else { - top += items[0].offsetHeight; - } - } - - select.xdsoftScroller(top / (select.children()[0].offsetHeight - (select[0].clientHeight))); - event.stopPropagation(); - return false; - }); - - mounth_picker - .find('.xdsoft_select') - .xdsoftScroller() - .on('touchstart mousedown.xdsoft', function (event) { - event.stopPropagation(); - event.preventDefault(); - }) - .on('touchstart mousedown.xdsoft', '.xdsoft_option', function (event) { - if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) { - _xdsoft_datetime.currentTime = _xdsoft_datetime.now(); - } - - var year = _xdsoft_datetime.currentTime.getFullYear(); - if (_xdsoft_datetime && _xdsoft_datetime.currentTime) { - _xdsoft_datetime.currentTime[$(this).parent().parent().hasClass('xdsoft_monthselect') ? 'setMonth' : 'setFullYear']($(this).data('value')); - } - - $(this).parent().parent().hide(); - - datetimepicker.trigger('xchange.xdsoft'); - if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) { - options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input')); - } - - if (year !== _xdsoft_datetime.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) { - options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input')); - } - }); - - datetimepicker.getValue = function () { - return _xdsoft_datetime.getCurrentTime(); - }; - - datetimepicker.setOptions = function (_options) { - var highlightedDates = {}; - - - options = $.extend(true, {}, options, _options); - - if (_options.allowTimes && $.isArray(_options.allowTimes) && _options.allowTimes.length) { - options.allowTimes = $.extend(true, [], _options.allowTimes); - } - - if (_options.weekends && $.isArray(_options.weekends) && _options.weekends.length) { - options.weekends = $.extend(true, [], _options.weekends); - } - - if (_options.allowDates && $.isArray(_options.allowDates) && _options.allowDates.length) { - options.allowDates = $.extend(true, [], _options.allowDates); - } - - if (_options.allowDateRe && Object.prototype.toString.call(_options.allowDateRe)==="[object String]") { - options.allowDateRe = new RegExp(_options.allowDateRe); - } - - if (_options.highlightedDates && $.isArray(_options.highlightedDates) && _options.highlightedDates.length) { - $.each(_options.highlightedDates, function (index, value) { - var splitData = $.map(value.split(','), $.trim), - exDesc, - hDate = new HighlightedDate(dateHelper.parseDate(splitData[0], options.formatDate), splitData[1], splitData[2]), // date, desc, style - keyDate = dateHelper.formatDate(hDate.date, options.formatDate); - if (highlightedDates[keyDate] !== undefined) { - exDesc = highlightedDates[keyDate].desc; - if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) { - highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc; - } - } else { - highlightedDates[keyDate] = hDate; - } - }); - - options.highlightedDates = $.extend(true, [], highlightedDates); - } - - if (_options.highlightedPeriods && $.isArray(_options.highlightedPeriods) && _options.highlightedPeriods.length) { - highlightedDates = $.extend(true, [], options.highlightedDates); - $.each(_options.highlightedPeriods, function (index, value) { - var dateTest, // start date - dateEnd, - desc, - hDate, - keyDate, - exDesc, - style; - if ($.isArray(value)) { - dateTest = value[0]; - dateEnd = value[1]; - desc = value[2]; - style = value[3]; - } - else { - var splitData = $.map(value.split(','), $.trim); - dateTest = dateHelper.parseDate(splitData[0], options.formatDate); - dateEnd = dateHelper.parseDate(splitData[1], options.formatDate); - desc = splitData[2]; - style = splitData[3]; - } - - while (dateTest <= dateEnd) { - hDate = new HighlightedDate(dateTest, desc, style); - keyDate = dateHelper.formatDate(dateTest, options.formatDate); - dateTest.setDate(dateTest.getDate() + 1); - if (highlightedDates[keyDate] !== undefined) { - exDesc = highlightedDates[keyDate].desc; - if (exDesc && exDesc.length && hDate.desc && hDate.desc.length) { - highlightedDates[keyDate].desc = exDesc + "\n" + hDate.desc; - } - } else { - highlightedDates[keyDate] = hDate; - } - } - }); - - options.highlightedDates = $.extend(true, [], highlightedDates); - } - - if (_options.disabledDates && $.isArray(_options.disabledDates) && _options.disabledDates.length) { - options.disabledDates = $.extend(true, [], _options.disabledDates); - } - - if (_options.disabledWeekDays && $.isArray(_options.disabledWeekDays) && _options.disabledWeekDays.length) { - options.disabledWeekDays = $.extend(true, [], _options.disabledWeekDays); - } - - if ((options.open || options.opened) && (!options.inline)) { - input.trigger('open.xdsoft'); - } - - if (options.inline) { - triggerAfterOpen = true; - datetimepicker.addClass('xdsoft_inline'); - input.after(datetimepicker).hide(); - } - - if (options.inverseButton) { - options.next = 'xdsoft_prev'; - options.prev = 'xdsoft_next'; - } - - if (options.datepicker) { - datepicker.addClass('active'); - } else { - datepicker.removeClass('active'); - } - - if (options.timepicker) { - timepicker.addClass('active'); - } else { - timepicker.removeClass('active'); - } - - if (options.value) { - _xdsoft_datetime.setCurrentTime(options.value); - if (input && input.val) { - input.val(_xdsoft_datetime.str); - } - } - - if (isNaN(options.dayOfWeekStart)) { - options.dayOfWeekStart = 0; - } else { - options.dayOfWeekStart = parseInt(options.dayOfWeekStart, 10) % 7; - } - - if (!options.timepickerScrollbar) { - timeboxparent.xdsoftScroller('hide'); - } - - if (options.minDate && /^[\+\-](.*)$/.test(options.minDate)) { - options.minDate = dateHelper.formatDate(_xdsoft_datetime.strToDateTime(options.minDate), options.formatDate); - } - - if (options.maxDate && /^[\+\-](.*)$/.test(options.maxDate)) { - options.maxDate = dateHelper.formatDate(_xdsoft_datetime.strToDateTime(options.maxDate), options.formatDate); - } - - applyButton.toggle(options.showApplyButton); - - mounth_picker - .find('.xdsoft_today_button') - .css('visibility', !options.todayButton ? 'hidden' : 'visible'); - - mounth_picker - .find('.' + options.prev) - .css('visibility', !options.prevButton ? 'hidden' : 'visible'); - - mounth_picker - .find('.' + options.next) - .css('visibility', !options.nextButton ? 'hidden' : 'visible'); - - setMask(options); - - if (options.validateOnBlur) { - input - .off('blur.xdsoft') - .on('blur.xdsoft', function () { - if (options.allowBlank && (!$.trim($(this).val()).length || $.trim($(this).val()) === options.mask.replace(/[0-9]/g, '_'))) { - $(this).val(null); - datetimepicker.data('xdsoft_datetime').empty(); - } else if (!dateHelper.parseDate($(this).val(), options.format)) { - var splittedHours = +([$(this).val()[0], $(this).val()[1]].join('')), - splittedMinutes = +([$(this).val()[2], $(this).val()[3]].join('')); - - // parse the numbers as 0312 => 03:12 - if (!options.datepicker && options.timepicker && splittedHours >= 0 && splittedHours < 24 && splittedMinutes >= 0 && splittedMinutes < 60) { - $(this).val([splittedHours, splittedMinutes].map(function (item) { - return item > 9 ? item : '0' + item; - }).join(':')); - } else { - $(this).val(dateHelper.formatDate(_xdsoft_datetime.now(), options.format)); - } - - datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val()); - } else { - datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val()); - } - - datetimepicker.trigger('changedatetime.xdsoft'); - datetimepicker.trigger('close.xdsoft'); - }); - } - options.dayOfWeekStartPrev = (options.dayOfWeekStart === 0) ? 6 : options.dayOfWeekStart - 1; - - datetimepicker - .trigger('xchange.xdsoft') - .trigger('afterOpen.xdsoft'); - }; - - datetimepicker - .data('options', options) - .on('touchstart mousedown.xdsoft', function (event) { - event.stopPropagation(); - event.preventDefault(); - yearselect.hide(); - monthselect.hide(); - return false; - }); - - //scroll_element = timepicker.find('.xdsoft_time_box'); - timeboxparent.append(timebox); - timeboxparent.xdsoftScroller(); - - datetimepicker.on('afterOpen.xdsoft', function () { - timeboxparent.xdsoftScroller(); - }); - - datetimepicker - .append(datepicker) - .append(timepicker); - - if (options.withoutCopyright !== true) { - datetimepicker - .append(xdsoft_copyright); - } - - datepicker - .append(mounth_picker) - .append(calendar) - .append(applyButton); - - $(options.parentID) - .append(datetimepicker); - - XDSoft_datetime = function () { - var _this = this; - _this.now = function (norecursion) { - var d = new Date(), - date, - time; - - if (!norecursion && options.defaultDate) { - date = _this.strToDateTime(options.defaultDate); - d.setFullYear(date.getFullYear()); - d.setMonth(date.getMonth()); - d.setDate(date.getDate()); - } - - if (options.yearOffset) { - d.setFullYear(d.getFullYear() + options.yearOffset); - } - - if (!norecursion && options.defaultTime) { - time = _this.strtotime(options.defaultTime); - d.setHours(time.getHours()); - d.setMinutes(time.getMinutes()); - } - return d; - }; - - _this.isValidDate = function (d) { - if (Object.prototype.toString.call(d) !== "[object Date]") { - return false; - } - return !isNaN(d.getTime()); - }; - - _this.setCurrentTime = function (dTime) { - _this.currentTime = (typeof dTime === 'string') ? _this.strToDateTime(dTime) : _this.isValidDate(dTime) ? dTime : _this.now(); - datetimepicker.trigger('xchange.xdsoft'); - }; - - _this.empty = function () { - _this.currentTime = null; - }; - - _this.getCurrentTime = function (dTime) { - return _this.currentTime; - }; - - _this.nextMonth = function () { - - if (_this.currentTime === undefined || _this.currentTime === null) { - _this.currentTime = _this.now(); - } - - var month = _this.currentTime.getMonth() + 1, - year; - if (month === 12) { - _this.currentTime.setFullYear(_this.currentTime.getFullYear() + 1); - month = 0; - } - - year = _this.currentTime.getFullYear(); - - _this.currentTime.setDate( - Math.min( - new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(), - _this.currentTime.getDate() - ) - ); - _this.currentTime.setMonth(month); - - if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) { - options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input')); - } - - if (year !== _this.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) { - options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input')); - } - - datetimepicker.trigger('xchange.xdsoft'); - return month; - }; - - _this.prevMonth = function () { - - if (_this.currentTime === undefined || _this.currentTime === null) { - _this.currentTime = _this.now(); - } - - var month = _this.currentTime.getMonth() - 1; - if (month === -1) { - _this.currentTime.setFullYear(_this.currentTime.getFullYear() - 1); - month = 11; - } - _this.currentTime.setDate( - Math.min( - new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(), - _this.currentTime.getDate() - ) - ); - _this.currentTime.setMonth(month); - if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) { - options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input')); - } - datetimepicker.trigger('xchange.xdsoft'); - return month; - }; - - _this.getWeekOfYear = function (datetime) { - if (options.onGetWeekOfYear && $.isFunction(options.onGetWeekOfYear)) { - var week = options.onGetWeekOfYear.call(datetimepicker, datetime); - if (typeof week !== 'undefined') { - return week; - } - } - var onejan = new Date(datetime.getFullYear(), 0, 1); - //First week of the year is th one with the first Thursday according to ISO8601 - if(onejan.getDay()!=4) - onejan.setMonth(0, 1 + ((4 - onejan.getDay()+ 7) % 7)); - return Math.ceil((((datetime - onejan) / 86400000) + onejan.getDay() + 1) / 7); - }; - - _this.strToDateTime = function (sDateTime) { - var tmpDate = [], timeOffset, currentTime; - - if (sDateTime && sDateTime instanceof Date && _this.isValidDate(sDateTime)) { - return sDateTime; - } - - tmpDate = /^(\+|\-)(.*)$/.exec(sDateTime); - if (tmpDate) { - tmpDate[2] = dateHelper.parseDate(tmpDate[2], options.formatDate); - } - if (tmpDate && tmpDate[2]) { - timeOffset = tmpDate[2].getTime() - (tmpDate[2].getTimezoneOffset()) * 60000; - currentTime = new Date((_this.now(true)).getTime() + parseInt(tmpDate[1] + '1', 10) * timeOffset); - } else { - currentTime = sDateTime ? dateHelper.parseDate(sDateTime, options.format) : _this.now(); - } - - if (!_this.isValidDate(currentTime)) { - currentTime = _this.now(); - } - - return currentTime; - }; - - _this.strToDate = function (sDate) { - if (sDate && sDate instanceof Date && _this.isValidDate(sDate)) { - return sDate; - } - - var currentTime = sDate ? dateHelper.parseDate(sDate, options.formatDate) : _this.now(true); - if (!_this.isValidDate(currentTime)) { - currentTime = _this.now(true); - } - return currentTime; - }; - - _this.strtotime = function (sTime) { - if (sTime && sTime instanceof Date && _this.isValidDate(sTime)) { - return sTime; - } - var currentTime = sTime ? dateHelper.parseDate(sTime, options.formatTime) : _this.now(true); - if (!_this.isValidDate(currentTime)) { - currentTime = _this.now(true); - } - return currentTime; - }; - - _this.str = function () { - return dateHelper.formatDate(_this.currentTime, options.format); - }; - _this.currentTime = this.now(); - }; - - _xdsoft_datetime = new XDSoft_datetime(); - - applyButton.on('touchend click', function (e) {//pathbrite - e.preventDefault(); - datetimepicker.data('changed', true); - _xdsoft_datetime.setCurrentTime(getCurrentValue()); - input.val(_xdsoft_datetime.str()); - datetimepicker.trigger('close.xdsoft'); - }); - mounth_picker - .find('.xdsoft_today_button') - .on('touchend mousedown.xdsoft', function () { - datetimepicker.data('changed', true); - _xdsoft_datetime.setCurrentTime(0); - datetimepicker.trigger('afterOpen.xdsoft'); - }).on('dblclick.xdsoft', function () { - var currentDate = _xdsoft_datetime.getCurrentTime(), minDate, maxDate; - currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate()); - minDate = _xdsoft_datetime.strToDate(options.minDate); - minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()); - if (currentDate < minDate) { - return; - } - maxDate = _xdsoft_datetime.strToDate(options.maxDate); - maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate()); - if (currentDate > maxDate) { - return; - } - input.val(_xdsoft_datetime.str()); - input.trigger('change'); - datetimepicker.trigger('close.xdsoft'); - }); - mounth_picker - .find('.xdsoft_prev,.xdsoft_next') - .on('touchend mousedown.xdsoft', function () { - var $this = $(this), - timer = 0, - stop = false; - - (function arguments_callee1(v) { - if ($this.hasClass(options.next)) { - _xdsoft_datetime.nextMonth(); - } else if ($this.hasClass(options.prev)) { - _xdsoft_datetime.prevMonth(); - } - if (options.monthChangeSpinner) { - if (!stop) { - timer = setTimeout(arguments_callee1, v || 100); - } - } - }(500)); - - $([document.body, window]).on('touchend mouseup.xdsoft', function arguments_callee2() { - clearTimeout(timer); - stop = true; - $([document.body, window]).off('touchend mouseup.xdsoft', arguments_callee2); - }); - }); - - timepicker - .find('.xdsoft_prev,.xdsoft_next') - .on('touchend mousedown.xdsoft', function () { - var $this = $(this), - timer = 0, - stop = false, - period = 110; - (function arguments_callee4(v) { - var pheight = timeboxparent[0].clientHeight, - height = timebox[0].offsetHeight, - top = Math.abs(parseInt(timebox.css('marginTop'), 10)); - if ($this.hasClass(options.next) && (height - pheight) - options.timeHeightInTimePicker >= top) { - timebox.css('marginTop', '-' + (top + options.timeHeightInTimePicker) + 'px'); - } else if ($this.hasClass(options.prev) && top - options.timeHeightInTimePicker >= 0) { - timebox.css('marginTop', '-' + (top - options.timeHeightInTimePicker) + 'px'); - } - timeboxparent.trigger('scroll_element.xdsoft_scroller', [Math.abs(parseInt(timebox.css('marginTop'), 10) / (height - pheight))]); - period = (period > 10) ? 10 : period - 10; - if (!stop) { - timer = setTimeout(arguments_callee4, v || period); - } - }(500)); - $([document.body, window]).on('touchend mouseup.xdsoft', function arguments_callee5() { - clearTimeout(timer); - stop = true; - $([document.body, window]) - .off('touchend mouseup.xdsoft', arguments_callee5); - }); - }); - - xchangeTimer = 0; - // base handler - generating a calendar and timepicker - datetimepicker - .on('xchange.xdsoft', function (event) { - clearTimeout(xchangeTimer); - xchangeTimer = setTimeout(function () { - - if (_xdsoft_datetime.currentTime === undefined || _xdsoft_datetime.currentTime === null) { - _xdsoft_datetime.currentTime = _xdsoft_datetime.now(); - } - - var table = '', - start = new Date(_xdsoft_datetime.currentTime.getFullYear(), _xdsoft_datetime.currentTime.getMonth(), 1, 12, 0, 0), - i = 0, - j, - today = _xdsoft_datetime.now(), - maxDate = false, - minDate = false, - hDate, - day, - d, - y, - m, - w, - classes = [], - customDateSettings, - newRow = true, - time = '', - h = '', - line_time, - description; - - while (start.getDay() !== options.dayOfWeekStart) { - start.setDate(start.getDate() - 1); - } - - table += '<table><thead><tr>'; - - if (options.weeks) { - table += '<th></th>'; - } - - for (j = 0; j < 7; j += 1) { - table += '<th>' + options.i18n[globalLocale].dayOfWeekShort[(j + options.dayOfWeekStart) % 7] + '</th>'; - } - - table += '</tr></thead>'; - table += '<tbody>'; - - if (options.maxDate !== false) { - maxDate = _xdsoft_datetime.strToDate(options.maxDate); - maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate(), 23, 59, 59, 999); - } - - if (options.minDate !== false) { - minDate = _xdsoft_datetime.strToDate(options.minDate); - minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate()); - } - - while (i < _xdsoft_datetime.currentTime.countDaysInMonth() || start.getDay() !== options.dayOfWeekStart || _xdsoft_datetime.currentTime.getMonth() === start.getMonth()) { - classes = []; - i += 1; - - day = start.getDay(); - d = start.getDate(); - y = start.getFullYear(); - m = start.getMonth(); - w = _xdsoft_datetime.getWeekOfYear(start); - description = ''; - - classes.push('xdsoft_date'); - - if (options.beforeShowDay && $.isFunction(options.beforeShowDay.call)) { - customDateSettings = options.beforeShowDay.call(datetimepicker, start); - } else { - customDateSettings = null; - } - - if(options.allowDateRe && Object.prototype.toString.call(options.allowDateRe) === "[object RegExp]"){ - if(!options.allowDateRe.test(dateHelper.formatDate(start, options.formatDate))){ - classes.push('xdsoft_disabled'); - } - } else if(options.allowDates && options.allowDates.length>0){ - if(options.allowDates.indexOf(dateHelper.formatDate(start, options.formatDate)) === -1){ - classes.push('xdsoft_disabled'); - } - } else if ((maxDate !== false && start > maxDate) || (minDate !== false && start < minDate) || (customDateSettings && customDateSettings[0] === false)) { - classes.push('xdsoft_disabled'); - } else if (options.disabledDates.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) { - classes.push('xdsoft_disabled'); - } else if (options.disabledWeekDays.indexOf(day) !== -1) { - classes.push('xdsoft_disabled'); - } - - if (customDateSettings && customDateSettings[1] !== "") { - classes.push(customDateSettings[1]); - } - - if (_xdsoft_datetime.currentTime.getMonth() !== m) { - classes.push('xdsoft_other_month'); - } - - if ((options.defaultSelect || datetimepicker.data('changed')) && dateHelper.formatDate(_xdsoft_datetime.currentTime, options.formatDate) === dateHelper.formatDate(start, options.formatDate)) { - classes.push('xdsoft_current'); - } - - if (dateHelper.formatDate(today, options.formatDate) === dateHelper.formatDate(start, options.formatDate)) { - classes.push('xdsoft_today'); - } - - if (start.getDay() === 0 || start.getDay() === 6 || options.weekends.indexOf(dateHelper.formatDate(start, options.formatDate)) !== -1) { - classes.push('xdsoft_weekend'); - } - - if (options.highlightedDates[dateHelper.formatDate(start, options.formatDate)] !== undefined) { - hDate = options.highlightedDates[dateHelper.formatDate(start, options.formatDate)]; - classes.push(hDate.style === undefined ? 'xdsoft_highlighted_default' : hDate.style); - description = hDate.desc === undefined ? '' : hDate.desc; - } - - if (options.beforeShowDay && $.isFunction(options.beforeShowDay)) { - classes.push(options.beforeShowDay(start)); - } - - if (newRow) { - table += '<tr>'; - newRow = false; - if (options.weeks) { - table += '<th>' + w + '</th>'; - } - } - - table += '<td data-date="' + d + '" data-month="' + m + '" data-year="' + y + '"' + ' class="xdsoft_date xdsoft_day_of_week' + start.getDay() + ' ' + classes.join(' ') + '" title="' + description + '">' + - '<div>' + d + '</div>' + - '</td>'; - - if (start.getDay() === options.dayOfWeekStartPrev) { - table += '</tr>'; - newRow = true; - } - - start.setDate(d + 1); - } - table += '</tbody></table>'; - - calendar.html(table); - - mounth_picker.find('.xdsoft_label span').eq(0).text(options.i18n[globalLocale].months[_xdsoft_datetime.currentTime.getMonth()]); - mounth_picker.find('.xdsoft_label span').eq(1).text(_xdsoft_datetime.currentTime.getFullYear()); - - // generate timebox - time = ''; - h = ''; - m = ''; - - line_time = function line_time(h, m) { - var now = _xdsoft_datetime.now(), optionDateTime, current_time, - isALlowTimesInit = options.allowTimes && $.isArray(options.allowTimes) && options.allowTimes.length; - now.setHours(h); - h = parseInt(now.getHours(), 10); - now.setMinutes(m); - m = parseInt(now.getMinutes(), 10); - optionDateTime = new Date(_xdsoft_datetime.currentTime); - optionDateTime.setHours(h); - optionDateTime.setMinutes(m); - classes = []; - if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || (options.maxTime !== false && _xdsoft_datetime.strtotime(options.maxTime).getTime() < now.getTime()) || (options.minTime !== false && _xdsoft_datetime.strtotime(options.minTime).getTime() > now.getTime())) { - classes.push('xdsoft_disabled'); - } - if ((options.minDateTime !== false && options.minDateTime > optionDateTime) || ((options.disabledMinTime !== false && now.getTime() > _xdsoft_datetime.strtotime(options.disabledMinTime).getTime()) && (options.disabledMaxTime !== false && now.getTime() < _xdsoft_datetime.strtotime(options.disabledMaxTime).getTime()))) { - classes.push('xdsoft_disabled'); - } - - current_time = new Date(_xdsoft_datetime.currentTime); - current_time.setHours(parseInt(_xdsoft_datetime.currentTime.getHours(), 10)); - - if (!isALlowTimesInit) { - current_time.setMinutes(Math[options.roundTime](_xdsoft_datetime.currentTime.getMinutes() / options.step) * options.step); - } - - if ((options.initTime || options.defaultSelect || datetimepicker.data('changed')) && current_time.getHours() === parseInt(h, 10) && ((!isALlowTimesInit && options.step > 59) || current_time.getMinutes() === parseInt(m, 10))) { - if (options.defaultSelect || datetimepicker.data('changed')) { - classes.push('xdsoft_current'); - } else if (options.initTime) { - classes.push('xdsoft_init_time'); - } - } - if (parseInt(today.getHours(), 10) === parseInt(h, 10) && parseInt(today.getMinutes(), 10) === parseInt(m, 10)) { - classes.push('xdsoft_today'); - } - time += '<div class="xdsoft_time ' + classes.join(' ') + '" data-hour="' + h + '" data-minute="' + m + '">' + dateHelper.formatDate(now, options.formatTime) + '</div>'; - }; - - if (!options.allowTimes || !$.isArray(options.allowTimes) || !options.allowTimes.length) { - for (i = 0, j = 0; i < (options.hours12 ? 12 : 24); i += 1) { - for (j = 0; j < 60; j += options.step) { - h = (i < 10 ? '0' : '') + i; - m = (j < 10 ? '0' : '') + j; - line_time(h, m); - } - } - } else { - for (i = 0; i < options.allowTimes.length; i += 1) { - h = _xdsoft_datetime.strtotime(options.allowTimes[i]).getHours(); - m = _xdsoft_datetime.strtotime(options.allowTimes[i]).getMinutes(); - line_time(h, m); - } - } - - timebox.html(time); - - opt = ''; - i = 0; - - for (i = parseInt(options.yearStart, 10) + options.yearOffset; i <= parseInt(options.yearEnd, 10) + options.yearOffset; i += 1) { - opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getFullYear() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + i + '</div>'; - } - yearselect.children().eq(0) - .html(opt); - - for (i = parseInt(options.monthStart, 10), opt = ''; i <= parseInt(options.monthEnd, 10); i += 1) { - opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getMonth() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + options.i18n[globalLocale].months[i] + '</div>'; - } - monthselect.children().eq(0).html(opt); - $(datetimepicker) - .trigger('generate.xdsoft'); - }, 10); - event.stopPropagation(); - }) - .on('afterOpen.xdsoft', function () { - if (options.timepicker) { - var classType, pheight, height, top; - if (timebox.find('.xdsoft_current').length) { - classType = '.xdsoft_current'; - } else if (timebox.find('.xdsoft_init_time').length) { - classType = '.xdsoft_init_time'; - } - if (classType) { - pheight = timeboxparent[0].clientHeight; - height = timebox[0].offsetHeight; - top = timebox.find(classType).index() * options.timeHeightInTimePicker + 1; - if ((height - pheight) < top) { - top = height - pheight; - } - timeboxparent.trigger('scroll_element.xdsoft_scroller', [parseInt(top, 10) / (height - pheight)]); - } else { - timeboxparent.trigger('scroll_element.xdsoft_scroller', [0]); - } - } - }); - - timerclick = 0; - calendar - .on('touchend click.xdsoft', 'td', function (xdevent) { - xdevent.stopPropagation(); // Prevents closing of Pop-ups, Modals and Flyouts in Bootstrap - timerclick += 1; - var $this = $(this), - currentTime = _xdsoft_datetime.currentTime; - - if (currentTime === undefined || currentTime === null) { - _xdsoft_datetime.currentTime = _xdsoft_datetime.now(); - currentTime = _xdsoft_datetime.currentTime; - } - - if ($this.hasClass('xdsoft_disabled')) { - return false; - } - - currentTime.setDate(1); - currentTime.setFullYear($this.data('year')); - currentTime.setMonth($this.data('month')); - currentTime.setDate($this.data('date')); - - datetimepicker.trigger('select.xdsoft', [currentTime]); - - input.val(_xdsoft_datetime.str()); - - if (options.onSelectDate && $.isFunction(options.onSelectDate)) { - options.onSelectDate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent); - } - - datetimepicker.data('changed', true); - datetimepicker.trigger('xchange.xdsoft'); - datetimepicker.trigger('changedatetime.xdsoft'); - if ((timerclick > 1 || (options.closeOnDateSelect === true || (options.closeOnDateSelect === false && !options.timepicker))) && !options.inline) { - datetimepicker.trigger('close.xdsoft'); - } - setTimeout(function () { - timerclick = 0; - }, 200); - }); - - timebox - .on('touchend click.xdsoft', 'div', function (xdevent) { - xdevent.stopPropagation(); - var $this = $(this), - currentTime = _xdsoft_datetime.currentTime; - - if (currentTime === undefined || currentTime === null) { - _xdsoft_datetime.currentTime = _xdsoft_datetime.now(); - currentTime = _xdsoft_datetime.currentTime; - } - - if ($this.hasClass('xdsoft_disabled')) { - return false; - } - currentTime.setHours($this.data('hour')); - currentTime.setMinutes($this.data('minute')); - datetimepicker.trigger('select.xdsoft', [currentTime]); - - datetimepicker.data('input').val(_xdsoft_datetime.str()); - - if (options.onSelectTime && $.isFunction(options.onSelectTime)) { - options.onSelectTime.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent); - } - datetimepicker.data('changed', true); - datetimepicker.trigger('xchange.xdsoft'); - datetimepicker.trigger('changedatetime.xdsoft'); - if (options.inline !== true && options.closeOnTimeSelect === true) { - datetimepicker.trigger('close.xdsoft'); - } - }); - - - datepicker - .on('mousewheel.xdsoft', function (event) { - if (!options.scrollMonth) { - return true; - } - if (event.deltaY < 0) { - _xdsoft_datetime.nextMonth(); - } else { - _xdsoft_datetime.prevMonth(); - } - return false; - }); - - input - .on('mousewheel.xdsoft', function (event) { - if (!options.scrollInput) { - return true; - } - if (!options.datepicker && options.timepicker) { - current_time_index = timebox.find('.xdsoft_current').length ? timebox.find('.xdsoft_current').eq(0).index() : 0; - if (current_time_index + event.deltaY >= 0 && current_time_index + event.deltaY < timebox.children().length) { - current_time_index += event.deltaY; - } - if (timebox.children().eq(current_time_index).length) { - timebox.children().eq(current_time_index).trigger('mousedown'); - } - return false; - } - if (options.datepicker && !options.timepicker) { - datepicker.trigger(event, [event.deltaY, event.deltaX, event.deltaY]); - if (input.val) { - input.val(_xdsoft_datetime.str()); - } - datetimepicker.trigger('changedatetime.xdsoft'); - return false; - } - }); - - datetimepicker - .on('changedatetime.xdsoft', function (event) { - if (options.onChangeDateTime && $.isFunction(options.onChangeDateTime)) { - var $input = datetimepicker.data('input'); - options.onChangeDateTime.call(datetimepicker, _xdsoft_datetime.currentTime, $input, event); - delete options.value; - $input.trigger('change'); - } - }) - .on('generate.xdsoft', function () { - if (options.onGenerate && $.isFunction(options.onGenerate)) { - options.onGenerate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input')); - } - if (triggerAfterOpen) { - datetimepicker.trigger('afterOpen.xdsoft'); - triggerAfterOpen = false; - } - }) - .on('click.xdsoft', function (xdevent) { - xdevent.stopPropagation(); - }); - - current_time_index = 0; - - setPos = function () { - /** - * 修复输入框在window最右边,且输入框的宽度小于日期控件宽度情况下,日期控件显示不全的bug。 - * Bug fixed - The datetimepicker will overflow-y when the width of the date input less than its, which - * could causes part of the datetimepicker being hidden. - * by Soon start - */ - var offset = datetimepicker.data('input').offset(), - datetimepickerelement = datetimepicker.data('input')[0], - top = offset.top + datetimepickerelement.offsetHeight - 1, - left = offset.left, - position = "absolute", - node; - - if ((document.documentElement.clientWidth - offset.left) < datepicker.parent().outerWidth(true)) { - var diff = datepicker.parent().outerWidth(true) - datetimepickerelement.offsetWidth; - left = left - diff; - } - /** - * by Soon end - */ - if (datetimepicker.data('input').parent().css('direction') == 'rtl') - left -= (datetimepicker.outerWidth() - datetimepicker.data('input').outerWidth()); - if (options.fixed) { - top -= $(window).scrollTop(); - left -= $(window).scrollLeft(); - position = "fixed"; - } else { - if (top + datetimepickerelement.offsetHeight > $(window).height() + $(window).scrollTop()) { - top = offset.top - datetimepickerelement.offsetHeight + 1; - } - if (top < 0) { - top = 0; - } - if (left + datetimepickerelement.offsetWidth > $(window).width()) { - left = $(window).width() - datetimepickerelement.offsetWidth; - } - } - - node = datetimepicker[0]; - do { - node = node.parentNode; - if (window.getComputedStyle(node).getPropertyValue('position') === 'relative' && $(window).width() >= node.offsetWidth) { - left = left - (($(window).width() - node.offsetWidth) / 2); - break; - } - } while (node.nodeName !== 'HTML'); - datetimepicker.css({ - left: left, - top: top, - position: position - }); - }; - datetimepicker - .on('open.xdsoft', function (event) { - var onShow = true; - if (options.onShow && $.isFunction(options.onShow)) { - onShow = options.onShow.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event); - } - if (onShow !== false) { - datetimepicker.show(); - setPos(); - $(window) - .off('resize.xdsoft', setPos) - .on('resize.xdsoft', setPos); - - if (options.closeOnWithoutClick) { - $([document.body, window]).on('touchstart mousedown.xdsoft', function arguments_callee6() { - datetimepicker.trigger('close.xdsoft'); - $([document.body, window]).off('touchstart mousedown.xdsoft', arguments_callee6); - }); - } - } - }) - .on('close.xdsoft', function (event) { - var onClose = true; - mounth_picker - .find('.xdsoft_month,.xdsoft_year') - .find('.xdsoft_select') - .hide(); - if (options.onClose && $.isFunction(options.onClose)) { - onClose = options.onClose.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event); - } - if (onClose !== false && !options.opened && !options.inline) { - datetimepicker.hide(); - } - event.stopPropagation(); - }) - .on('toggle.xdsoft', function (event) { - if (datetimepicker.is(':visible')) { - datetimepicker.trigger('close.xdsoft'); - } else { - datetimepicker.trigger('open.xdsoft'); - } - }) - .data('input', input); - - timer = 0; - timer1 = 0; - - datetimepicker.data('xdsoft_datetime', _xdsoft_datetime); - datetimepicker.setOptions(options); - - function getCurrentValue() { - var ct = false, time; - - if (options.startDate) { - ct = _xdsoft_datetime.strToDate(options.startDate); - } else { - ct = options.value || ((input && input.val && input.val()) ? input.val() : ''); - if (ct) { - ct = _xdsoft_datetime.strToDateTime(ct); - } else if (options.defaultDate) { - ct = _xdsoft_datetime.strToDateTime(options.defaultDate); - if (options.defaultTime) { - time = _xdsoft_datetime.strtotime(options.defaultTime); - ct.setHours(time.getHours()); - ct.setMinutes(time.getMinutes()); - } - } - } - - if (ct && _xdsoft_datetime.isValidDate(ct)) { - datetimepicker.data('changed', true); - } else { - ct = ''; - } - - return ct || 0; - } - - function setMask(options) { - - var isValidValue = function (mask, value) { - var reg = mask - .replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g, '\\$1') - .replace(/_/g, '{digit+}') - .replace(/([0-9]{1})/g, '{digit$1}') - .replace(/\{digit([0-9]{1})\}/g, '[0-$1_]{1}') - .replace(/\{digit[\+]\}/g, '[0-9_]{1}'); - return (new RegExp(reg)).test(value); - }, - getCaretPos = function (input) { - try { - if (document.selection && document.selection.createRange) { - var range = document.selection.createRange(); - return range.getBookmark().charCodeAt(2) - 2; - } - if (input.setSelectionRange) { - return input.selectionStart; - } - } catch (e) { - return 0; - } - }, - setCaretPos = function (node, pos) { - node = (typeof node === "string" || node instanceof String) ? document.getElementById(node) : node; - if (!node) { - return false; - } - if (node.createTextRange) { - var textRange = node.createTextRange(); - textRange.collapse(true); - textRange.moveEnd('character', pos); - textRange.moveStart('character', pos); - textRange.select(); - return true; - } - if (node.setSelectionRange) { - node.setSelectionRange(pos, pos); - return true; - } - return false; - }; - if(options.mask) { - input.off('keydown.xdsoft'); - } - if (options.mask === true) { - if (typeof moment != 'undefined') { - options.mask = options.format - .replace(/Y{4}/g, '9999') - .replace(/Y{2}/g, '99') - .replace(/M{2}/g, '19') - .replace(/D{2}/g, '39') - .replace(/H{2}/g, '29') - .replace(/m{2}/g, '59') - .replace(/s{2}/g, '59'); - } else { - options.mask = options.format - .replace(/Y/g, '9999') - .replace(/F/g, '9999') - .replace(/m/g, '19') - .replace(/d/g, '39') - .replace(/H/g, '29') - .replace(/i/g, '59') - .replace(/s/g, '59'); - } - } - - if ($.type(options.mask) === 'string') { - if (!isValidValue(options.mask, input.val())) { - input.val(options.mask.replace(/[0-9]/g, '_')); - setCaretPos(input[0], 0); - } - - input.on('keydown.xdsoft', function (event) { - var val = this.value, - key = event.which, - pos, - digit; - - if (((key >= KEY0 && key <= KEY9) || (key >= _KEY0 && key <= _KEY9)) || (key === BACKSPACE || key === DEL)) { - pos = getCaretPos(this); - digit = (key !== BACKSPACE && key !== DEL) ? String.fromCharCode((_KEY0 <= key && key <= _KEY9) ? key - KEY0 : key) : '_'; - - if ((key === BACKSPACE || key === DEL) && pos) { - pos -= 1; - digit = '_'; - } - - while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) { - pos += (key === BACKSPACE || key === DEL) ? -1 : 1; - } - - val = val.substr(0, pos) + digit + val.substr(pos + 1); - if ($.trim(val) === '') { - val = options.mask.replace(/[0-9]/g, '_'); - } else { - if (pos === options.mask.length) { - event.preventDefault(); - return false; - } - } - - pos += (key === BACKSPACE || key === DEL) ? 0 : 1; - while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) { - pos += (key === BACKSPACE || key === DEL) ? -1 : 1; - } - - if (isValidValue(options.mask, val)) { - this.value = val; - setCaretPos(this, pos); - } else if ($.trim(val) === '') { - this.value = options.mask.replace(/[0-9]/g, '_'); - } else { - input.trigger('error_input.xdsoft'); - } - } else { - if (([AKEY, CKEY, VKEY, ZKEY, YKEY].indexOf(key) !== -1 && ctrlDown) || [ESC, ARROWUP, ARROWDOWN, ARROWLEFT, ARROWRIGHT, F5, CTRLKEY, TAB, ENTER].indexOf(key) !== -1) { - return true; - } - } - - event.preventDefault(); - return false; - }); - } - } - - _xdsoft_datetime.setCurrentTime(getCurrentValue()); - - input - .data('xdsoft_datetimepicker', datetimepicker) - .on('open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart', function (event) { - if (input.is(':disabled') || (input.data('xdsoft_datetimepicker').is(':visible') && options.closeOnInputClick)) { - return; - } - clearTimeout(timer); - timer = setTimeout(function () { - if (input.is(':disabled')) { - return; - } - - triggerAfterOpen = true; - _xdsoft_datetime.setCurrentTime(getCurrentValue()); - if(options.mask) { - setMask(options); - } - datetimepicker.trigger('open.xdsoft'); - }, 100); - }) - .on('keydown.xdsoft', function (event) { - var val = this.value, elementSelector, - key = event.which; - if ([ENTER].indexOf(key) !== -1 && options.enterLikeTab) { - elementSelector = $("input:visible,textarea:visible,button:visible,a:visible"); - datetimepicker.trigger('close.xdsoft'); - elementSelector.eq(elementSelector.index(this) + 1).focus(); - return false; - } - if ([TAB].indexOf(key) !== -1) { - datetimepicker.trigger('close.xdsoft'); - return true; - } - }) - .on('blur.xdsoft', function () { - datetimepicker.trigger('close.xdsoft'); - }); - }; - destroyDateTimePicker = function (input) { - var datetimepicker = input.data('xdsoft_datetimepicker'); - if (datetimepicker) { - datetimepicker.data('xdsoft_datetime', null); - datetimepicker.remove(); - input - .data('xdsoft_datetimepicker', null) - .off('.xdsoft'); - $(window).off('resize.xdsoft'); - $([window, document.body]).off('mousedown.xdsoft touchstart'); - if (input.unmousewheel) { - input.unmousewheel(); - } - } - }; - $(document) - .off('keydown.xdsoftctrl keyup.xdsoftctrl') - .on('keydown.xdsoftctrl', function (e) { - if (e.keyCode === CTRLKEY) { - ctrlDown = true; - } - }) - .on('keyup.xdsoftctrl', function (e) { - if (e.keyCode === CTRLKEY) { - ctrlDown = false; - } - }); - - this.each(function () { - var datetimepicker = $(this).data('xdsoft_datetimepicker'), $input; - if (datetimepicker) { - if ($.type(opt) === 'string') { - switch (opt) { - case 'show': - $(this).select().focus(); - datetimepicker.trigger('open.xdsoft'); - break; - case 'hide': - datetimepicker.trigger('close.xdsoft'); - break; - case 'toggle': - datetimepicker.trigger('toggle.xdsoft'); - break; - case 'destroy': - destroyDateTimePicker($(this)); - break; - case 'reset': - this.value = this.defaultValue; - if (!this.value || !datetimepicker.data('xdsoft_datetime').isValidDate(dateHelper.parseDate(this.value, options.format))) { - datetimepicker.data('changed', false); - } - datetimepicker.data('xdsoft_datetime').setCurrentTime(this.value); - break; - case 'validate': - $input = datetimepicker.data('input'); - $input.trigger('blur.xdsoft'); - break; - default: - if (datetimepicker[opt] && $.isFunction(datetimepicker[opt])) { - result = datetimepicker[opt](opt2); - } - } - } else { - datetimepicker - .setOptions(opt); - } - return 0; - } - if ($.type(opt) !== 'string') { - if (!options.lazyInit || options.open || options.inline) { - createDateTimePicker($(this)); - } else { - lazyInit($(this)); - } - } - }); - - return result; - }; - $.fn.datetimepicker.defaults = default_options; - - function HighlightedDate(date, desc, style) { - "use strict"; - this.date = date; - this.desc = desc; - this.style = style; - } - -})); -/*! - * jQuery Mousewheel 3.1.13 - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - */ - -(function (factory) { - if ( typeof define === 'function' && define.amd ) { - // AMD. Register as an anonymous module. - define(['jquery'], factory); - } else if (typeof exports === 'object') { - // Node/CommonJS style for Browserify - module.exports = factory; - } else { - // Browser globals - factory(jQuery); - } -}(function ($) { - - var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'], - toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ? - ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'], - slice = Array.prototype.slice, - nullLowestDeltaTimeout, lowestDelta; - - if ( $.event.fixHooks ) { - for ( var i = toFix.length; i; ) { - $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; - } - } - - var special = $.event.special.mousewheel = { - version: '3.1.12', - - setup: function() { - if ( this.addEventListener ) { - for ( var i = toBind.length; i; ) { - this.addEventListener( toBind[--i], handler, false ); - } - } else { - this.onmousewheel = handler; - } - // Store the line height and page height for this particular element - $.data(this, 'mousewheel-line-height', special.getLineHeight(this)); - $.data(this, 'mousewheel-page-height', special.getPageHeight(this)); - }, - - teardown: function() { - if ( this.removeEventListener ) { - for ( var i = toBind.length; i; ) { - this.removeEventListener( toBind[--i], handler, false ); - } - } else { - this.onmousewheel = null; - } - // Clean up the data we added to the element - $.removeData(this, 'mousewheel-line-height'); - $.removeData(this, 'mousewheel-page-height'); - }, - - getLineHeight: function(elem) { - var $elem = $(elem), - $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent'](); - if (!$parent.length) { - $parent = $('body'); - } - return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16; - }, - - getPageHeight: function(elem) { - return $(elem).height(); - }, - - settings: { - adjustOldDeltas: true, // see shouldAdjustOldDeltas() below - normalizeOffset: true // calls getBoundingClientRect for each event - } - }; - - $.fn.extend({ - mousewheel: function(fn) { - return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel'); - }, - - unmousewheel: function(fn) { - return this.unbind('mousewheel', fn); - } - }); - - - function handler(event) { - var orgEvent = event || window.event, - args = slice.call(arguments, 1), - delta = 0, - deltaX = 0, - deltaY = 0, - absDelta = 0, - offsetX = 0, - offsetY = 0; - event = $.event.fix(orgEvent); - event.type = 'mousewheel'; - - // Old school scrollwheel delta - if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; } - if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; } - if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; } - if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; } - - // Firefox < 17 horizontal scrolling related to DOMMouseScroll event - if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { - deltaX = deltaY * -1; - deltaY = 0; - } - - // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy - delta = deltaY === 0 ? deltaX : deltaY; - - // New school wheel delta (wheel event) - if ( 'deltaY' in orgEvent ) { - deltaY = orgEvent.deltaY * -1; - delta = deltaY; - } - if ( 'deltaX' in orgEvent ) { - deltaX = orgEvent.deltaX; - if ( deltaY === 0 ) { delta = deltaX * -1; } - } - - // No change actually happened, no reason to go any further - if ( deltaY === 0 && deltaX === 0 ) { return; } - - // Need to convert lines and pages to pixels if we aren't already in pixels - // There are three delta modes: - // * deltaMode 0 is by pixels, nothing to do - // * deltaMode 1 is by lines - // * deltaMode 2 is by pages - if ( orgEvent.deltaMode === 1 ) { - var lineHeight = $.data(this, 'mousewheel-line-height'); - delta *= lineHeight; - deltaY *= lineHeight; - deltaX *= lineHeight; - } else if ( orgEvent.deltaMode === 2 ) { - var pageHeight = $.data(this, 'mousewheel-page-height'); - delta *= pageHeight; - deltaY *= pageHeight; - deltaX *= pageHeight; - } - - // Store lowest absolute delta to normalize the delta values - absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) ); - - if ( !lowestDelta || absDelta < lowestDelta ) { - lowestDelta = absDelta; - - // Adjust older deltas if necessary - if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { - lowestDelta /= 40; - } - } - - // Adjust older deltas if necessary - if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { - // Divide all the things by 40! - delta /= 40; - deltaX /= 40; - deltaY /= 40; - } - - // Get a whole, normalized value for the deltas - delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta); - deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta); - deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta); - - // Normalise offsetX and offsetY properties - if ( special.settings.normalizeOffset && this.getBoundingClientRect ) { - var boundingRect = this.getBoundingClientRect(); - offsetX = event.clientX - boundingRect.left; - offsetY = event.clientY - boundingRect.top; - } - - // Add information to the event object - event.deltaX = deltaX; - event.deltaY = deltaY; - event.deltaFactor = lowestDelta; - event.offsetX = offsetX; - event.offsetY = offsetY; - // Go ahead and set deltaMode to 0 since we converted to pixels - // Although this is a little odd since we overwrite the deltaX/Y - // properties with normalized deltas. - event.deltaMode = 0; - - // Add event and delta to the front of the arguments - args.unshift(event, delta, deltaX, deltaY); - - // Clearout lowestDelta after sometime to better - // handle multiple device types that give different - // a different lowestDelta - // Ex: trackpad = 3 and mouse wheel = 120 - if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); } - nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200); - - return ($.event.dispatch || $.event.handle).apply(this, args); - } - - function nullLowestDelta() { - lowestDelta = null; - } - - function shouldAdjustOldDeltas(orgEvent, absDelta) { - // If this is an older event and the delta is divisable by 120, - // then we are assuming that the browser is treating this as an - // older mouse wheel event and that we should divide the deltas - // by 40 to try and get a more usable deltaFactor. - // Side note, this actually impacts the reported scroll distance - // in older browsers and can cause scrolling to be slower than native. - // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false. - return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0; - } - -})); - -$(document).ready(function(){ - $.datetimepicker.setLocale('en'); -}); diff --git a/web/js/jquery.min.js b/web/js/jquery.min.js deleted file mode 100644 index e6a051d..0000000 --- a/web/js/jquery.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.11.2 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.2",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},eb=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fb){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function gb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+rb(o[l]);w=ab.test(a)&&pb(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function hb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ib(a){return a[u]=!0,a}function jb(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function kb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function lb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function nb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function ob(a){return ib(function(b){return b=+b,ib(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pb(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=gb.support={},f=gb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=gb.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",eb,!1):e.attachEvent&&e.attachEvent("onunload",eb)),p=!f(g),c.attributes=jb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=jb(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=jb(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(jb(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),jb(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&jb(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return lb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=gb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=gb.selectors={cacheLength:50,createPseudo:ib,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||gb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&gb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=gb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=mb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=nb(b);function qb(){}qb.prototype=d.filters=d.pseudos,d.setFilters=new qb,g=gb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?gb.error(a):z(a,i).slice(0)};function rb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function tb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sb(tb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),gb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; -return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==cb()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===cb()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ab:bb):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:bb,isPropagationStopped:bb,isImmediatePropagationStopped:bb,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ab,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ab,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ab,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=bb;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=bb),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function db(a){var b=eb.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var eb="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fb=/ jQuery\d+="(?:null|\d+)"/g,gb=new RegExp("<(?:"+eb+")[\\s/>]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/<tbody/i,lb=/<|&#?\w+;/,mb=/<(?:script|style|link)/i,nb=/checked\s*(?:[^=]|=\s*.checked.)/i,ob=/^$|\/(?:java|ecma)script/i,pb=/^true\/(.*)/,qb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,rb={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?"<table>"!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e) -}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$b=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_b||(_b=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_b),_b=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m}); diff --git a/web/js/moment.min.js b/web/js/moment.min.js deleted file mode 100644 index 25fa625..0000000 --- a/web/js/moment.min.js +++ /dev/null @@ -1,7 +0,0 @@ -//! moment.js -//! version : 2.18.1 -//! authors : Tim Wood, Iskren Chernev, Moment.js contributors -//! license : MIT -//! momentjs.com -!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return sd.apply(null,arguments)}function b(a){sd=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){return null!=a&&"[object Object]"===Object.prototype.toString.call(a)}function e(a){var b;for(b in a)return!1;return!0}function f(a){return void 0===a}function g(a){return"number"==typeof a||"[object Number]"===Object.prototype.toString.call(a)}function h(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function i(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function j(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function k(a,b){for(var c in b)j(b,c)&&(a[c]=b[c]);return j(b,"toString")&&(a.toString=b.toString),j(b,"valueOf")&&(a.valueOf=b.valueOf),a}function l(a,b,c,d){return sb(a,b,c,d,!0).utc()}function m(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}}function n(a){return null==a._pf&&(a._pf=m()),a._pf}function o(a){if(null==a._isValid){var b=n(a),c=ud.call(b.parsedDateParts,function(a){return null!=a}),d=!isNaN(a._d.getTime())&&b.overflow<0&&!b.empty&&!b.invalidMonth&&!b.invalidWeekday&&!b.nullInput&&!b.invalidFormat&&!b.userInvalidated&&(!b.meridiem||b.meridiem&&c);if(a._strict&&(d=d&&0===b.charsLeftOver&&0===b.unusedTokens.length&&void 0===b.bigHour),null!=Object.isFrozen&&Object.isFrozen(a))return d;a._isValid=d}return a._isValid}function p(a){var b=l(NaN);return null!=a?k(n(b),a):n(b).userInvalidated=!0,b}function q(a,b){var c,d,e;if(f(b._isAMomentObject)||(a._isAMomentObject=b._isAMomentObject),f(b._i)||(a._i=b._i),f(b._f)||(a._f=b._f),f(b._l)||(a._l=b._l),f(b._strict)||(a._strict=b._strict),f(b._tzm)||(a._tzm=b._tzm),f(b._isUTC)||(a._isUTC=b._isUTC),f(b._offset)||(a._offset=b._offset),f(b._pf)||(a._pf=n(b)),f(b._locale)||(a._locale=b._locale),vd.length>0)for(c=0;c<vd.length;c++)d=vd[c],e=b[d],f(e)||(a[d]=e);return a}function r(b){q(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),wd===!1&&(wd=!0,a.updateOffset(this),wd=!1)}function s(a){return a instanceof r||null!=a&&null!=a._isAMomentObject}function t(a){return a<0?Math.ceil(a)||0:Math.floor(a)}function u(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=t(b)),c}function v(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;d<e;d++)(c&&a[d]!==b[d]||!c&&u(a[d])!==u(b[d]))&&g++;return g+f}function w(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function x(b,c){var d=!0;return k(function(){if(null!=a.deprecationHandler&&a.deprecationHandler(null,b),d){for(var e,f=[],g=0;g<arguments.length;g++){if(e="","object"==typeof arguments[g]){e+="\n["+g+"] ";for(var h in arguments[0])e+=h+": "+arguments[0][h]+", ";e=e.slice(0,-2)}else e=arguments[g];f.push(e)}w(b+"\nArguments: "+Array.prototype.slice.call(f).join("")+"\n"+(new Error).stack),d=!1}return c.apply(this,arguments)},c)}function y(b,c){null!=a.deprecationHandler&&a.deprecationHandler(b,c),xd[b]||(w(c),xd[b]=!0)}function z(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}function A(a){var b,c;for(c in a)b=a[c],z(b)?this[c]=b:this["_"+c]=b;this._config=a,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)}function B(a,b){var c,e=k({},a);for(c in b)j(b,c)&&(d(a[c])&&d(b[c])?(e[c]={},k(e[c],a[c]),k(e[c],b[c])):null!=b[c]?e[c]=b[c]:delete e[c]);for(c in a)j(a,c)&&!j(b,c)&&d(a[c])&&(e[c]=k({},e[c]));return e}function C(a){null!=a&&this.set(a)}function D(a,b,c){var d=this._calendar[a]||this._calendar.sameElse;return z(d)?d.call(b,c):d}function E(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function F(){return this._invalidDate}function G(a){return this._ordinal.replace("%d",a)}function H(a,b,c,d){var e=this._relativeTime[c];return z(e)?e(a,b,c,d):e.replace(/%d/i,a)}function I(a,b){var c=this._relativeTime[a>0?"future":"past"];return z(c)?c(b):c.replace(/%s/i,b)}function J(a,b){var c=a.toLowerCase();Hd[c]=Hd[c+"s"]=Hd[b]=a}function K(a){return"string"==typeof a?Hd[a]||Hd[a.toLowerCase()]:void 0}function L(a){var b,c,d={};for(c in a)j(a,c)&&(b=K(c),b&&(d[b]=a[c]));return d}function M(a,b){Id[a]=b}function N(a){var b=[];for(var c in a)b.push({unit:c,priority:Id[c]});return b.sort(function(a,b){return a.priority-b.priority}),b}function O(b,c){return function(d){return null!=d?(Q(this,b,d),a.updateOffset(this,c),this):P(this,b)}}function P(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function Q(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function R(a){return a=K(a),z(this[a])?this[a]():this}function S(a,b){if("object"==typeof a){a=L(a);for(var c=N(a),d=0;d<c.length;d++)this[c[d].unit](a[c[d].unit])}else if(a=K(a),z(this[a]))return this[a](b);return this}function T(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function U(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(Md[a]=e),b&&(Md[b[0]]=function(){return T(e.apply(this,arguments),b[1],b[2])}),c&&(Md[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function V(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function W(a){var b,c,d=a.match(Jd);for(b=0,c=d.length;b<c;b++)Md[d[b]]?d[b]=Md[d[b]]:d[b]=V(d[b]);return function(b){var e,f="";for(e=0;e<c;e++)f+=z(d[e])?d[e].call(b,a):d[e];return f}}function X(a,b){return a.isValid()?(b=Y(b,a.localeData()),Ld[b]=Ld[b]||W(b),Ld[b](a)):a.localeData().invalidDate()}function Y(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Kd.lastIndex=0;d>=0&&Kd.test(a);)a=a.replace(Kd,c),Kd.lastIndex=0,d-=1;return a}function Z(a,b,c){ce[a]=z(b)?b:function(a,d){return a&&c?c:b}}function $(a,b){return j(ce,a)?ce[a](b._strict,b._locale):new RegExp(_(a))}function _(a){return aa(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function aa(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function ba(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),g(b)&&(d=function(a,c){c[b]=u(a)}),c=0;c<a.length;c++)de[a[c]]=d}function ca(a,b){ba(a,function(a,c,d,e){d._w=d._w||{},b(a,d._w,d,e)})}function da(a,b,c){null!=b&&j(de,a)&&de[a](b,c._a,c,a)}function ea(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function fa(a,b){return a?c(this._months)?this._months[a.month()]:this._months[(this._months.isFormat||oe).test(b)?"format":"standalone"][a.month()]:c(this._months)?this._months:this._months.standalone}function ga(a,b){return a?c(this._monthsShort)?this._monthsShort[a.month()]:this._monthsShort[oe.test(b)?"format":"standalone"][a.month()]:c(this._monthsShort)?this._monthsShort:this._monthsShort.standalone}function ha(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],d=0;d<12;++d)f=l([2e3,d]),this._shortMonthsParse[d]=this.monthsShort(f,"").toLocaleLowerCase(),this._longMonthsParse[d]=this.months(f,"").toLocaleLowerCase();return c?"MMM"===b?(e=ne.call(this._shortMonthsParse,g),e!==-1?e:null):(e=ne.call(this._longMonthsParse,g),e!==-1?e:null):"MMM"===b?(e=ne.call(this._shortMonthsParse,g),e!==-1?e:(e=ne.call(this._longMonthsParse,g),e!==-1?e:null)):(e=ne.call(this._longMonthsParse,g),e!==-1?e:(e=ne.call(this._shortMonthsParse,g),e!==-1?e:null))}function ia(a,b,c){var d,e,f;if(this._monthsParseExact)return ha.call(this,a,b,c);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;d<12;d++){if(e=l([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}}function ja(a,b){var c;if(!a.isValid())return a;if("string"==typeof b)if(/^\d+$/.test(b))b=u(b);else if(b=a.localeData().monthsParse(b),!g(b))return a;return c=Math.min(a.date(),ea(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a}function ka(b){return null!=b?(ja(this,b),a.updateOffset(this,!0),this):P(this,"Month")}function la(){return ea(this.year(),this.month())}function ma(a){return this._monthsParseExact?(j(this,"_monthsRegex")||oa.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):(j(this,"_monthsShortRegex")||(this._monthsShortRegex=re),this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex)}function na(a){return this._monthsParseExact?(j(this,"_monthsRegex")||oa.call(this),a?this._monthsStrictRegex:this._monthsRegex):(j(this,"_monthsRegex")||(this._monthsRegex=se),this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex)}function oa(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;b<12;b++)c=l([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(d.sort(a),e.sort(a),f.sort(a),b=0;b<12;b++)d[b]=aa(d[b]),e[b]=aa(e[b]);for(b=0;b<24;b++)f[b]=aa(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")","i")}function pa(a){return qa(a)?366:365}function qa(a){return a%4===0&&a%100!==0||a%400===0}function ra(){return qa(this.year())}function sa(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return a<100&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function ta(a){var b=new Date(Date.UTC.apply(null,arguments));return a<100&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function ua(a,b,c){var d=7+b-c,e=(7+ta(a,0,d).getUTCDay()-b)%7;return-e+d-1}function va(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=ua(a,d,e),j=1+7*(b-1)+h+i;return j<=0?(f=a-1,g=pa(f)+j):j>pa(a)?(f=a+1,g=j-pa(a)):(f=a,g=j),{year:f,dayOfYear:g}}function wa(a,b,c){var d,e,f=ua(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return g<1?(e=a.year()-1,d=g+xa(e,b,c)):g>xa(a.year(),b,c)?(d=g-xa(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function xa(a,b,c){var d=ua(a,b,c),e=ua(a+1,b,c);return(pa(a)-d+e)/7}function ya(a){return wa(a,this._week.dow,this._week.doy).week}function za(){return this._week.dow}function Aa(){return this._week.doy}function Ba(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function Ca(a){var b=wa(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function Da(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function Ea(a,b){return"string"==typeof a?b.weekdaysParse(a)%7||7:isNaN(a)?null:a}function Fa(a,b){return a?c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]:c(this._weekdays)?this._weekdays:this._weekdays.standalone}function Ga(a){return a?this._weekdaysShort[a.day()]:this._weekdaysShort}function Ha(a){return a?this._weekdaysMin[a.day()]:this._weekdaysMin}function Ia(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],d=0;d<7;++d)f=l([2e3,1]).day(d),this._minWeekdaysParse[d]=this.weekdaysMin(f,"").toLocaleLowerCase(),this._shortWeekdaysParse[d]=this.weekdaysShort(f,"").toLocaleLowerCase(),this._weekdaysParse[d]=this.weekdays(f,"").toLocaleLowerCase();return c?"dddd"===b?(e=ne.call(this._weekdaysParse,g),e!==-1?e:null):"ddd"===b?(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:null):(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null):"dddd"===b?(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null))):"ddd"===b?(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:null))):(e=ne.call(this._minWeekdaysParse,g),e!==-1?e:(e=ne.call(this._weekdaysParse,g),e!==-1?e:(e=ne.call(this._shortWeekdaysParse,g),e!==-1?e:null)))}function Ja(a,b,c){var d,e,f;if(this._weekdaysParseExact)return Ia.call(this,a,b,c);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;d<7;d++){if(e=l([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function Ka(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Da(a,this.localeData()),this.add(a-b,"d")):b}function La(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function Ma(a){if(!this.isValid())return null!=a?this:NaN;if(null!=a){var b=Ea(a,this.localeData());return this.day(this.day()%7?b:b-7)}return this.day()||7}function Na(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysStrictRegex:this._weekdaysRegex):(j(this,"_weekdaysRegex")||(this._weekdaysRegex=ye),this._weekdaysStrictRegex&&a?this._weekdaysStrictRegex:this._weekdaysRegex)}function Oa(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(j(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=ze),this._weekdaysShortStrictRegex&&a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Pa(a){return this._weekdaysParseExact?(j(this,"_weekdaysRegex")||Qa.call(this),a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(j(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Ae),this._weekdaysMinStrictRegex&&a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Qa(){function a(a,b){return b.length-a.length}var b,c,d,e,f,g=[],h=[],i=[],j=[];for(b=0;b<7;b++)c=l([2e3,1]).day(b),d=this.weekdaysMin(c,""),e=this.weekdaysShort(c,""),f=this.weekdays(c,""),g.push(d),h.push(e),i.push(f),j.push(d),j.push(e),j.push(f);for(g.sort(a),h.sort(a),i.sort(a),j.sort(a),b=0;b<7;b++)h[b]=aa(h[b]),i[b]=aa(i[b]),j[b]=aa(j[b]);this._weekdaysRegex=new RegExp("^("+j.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+h.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+g.join("|")+")","i")}function Ra(){return this.hours()%12||12}function Sa(){return this.hours()||24}function Ta(a,b){U(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function Ua(a,b){return b._meridiemParse}function Va(a){return"p"===(a+"").toLowerCase().charAt(0)}function Wa(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function Xa(a){return a?a.toLowerCase().replace("_","-"):a}function Ya(a){for(var b,c,d,e,f=0;f<a.length;){for(e=Xa(a[f]).split("-"),b=e.length,c=Xa(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=Za(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&v(e,c,!0)>=b-1)break;b--}f++}return null}function Za(a){var b=null;if(!Fe[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=Be._abbr,require("./locale/"+a),$a(b)}catch(a){}return Fe[a]}function $a(a,b){var c;return a&&(c=f(b)?bb(a):_a(a,b),c&&(Be=c)),Be._abbr}function _a(a,b){if(null!==b){var c=Ee;if(b.abbr=a,null!=Fe[a])y("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),c=Fe[a]._config;else if(null!=b.parentLocale){if(null==Fe[b.parentLocale])return Ge[b.parentLocale]||(Ge[b.parentLocale]=[]),Ge[b.parentLocale].push({name:a,config:b}),null;c=Fe[b.parentLocale]._config}return Fe[a]=new C(B(c,b)),Ge[a]&&Ge[a].forEach(function(a){_a(a.name,a.config)}),$a(a),Fe[a]}return delete Fe[a],null}function ab(a,b){if(null!=b){var c,d=Ee;null!=Fe[a]&&(d=Fe[a]._config),b=B(d,b),c=new C(b),c.parentLocale=Fe[a],Fe[a]=c,$a(a)}else null!=Fe[a]&&(null!=Fe[a].parentLocale?Fe[a]=Fe[a].parentLocale:null!=Fe[a]&&delete Fe[a]);return Fe[a]}function bb(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return Be;if(!c(a)){if(b=Za(a))return b;a=[a]}return Ya(a)}function cb(){return Ad(Fe)}function db(a){var b,c=a._a;return c&&n(a).overflow===-2&&(b=c[fe]<0||c[fe]>11?fe:c[ge]<1||c[ge]>ea(c[ee],c[fe])?ge:c[he]<0||c[he]>24||24===c[he]&&(0!==c[ie]||0!==c[je]||0!==c[ke])?he:c[ie]<0||c[ie]>59?ie:c[je]<0||c[je]>59?je:c[ke]<0||c[ke]>999?ke:-1,n(a)._overflowDayOfYear&&(b<ee||b>ge)&&(b=ge),n(a)._overflowWeeks&&b===-1&&(b=le),n(a)._overflowWeekday&&b===-1&&(b=me),n(a).overflow=b),a}function eb(a){var b,c,d,e,f,g,h=a._i,i=He.exec(h)||Ie.exec(h);if(i){for(n(a).iso=!0,b=0,c=Ke.length;b<c;b++)if(Ke[b][1].exec(i[1])){e=Ke[b][0],d=Ke[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=Le.length;b<c;b++)if(Le[b][1].exec(i[3])){f=(i[2]||" ")+Le[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!Je.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),lb(a)}else a._isValid=!1}function fb(a){var b,c,d,e,f,g,h,i,j={" GMT":" +0000"," EDT":" -0400"," EST":" -0500"," CDT":" -0500"," CST":" -0600"," MDT":" -0600"," MST":" -0700"," PDT":" -0700"," PST":" -0800"},k="YXWVUTSRQPONZABCDEFGHIKLM";if(b=a._i.replace(/\([^\)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s|\s$/g,""),c=Ne.exec(b)){if(d=c[1]?"ddd"+(5===c[1].length?", ":" "):"",e="D MMM "+(c[2].length>10?"YYYY ":"YY "),f="HH:mm"+(c[4]?":ss":""),c[1]){var l=new Date(c[2]),m=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][l.getDay()];if(c[1].substr(0,3)!==m)return n(a).weekdayMismatch=!0,void(a._isValid=!1)}switch(c[5].length){case 2:0===i?h=" +0000":(i=k.indexOf(c[5][1].toUpperCase())-12,h=(i<0?" -":" +")+(""+i).replace(/^-?/,"0").match(/..$/)[0]+"00");break;case 4:h=j[c[5]];break;default:h=j[" GMT"]}c[5]=h,a._i=c.splice(1).join(""),g=" ZZ",a._f=d+e+f+g,lb(a),n(a).rfc2822=!0}else a._isValid=!1}function gb(b){var c=Me.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(eb(b),void(b._isValid===!1&&(delete b._isValid,fb(b),b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b)))))}function hb(a,b,c){return null!=a?a:null!=b?b:c}function ib(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function jb(a){var b,c,d,e,f=[];if(!a._d){for(d=ib(a),a._w&&null==a._a[ge]&&null==a._a[fe]&&kb(a),null!=a._dayOfYear&&(e=hb(a._a[ee],d[ee]),(a._dayOfYear>pa(e)||0===a._dayOfYear)&&(n(a)._overflowDayOfYear=!0),c=ta(e,0,a._dayOfYear),a._a[fe]=c.getUTCMonth(),a._a[ge]=c.getUTCDate()),b=0;b<3&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;b<7;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[he]&&0===a._a[ie]&&0===a._a[je]&&0===a._a[ke]&&(a._nextDay=!0,a._a[he]=0),a._d=(a._useUTC?ta:sa).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[he]=24)}}function kb(a){var b,c,d,e,f,g,h,i;if(b=a._w,null!=b.GG||null!=b.W||null!=b.E)f=1,g=4,c=hb(b.GG,a._a[ee],wa(tb(),1,4).year),d=hb(b.W,1),e=hb(b.E,1),(e<1||e>7)&&(i=!0);else{f=a._locale._week.dow,g=a._locale._week.doy;var j=wa(tb(),f,g);c=hb(b.gg,a._a[ee],j.year),d=hb(b.w,j.week),null!=b.d?(e=b.d,(e<0||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f}d<1||d>xa(c,f,g)?n(a)._overflowWeeks=!0:null!=i?n(a)._overflowWeekday=!0:(h=va(c,d,e,f,g),a._a[ee]=h.year,a._dayOfYear=h.dayOfYear)}function lb(b){if(b._f===a.ISO_8601)return void eb(b);if(b._f===a.RFC_2822)return void fb(b);b._a=[],n(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=Y(b._f,b._locale).match(Jd)||[],c=0;c<e.length;c++)f=e[c],d=(h.match($(f,b))||[])[0],d&&(g=h.substr(0,h.indexOf(d)),g.length>0&&n(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),Md[f]?(d?n(b).empty=!1:n(b).unusedTokens.push(f),da(f,d,b)):b._strict&&!d&&n(b).unusedTokens.push(f);n(b).charsLeftOver=i-j,h.length>0&&n(b).unusedInput.push(h),b._a[he]<=12&&n(b).bigHour===!0&&b._a[he]>0&&(n(b).bigHour=void 0),n(b).parsedDateParts=b._a.slice(0),n(b).meridiem=b._meridiem,b._a[he]=mb(b._locale,b._a[he],b._meridiem),jb(b),db(b)}function mb(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&b<12&&(b+=12),d||12!==b||(b=0),b):b}function nb(a){var b,c,d,e,f;if(0===a._f.length)return n(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;e<a._f.length;e++)f=0,b=q({},a),null!=a._useUTC&&(b._useUTC=a._useUTC),b._f=a._f[e],lb(b),o(b)&&(f+=n(b).charsLeftOver,f+=10*n(b).unusedTokens.length,n(b).score=f,(null==d||f<d)&&(d=f,c=b));k(a,c||b)}function ob(a){if(!a._d){var b=L(a._i);a._a=i([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),jb(a)}}function pb(a){var b=new r(db(qb(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function qb(a){var b=a._i,d=a._f;return a._locale=a._locale||bb(a._l),null===b||void 0===d&&""===b?p({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),s(b)?new r(db(b)):(h(b)?a._d=b:c(d)?nb(a):d?lb(a):rb(a),o(a)||(a._d=null),a))}function rb(b){var e=b._i;f(e)?b._d=new Date(a.now()):h(e)?b._d=new Date(e.valueOf()):"string"==typeof e?gb(b):c(e)?(b._a=i(e.slice(0),function(a){return parseInt(a,10)}),jb(b)):d(e)?ob(b):g(e)?b._d=new Date(e):a.createFromInputFallback(b)}function sb(a,b,f,g,h){var i={};return f!==!0&&f!==!1||(g=f,f=void 0),(d(a)&&e(a)||c(a)&&0===a.length)&&(a=void 0),i._isAMomentObject=!0,i._useUTC=i._isUTC=h,i._l=f,i._i=a,i._f=b,i._strict=g,pb(i)}function tb(a,b,c,d){return sb(a,b,c,d,!1)}function ub(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return tb();for(d=b[0],e=1;e<b.length;++e)b[e].isValid()&&!b[e][a](d)||(d=b[e]);return d}function vb(){var a=[].slice.call(arguments,0);return ub("isBefore",a)}function wb(){var a=[].slice.call(arguments,0);return ub("isAfter",a)}function xb(a){for(var b in a)if(Re.indexOf(b)===-1||null!=a[b]&&isNaN(a[b]))return!1;for(var c=!1,d=0;d<Re.length;++d)if(a[Re[d]]){if(c)return!1;parseFloat(a[Re[d]])!==u(a[Re[d]])&&(c=!0)}return!0}function yb(){return this._isValid}function zb(){return Sb(NaN)}function Ab(a){var b=L(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._isValid=xb(b),this._milliseconds=+k+1e3*j+6e4*i+1e3*h*60*60,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=bb(),this._bubble()}function Bb(a){return a instanceof Ab}function Cb(a){return a<0?Math.round(-1*a)*-1:Math.round(a)}function Db(a,b){U(a,0,0,function(){var a=this.utcOffset(),c="+";return a<0&&(a=-a,c="-"),c+T(~~(a/60),2)+b+T(~~a%60,2)})}function Eb(a,b){var c=(b||"").match(a);if(null===c)return null;var d=c[c.length-1]||[],e=(d+"").match(Se)||["-",0,0],f=+(60*e[1])+u(e[2]);return 0===f?0:"+"===e[0]?f:-f}function Fb(b,c){var d,e;return c._isUTC?(d=c.clone(),e=(s(b)||h(b)?b.valueOf():tb(b).valueOf())-d.valueOf(),d._d.setTime(d._d.valueOf()+e),a.updateOffset(d,!1),d):tb(b).local()}function Gb(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Hb(b,c,d){var e,f=this._offset||0;if(!this.isValid())return null!=b?this:NaN;if(null!=b){if("string"==typeof b){if(b=Eb(_d,b),null===b)return this}else Math.abs(b)<16&&!d&&(b=60*b);return!this._isUTC&&c&&(e=Gb(this)),this._offset=b,this._isUTC=!0,null!=e&&this.add(e,"m"),f!==b&&(!c||this._changeInProgress?Xb(this,Sb(b-f,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?f:Gb(this)}function Ib(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Jb(a){return this.utcOffset(0,a)}function Kb(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Gb(this),"m")),this}function Lb(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var a=Eb($d,this._i);null!=a?this.utcOffset(a):this.utcOffset(0,!0)}return this}function Mb(a){return!!this.isValid()&&(a=a?tb(a).utcOffset():0,(this.utcOffset()-a)%60===0)}function Nb(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Ob(){if(!f(this._isDSTShifted))return this._isDSTShifted;var a={};if(q(a,this),a=qb(a),a._a){var b=a._isUTC?l(a._a):tb(a._a);this._isDSTShifted=this.isValid()&&v(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Pb(){return!!this.isValid()&&!this._isUTC}function Qb(){return!!this.isValid()&&this._isUTC}function Rb(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function Sb(a,b){var c,d,e,f=a,h=null;return Bb(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:g(a)?(f={},b?f[b]=a:f.milliseconds=a):(h=Te.exec(a))?(c="-"===h[1]?-1:1,f={y:0,d:u(h[ge])*c,h:u(h[he])*c,m:u(h[ie])*c,s:u(h[je])*c,ms:u(Cb(1e3*h[ke]))*c}):(h=Ue.exec(a))?(c="-"===h[1]?-1:1,f={y:Tb(h[2],c),M:Tb(h[3],c),w:Tb(h[4],c),d:Tb(h[5],c),h:Tb(h[6],c),m:Tb(h[7],c),s:Tb(h[8],c)}):null==f?f={}:"object"==typeof f&&("from"in f||"to"in f)&&(e=Vb(tb(f.from),tb(f.to)),f={},f.ms=e.milliseconds,f.M=e.months),d=new Ab(f),Bb(a)&&j(a,"_locale")&&(d._locale=a._locale),d}function Tb(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function Ub(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function Vb(a,b){var c;return a.isValid()&&b.isValid()?(b=Fb(b,a),a.isBefore(b)?c=Ub(a,b):(c=Ub(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function Wb(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(y(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Sb(c,d),Xb(this,e,a),this}}function Xb(b,c,d,e){var f=c._milliseconds,g=Cb(c._days),h=Cb(c._months);b.isValid()&&(e=null==e||e,f&&b._d.setTime(b._d.valueOf()+f*d),g&&Q(b,"Date",P(b,"Date")+g*d),h&&ja(b,P(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function Yb(a,b){var c=a.diff(b,"days",!0);return c<-6?"sameElse":c<-1?"lastWeek":c<0?"lastDay":c<1?"sameDay":c<2?"nextDay":c<7?"nextWeek":"sameElse"}function Zb(b,c){var d=b||tb(),e=Fb(d,this).startOf("day"),f=a.calendarFormat(this,e)||"sameElse",g=c&&(z(c[f])?c[f].call(this,d):c[f]);return this.format(g||this.localeData().calendar(f,this,tb(d)))}function $b(){return new r(this)}function _b(a,b){var c=s(a)?a:tb(a);return!(!this.isValid()||!c.isValid())&&(b=K(f(b)?"millisecond":b),"millisecond"===b?this.valueOf()>c.valueOf():c.valueOf()<this.clone().startOf(b).valueOf())}function ac(a,b){var c=s(a)?a:tb(a);return!(!this.isValid()||!c.isValid())&&(b=K(f(b)?"millisecond":b),"millisecond"===b?this.valueOf()<c.valueOf():this.clone().endOf(b).valueOf()<c.valueOf())}function bc(a,b,c,d){return d=d||"()",("("===d[0]?this.isAfter(a,c):!this.isBefore(a,c))&&(")"===d[1]?this.isBefore(b,c):!this.isAfter(b,c))}function cc(a,b){var c,d=s(a)?a:tb(a);return!(!this.isValid()||!d.isValid())&&(b=K(b||"millisecond"),"millisecond"===b?this.valueOf()===d.valueOf():(c=d.valueOf(),this.clone().startOf(b).valueOf()<=c&&c<=this.clone().endOf(b).valueOf()))}function dc(a,b){return this.isSame(a,b)||this.isAfter(a,b)}function ec(a,b){return this.isSame(a,b)||this.isBefore(a,b)}function fc(a,b,c){var d,e,f,g;return this.isValid()?(d=Fb(a,this),d.isValid()?(e=6e4*(d.utcOffset()-this.utcOffset()),b=K(b),"year"===b||"month"===b||"quarter"===b?(g=gc(this,d),"quarter"===b?g/=3:"year"===b&&(g/=12)):(f=this-d,g="second"===b?f/1e3:"minute"===b?f/6e4:"hour"===b?f/36e5:"day"===b?(f-e)/864e5:"week"===b?(f-e)/6048e5:f),c?g:t(g)):NaN):NaN}function gc(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return b-f<0?(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)||0}function hc(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function ic(){if(!this.isValid())return null;var a=this.clone().utc();return a.year()<0||a.year()>9999?X(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):z(Date.prototype.toISOString)?this.toDate().toISOString():X(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function jc(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var a="moment",b="";this.isLocal()||(a=0===this.utcOffset()?"moment.utc":"moment.parseZone",b="Z");var c="["+a+'("]',d=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",e="-MM-DD[T]HH:mm:ss.SSS",f=b+'[")]';return this.format(c+d+e+f)}function kc(b){b||(b=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var c=X(this,b);return this.localeData().postformat(c)}function lc(a,b){return this.isValid()&&(s(a)&&a.isValid()||tb(a).isValid())?Sb({to:this,from:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function mc(a){return this.from(tb(),a)}function nc(a,b){return this.isValid()&&(s(a)&&a.isValid()||tb(a).isValid())?Sb({from:this,to:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function oc(a){return this.to(tb(),a)}function pc(a){var b;return void 0===a?this._locale._abbr:(b=bb(a),null!=b&&(this._locale=b),this)}function qc(){return this._locale}function rc(a){switch(a=K(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":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}function sc(a){return a=K(a),void 0===a||"millisecond"===a?this:("date"===a&&(a="day"),this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms"))}function tc(){return this._d.valueOf()-6e4*(this._offset||0)}function uc(){return Math.floor(this.valueOf()/1e3)}function vc(){return new Date(this.valueOf())}function wc(){var a=this;return[a.year(),a.month(),a.date(),a.hour(),a.minute(),a.second(),a.millisecond()]}function xc(){var a=this;return{years:a.year(),months:a.month(),date:a.date(),hours:a.hours(),minutes:a.minutes(),seconds:a.seconds(),milliseconds:a.milliseconds()}}function yc(){return this.isValid()?this.toISOString():null}function zc(){return o(this)}function Ac(){ -return k({},n(this))}function Bc(){return n(this).overflow}function Cc(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Dc(a,b){U(0,[a,a.length],0,b)}function Ec(a){return Ic.call(this,a,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function Fc(a){return Ic.call(this,a,this.isoWeek(),this.isoWeekday(),1,4)}function Gc(){return xa(this.year(),1,4)}function Hc(){var a=this.localeData()._week;return xa(this.year(),a.dow,a.doy)}function Ic(a,b,c,d,e){var f;return null==a?wa(this,d,e).year:(f=xa(a,d,e),b>f&&(b=f),Jc.call(this,a,b,c,d,e))}function Jc(a,b,c,d,e){var f=va(a,b,c,d,e),g=ta(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Kc(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Lc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function Mc(a,b){b[ke]=u(1e3*("0."+a))}function Nc(){return this._isUTC?"UTC":""}function Oc(){return this._isUTC?"Coordinated Universal Time":""}function Pc(a){return tb(1e3*a)}function Qc(){return tb.apply(null,arguments).parseZone()}function Rc(a){return a}function Sc(a,b,c,d){var e=bb(),f=l().set(d,b);return e[c](f,a)}function Tc(a,b,c){if(g(a)&&(b=a,a=void 0),a=a||"",null!=b)return Sc(a,b,c,"month");var d,e=[];for(d=0;d<12;d++)e[d]=Sc(a,d,c,"month");return e}function Uc(a,b,c,d){"boolean"==typeof a?(g(b)&&(c=b,b=void 0),b=b||""):(b=a,c=b,a=!1,g(b)&&(c=b,b=void 0),b=b||"");var e=bb(),f=a?e._week.dow:0;if(null!=c)return Sc(b,(c+f)%7,d,"day");var h,i=[];for(h=0;h<7;h++)i[h]=Sc(b,(h+f)%7,d,"day");return i}function Vc(a,b){return Tc(a,b,"months")}function Wc(a,b){return Tc(a,b,"monthsShort")}function Xc(a,b,c){return Uc(a,b,c,"weekdays")}function Yc(a,b,c){return Uc(a,b,c,"weekdaysShort")}function Zc(a,b,c){return Uc(a,b,c,"weekdaysMin")}function $c(){var a=this._data;return this._milliseconds=df(this._milliseconds),this._days=df(this._days),this._months=df(this._months),a.milliseconds=df(a.milliseconds),a.seconds=df(a.seconds),a.minutes=df(a.minutes),a.hours=df(a.hours),a.months=df(a.months),a.years=df(a.years),this}function _c(a,b,c,d){var e=Sb(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function ad(a,b){return _c(this,a,b,1)}function bd(a,b){return _c(this,a,b,-1)}function cd(a){return a<0?Math.floor(a):Math.ceil(a)}function dd(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||f<=0&&g<=0&&h<=0||(f+=864e5*cd(fd(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=t(f/1e3),i.seconds=a%60,b=t(a/60),i.minutes=b%60,c=t(b/60),i.hours=c%24,g+=t(c/24),e=t(ed(g)),h+=e,g-=cd(fd(e)),d=t(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function ed(a){return 4800*a/146097}function fd(a){return 146097*a/4800}function gd(a){if(!this.isValid())return NaN;var b,c,d=this._milliseconds;if(a=K(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+ed(b),"month"===a?c:c/12;switch(b=this._days+Math.round(fd(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function hd(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*u(this._months/12):NaN}function id(a){return function(){return this.as(a)}}function jd(a){return a=K(a),this.isValid()?this[a+"s"]():NaN}function kd(a){return function(){return this.isValid()?this._data[a]:NaN}}function ld(){return t(this.days()/7)}function md(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function nd(a,b,c){var d=Sb(a).abs(),e=uf(d.as("s")),f=uf(d.as("m")),g=uf(d.as("h")),h=uf(d.as("d")),i=uf(d.as("M")),j=uf(d.as("y")),k=e<=vf.ss&&["s",e]||e<vf.s&&["ss",e]||f<=1&&["m"]||f<vf.m&&["mm",f]||g<=1&&["h"]||g<vf.h&&["hh",g]||h<=1&&["d"]||h<vf.d&&["dd",h]||i<=1&&["M"]||i<vf.M&&["MM",i]||j<=1&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,md.apply(null,k)}function od(a){return void 0===a?uf:"function"==typeof a&&(uf=a,!0)}function pd(a,b){return void 0!==vf[a]&&(void 0===b?vf[a]:(vf[a]=b,"s"===a&&(vf.ss=b-1),!0))}function qd(a){if(!this.isValid())return this.localeData().invalidDate();var b=this.localeData(),c=nd(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function rd(){if(!this.isValid())return this.localeData().invalidDate();var a,b,c,d=wf(this._milliseconds)/1e3,e=wf(this._days),f=wf(this._months);a=t(d/60),b=t(a/60),d%=60,a%=60,c=t(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(m<0?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var sd,td;td=Array.prototype.some?Array.prototype.some:function(a){for(var b=Object(this),c=b.length>>>0,d=0;d<c;d++)if(d in b&&a.call(this,b[d],d,b))return!0;return!1};var ud=td,vd=a.momentProperties=[],wd=!1,xd={};a.suppressDeprecationWarnings=!1,a.deprecationHandler=null;var yd;yd=Object.keys?Object.keys:function(a){var b,c=[];for(b in a)j(a,b)&&c.push(b);return c};var zd,Ad=yd,Bd={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Cd={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Dd="Invalid date",Ed="%d",Fd=/\d{1,2}/,Gd={future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d 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"},Hd={},Id={},Jd=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Kd=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Ld={},Md={},Nd=/\d/,Od=/\d\d/,Pd=/\d{3}/,Qd=/\d{4}/,Rd=/[+-]?\d{6}/,Sd=/\d\d?/,Td=/\d\d\d\d?/,Ud=/\d\d\d\d\d\d?/,Vd=/\d{1,3}/,Wd=/\d{1,4}/,Xd=/[+-]?\d{1,6}/,Yd=/\d+/,Zd=/[+-]?\d+/,$d=/Z|[+-]\d\d:?\d\d/gi,_d=/Z|[+-]\d\d(?::?\d\d)?/gi,ae=/[+-]?\d+(\.\d{1,3})?/,be=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,ce={},de={},ee=0,fe=1,ge=2,he=3,ie=4,je=5,ke=6,le=7,me=8;zd=Array.prototype.indexOf?Array.prototype.indexOf:function(a){var b;for(b=0;b<this.length;++b)if(this[b]===a)return b;return-1};var ne=zd;U("M",["MM",2],"Mo",function(){return this.month()+1}),U("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),U("MMMM",0,0,function(a){return this.localeData().months(this,a)}),J("month","M"),M("month",8),Z("M",Sd),Z("MM",Sd,Od),Z("MMM",function(a,b){return b.monthsShortRegex(a)}),Z("MMMM",function(a,b){return b.monthsRegex(a)}),ba(["M","MM"],function(a,b){b[fe]=u(a)-1}),ba(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[fe]=e:n(c).invalidMonth=a});var oe=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,pe="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),qe="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),re=be,se=be;U("Y",0,0,function(){var a=this.year();return a<=9999?""+a:"+"+a}),U(0,["YY",2],0,function(){return this.year()%100}),U(0,["YYYY",4],0,"year"),U(0,["YYYYY",5],0,"year"),U(0,["YYYYYY",6,!0],0,"year"),J("year","y"),M("year",1),Z("Y",Zd),Z("YY",Sd,Od),Z("YYYY",Wd,Qd),Z("YYYYY",Xd,Rd),Z("YYYYYY",Xd,Rd),ba(["YYYYY","YYYYYY"],ee),ba("YYYY",function(b,c){c[ee]=2===b.length?a.parseTwoDigitYear(b):u(b)}),ba("YY",function(b,c){c[ee]=a.parseTwoDigitYear(b)}),ba("Y",function(a,b){b[ee]=parseInt(a,10)}),a.parseTwoDigitYear=function(a){return u(a)+(u(a)>68?1900:2e3)};var te=O("FullYear",!0);U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),J("week","w"),J("isoWeek","W"),M("week",5),M("isoWeek",5),Z("w",Sd),Z("ww",Sd,Od),Z("W",Sd),Z("WW",Sd,Od),ca(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=u(a)});var ue={dow:0,doy:6};U("d",0,"do","day"),U("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),U("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),U("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),J("day","d"),J("weekday","e"),J("isoWeekday","E"),M("day",11),M("weekday",11),M("isoWeekday",11),Z("d",Sd),Z("e",Sd),Z("E",Sd),Z("dd",function(a,b){return b.weekdaysMinRegex(a)}),Z("ddd",function(a,b){return b.weekdaysShortRegex(a)}),Z("dddd",function(a,b){return b.weekdaysRegex(a)}),ca(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:n(c).invalidWeekday=a}),ca(["d","e","E"],function(a,b,c,d){b[d]=u(a)});var ve="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),we="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xe="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),ye=be,ze=be,Ae=be;U("H",["HH",2],0,"hour"),U("h",["hh",2],0,Ra),U("k",["kk",2],0,Sa),U("hmm",0,0,function(){return""+Ra.apply(this)+T(this.minutes(),2)}),U("hmmss",0,0,function(){return""+Ra.apply(this)+T(this.minutes(),2)+T(this.seconds(),2)}),U("Hmm",0,0,function(){return""+this.hours()+T(this.minutes(),2)}),U("Hmmss",0,0,function(){return""+this.hours()+T(this.minutes(),2)+T(this.seconds(),2)}),Ta("a",!0),Ta("A",!1),J("hour","h"),M("hour",13),Z("a",Ua),Z("A",Ua),Z("H",Sd),Z("h",Sd),Z("k",Sd),Z("HH",Sd,Od),Z("hh",Sd,Od),Z("kk",Sd,Od),Z("hmm",Td),Z("hmmss",Ud),Z("Hmm",Td),Z("Hmmss",Ud),ba(["H","HH"],he),ba(["k","kk"],function(a,b,c){var d=u(a);b[he]=24===d?0:d}),ba(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),ba(["h","hh"],function(a,b,c){b[he]=u(a),n(c).bigHour=!0}),ba("hmm",function(a,b,c){var d=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d)),n(c).bigHour=!0}),ba("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d,2)),b[je]=u(a.substr(e)),n(c).bigHour=!0}),ba("Hmm",function(a,b,c){var d=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d))}),ba("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[he]=u(a.substr(0,d)),b[ie]=u(a.substr(d,2)),b[je]=u(a.substr(e))});var Be,Ce=/[ap]\.?m?\.?/i,De=O("Hours",!0),Ee={calendar:Bd,longDateFormat:Cd,invalidDate:Dd,ordinal:Ed,dayOfMonthOrdinalParse:Fd,relativeTime:Gd,months:pe,monthsShort:qe,week:ue,weekdays:ve,weekdaysMin:xe,weekdaysShort:we,meridiemParse:Ce},Fe={},Ge={},He=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Ie=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Je=/Z|[+-]\d\d(?::?\d\d)?/,Ke=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Le=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Me=/^\/?Date\((\-?\d+)/i,Ne=/^((?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d?\d\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(?:\d\d)?\d\d\s)(\d\d:\d\d)(\:\d\d)?(\s(?:UT|GMT|[ECMP][SD]T|[A-IK-Za-ik-z]|[+-]\d{4}))$/;a.createFromInputFallback=x("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),a.ISO_8601=function(){},a.RFC_2822=function(){};var Oe=x("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=tb.apply(null,arguments);return this.isValid()&&a.isValid()?a<this?this:a:p()}),Pe=x("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=tb.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:p()}),Qe=function(){return Date.now?Date.now():+new Date},Re=["year","quarter","month","week","day","hour","minute","second","millisecond"];Db("Z",":"),Db("ZZ",""),Z("Z",_d),Z("ZZ",_d),ba(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Eb(_d,a)});var Se=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var Te=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Ue=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;Sb.fn=Ab.prototype,Sb.invalid=zb;var Ve=Wb(1,"add"),We=Wb(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Xe=x("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});U(0,["gg",2],0,function(){return this.weekYear()%100}),U(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Dc("gggg","weekYear"),Dc("ggggg","weekYear"),Dc("GGGG","isoWeekYear"),Dc("GGGGG","isoWeekYear"),J("weekYear","gg"),J("isoWeekYear","GG"),M("weekYear",1),M("isoWeekYear",1),Z("G",Zd),Z("g",Zd),Z("GG",Sd,Od),Z("gg",Sd,Od),Z("GGGG",Wd,Qd),Z("gggg",Wd,Qd),Z("GGGGG",Xd,Rd),Z("ggggg",Xd,Rd),ca(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=u(a)}),ca(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),U("Q",0,"Qo","quarter"),J("quarter","Q"),M("quarter",7),Z("Q",Nd),ba("Q",function(a,b){b[fe]=3*(u(a)-1)}),U("D",["DD",2],"Do","date"),J("date","D"),M("date",9),Z("D",Sd),Z("DD",Sd,Od),Z("Do",function(a,b){return a?b._dayOfMonthOrdinalParse||b._ordinalParse:b._dayOfMonthOrdinalParseLenient}),ba(["D","DD"],ge),ba("Do",function(a,b){b[ge]=u(a.match(Sd)[0],10)});var Ye=O("Date",!0);U("DDD",["DDDD",3],"DDDo","dayOfYear"),J("dayOfYear","DDD"),M("dayOfYear",4),Z("DDD",Vd),Z("DDDD",Pd),ba(["DDD","DDDD"],function(a,b,c){c._dayOfYear=u(a)}),U("m",["mm",2],0,"minute"),J("minute","m"),M("minute",14),Z("m",Sd),Z("mm",Sd,Od),ba(["m","mm"],ie);var Ze=O("Minutes",!1);U("s",["ss",2],0,"second"),J("second","s"),M("second",15),Z("s",Sd),Z("ss",Sd,Od),ba(["s","ss"],je);var $e=O("Seconds",!1);U("S",0,0,function(){return~~(this.millisecond()/100)}),U(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),U(0,["SSS",3],0,"millisecond"),U(0,["SSSS",4],0,function(){return 10*this.millisecond()}),U(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),U(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),U(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),U(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),U(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),J("millisecond","ms"),M("millisecond",16),Z("S",Vd,Nd),Z("SS",Vd,Od),Z("SSS",Vd,Pd);var _e;for(_e="SSSS";_e.length<=9;_e+="S")Z(_e,Yd);for(_e="S";_e.length<=9;_e+="S")ba(_e,Mc);var af=O("Milliseconds",!1);U("z",0,0,"zoneAbbr"),U("zz",0,0,"zoneName");var bf=r.prototype;bf.add=Ve,bf.calendar=Zb,bf.clone=$b,bf.diff=fc,bf.endOf=sc,bf.format=kc,bf.from=lc,bf.fromNow=mc,bf.to=nc,bf.toNow=oc,bf.get=R,bf.invalidAt=Bc,bf.isAfter=_b,bf.isBefore=ac,bf.isBetween=bc,bf.isSame=cc,bf.isSameOrAfter=dc,bf.isSameOrBefore=ec,bf.isValid=zc,bf.lang=Xe,bf.locale=pc,bf.localeData=qc,bf.max=Pe,bf.min=Oe,bf.parsingFlags=Ac,bf.set=S,bf.startOf=rc,bf.subtract=We,bf.toArray=wc,bf.toObject=xc,bf.toDate=vc,bf.toISOString=ic,bf.inspect=jc,bf.toJSON=yc,bf.toString=hc,bf.unix=uc,bf.valueOf=tc,bf.creationData=Cc,bf.year=te,bf.isLeapYear=ra,bf.weekYear=Ec,bf.isoWeekYear=Fc,bf.quarter=bf.quarters=Kc,bf.month=ka,bf.daysInMonth=la,bf.week=bf.weeks=Ba,bf.isoWeek=bf.isoWeeks=Ca,bf.weeksInYear=Hc,bf.isoWeeksInYear=Gc,bf.date=Ye,bf.day=bf.days=Ka,bf.weekday=La,bf.isoWeekday=Ma,bf.dayOfYear=Lc,bf.hour=bf.hours=De,bf.minute=bf.minutes=Ze,bf.second=bf.seconds=$e,bf.millisecond=bf.milliseconds=af,bf.utcOffset=Hb,bf.utc=Jb,bf.local=Kb,bf.parseZone=Lb,bf.hasAlignedHourOffset=Mb,bf.isDST=Nb,bf.isLocal=Pb,bf.isUtcOffset=Qb,bf.isUtc=Rb,bf.isUTC=Rb,bf.zoneAbbr=Nc,bf.zoneName=Oc,bf.dates=x("dates accessor is deprecated. Use date instead.",Ye),bf.months=x("months accessor is deprecated. Use month instead",ka),bf.years=x("years accessor is deprecated. Use year instead",te),bf.zone=x("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",Ib),bf.isDSTShifted=x("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Ob);var cf=C.prototype;cf.calendar=D,cf.longDateFormat=E,cf.invalidDate=F,cf.ordinal=G,cf.preparse=Rc,cf.postformat=Rc,cf.relativeTime=H,cf.pastFuture=I,cf.set=A,cf.months=fa,cf.monthsShort=ga,cf.monthsParse=ia,cf.monthsRegex=na,cf.monthsShortRegex=ma,cf.week=ya,cf.firstDayOfYear=Aa,cf.firstDayOfWeek=za,cf.weekdays=Fa,cf.weekdaysMin=Ha,cf.weekdaysShort=Ga,cf.weekdaysParse=Ja,cf.weekdaysRegex=Na,cf.weekdaysShortRegex=Oa,cf.weekdaysMinRegex=Pa,cf.isPM=Va,cf.meridiem=Wa,$a("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===u(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=x("moment.lang is deprecated. Use moment.locale instead.",$a),a.langData=x("moment.langData is deprecated. Use moment.localeData instead.",bb);var df=Math.abs,ef=id("ms"),ff=id("s"),gf=id("m"),hf=id("h"),jf=id("d"),kf=id("w"),lf=id("M"),mf=id("y"),nf=kd("milliseconds"),of=kd("seconds"),pf=kd("minutes"),qf=kd("hours"),rf=kd("days"),sf=kd("months"),tf=kd("years"),uf=Math.round,vf={ss:44,s:45,m:45,h:22,d:26,M:11},wf=Math.abs,xf=Ab.prototype;return xf.isValid=yb,xf.abs=$c,xf.add=ad,xf.subtract=bd,xf.as=gd,xf.asMilliseconds=ef,xf.asSeconds=ff,xf.asMinutes=gf,xf.asHours=hf,xf.asDays=jf,xf.asWeeks=kf,xf.asMonths=lf,xf.asYears=mf,xf.valueOf=hd,xf._bubble=dd,xf.get=jd,xf.milliseconds=nf,xf.seconds=of,xf.minutes=pf,xf.hours=qf,xf.days=rf,xf.weeks=ld,xf.months=sf,xf.years=tf,xf.humanize=qd,xf.toISOString=rd,xf.toString=rd,xf.toJSON=rd,xf.locale=pc,xf.localeData=qc,xf.toIsoString=x("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",rd),xf.lang=Xe,U("X",0,0,"unix"),U("x",0,0,"valueOf"),Z("x",Zd),Z("X",ae),ba("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),ba("x",function(a,b,c){c._d=new Date(u(a))}),a.version="2.18.1",b(tb),a.fn=bf,a.min=vb,a.max=wb,a.now=Qe,a.utc=l,a.unix=Pc,a.months=Vc,a.isDate=h,a.locale=$a,a.invalid=p,a.duration=Sb,a.isMoment=s,a.weekdays=Xc,a.parseZone=Qc,a.localeData=bb,a.isDuration=Bb,a.monthsShort=Wc,a.weekdaysMin=Zc,a.defineLocale=_a,a.updateLocale=ab,a.locales=cb,a.weekdaysShort=Yc,a.normalizeUnits=K,a.relativeTimeRounding=od,a.relativeTimeThreshold=pd,a.calendarFormat=Yb,a.prototype=bf,a}); diff --git a/web/js/nms-admin-pane.js b/web/js/nms-admin-pane.js deleted file mode 100644 index 235da8d..0000000 --- a/web/js/nms-admin-pane.js +++ /dev/null @@ -1,99 +0,0 @@ -"use strict"; - - - -var nmsAdmin = nmsAdmin || { - _populated: false, - _elements: {}, - _main: { - 'shortname':"Short name", - 'publicvhost': "Public VHOST", - 'data': "Misc data" - } -}; - -nmsAdmin._populatePane = function() { - var form = document.createElement("div"); - form.classList.add("form-group"); - for (var v in nmsAdmin._main) { - var x = document.createElement('label'); - var y = document.createElement('input'); - y.classList.add("form-control"); - y.id = "nmsAdmin-input-" + v; - x.innerText = nmsAdmin._main[v]; - x.htmlFor = y.id; - form.appendChild(x); - form.appendChild(y); - nmsAdmin._elements[v] = y; - } - var submit = document.createElement("button"); - submit.classList.add("btn"); - submit.classList.add("btn-default"); - submit.onclick = nmsAdmin._commitData; - submit.innerHTML = "Save"; - var topel = document.getElementById("admin-row"); - topel.appendChild(form); - topel.appendChild(submit); - nmsAdmin._populated = true; -} - -nmsAdmin._setReadOnly = function(ro) { - for (var v in nmsAdmin._main) { - nmsAdmin._elements[v].readOnly = ro; - } -} - -nmsAdmin._commitData = function() { - var myData = {}; - for (var v in nmsAdmin._main) { - if (v != "data") { - myData[v] = nmsAdmin._elements[v].value; - } else { - myData[v] = JSON.parse(nmsAdmin._elements[v].value); - } - } - myData = JSON.stringify(myData); - nmsAdmin._setReadOnly(true); - $.ajax({ - type: "POST", - url: "/api/write/config", - dataType: "text", - data:myData, - success: function (data, textStatus, jqXHR) { - nmsData.invalidate("config"); - nmsAdmin._setReadOnly(false); - } - }); -} - -nmsAdmin.updateConfigPane = function() { - if (nmsAdmin._populated == false) { - nmsAdmin._populatePane(); - } - for (var v in nmsAdmin._main) { - if (v != "data") { - nmsAdmin._elements[v].value = nmsData['config']['config'][v]; - } else { - nmsAdmin._elements[v].value = JSON.stringify(nmsData['config']['config'][v]); - } - } -} - -nmsAdmin.addLinknet = function() { - var myData = { - "switch1": document.getElementById("admin-input-linknet1").value, - "switch2": document.getElementById("admin-input-linknet2").value - }; - myData = JSON.stringify(myData); - $.ajax({ - type: "POST", - url: "/api/write/linknet-add", - dataType: "text", - data:myData, - success: function (data, textStatus, jqXHR) { - nmsData.invalidate("switches"); - document.getElementById("admin-input-linknet1").value = ""; - document.getElementById("admin-input-linknet2").value = ""; - } - }); -} diff --git a/web/js/nms-color-util.js b/web/js/nms-color-util.js index 0f50126..d1336c3 100644 --- a/web/js/nms-color-util.js +++ b/web/js/nms-color-util.js @@ -7,32 +7,36 @@ */ var nmsColor = nmsColor || { - _cache: [], - lightblue: "#d9edf7", - lightgreen: "#dff0d8", - lightred: "#f2dede", - lightorange: "#fcf8e3", - blue: "#337ab7", - green: "#5cb85c", - teal: "#5bc0de", - orange: "#f0ad4e", - red: "#d9534f", - white: "#ffffff" -} + _cache: [], + cyan: "#0dcaf0", + blue: "#0d6efd", + green: "#198754", + teal: "#20c997", + orange: "#fd7e14", + red: "#dc3545", + white: "#fff", +}; /* * Return a random-ish color (for testing) */ -nmsColor.random = function() -{ - var colors = [ "white", nmsColor.red, nmsColor.teal, nmsColor.orange, nmsColor.green, nmsColor.blue ]; - var i = Math.round(Math.random() * (colors.length-1)); - return colors[i]; -} +nmsColor.random = function () { + var colors = [ + nmsColor.white, + nmsColor.red, + nmsColor.teal, + nmsColor.orange, + nmsColor.green, + nmsColor.blue, + nmsColor.cyan, + ]; + var i = Math.round(Math.random() * (colors.length - 1)); + return colors[i]; +}; /* * Set up the hidden gradient canvas, using an array as input. - * + * * This gives us a flexible way to get gradients between any number of * colors (green to red, or blue to green to orange to red to white to pink * to black and so on). @@ -44,57 +48,52 @@ nmsColor.random = function() * resize for the moment, because this canvas is also re-sized (which isn't * really necessary, but avoids special handling). */ -nmsColor.drawGradient = function(gradients) { - var ctx = nmsMap._c.hidden.ctx; // FIXME: Move it away... - var gradient = ctx.createLinearGradient(0,0,1000,0); - var stops = gradients.length - 1; - nmsColor._cache = []; - nms.gradients = gradients; - for (var color in gradients) { - var i = color / stops; - gradient.addColorStop(i, gradients[color]); - } - ctx.beginPath(); - ctx.strokeStyle = gradient; - ctx.moveTo(0,0); - ctx.lineTo(1000,0); - ctx.lineWidth = 10; - ctx.closePath(); - ctx.stroke(); - ctx.moveTo(0,0); -} +nmsColor.drawGradient = function (gradients) { + var ctx = nmsMap._c.hidden.ctx; // FIXME: Move it away... + var gradient = ctx.createLinearGradient(0, 0, 1000, 0); + var stops = gradients.length - 1; + nmsColor._cache = []; + nms.gradients = gradients; + for (var color in gradients) { + var i = color / stops; + gradient.addColorStop(i, gradients[color]); + } + ctx.beginPath(); + ctx.strokeStyle = gradient; + ctx.moveTo(0, 0); + ctx.lineTo(1000, 0); + ctx.lineWidth = 10; + ctx.closePath(); + ctx.stroke(); + ctx.moveTo(0, 0); +}; /* * Get the color of a gradient, range is from 0 to 999 (inclusive). */ -nmsColor.getColorStop = function(x) { - x = parseInt(x); - if (isNaN(x)) - x = 0; - if (x > 999) - x = 999; - if (x < 0) - x = 0; - return nmsColor._getColor(x,0); -} +nmsColor.getColorStop = function (x) { + x = parseInt(x); + if (isNaN(x)) x = 0; + if (x > 999) x = 999; + if (x < 0) x = 0; + return nmsColor._getColor(x, 0); +}; /* * Get the color on the hidden canvas at a specific point. Could easily be * made generic. */ -nmsColor._getColor = function(x,y) { - if (nmsColor._cache[x] != undefined) - return nmsColor._cache[x]; - var ctx = nmsMap._c.hidden.ctx; // FIXME: Move it away... - try { - var imageData = ctx.getImageData(x, y, 1, 1); - } catch(e) { - console.log("x: " + x); - console.log(e); - } - var data = imageData.data; - if (data.length < 4) - return false; - nmsColor._cache[x] = 'rgb(' + data[0] + ',' + data[1] + ',' + data[2] + ')'; - return nmsColor._cache[x]; -} +nmsColor._getColor = function (x, y) { + if (nmsColor._cache[x] != undefined) return nmsColor._cache[x]; + var ctx = nmsMap._c.hidden.ctx; // FIXME: Move it away... + try { + var imageData = ctx.getImageData(x, y, 1, 1); + } catch (e) { + console.log("x: " + x); + console.log(e); + } + var data = imageData.data; + if (data.length < 4) return false; + nmsColor._cache[x] = "rgb(" + data[0] + "," + data[1] + "," + data[2] + ")"; + return nmsColor._cache[x]; +}; diff --git a/web/js/nms-data.js b/web/js/nms-data.js index c923e08..6a00fba 100644 --- a/web/js/nms-data.js +++ b/web/js/nms-data.js @@ -23,78 +23,82 @@ * nmsData.invalidate() - Invalidate browser-cache. */ - var nmsData = nmsData || { - old: {}, // Single copy of previous data. Automatically populated. - stats: { - identicalFetches:0, - outstandingAjaxRequests:0, - ajaxOverflow:0, - pollClearsEmpty:0, - pollClears:0, - pollSets:0, - newSource:0, - oldSource:0 - }, - _pulseBeat: 0, - /* - * The last time stamp of any data received, regardless of source. - * - * Used as a fallback for blank now, but can also be used to check - * "freshness", I suppose. - */ - _last: undefined, - _now: undefined, + old: {}, // Single copy of previous data. Automatically populated. + stats: { + identicalFetches: 0, + outstandingAjaxRequests: 0, + ajaxOverflow: 0, + pollClearsEmpty: 0, + pollClears: 0, + pollSets: 0, + newSource: 0, + oldSource: 0, + allFetches: 0, + allRequests: 0, + failedFetches: 0, + jsonParse: 0, + }, + _pulseBeat: 0, + /* + * The last time stamp of any data received, regardless of source. + * + * Used as a fallback for blank now, but can also be used to check + * "freshness", I suppose. + */ + _last: undefined, + _now: undefined, - /* - * These are provided so we can introduce error checking when we - * have time. - * - * now() represents the data, not the intent. That means that if - * you want to check if we are traveling in time you should not - * check nmsData.now. That will always return a value as long as - * we've had a single piece of data. - */ - get now() { return this._now || this._last; }, - set now(val) { - if (val == undefined || !val) { - nmsData._now = undefined; - } else { - // FIXME: Check if now is valid syntax. - nmsData._now = val; - } - }, - /* - * List of sources, name, handler, etc - */ - _sources: {}, + /* + * These are provided so we can introduce error checking when we + * have time. + * + * now() represents the data, not the intent. That means that if + * you want to check if we are traveling in time you should not + * check nmsData.now. That will always return a value as long as + * we've had a single piece of data. + */ + get now() { + return this._now || this._last; + }, + set now(val) { + if (val == undefined || !val) { + nmsData._now = undefined; + } else { + // FIXME: Check if now is valid syntax. + nmsData._now = val; + } + }, + /* + * List of sources, name, handler, etc + */ + _sources: {}, - /* - * Maximum number of AJAX requests in transit before we start - * skipping updates. - * - * A problem right now is that it will typically always hit the - * same thing since everything starts at the same time... - */ - _ajaxThreshold: 10 + /* + * Maximum number of AJAX requests in transit before we start + * skipping updates. + * + * A problem right now is that it will typically always hit the + * same thing since everything starts at the same time... + */ + _ajaxThreshold: 10, }; - nmsData._dropData = function (name) { - delete this[name]; - delete this.old[name]; + delete this[name]; + delete this.old[name]; }; nmsData.removeSource = function (name) { - if (this._sources[name] == undefined) { - this.stats.pollClearsEmpty++; - return true; - } - if (this._sources[name]['handle']) { - this.stats.pollClears++; - clearInterval(this._sources[name]['handle']); - } - delete this._sources[name]; + if (this._sources[name] == undefined) { + this.stats.pollClearsEmpty++; + return true; + } + if (this._sources[name]["handle"]) { + this.stats.pollClears++; + clearInterval(this._sources[name]["handle"]); + } + delete this._sources[name]; }; /* @@ -112,15 +116,17 @@ nmsData.removeSource = function (name) { * * FIXME: Should be unified with nmsTimers() somehow. */ -nmsData.registerSource = function(name, target) { - if (this._sources[name] == undefined) { - this._sources[name] = { target: target, cbs: {}, fresh: true }; - this._sources[name]['handle'] = setInterval(function(){nmsData.updateSource(name)}, 1000); - this.stats.newSource++; - } else { - this.stats.oldSource++; - } - this.stats.pollSets++; +nmsData.registerSource = function (name, target) { + if (this._sources[name] == undefined) { + this._sources[name] = { target: target, cbs: {}, fresh: true }; + this._sources[name]["handle"] = setInterval(function () { + nmsData.updateSource(name); + }, 1000); + this.stats.newSource++; + } else { + this.stats.oldSource++; + } + this.stats.pollSets++; }; /* @@ -132,45 +138,44 @@ nmsData.registerSource = function(name, target) { * The actual html might not be the best choice, but I think the general * idea of some sort of heartbeat is needed. */ -nmsData._pulse = function() { - if (nmsData._pulseElement == undefined) { - try { - nmsData._pulseElement = document.getElementById("heartbeat"); - } catch(e) { - nmsData._pulseElement = null; - } - } - if (nmsData._pulseElement == null) - return; - if (nmsData._pulseBeat > 20) { - if (nmsData._pulseElement.classList.contains("pulse-on")) { - nmsData._pulseElement.classList.remove("pulse-on"); - } else { - nmsData._pulseElement.classList.add("pulse-on"); - } - nmsData._pulseBeat = 0; - } - nmsData._pulseBeat++; -} +nmsData._pulse = function () { + if (nmsData._pulseElement == undefined) { + try { + nmsData._pulseElement = document.getElementById("heartbeat"); + } catch (e) { + nmsData._pulseElement = null; + } + } + if (nmsData._pulseElement == null) return; + if (nmsData._pulseBeat > 20) { + if (nmsData._pulseElement.classList.contains("pulse-on")) { + nmsData._pulseElement.classList.remove("pulse-on"); + } else { + nmsData._pulseElement.classList.add("pulse-on"); + } + nmsData._pulseBeat = 0; + } + nmsData._pulseBeat++; +}; /* * Add a handler (callback) for a source, using an id. * * This is idempotent: if the id is the same, it will just overwrite the * old id, not add a copy. */ -nmsData.addHandler = function(name, id, cb, cbdata) { - var cbob = { - id: id, - name: name, - cb: cb, - fresh: true, - cbdata: cbdata - }; - if (id == undefined) { - return; - } - this._sources[name].cbs[id] = cbob; - this.updateSource(name); +nmsData.addHandler = function (name, id, cb, cbdata) { + var cbob = { + id: id, + name: name, + cb: cb, + fresh: true, + cbdata: cbdata, + }; + if (id == undefined) { + return; + } + this._sources[name].cbs[id] = cbob; + this.updateSource(name); }; /* @@ -179,14 +184,14 @@ nmsData.addHandler = function(name, id, cb, cbdata) { * Mainly used to avoid fini() functions in the map handlers. E.g.: just * reuse "mapHandler" as id. */ -nmsData.unregisterHandlerWildcard = function(id) { - for (var v in nmsData._sources) { - this.unregisterHandler(v, id); - } +nmsData.unregisterHandlerWildcard = function (id) { + for (var v in nmsData._sources) { + this.unregisterHandler(v, id); + } }; -nmsData.unregisterHandler = function(name, id) { - delete this._sources[name].cbs[id]; +nmsData.unregisterHandler = function (name, id) { + delete this._sources[name].cbs[id]; }; /* @@ -196,34 +201,34 @@ nmsData.unregisterHandler = function(name, id) { * known action that updates the underlying data (e.g: update comments * after a comment is posted). */ -nmsData.updateSource = function(name) { - /* - * See comment in nms.js nmsINIT(); - */ - if (name == "ticker" ) { - for (var i in nmsData._sources[name].cbs) { - var tmp = nmsData._sources[name].cbs[i]; - if (tmp.cb != undefined) { - tmp.cb(tmp.cbdata); - } - } - return; - } - this._genericUpdater(name, true); +nmsData.updateSource = function (name) { + /* + * See comment in nms.js nmsINIT(); + */ + if (name == "ticker") { + for (var i in nmsData._sources[name].cbs) { + var tmp = nmsData._sources[name].cbs[i]; + if (tmp.cb != undefined) { + tmp.cb(tmp.cbdata); + } + } + return; + } + this._genericUpdater(name, true); }; -nmsData.invalidate = function(name) { - this._genericUpdater(name, false); +nmsData.invalidate = function (name) { + this._genericUpdater(name, false); }; /* * Reset a source, deleting all data, including old. * * Useful if traveling in time, for example. */ -nmsData.resetSource = function(name) { - this[name] = {}; - this.old[name] = {}; - this.updateSource(name); +nmsData.resetSource = function (name) { + this[name] = {}; + this.old[name] = {}; + this.updateSource(name); }; /* @@ -233,77 +238,95 @@ nmsData.resetSource = function(name) { * Do not use this directly. Use updateSource(). * */ -nmsData._genericUpdater = function(name, cacheok) { - if (this.stats.outstandingAjaxRequests++ > this._ajaxThreshold) { - this.stats.outstandingAjaxRequests--; - this.stats.ajaxOverflow++; - return; - } - var now = ""; - if (this._now != undefined) - now = "now=" + this._now; - if (now != "") { - if (this._sources[name].target.match("\\?")) - now = "&" + now; - else - now = "?" + now; - } - var heads = {}; - if (cacheok == false) { - heads['Cache-Control'] = "max-age=0, no-cache, stale-while-revalidate=0"; - } +nmsData._genericUpdater = function (name, cacheok) { + if (this.stats.outstandingAjaxRequests++ > this._ajaxThreshold) { + this.stats.outstandingAjaxRequests--; + this.stats.ajaxOverflow++; + return; + } + var now = ""; + if (this._now != undefined) now = "now=" + this._now; + if (now != "") { + if (this._sources[name].target.match("\\?")) now = "&" + now; + else now = "?" + now; + } + + // TODO + var heads = {}; + if (cacheok == false) { + heads["Cache-Control"] = "max-age=0, no-cache, stale-while-revalidate=0"; + } + + /* + * + * We can be smarter than fetch here. We know that the ETag can be + * used to evaluate against our cached copy. If the ETag is a + * match, we never have to do the potentially extensive JSON + * parsing. + * + * Also note that we accept weakened ETags too (ETags with W/ + * prefixed). This is typically if the intermediate cache has + * compressed the content for us, so this is fine. DO WE? + * + * This is particularly important because we poll everything even + * though we _know_ it will hit both browser cache and most likely + * Varnish. JSON.Parse was one of the biggest CPU hogs before this. + */ + + const request = new Request(this._sources[name].target + now, { + method: "GET", + headers: { "Content-Type": "application/json", "If-None-Match": nmsData[name] != undefined ? nmsData[name]["hash"] : null }, + signal: AbortSignal.timeout(2000), // 2s timeout + }); - /* - * Note that we intentionally set dataType: "text" here. - * - * We can be smarter than jQuery here. We know that the ETag can be - * used to evaluate against our cached copy. If the ETag is a - * match, we never have to do the potentially extensive JSON - * parsing. - * - * Also note that we accept weakened ETags too (ETags with W/ - * prefixed). This is typically if the intermediate cache has - * compressed the content for us, so this is fine. - * - * This is particularly important because we poll everything even - * though we _know_ it will hit both browser cache and most likely - * Varnish. JSON.Parse was one of the biggest CPU hogs before this. - */ - $.ajax({ - type: "GET", - headers: heads, - url: this._sources[name].target + now, - dataType: "text", - success: function (indata, textStatus, jqXHR) { - var etag = jqXHR.getResponseHeader("ETag"); - if (nmsData[name] == undefined || (nmsData[name]['hash'] != etag && nmsData[name]['hash'] != etag.slice(2))) { - var data = JSON.parse(indata); - if (name == "ping") { - nmsData._last = data['time']; - nmsMap.drawNow(); - } - nmsData.old[name] = nmsData[name]; - nmsData[name] = data; - for (var i in nmsData._sources[name].cbs) { - var tmp2 = nmsData._sources[name].cbs[i]; - if (tmp2.cb != undefined) { - tmp2.cb(tmp2.cbdata); - } - } - } else { - for (var j in nmsData._sources[name].cbs) { - var tmp = nmsData._sources[name].cbs[j]; - if (tmp.cb != undefined && tmp.fresh) { - nmsData._sources[name].cbs[j].fresh = false; - tmp.cb(tmp.cbdata); - } - } - nmsData.stats.identicalFetches++; - } - nmsData._pulse(); - }, - complete: function(jqXHR, textStatus) { - nmsData.stats.outstandingAjaxRequests--; - } - }); + nmsData.stats.allRequests++; + fetch(request) + .then((r) => { + nmsData.stats.allFetches++; + if (!r.ok && r.status != 304) { + throw new Error("Fetch failed with status: " + r.status); + } + var etag = r.headers.get("etag"); + if ( + r.status != 304 && ( + etag == null || + nmsData[name] == undefined || + (nmsData[name]["hash"] != etag && + nmsData[name]["hash"] != etag.slice(2)) + ) + ) { + r.json().then((data) => { + nmsData.stats.jsonParse++; + if (name == "ping") { + nmsData._last = data["time"]; + nmsMap.drawNow(); + } + nmsData.old[name] = nmsData[name]; + nmsData[name] = data; + for (var i in nmsData._sources[name].cbs) { + var tmp2 = nmsData._sources[name].cbs[i]; + if (tmp2.cb != undefined) { + tmp2.cb(tmp2.cbdata); + } + } + }); + } else { + for (var j in nmsData._sources[name].cbs) { + var tmp = nmsData._sources[name].cbs[j]; + if (tmp.cb != undefined && tmp.fresh) { + nmsData._sources[name].cbs[j].fresh = false; + tmp.cb(tmp.cbdata); + } + } + nmsData.stats.identicalFetches++; + } + }) + .catch((err) => { + nmsData.stats.failedFetches++; + console.log("(" + name + "): " + err); + }) + .finally(() => { + nmsData._pulse(); + nmsData.stats.outstandingAjaxRequests--; + }); }; diff --git a/web/js/nms-dhcp.js b/web/js/nms-dhcp.js index dd2e96d..2c91a38 100644 --- a/web/js/nms-dhcp.js +++ b/web/js/nms-dhcp.js @@ -1,26 +1,27 @@ "use strict"; -var nmsDhcp = nmsDhcp || { +var nmsDhcp = nmsDhcp || {}; -} +nmsDhcp.init = function () { + //nmsData.addHandler("dhcpsummary", "nmsDhcpHandler", nmsDhcp.updateSummary); +}; -nmsDhcp.init = function() { - nmsData.addHandler("dhcpsummary", "nmsDhcpHandler", nmsDhcp.updateSummary); -} - -nmsDhcp.updateSummary = function() { - var e = document.getElementById("dhcp-summary"); - if (e == undefined) { - return; - } - e.innerHTML = ""; - if(nmsData.dhcpsummary.dhcp[4] != undefined){ - e.innerHTML = e.innerHTML + nmsData.dhcpsummary.dhcp[4] + " IPv4 clients"; - } - if(nmsData.dhcpsummary.dhcp[4] != undefined && nmsData.dhcpsummary.dhcp[6] != undefined){ - e.innerHTML = e.innerHTML + " | "; - } - if(nmsData.dhcpsummary.dhcp[6] != undefined){ - e.innerHTML = e.innerHTML + nmsData.dhcpsummary.dhcp[6] + " IPv6 clients"; - } -} +nmsDhcp.updateSummary = function () { + var e = document.getElementById("dhcp-summary"); + if (e == undefined) { + return; + } + e.innerHTML = ""; + if (nmsData.dhcpsummary.dhcp[4] != undefined) { + e.innerHTML = e.innerHTML + nmsData.dhcpsummary.dhcp[4] + " IPv4 clients"; + } + if ( + nmsData.dhcpsummary.dhcp[4] != undefined && + nmsData.dhcpsummary.dhcp[6] != undefined + ) { + e.innerHTML = e.innerHTML + " | "; + } + if (nmsData.dhcpsummary.dhcp[6] != undefined) { + e.innerHTML = e.innerHTML + nmsData.dhcpsummary.dhcp[6] + " IPv6 clients"; + } +}; diff --git a/web/js/nms-draw-chart.js b/web/js/nms-draw-chart.js index 4145a9a..2139992 100644 --- a/web/js/nms-draw-chart.js +++ b/web/js/nms-draw-chart.js @@ -1,81 +1,92 @@ "use strict"; function setNightModeChart(night) { - if(night) { + if (night) { Chart.defaults.global.defaultFontColor = "#fff"; - Chart.defaults.scale.gridLines.color = "#444" - } - else { + Chart.defaults.scale.gridLines.color = "#444"; + } else { Chart.defaults.global.defaultFontColor = "#222"; - Chart.defaults.scale.gridLines.color = "#ddd" + Chart.defaults.scale.gridLines.color = "#ddd"; } } function drawLatency(canvas, sw, chart, callback) { - var q = encodeURIComponent('SELECT mean("latency") AS "mean_latency" FROM "ping" WHERE time > now() - 1h AND "switch"=\''+sw+'\' GROUP BY time(60s), "version" fill(null)'); + var q = encodeURIComponent( + 'SELECT mean("latency") AS "mean_latency" FROM "ping" WHERE time > now() - 1h AND "switch"=\'' + + sw + + '\' GROUP BY time(60s), "version" fill(null)' + ); var dataset = []; - $.getJSON( "/query?db=gondul&q="+q, function( results ) { + $.getJSON("/query?db=gondul&q=" + q, function (results) { try { - results['results'][0]['series'].forEach(function(serie) { + results["results"][0]["series"].forEach(function (serie) { var data = []; - serie['values'].forEach(function(element) { - data.push({t: new Date(element[0]), y: element[1]}); + serie["values"].forEach(function (element) { + data.push({ t: new Date(element[0]), y: element[1] }); }); var borderColor = "rgba(0,155,200,255)"; - if(serie['tags']['version'] === "v6") { + if (serie["tags"]["version"] === "v6") { borderColor = "rgba(100,155,100,255)"; } - dataset.push({data: data, fill:false, borderColor:borderColor, label:serie['tags']['version'] }); + dataset.push({ + data: data, + fill: false, + borderColor: borderColor, + label: serie["tags"]["version"], + }); }); - if(chart != false) { + if (chart != false) { chart.data.datasets = dataset; chart.update(); return; } - var ctx = document.getElementById(canvas).getContext('2d'); + var ctx = document.getElementById(canvas).getContext("2d"); var myChart = new Chart(ctx, { - type: 'line', + type: "line", data: { - datasets: dataset + datasets: dataset, }, options: { legend: { - display: false + display: false, }, scales: { - xAxes:[{ - type: 'time', - time: { - parser: "HH:mm", - unit: 'minute', - tooltipFormat: 'HH:mm', - displayFormats: { - 'minute': 'HH:mm', - 'hour': 'HH:mm', - min: '00:00', - max: '23:59' + xAxes: [ + { + type: "time", + time: { + parser: "HH:mm", + unit: "minute", + tooltipFormat: "HH:mm", + displayFormats: { + minute: "HH:mm", + hour: "HH:mm", + min: "00:00", + max: "23:59", + }, }, - } - }], - yAxes: [{ - ticks: { - beginAtZero: true - } - }] + }, + ], + yAxes: [ + { + ticks: { + beginAtZero: true, + }, + }, + ], }, responsive: true, animation: false, elements: { line: { - tension: 0.05 - } - } - } + tension: 0.05, + }, + }, + }, }); - } catch(e) { - } - if(callback != undefined) { + } catch (e) {} + if (callback != undefined) { callback(myChart); } }); @@ -87,29 +98,33 @@ function drawSumOfPorts(canvas, sw) { var gigabit = megabit * 1024; var terabit = gigabit * 1024; - var q = encodeURIComponent('SELECT non_negative_derivative(first("ifHCInOctets"), 1s) * 8 AS "ifHCInOctets", non_negative_derivative(first("ifHCOutOctets"), 1s) * 8 AS "ifHCOutOctets" FROM "ports" WHERE time > now() - 30m AND "switch"=\''+sw+'\' GROUP BY time(90s),"interface" fill(null)'); + var q = encodeURIComponent( + 'SELECT non_negative_derivative(first("ifHCInOctets"), 1s) * 8 AS "ifHCInOctets", non_negative_derivative(first("ifHCOutOctets"), 1s) * 8 AS "ifHCOutOctets" FROM "ports" WHERE time > now() - 30m AND "switch"=\'' + + sw + + '\' GROUP BY time(90s),"interface" fill(null)' + ); var dataset = []; - $.getJSON( "/query?db=gondul&q="+q, function( results ) { + $.getJSON("/query?db=gondul&q=" + q, function (results) { var bits_in = []; var bits_out = []; - results['results'][0]['series'].forEach(function(serie) { + results["results"][0]["series"].forEach(function (serie) { // Bytes in - serie['values'].forEach(function(element) { + serie["values"].forEach(function (element) { bits_in.push(element[1]); }); // Bytes out - serie['values'].forEach(function(element) { + serie["values"].forEach(function (element) { bits_out.push(element[2]); }); }); - var bits_in_size = bitToSize(Math.max.apply( Math, bits_in )); - var bits_out_size = bitToSize(Math.max.apply( Math, bits_out )); + var bits_in_size = bitToSize(Math.max.apply(Math, bits_in)); + var bits_out_size = bitToSize(Math.max.apply(Math, bits_out)); var size = 0; - if(bits_in_size >= bits_out_size) { + if (bits_in_size >= bits_out_size) { size = bits_in_size; } else { size = bits_out_size; @@ -133,107 +148,126 @@ function drawSumOfPorts(canvas, sw) { size_divider = terabit; break; } - results['results'][0]['series'].forEach(function(serie) { + results["results"][0]["series"].forEach(function (serie) { // Bytes in var data = []; - serie['values'].forEach(function(element) { - data.push({t: new Date(element[0]), y: element[1] / size_divider }); + serie["values"].forEach(function (element) { + data.push({ t: new Date(element[0]), y: element[1] / size_divider }); + }); + dataset.push({ + data: data, + backgroundColor: "rgba(58,125,48,200)", + label: "Traffic in (" + sizeToText(size) + ")", }); - dataset.push({data: data, backgroundColor:'rgba(58,125,48,200)', label:'Traffic in (' + sizeToText(size)+')'}); // Bytes out data = []; - serie['values'].forEach(function(element) { - data.push({t: new Date(element[0]), y: -Math.abs(element[2] / size_divider) }); + serie["values"].forEach(function (element) { + data.push({ + t: new Date(element[0]), + y: -Math.abs(element[2] / size_divider), + }); + }); + dataset.push({ + data: data, + backgroundColor: "rgba(84,84,142,225)", + label: "Traffic out (" + sizeToText(size) + ")", }); - dataset.push({data: data, backgroundColor:'rgba(84,84,142,225)', label:'Traffic out (' + sizeToText(size)+')'}); }); // Draw the chart - var ctx = document.getElementById(canvas).getContext('2d'); + var ctx = document.getElementById(canvas).getContext("2d"); var myChart = new Chart(ctx, { - type: 'line', + type: "line", data: { - datasets: dataset + datasets: dataset, }, options: { legend: { - display: false + display: false, }, scales: { - xAxes:[{ - type: 'time', - time: { - parser: "HH:mm", - unit: 'minute', - tooltipFormat: 'HH:mm', - displayFormats: { - 'minute': 'HH:mm', - 'hour': 'HH:mm', - min: '00:00', - max: '23:59' + xAxes: [ + { + type: "time", + time: { + parser: "HH:mm", + unit: "minute", + tooltipFormat: "HH:mm", + displayFormats: { + minute: "HH:mm", + hour: "HH:mm", + min: "00:00", + max: "23:59", + }, + }, + }, + ], + yAxes: [ + { + stacked: true, + ticks: { + callback: function (label, index, labels) { + return Math.abs(label) + " " + sizeToText(size); + }, + }, + scaleLabel: { + display: true, + labelString: sw + " - All ports", }, - } - }], - yAxes: [{ - stacked: true, - ticks: { - callback: function(label, index, labels) { - return Math.abs(label)+' '+sizeToText(size); - } }, - scaleLabel: { - display: true, - labelString: sw+' - All ports' - } - }] + ], }, responsive: true, animation: false, elements: { point: { - radius: 0 + radius: 0, }, line: { - tension: 0 - } - } - } + tension: 0, + }, + }, + }, }); }); } - function drawPort(canvas, sw, port) { - var kilobit = 1024; var megabit = kilobit * 1024; var gigabit = megabit * 1024; var terabit = gigabit * 1024; - var q = encodeURIComponent('SELECT non_negative_derivative(first("ifHCInOctets"), 1s) * 8 AS "ifHCInOctets", non_negative_derivative(first("ifHCOutOctets"), 1s) * 8 AS "ifHCOutOctets" FROM "ports" WHERE time > now() - 30m AND "switch"=\''+sw+'\' AND "interface"=\''+port+'\' GROUP BY time(30s) fill(null)'); + var q = encodeURIComponent( + 'SELECT non_negative_derivative(first("ifHCInOctets"), 1s) * 8 AS "ifHCInOctets", non_negative_derivative(first("ifHCOutOctets"), 1s) * 8 AS "ifHCOutOctets" FROM "ports" WHERE time > now() - 30m AND "switch"=\'' + + sw + + "' AND \"interface\"='" + + port + + "' GROUP BY time(30s) fill(null)" + ); var dataset = []; - $.getJSON( "/query?db=gondul&q="+q, function( results ) { - var serie = results['results'][0]['series'][0]; + $.getJSON("/query?db=gondul&q=" + q, function (results) { + var serie = results["results"][0]["series"][0]; var bits_in = []; var bits_out = []; // Bytes in - serie['values'].forEach(function(element) { + serie["values"].forEach(function (element) { bits_in.push(element[1]); }); // Bytes out - serie['values'].forEach(function(element) { + serie["values"].forEach(function (element) { bits_out.push(element[2]); }); - var bits_in_size = bitToSize(Math.max.apply( Math, bits_in )); - var bits_out_size = bitToSize(Math.max.apply( Math, bits_out )); + var bits_in_size = bitToSize(Math.max.apply(Math, bits_in)); + var bits_out_size = bitToSize(Math.max.apply(Math, bits_out)); var size = 0; - if(bits_in_size >= bits_out_size) { + if (bits_in_size >= bits_out_size) { size = bits_in_size; } else { size = bits_out_size; @@ -260,107 +294,115 @@ function drawPort(canvas, sw, port) { // Bytes in var data = []; - serie['values'].forEach(function(element) { - data.push({t: new Date(element[0]), y: element[1] / size_divider }); + serie["values"].forEach(function (element) { + data.push({ t: new Date(element[0]), y: element[1] / size_divider }); + }); + dataset.push({ + data: data, + backgroundColor: "rgba(58,125,48,200)", + label: "Traffic in (" + sizeToText(size) + ")", }); - dataset.push({data: data, backgroundColor:'rgba(58,125,48,200)', label:'Traffic in (' + sizeToText(size)+')'}); // Bytes out data = []; - serie['values'].forEach(function(element) { - data.push({t: new Date(element[0]), y: -Math.abs(element[2] / size_divider) }); + serie["values"].forEach(function (element) { + data.push({ + t: new Date(element[0]), + y: -Math.abs(element[2] / size_divider), + }); + }); + dataset.push({ + data: data, + backgroundColor: "rgba(84,84,142,225)", + label: "Traffic out (" + sizeToText(size) + ")", }); - dataset.push({data: data, backgroundColor:'rgba(84,84,142,225)', label:'Traffic out (' + sizeToText(size)+')'}); - // Draw the chart - var ctx = document.getElementById(canvas).getContext('2d'); + var ctx = document.getElementById(canvas).getContext("2d"); var myChart = new Chart(ctx, { - type: 'line', + type: "line", data: { - datasets: dataset + datasets: dataset, }, options: { scales: { - xAxes:[{ - type: 'time', - time: { - parser: "HH:mm", - unit: 'minute', - tooltipFormat: 'HH:mm', - displayFormats: { - 'minute': 'HH:mm', - 'hour': 'HH:mm', - min: '00:00', - max: '23:59' + xAxes: [ + { + type: "time", + time: { + parser: "HH:mm", + unit: "minute", + tooltipFormat: "HH:mm", + displayFormats: { + minute: "HH:mm", + hour: "HH:mm", + min: "00:00", + max: "23:59", + }, + }, + }, + ], + yAxes: [ + { + ticks: { + callback: function (label, index, labels) { + return Math.abs(label) + " " + sizeToText(size); + }, + }, + scaleLabel: { + display: true, + labelString: sw + " - " + port, }, - } - }], - yAxes: [{ - ticks: { - callback: function(label, index, labels) { - return Math.abs(label)+' '+sizeToText(size); - } }, - scaleLabel: { - display: true, - labelString: sw+' - '+port - } - }] + ], }, responsive: true, animation: false, elements: { line: { - tension: 0 - } - } - - } + tension: 0, + }, + }, + }, }); }); } - function bitToSize(bits) { var kilobit = 1024; var megabit = kilobit * 1024; var gigabit = megabit * 1024; var terabit = gigabit * 1024; - if(bits >= 0 && bits < kilobit) { + if (bits >= 0 && bits < kilobit) { return 0; - } - else if(bits >= kilobit && bits < megabit){ + } else if (bits >= kilobit && bits < megabit) { return 1; - } - else if(bits >= megabit && bits < gigabit){ + } else if (bits >= megabit && bits < gigabit) { return 2; - } - else if(bits >= gigabit && bits < terabit){ + } else if (bits >= gigabit && bits < terabit) { return 3; - } - else if(bits >= terabit) { + } else if (bits >= terabit) { return 4; } } function sizeToText(size) { - switch(size) { + switch (size) { case 0: - return 'bit/s'; + return "bit/s"; break; case 1: - return 'Kb/s'; + return "Kb/s"; break; case 2: - return 'Mb/s'; + return "Mb/s"; break; case 3: - return 'Gb/s'; + return "Gb/s"; break; case 4: - return 'Tb/s'; + return "Tb/s"; break; } } diff --git a/web/js/nms-fetch.js b/web/js/nms-fetch.js new file mode 100644 index 0000000..da2162c --- /dev/null +++ b/web/js/nms-fetch.js @@ -0,0 +1,38 @@ +async function getData(url) { + var data; + const request = new Request(url, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + + await fetch(request) + .then((response) => response.json()) + .then((json) => { + data = json; + }) + .catch(console.error); + + return data; +} + +async function postData(url, data) { + var data; + const request = new Request(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data) + }); + + await fetch(request) + .then((response) => response.json()) + .then((json) => { + data = json; + }) + .catch(console.error); + + return data; +} diff --git a/web/js/nms-info-box.js b/web/js/nms-info-box.js index 1a15e6c..f79fc7a 100644 --- a/web/js/nms-info-box.js +++ b/web/js/nms-info-box.js @@ -29,220 +29,224 @@ * Basic configuration */ var nmsInfoBox = nmsInfoBox || { - stats: {}, - _container: false, //Container window - _windowHandler: false, //Window handler - _sw: false, //Name of last switch opened, used for toggle-click - _windowTypes: [ - { - 'id': 'switchInfo', - 'title': 'Switch info', - 'views': { - 'initial': { - 'name': 'Summary', - 'panels': ['switchLatency','switchSummary','switchComments'], - 'public': true - }, - 'ports': { - 'name': 'Ports', - 'panels': ['switchPorts'] - }, - 'misc': { - 'name': 'SNMP', - 'panels': ['switchSNMP:misc'] - }, - 'links': { - 'name': 'Links', - 'panels': ['switchLinks'] - }, - 'edit': { - 'name': 'Edit settings', - 'panels': ['switchEdit'] - } - } - }, - { - 'id': 'networkInfo', - 'title': 'Network info', - 'views': { - 'initial': { - 'name': 'Summary', - 'panels': ['networkSummary'] - }, - 'edit': { - 'name': 'Edit settings', - 'panels': ['networkEdit'] - } - } - }, - { - 'id': 'addSwitch', - 'title': 'Add new switch(es)', - 'views': { - 'initial': { - 'name': 'Add switch', - 'panels': ['switchAdd'] - } - } - }, - { - 'id': 'addNetwork', - 'title': 'Add new network(s)', - 'views': { - 'initial': { - 'name': 'Add network', - 'panels': ['networkAdd'] - } - } - }, - { - 'id': 'searchHelp', - 'title': 'Search help', - 'views': { - 'initial': { - 'name': 'Search help', - 'panels': ['searchHelp'] - } - } - }, - { - 'id': 'searchResults', - 'title': 'Search Results', - 'views': { - 'initial': { - 'name': 'Search Results', - 'panels': ['searchResults'] - } - } - }, - { - 'id': 'listNetwork', - 'title': 'Networks', - 'views': { - 'initial': { - 'name': 'List all networks', - 'panels': ['listNetworks'] - } - } - }, -], - _panelTypes: {} //Populate by using the nmsInfoBox.addPanelType method + stats: {}, + _container: false, //Container window + _windowHandler: false, //Window handler + _sw: false, //Name of last switch opened, used for toggle-click + _windowTypes: [ + { + id: "switchInfo", + title: "Switch info", + views: { + initial: { + name: "Summary", + panels: ["switchLatency", "switchSummary", "switchLinks", "switchComments"], + public: true, + }, + ports: { + name: "Ports", + panels: ["switchPorts"], + }, + misc: { + name: "SNMP", + panels: ["switchSNMP:misc"], + }, + edit: { + name: "Settings", + panels: ["switchEdit"], + }, + }, + }, + { + id: "networkInfo", + title: "Network info", + views: { + initial: { + name: "Summary", + panels: ["networkSummary"], + }, + edit: { + name: "Settings", + panels: ["networkEdit"], + }, + }, + }, + { + id: "addSwitch", + title: "Add new switch(es)", + views: { + initial: { + name: "Add switch", + panels: ["switchAdd"], + }, + }, + }, + { + id: "addNetwork", + title: "Add new network(s)", + views: { + initial: { + name: "Add network", + panels: ["networkAdd"], + }, + }, + }, + { + id: "searchHelp", + title: "Search help", + views: { + initial: { + name: "Search help", + panels: ["searchHelp"], + }, + }, + }, + { + id: "searchResults", + title: "Search Results", + views: { + initial: { + name: "Search Results", + panels: ["searchResults"], + }, + }, + }, + { + id: "listNetwork", + title: "Networks", + views: { + initial: { + name: "List all networks", + panels: ["listNetworks"], + }, + }, + }, + { + id: "debug", + title: "Debug", + views: { + initial: { + name: "Debug", + panels: ["debugInfo"], + }, + stats: { + name: "Stats", + panels: ["debugStats"], + }, + }, + }, + ], + _panelTypes: {}, //Populate by using the nmsInfoBox.addPanelType method }; /* * Shows a window, and triggers initial load if needed */ -nmsInfoBox.showWindow = function (windowName,argument) { - if(windowName == "switchInfo" && argument != '' && argument == this._sw) { - nmsInfoBox.hide(); - return; - } - - if(!this._container) - this._load(); - if(!windowName) - windowName = 'switchInfo'; - - this._sw = argument; - - this._windowHandler.showWindow(windowName,argument) - - $(this._windowHandler.getTitleObj()).on('mousedown', function(e) { - var cont = $(nmsInfoBox._container); - var dimensions = nmsInfoBox._container.getBoundingClientRect(); - var startLeft = dimensions.left; - var startTop = dimensions.top; - nmsInfoBox.startDrag(e.screenX, e.screenY, startLeft, startTop); - }); - $(this._windowHandler.getTitleObj()).on('mouseup',nmsInfoBox.stopDrag); +nmsInfoBox.showWindow = function (windowName, argument) { + if (windowName == "switchInfo" && argument != "" && argument == this._sw) { + nmsInfoBox.hide(); + return; + } + + if (!this._container) this._load(); + if (!windowName) windowName = "switchInfo"; + + this._sw = argument; + + this._windowHandler.showWindow(windowName, argument); }; /* * Internal function to load and register the initial html objects */ -nmsInfoBox._load = function() { - var infoBox = document.createElement("div"); - infoBox.classList.add("panel", "panel-default"); - var title = document.createElement("div"); - title.id = "info-box-title"; - title.classList.add("panel-heading"); - var nav = document.createElement("div"); - nav.id = "info-box-nav"; - nav.classList.add("panel-body"); - var body = document.createElement("div"); - body.id = "info-box-body"; - body.classList.add("panel-body"); - - infoBox.appendChild(title); - infoBox.appendChild(nav); - infoBox.appendChild(body); - - this._container = document.getElementById("info-box-container"); - this._container.appendChild(infoBox); - - this._windowHandler = new windowHandler(); - this._windowHandler.setContainerObj(document.getElementById("info-box-container")); - this._windowHandler.setTitleObj(document.getElementById("info-box-title")); - this._windowHandler.setBodyObj(document.getElementById("info-box-body")); - this._windowHandler.setNavObj(document.getElementById("info-box-nav")); - this._windowHandler.setPanelTypes(this._panelTypes); - this._windowHandler.setWindowTypes(this._windowTypes); +nmsInfoBox._load = function () { + var modalBox = document.createElement("div"); + modalBox.classList.add("modal", "show"); + modalBox.style = "display: block;"; + // did not work + // modalBox.setAttribute('data-bs-backdrop', "false"); + + var dialogBox = document.createElement("div"); + dialogBox.classList.add( + "modal-dialog", + "modal-lg", + "modal-dialog-scrollable" + ); + + var dialogContentBox = document.createElement("div"); + dialogContentBox.classList.add("modal-content"); + + var dialogHeader = document.createElement("div"); + dialogHeader.classList.add("modal-header"); + + modalBox.appendChild(dialogBox); + + dialogBox.appendChild(dialogContentBox); + + var title = document.createElement("div"); + title.id = "info-box-title"; + title.classList.add("modal-title"); + + var nav = document.createElement("div"); + nav.id = "info-box-nav"; + + var body = document.createElement("div"); + body.id = "info-box-body"; + body.classList.add("modal-body"); + + var closeButton = document.createElement("button"); + // <button type="button" class="btn-close" data-bs-dismiss="modal" data-bs-target="#my-modal" aria-label="Close"></button> + closeButton.classList.add("btn-close"); + closeButton.onclick = function () { + nmsInfoBox.hide(); + }; + + dialogContentBox.appendChild(dialogHeader); + dialogContentBox.appendChild(body); + dialogHeader.appendChild(title); + dialogHeader.appendChild(nav); + dialogHeader.appendChild(closeButton); + + this._container = document.getElementById("info-box-container"); + this._container.appendChild(modalBox); + + this._windowHandler = new windowHandler(); + this._windowHandler.setContainerObj( + document.getElementById("info-box-container") + ); + this._windowHandler.setTitleObj(document.getElementById("info-box-title")); + this._windowHandler.setBodyObj(document.getElementById("info-box-body")); + this._windowHandler.setNavObj(document.getElementById("info-box-nav")); + this._windowHandler.setPanelTypes(this._panelTypes); + this._windowHandler.setWindowTypes(this._windowTypes); }; /* * Adds a panel type to _panelTypes for usage in windows and views */ nmsInfoBox.addPanelType = function (id, obj) { - this._panelTypes[id] = obj; + this._panelTypes[id] = obj; }; - /* * Hide the active window and tell it to unload */ -nmsInfoBox.hide = function() { - this._sw = false; - if (this._windowHandler != undefined && this._windowHandler.hide != undefined) { - this._windowHandler.hide(); - this._windowHandler.unloadWindow(); - } - nmsInfoBox.resetDrag(); -}; - -/* - * Start window drag - */ -nmsInfoBox.startDrag = function(mouseStartX, mouseStartY, startLeft, startTop) { - document.onmousemove = function(e) { - var mouseOffsetX = e.screenX - mouseStartX; - var mouseOffsetY = e.screenY - mouseStartY; - $(nmsInfoBox._container).css('left', startLeft + mouseOffsetX + 'px'); - $(nmsInfoBox._container).css('top', startTop + mouseOffsetY + 'px'); - }; -}; - -/* - * Reset drag - */ -nmsInfoBox.resetDrag = function() { - nmsInfoBox.stopDrag(); - $(nmsInfoBox._container).css('left',''); - $(nmsInfoBox._container).css('top',''); -}; - -/* - * Stop window drag - */ -nmsInfoBox.stopDrag = function() { - document.onmousemove = null; +nmsInfoBox.hide = function () { + this._sw = false; + if ( + this._windowHandler != undefined && + this._windowHandler.hide != undefined + ) { + this._windowHandler.hide(); + this._windowHandler.unloadWindow(); + } }; /* * Click a switch and display it. */ -nmsInfoBox.click = function(sw) -{ - this.showWindow("switchInfo",sw); +nmsInfoBox.click = function (sw) { + this.showWindow("switchInfo", sw); }; /* @@ -262,159 +266,163 @@ nmsInfoBox.click = function(sw) * */ var windowHandler = function () { - this.containerObj = false; - this.titleObj = false; - this.navObj = false; - this.bodyObj = false; - this._panels = {}; - this._view = ""; - this._viewId = {}; - this._window = {}; - this.windowTypes = false; - this.panelTypes = false; - this.argument = false; - this.show = function () { - this.containerObj.classList.remove("hidden"); - }; - this.hide = function () { - this.containerObj.classList.add("hidden"); - }; - this.setContainerObj = function (containerObj) { - this.containerObj = containerObj; - }; - this.setTitleObj = function (titleObj) { - this.titleObj = titleObj; - }; - this.getTitleObj = function (titleObj) { - return this.titleObj; - }; - this.setNavObj = function (navObj) { - this.navObj = navObj; - }; - this.setBodyObj = function (bodyObj) { - this.bodyObj = bodyObj; - }; - this.setPanelTypes = function (panelTypes) { - this.panelTypes = panelTypes; - }; - this.setWindowTypes = function (windowTypes) { - this.windowTypes = {}; - for(var i in windowTypes) { - this.windowTypes[windowTypes[i].id] = windowTypes[i]; - } - }; - this.setArgument = function (argument) { - if(this.argument != argument) { - this.argument = argument; - this.showView(this._view); - } - }; - this.showPanel = function (panelName) { - var panelArray = panelName.split(":"); - var panelName = panelArray[0]; - var panelMode = panelArray[1]; - if(this.panelTypes[panelName]) { - var id = (Math.random().toString(36)+'00000000000000000').slice(2, 10+2); - var panel = new this.panelTypes[panelName]; - panel.setId(id); - if(!!panelMode) - panel.setMode(panelMode); - panel.load(this.bodyObj,this.argument); - this._panels[id] = panel; - } - }; - this.showTitle = function (title) { - this.titleObj.innerHTML = '<button type="button" class="close" aria-label="Close" onclick="nmsInfoBox.hide();" style="float: right;"><span aria-hidden="true">×</span></button><h4>' + title + '</h4>'; - }; - this.showNav = function () { - if(!this._window.views) - this.navObj.innerHTML = ''; - var output = '<ul class="nav nav-pills small">'; - var i = 0; - for(var view in this._window.views) { - var viewObj = this._window.views[view]; - var active = ''; - if (viewObj.public == null || viewObj.public == false) - active = ' class="gondul-is-private" ' - if(this._view == view) - active = ' class="active" '; - output += '<li' + active + '><a class="' + view + '" aria-label="' + viewObj.name + '" onclick="nmsInfoBox._windowHandler.showView(\'' + view + '\');">' + viewObj.name + '</a></li> '; - i++; - } - output += '</ul>'; - if(i < 2) { - this.navObj.innerHTML = ''; - } else { - this.navObj.innerHTML = output; - } - }; - this.addWindow = function (windowObj) { - this.windowTypes[windowObj.id] = windowObj; - }; - this.showWindow = function (windowName,argument) { - if(!this.windowTypes[windowName]) - return; - this.unloadWindow(); - this.argument = argument; - this._window = this.windowTypes[windowName]; - this.showTitle(this._window.title + " " + (argument ? argument : "")); - this.showView(); - this.show(); - }; - this.showView = function (viewId) { - if(!viewId || viewId == '') { - if (this._viewId[this._window.id] == undefined) - viewId = "initial"; - else - viewId = this._viewId[this._window.id]; - } else { - this._viewId[this._window.id] = viewId; - } - if(!this._window.views || !this._window.views[viewId]) - return; - this.unloadView(); - for(var panel in this._window.views[viewId].panels) { - this.showPanel(this._window.views[viewId].panels[panel]); - } - this._view = viewId; - this.showNav(); - }; - this.removePanel = function (panelId) { - if(!!panelId) - this.unloadPanel(panelId); - }; - this.unloadView = function () { - this.unloadPanel(); - }; - this.unloadWindow = function() { - this.hide(); - this.unloadPanel(); - }; - this.unloadPanel = function (panelId) { - if(!panelId) { - for(var i in this._panels) { - this._panels[i].unload(); - } - this._panels = {}; - } else { - try { - this._panels[panelId].unload(); - } catch (e) {} - delete this._panels[panelId]; - } - }; - //Method for triggering a function in an active panel - this.doInPanel = function (panelId, action, argument) { - if(!this._panels[panelId]) - return; - if(typeof this._panels[panelId][action] === "function") { - if(!argument) { - this._panels[panelId][action](); - } else { - this._panels[panelId][action](argument); - } - } - }; + this.containerObj = false; + this.titleObj = false; + this.navObj = false; + this.bodyObj = false; + this._panels = {}; + this._view = ""; + this._viewId = {}; + this._window = {}; + this.windowTypes = false; + this.panelTypes = false; + this.argument = false; + this.show = function () { + this.containerObj.classList.remove("d-none"); + }; + this.hide = function () { + this.containerObj.classList.add("d-none"); + }; + this.setContainerObj = function (containerObj) { + this.containerObj = containerObj; + }; + this.setTitleObj = function (titleObj) { + this.titleObj = titleObj; + }; + this.getTitleObj = function (titleObj) { + return this.titleObj; + }; + this.setNavObj = function (navObj) { + this.navObj = navObj; + }; + this.setBodyObj = function (bodyObj) { + this.bodyObj = bodyObj; + }; + this.setPanelTypes = function (panelTypes) { + this.panelTypes = panelTypes; + }; + this.setWindowTypes = function (windowTypes) { + this.windowTypes = {}; + for (var i in windowTypes) { + this.windowTypes[windowTypes[i].id] = windowTypes[i]; + } + }; + this.setArgument = function (argument) { + if (this.argument != argument) { + this.argument = argument; + this.showView(this._view); + } + }; + this.showPanel = function (panelName) { + var panelArray = panelName.split(":"); + var panelName = panelArray[0]; + var panelMode = panelArray[1]; + if (this.panelTypes[panelName]) { + var id = (Math.random().toString(36) + "00000000000000000").slice( + 2, + 10 + 2 + ); + var panel = new this.panelTypes[panelName](); + panel.setId(id); + if (!!panelMode) panel.setMode(panelMode); + panel.load(this.bodyObj, this.argument); + this._panels[id] = panel; + } + }; + this.showTitle = function (title) { + this.titleObj.innerHTML = '<h1 class="modal-title fs-4">' + title + "</h1>"; + }; + this.showNav = function () { + if (!this._window.views) this.navObj.innerHTML = ""; + var output = '<ul class="nav nav-tabs">'; + var i = 0; + for (var view in this._window.views) { + var viewObj = this._window.views[view]; + var active = '><a class="nav-link '; + if (this._view == view) { + active = '><a class="nav-link active '; + } + output += + "<li" + + ' class="nav-item gondul-is-private" ' + + active + + view + + '" aria-label="' + + viewObj.name + + '" onclick="nmsInfoBox._windowHandler.showView(\'' + + view + + "');\">" + + viewObj.name + + "</a></li> "; + i++; + } + if (i < 2) { + this.navObj.innerHTML = ""; + } else { + this.navObj.innerHTML = output; + } + }; + this.addWindow = function (windowObj) { + this.windowTypes[windowObj.id] = windowObj; + }; + this.showWindow = function (windowName, argument) { + if (!this.windowTypes[windowName]) return; + this.unloadWindow(); + this.argument = argument; + this._window = this.windowTypes[windowName]; + this.showTitle(this._window.title + " " + (argument ? argument : "")); + this.showView(); + this.show(); + }; + this.showView = function (viewId) { + if (!viewId || viewId == "") { + if (this._viewId[this._window.id] == undefined) viewId = "initial"; + else viewId = this._viewId[this._window.id]; + } else { + this._viewId[this._window.id] = viewId; + } + if (!this._window.views || !this._window.views[viewId]) return; + this.unloadView(); + for (var panel in this._window.views[viewId].panels) { + this.showPanel(this._window.views[viewId].panels[panel]); + } + this._view = viewId; + this.showNav(); + }; + this.removePanel = function (panelId) { + if (!!panelId) this.unloadPanel(panelId); + }; + this.unloadView = function () { + this.unloadPanel(); + }; + this.unloadWindow = function () { + this.hide(); + this.unloadPanel(); + }; + this.unloadPanel = function (panelId) { + if (!panelId) { + for (var i in this._panels) { + this._panels[i].unload(); + } + this._panels = {}; + } else { + try { + this._panels[panelId].unload(); + } catch (e) {} + delete this._panels[panelId]; + } + }; + //Method for triggering a function in an active panel + this.doInPanel = function (panelId, action, argument) { + if (!this._panels[panelId]) return; + if (typeof this._panels[panelId][action] === "function") { + if (!argument) { + this._panels[panelId][action](); + } else { + this._panels[panelId][action](argument); + } + } + }; }; /* @@ -432,122 +440,125 @@ var windowHandler = function () { * }; * */ -var nmsInfoPanel = function nmsInfoPanel(name,id) { - this.name = name; - this.id = id; - this.sw = false; - this.container = false; - this.classList = ['info-panel']; - this.me = false; - this.handlers = []; - this.mode = "initial"; - - if(!this.id) - this.id = (Math.random().toString(36)+'00000000000000000').slice(2, 10+2); - - //Method for loading the general panel properties - this.load = function (container,argument) { - this.container = container; - this.sw = argument; - this.me = document.createElement("div"); - this.me.id = this.id; - for(var i in this.classList) - this.me.classList.add(this.classList[i]); - this.container.appendChild(this.me); - this.init(argument); - }; - - //Method for making this specific panel-instance ready for first refresh - //Override in children when any custom init-functionality is needed - this.init = function (argument) { - this.refresh("init"); - }; - - //Methods for getting and setting panel id - this.setId = function (id) { - this.id = id; - }; - this.getId = function () { - return this.id; - }; - - //Methods for setting and getting mode (default "initial") - this.setMode = function (mode) { - this.mode = mode; - }; - this.getMode = function () { - return this.mode; - }; - - //Internal method for rendering content - this._render = function (newContent) { - if(!newContent || !this.me) - return; - this.me.innerHTML = newContent.outerHTML; - }; - - //Helper method for rendering error messages in a unified way - this._renderError = function (message) { - var error = document.createElement("div"); - error.className = "alert alert-info"; - error.innerHTML = message; - this._render(error); - }; - - //Method for unloading any local data - this.unload = function () { - if(!this.me) - return; - this.me.remove(); - this.removeHandlers(); - this.sw = false; - this.container = false; - this.me = false; - this.id = false; - }; - - //Method for loading new data and triggering a _render if needed - //Implemented in children only - this.refresh = function (reason) {}; - - //Methods for adding and removing classes - this.addClass = function (className) { - if(this.classList.indexOf(className) == -1) { - this.classList.push(className); - this.me.classList.add(className); - } - }; - this.removeClass = function (className) { - var index = this.classList.indexOf(className); - if(index != -1) { - this.classList.splice(index,1); - this.me.classList.remove(className); - } - }; - - //Method for registering a data handler (lets us clean them up later) - this.addHandler = function (dataType,targetFunction) { - if(!targetFunction) - targetFunction = "refresh"; - nmsData.addHandler(dataType,this.id,(this[targetFunction]).bind(this),"handler-"+dataType); - this.handlers.push(dataType); - }; - - //Method for removing all handlers we have registered - this.removeHandlers = function () { - for(var i in this.handlers) { - nmsData.unregisterHandler(this.handlers[i],this.id); - } - }; - - //Method for checking if we have handlers registered - this.hasHandler = function (dataType) { - for(var i in this.handlers) { - if(this.handlers[i] == dataType) - return true; - } - return false; - }; +var nmsInfoPanel = function nmsInfoPanel(name, id) { + this.name = name; + this.id = id; + this.sw = false; + this.container = false; + this.classList = ["info-panel"]; + this.me = false; + this.handlers = []; + this.mode = "initial"; + + if (!this.id) + this.id = (Math.random().toString(36) + "00000000000000000").slice( + 2, + 10 + 2 + ); + + //Method for loading the general panel properties + this.load = function (container, argument) { + this.container = container; + this.sw = argument; + this.me = document.createElement("div"); + this.me.id = this.id; + for (var i in this.classList) this.me.classList.add(this.classList[i]); + this.container.appendChild(this.me); + this.init(argument); + }; + + //Method for making this specific panel-instance ready for first refresh + //Override in children when any custom init-functionality is needed + this.init = function (argument) { + this.refresh("init"); + }; + + //Methods for getting and setting panel id + this.setId = function (id) { + this.id = id; + }; + this.getId = function () { + return this.id; + }; + + //Methods for setting and getting mode (default "initial") + this.setMode = function (mode) { + this.mode = mode; + }; + this.getMode = function () { + return this.mode; + }; + + //Internal method for rendering content + this._render = function (newContent) { + if (!newContent || !this.me) return; + this.me.innerHTML = newContent.outerHTML; + }; + + //Helper method for rendering error messages in a unified way + this._renderError = function (message) { + var error = document.createElement("div"); + error.className = "alert alert-info"; + error.innerHTML = message; + this._render(error); + }; + + //Method for unloading any local data + this.unload = function () { + if (!this.me) return; + this.me.remove(); + this.removeHandlers(); + this.sw = false; + this.container = false; + this.me = false; + this.id = false; + }; + + //Method for loading new data and triggering a _render if needed + //Implemented in children only + this.refresh = function (reason) {}; + + //Methods for adding and removing classes + this.addClass = function (className) { + if (this.classList.indexOf(className) == -1) { + this.classList.push(className); + this.me.classList.add(className); + } + }; + this.removeClass = function (className) { + var index = this.classList.indexOf(className); + if (index != -1) { + this.classList.splice(index, 1); + this.me.classList.remove(className); + } + }; + + //Method for registering a data handler (lets us clean them up later) + this.addHandler = function (dataType, targetFunction) { + if (!targetFunction) targetFunction = "refresh"; + nmsData.addHandler( + dataType, + this.id, + this[targetFunction].bind(this), + "handler-" + dataType + ); + this.handlers.push(dataType); + }; + + //Method for removing all handlers we have registered + this.removeHandlers = function () { + for (var i in this.handlers) { + nmsData.unregisterHandler(this.handlers[i], this.id); + } + }; + + //Method for checking if we have handlers registered + this.hasHandler = function (dataType) { + for (var i in this.handlers) { + if (this.handlers[i] == dataType) return true; + } + return false; + }; }; /* @@ -559,220 +570,228 @@ var nmsInfoPanel = function nmsInfoPanel(name,id) { * */ var switchSNMPPanel = function () { - nmsInfoPanel.call(this,"switchSNMP"); - this.init = function() { - this.refresh(); - }; - this.refresh = function(reason) { - var domObj = document.createElement("div"); - domObj.classList.add("panel-group"); - - try { - var snmpJson = nmsData.snmp.snmp[this.sw][this.mode]; - } catch(e) { - this._renderError("Waiting for data."); - return; - } - - for(var obj in snmpJson) { - - var cleanObj = obj.replace(/\W+/g, ""); - - var groupObj = document.createElement("div"); - groupObj.classList.add("panel","panel-default","nms-panel-small"); - groupObj.innerHTML = '<a class="panel-heading collapse-controller" style="display:block;" role="button" data-toggle="collapse" href="#'+cleanObj+'-group">' + obj + '</a>'; - - var groupObjCollapse = document.createElement("div"); - groupObjCollapse.id = cleanObj + "-group"; - groupObjCollapse.classList.add("collapse"); - - var panelBodyObj = document.createElement("div"); - panelBodyObj.classList.add("panel-body"); - - var tableObj = document.createElement("table"); - tableObj.classList.add("table","table-condensed"); - - var tbody = document.createElement("tbody"); - - for(var prop in snmpJson[obj]) { - var propObj = document.createElement("tr"); - propObj.innerHTML = '<td>' + prop + '</td><td>' + snmpJson[obj][prop] + '</td>'; - tbody.appendChild(propObj); - } - - tableObj.appendChild(tbody); - panelBodyObj.appendChild(tableObj); - groupObjCollapse.appendChild(panelBodyObj); - groupObj.appendChild(groupObjCollapse); - domObj.appendChild(groupObj); - - } - - this._render(domObj); - }; + nmsInfoPanel.call(this, "switchSNMP"); + this.init = function () { + this.refresh(); + }; + this.refresh = function (reason) { + var domObj = document.createElement("div"); + domObj.classList.add("panel-group"); + + try { + var snmpJson = nmsData.snmp.snmp[this.sw][this.mode]; + } catch (e) { + this._renderError("Waiting for data."); + return; + } + + for (var obj in snmpJson) { + var cleanObj = obj.replace(/\W+/g, ""); + + var groupObj = document.createElement("div"); + groupObj.classList.add("panel", "panel-default", "nms-panel-small"); + groupObj.innerHTML = + '<h6 class="">' + obj + '</h6>'; + + var groupObjCollapse = document.createElement("div"); + groupObjCollapse.id = cleanObj + "-group"; + //groupObjCollapse.classList.add("collapse"); + + var panelBodyObj = document.createElement("div"); + panelBodyObj.classList.add("panel-body"); + + var tableObj = document.createElement("table"); + tableObj.classList.add("table"); + + var tbody = document.createElement("tbody"); + + for (var prop in snmpJson[obj]) { + var propObj = document.createElement("tr"); + propObj.innerHTML = + "<td>" + prop + "</td><td>" + snmpJson[obj][prop] + "</td>"; + tbody.appendChild(propObj); + } + + tableObj.appendChild(tbody); + panelBodyObj.appendChild(tableObj); + groupObjCollapse.appendChild(panelBodyObj); + groupObj.appendChild(groupObjCollapse); + domObj.appendChild(groupObj); + } + + this._render(domObj); + }; }; -nmsInfoBox.addPanelType("switchSNMP",switchSNMPPanel); +nmsInfoBox.addPanelType("switchSNMP", switchSNMPPanel); var switchPortsPanel = function () { - nmsInfoPanel.call(this,"switchPorts"); - this.init = function() { - this.refresh(); - }; - this.refresh = function(reason) { - var domObj = document.createElement("div"); - domObj.classList.add("panel-group"); - - try { - var snmpOldJson; - var snmpJson = nmsData.snmp.snmp[this.sw]['ports']; - if (nmsData.old.snmp != undefined) { - snmpOldJson = nmsData.old.snmp.snmp[this.sw]['ports']; - } - } catch(e) { - this._renderError("Waiting for data."); - return; - } - var chart = document.createElement("canvas"); - chart.id = this.sw+'port-total-chart'; - drawSumOfPorts(this.sw+'port-total-chart',this.sw) - var expanderButton = document.createElement("a"); - expanderButton.innerHTML = "Toggle all"; - expanderButton.setAttribute("onclick","$('.collapse-top').collapse('toggle');"); - expanderButton.setAttribute("role","button"); - - var interfaceAliasButton = document.createElement("a"); - interfaceAliasButton.innerHTML = "Toggle interfaces without ifAlias"; - interfaceAliasButton.setAttribute("onclick", "$('.nms-interface-missing-alias').toggle();"); - interfaceAliasButton.setAttribute("role","button"); - - domObj.appendChild(chart); - domObj.appendChild(expanderButton); - domObj.appendChild(document.createElement("br")); - domObj.appendChild(interfaceAliasButton); - var indicies = []; - for (var obj in snmpJson) { - indicies.push(obj); - } - indicies.sort(function(a,b) { - var tmpx = [ snmpJson[a].ifName, snmpJson[b].ifName ]; - tmpx.sort(); - if (tmpx[0] == snmpJson[a].ifName) { - return -1; - } else { - return 1; - } - }); - for(var obji in indicies) { - var obj = indicies[obji]; - var cleanObj = obj.replace(/\W+/g, ""); - var groupObj = document.createElement("div"); - groupObj.classList.add("panel","panel-default","nms-panel-small"); - var glyphicon = "glyphicon-remove"; - var button = "btn-danger"; - var title = "link down"; - groupObj.classList.add("nms-interface-down"); - if (snmpJson[obj].ifOperStatus == "up") { - glyphicon = "glyphicon-ok"; - button = "btn-success"; - title = "link up"; - groupObj.classList.remove("nms-interface-down"); - } - if (snmpJson[obj].ifAdminStatus == "down") { - glyphicon = "glyphicon-ban-circle"; - title = "admin down"; - button = "btn-info"; - } - var traffic = ""; - try { - var nowin = parseInt(snmpJson[obj].ifHCInOctets); - var nowout = parseInt(snmpJson[obj].ifHCOutOctets); - if (!isNaN(nowin) && !isNaN(nowout)) { - traffic = "<small>" + byteCount(nowin) + "B in | " + byteCount(nowout) + "B out </small>"; - } - } catch(e) {}; - - if(snmpJson[obj].ifAlias == null || snmpJson[obj].ifAlias == '') { - groupObj.classList.add("nms-interface-missing-alias"); - } - groupObj.innerHTML = '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#'+cleanObj+'-group">' + snmpJson[obj].ifName + ' </a><small>' + snmpJson[obj].ifAlias + '</small><span class="pull-right">' + traffic + '<i class="btn-xs ' + button + '"><span class="glyphicon ' + glyphicon + '" title="' + title + '" aria-hidden="true"></span></i></span></span>'; - - var groupObjCollapse = document.createElement("div"); - groupObjCollapse.id = cleanObj + "-group"; - groupObjCollapse.classList.add("collapse"); - groupObjCollapse.classList.add("collapse-top"); - - var panelBodyObj = document.createElement("div"); - panelBodyObj.classList.add("panel-body"); - - var tableObj = document.createElement("table"); - tableObj.classList.add("table","table-condensed"); - - var tbody = document.createElement("tbody"); - var props = []; - for (var prop in snmpJson[obj]) { - props.push(prop); - } - props.sort(); - for(var index in props) { - var prop = props[index]; - var propObj = document.createElement("tr"); - var append = ""; - var value = snmpJson[obj][prop]; - if (!isNaN(parseInt(value))) { - append = byteCount(value, 2); - if (append != value) - append = " (" + append + ")"; - else - append = ""; - } - propObj.innerHTML = '<td>' + prop + '</td><td>' + value + append + '</td>'; - tbody.appendChild(propObj); - } - - tableObj.appendChild(tbody); - if (snmpJson[obj].ifHCInOctets != 0 - || snmpJson[obj].ifHCOutOctets != 0) { - var chart = document.createElement("canvas"); - chart.id = this.sw+'port-'+obj+'-chart'; - drawPort(this.sw+'port-'+obj+'-chart',this.sw,obj) - - panelBodyObj.appendChild(chart); - } - var tableTopObj = document.createElement("div"); - tableTopObj.innerHTML = '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#'+cleanObj+'-table-group">Details</a></span>'; - var tableTopObjCollapse = document.createElement("div"); - tableTopObjCollapse.id = cleanObj + "-table-group"; - tableTopObjCollapse.classList.add("collapse"); - tableTopObjCollapse.classList.add("collapse-detail"); - tableTopObjCollapse.appendChild(tableObj); - tableTopObj.appendChild(tableTopObjCollapse); - panelBodyObj.appendChild(tableTopObj); - //panelBodyObj.appendChild(tableObj); - groupObjCollapse.appendChild(panelBodyObj); - groupObj.appendChild(groupObjCollapse); - domObj.appendChild(groupObj); - - } - - this._render(domObj); - }; + nmsInfoPanel.call(this, "switchPorts"); + this.init = function () { + this.refresh(); + }; + this.refresh = function (reason) { + var domObj = document.createElement("div"); + domObj.classList.add("panel-group"); + + try { + var snmpOldJson; + var snmpJson = nmsData.snmp.snmp[this.sw]["ports"]; + if (nmsData.old.snmp != undefined) { + snmpOldJson = nmsData.old.snmp.snmp[this.sw]["ports"]; + } + } catch (e) { + this._renderError("Waiting for data."); + return; + } + //var expanderButton = document.createElement("a"); + //expanderButton.innerHTML = "Toggle all"; + //expanderButton.setAttribute("onclick","$('.collapse-top').collapse('toggle');"); + //expanderButton.setAttribute("role", "button"); + + //var interfaceAliasButton = document.createElement("a"); + //interfaceAliasButton.innerHTML = "Toggle interfaces without ifAlias"; + //interfaceAliasButton.setAttribute("onclick", "$('.nms-interface-missing-alias').toggle();"); + //interfaceAliasButton.setAttribute("role", "button"); + + //domObj.appendChild(expanderButton); + //domObj.appendChild(document.createElement("br")); + //domObj.appendChild(interfaceAliasButton); + var indicies = []; + for (var obj in snmpJson) { + indicies.push(obj); + } + indicies.sort(function (a, b) { + var tmpx = [snmpJson[a].ifName, snmpJson[b].ifName]; + tmpx.sort(); + if (tmpx[0] == snmpJson[a].ifName) { + return -1; + } else { + return 1; + } + }); + for (var obji in indicies) { + var obj = indicies[obji]; + var cleanObj = obj.replace(/\W+/g, ""); + var groupObj = document.createElement("div"); + groupObj.classList.add("panel", "panel-default", "nms-panel-small"); + var glyphicon = "glyphicon-remove"; + var button = "btn-danger"; + var title = "link down"; + groupObj.classList.add("nms-interface-down"); + if (snmpJson[obj].ifOperStatus == "up") { + glyphicon = "glyphicon-ok"; + button = "btn-success"; + title = "link up"; + groupObj.classList.remove("nms-interface-down"); + } + if (snmpJson[obj].ifAdminStatus == "down") { + glyphicon = "glyphicon-ban-circle"; + title = "admin down"; + button = "btn-info"; + } + var traffic = ""; + try { + var nowin = parseInt(snmpJson[obj].ifHCInOctets); + var nowout = parseInt(snmpJson[obj].ifHCOutOctets); + if (!isNaN(nowin) && !isNaN(nowout)) { + traffic = + "<small>" + + byteCount(nowin) + + "B in | " + + byteCount(nowout) + + "B out </small>"; + } + } catch (e) {} + + if (snmpJson[obj].ifAlias == null || snmpJson[obj].ifAlias == "") { + groupObj.classList.add("nms-interface-missing-alias"); + } + groupObj.innerHTML = + '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#' + + cleanObj + + '-group">' + + snmpJson[obj].ifName + + " </a><small>" + + snmpJson[obj].ifAlias + + '</small><span class="pull-right">' + + traffic + + '<i class="btn-xs ' + + button + + '"><span class="glyphicon ' + + glyphicon + + '" title="' + + title + + '" aria-hidden="true"></span></i></span></span>'; + + var groupObjCollapse = document.createElement("div"); + groupObjCollapse.id = cleanObj + "-group"; + //groupObjCollapse.classList.add("collapse"); + //groupObjCollapse.classList.add("collapse-top"); + + var panelBodyObj = document.createElement("div"); + panelBodyObj.classList.add("panel-body"); + + var tableObj = document.createElement("table"); + tableObj.classList.add("table", "table-condensed"); + + var tbody = document.createElement("tbody"); + var props = []; + for (var prop in snmpJson[obj]) { + props.push(prop); + } + props.sort(); + for (var index in props) { + var prop = props[index]; + var propObj = document.createElement("tr"); + var append = ""; + var value = snmpJson[obj][prop]; + if (!isNaN(parseInt(value))) { + append = byteCount(value, 2); + if (append != value) append = " (" + append + ")"; + else append = ""; + } + propObj.innerHTML = + "<td>" + prop + "</td><td>" + value + append + "</td>"; + tbody.appendChild(propObj); + } + + tableObj.appendChild(tbody); + var tableTopObj = document.createElement("div"); + tableTopObj.innerHTML = + '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#' + + cleanObj; + //'-table-group">Details</a></span>'; + var tableTopObjCollapse = document.createElement("div"); + tableTopObjCollapse.id = cleanObj + "-table-group"; + //tableTopObjCollapse.classList.add("collapse"); + //tableTopObjCollapse.classList.add("collapse-detail"); + tableTopObjCollapse.appendChild(tableObj); + tableTopObj.appendChild(tableTopObjCollapse); + panelBodyObj.appendChild(tableTopObj); + //panelBodyObj.appendChild(tableObj); + groupObjCollapse.appendChild(panelBodyObj); + groupObj.appendChild(groupObjCollapse); + domObj.appendChild(groupObj); + } + + this._render(domObj); + }; }; -nmsInfoBox.addPanelType("switchPorts",switchPortsPanel); - -var searchHelpPanel = function() { - nmsInfoPanel.call(this,"searchHelp"); - this.refresh = function(reason) { - var x = document.createElement("div"); - var searchHelp = nmsSearch.helpText; - for (var a in searchHelp) { - var c = document.createElement("p"); - c.innerText = searchHelp[a]; - x.appendChild(c); - } - this._render(x); - }; +nmsInfoBox.addPanelType("switchPorts", switchPortsPanel); + +var searchHelpPanel = function () { + nmsInfoPanel.call(this, "searchHelp"); + this.refresh = function (reason) { + var x = document.createElement("div"); + var searchHelp = nmsSearch.helpText; + for (var a in searchHelp) { + var c = document.createElement("p"); + c.innerText = searchHelp[a]; + x.appendChild(c); + } + this._render(x); + }; }; -nmsInfoBox.addPanelType("searchHelp",searchHelpPanel); - +nmsInfoBox.addPanelType("searchHelp", searchHelpPanel); /* * Panel type: Search Results @@ -780,28 +799,36 @@ nmsInfoBox.addPanelType("searchHelp",searchHelpPanel); * Show the search results * */ -var searchResultsPanel = function() { - var searchPage = 0; - nmsInfoPanel.call(this,"searchResults"); - this.refresh = function(reason) { - var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'}); - var switches = nmsSearch.matches.sort(collator.compare); - var table = document.createElement('table'); - table.className = "table table-condensed"; - table.id = "searchResults-table" - for (var sw in switches) { - var row = table.insertRow(sw); - var cell1 = row.insertCell(0); - var cell2 = row.insertCell(1); - var cell3 = row.insertCell(2); - cell1.innerHTML = "<a href='#' onclick='nmsInfoBox.showWindow(\"switchInfo\",\""+switches[sw]+"\");'>"+switches[sw]+ '</a>'; - cell2.innerHTML = nmsData.switches["switches"][switches[sw]].distro_name; - cell3.innerHTML = handlers[0].getInfo(switches[sw]).why; - } - this._render(table); - } +var searchResultsPanel = function () { + var searchPage = 0; + nmsInfoPanel.call(this, "searchResults"); + this.refresh = function (reason) { + var collator = new Intl.Collator(undefined, { + numeric: true, + sensitivity: "base", + }); + var switches = nmsSearch.matches.sort(collator.compare); + var table = document.createElement("table"); + table.className = "table table-condensed"; + table.id = "searchResults-table"; + for (var sw in switches) { + var row = table.insertRow(sw); + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + cell1.innerHTML = + "<a href='#' onclick='nmsInfoBox.showWindow(\"switchInfo\",\"" + + switches[sw] + + "\");'>" + + switches[sw] + + "</a>"; + cell2.innerHTML = nmsData.switches["switches"][switches[sw]].distro_name; + cell3.innerHTML = handlers[0].getInfo(switches[sw]).why; + } + this._render(table); + }; }; -nmsInfoBox.addPanelType("searchResults",searchResultsPanel); +nmsInfoBox.addPanelType("searchResults", searchResultsPanel); /* * Panel type: Edit switch @@ -810,16 +837,17 @@ nmsInfoBox.addPanelType("searchResults",searchResultsPanel); * */ var switchEditPanel = function () { - nmsInfoPanel.call(this,"switchEdit"); - this.refresh = function (reason) { - if (this.box) { return; } - this.box = new nmsModSwitch(this.sw); - this.box.attach(this.me) - this.box.show() - }; - + nmsInfoPanel.call(this, "switchEdit"); + this.refresh = function (reason) { + if (this.box) { + return; + } + this.box = new nmsModSwitch(this.sw); + this.box.attach(this.me); + this.box.show(); + }; }; -nmsInfoBox.addPanelType("switchEdit",switchEditPanel); +nmsInfoBox.addPanelType("switchEdit", switchEditPanel); /* * Panel type: Switch comments @@ -828,80 +856,79 @@ nmsInfoBox.addPanelType("switchEdit",switchEditPanel); * */ var switchCommentsPanel = function () { - nmsInfoPanel.call(this,"switchComments"); - this.commentsHash = false; - this.refresh = function (reason) { - var domObj = document.createElement("div"); - domObj.className = 'gondul-is-private'; - var comments = []; - var logs = nmsOplog.getSwitchLogs(this.sw); - var table = document.createElement("table"); - var tr; - var td1; - var td2; - var td3; - table.className = "table"; - table.classList.add("table"); - table.classList.add("table-condensed"); - var cap = document.createElement("caption"); - cap.textContent = "Relevant log entries"; - table.appendChild(cap); - for (var v in logs) { - tr = table.insertRow(-1); - tr.className = - td1 = tr.insertCell(0); - td2 = tr.insertCell(1); - var date = new Date(logs[v]['timestamp']); - var month = date.getMonth() + 1; - var day = date.getDate(); - var tmp = (date.getYear() + 1900) + "-" + (month < 10 ? "0": "") + month + "-" + (day < 10 ? "0" : "") + day + " " + date.toTimeString().replace(/:\d\d .*$/,""); - td1.textContent = tmp; - td1.classList.add("left"); - td2.textContent = logs[v]['systems'] + "[" + logs[v]['username'] + "] " + logs[v]['log']; - } - domObj.appendChild(table); - this._render(domObj); - }; + nmsInfoPanel.call(this, "switchComments"); + this.commentsHash = false; + this.refresh = function (reason) { + var domObj = document.createElement("div"); + domObj.className = "gondul-is-private"; + var comments = []; + var logs = nmsOplog.getSwitchLogs(this.sw); + var table = document.createElement("table"); + var tr; + var td1; + var td2; + var td3; + table.className = "table"; + table.classList.add("table"); + table.classList.add("table-condensed"); + var cap = document.createElement("h5"); + cap.textContent = "Relevant log entries"; + table.appendChild(cap); + for (var v in logs) { + tr = table.insertRow(-1); + tr.className = td1 = tr.insertCell(0); + td2 = tr.insertCell(1); + var date = new Date(logs[v]["time"] * 1000); + var month = date.getMonth() + 1; + var day = date.getDate(); + var tmp = + date.getYear() + + 1900 + + "-" + + (month < 10 ? "0" : "") + + month + + "-" + + (day < 10 ? "0" : "") + + day + + " " + + date.toTimeString().replace(/:\d\d .*$/, ""); + td1.textContent = tmp; + td1.classList.add("left"); + td2.textContent = + logs[v]["systems"] + "[" + logs[v]["username"] + "] " + logs[v]["message"]; + } + domObj.appendChild(table); + this._render(domObj); + }; }; -nmsInfoBox.addPanelType("switchComments",switchCommentsPanel); +nmsInfoBox.addPanelType("switchComments", switchCommentsPanel); /* - * Panel type: Switch latency + * Panel type: Switch links + * * - * Display a live line chart with latency * */ -var switchLatencyPanel = function() { - nmsInfoPanel.call(this,"switchLatency"); - var latencyChart; - this.init = function() { - if(nms._public == false) { - this.addHandler("ticker"); - this.refresh(); - } - }; - this.refresh = function(reason) { - if (this.sw == false) { - console.log("ugh, cleanup failed?"); - return; - } - - if(reason == 'handler-ticker' && latencyChart != undefined) { - drawLatency(this.sw+'latency_chart',this.sw, latencyChart); - return; - } - - var topper = document.createElement("div"); - var latency = document.createElement("canvas"); - latency.id = this.sw+'latency_chart'; - latency.width = 500; - latency.height = 50; - drawLatency(this.sw+'latency_chart',this.sw, false, function(chart) { latencyChart = chart; }); - topper.appendChild(latency); - this._render(topper); - }; +var switchLinksPanel = function () { + nmsInfoPanel.call(this, "switchLinks"); + this.commentsHash = false; + this.refresh = function (reason) { + var domObj = document.createElement("div"); + domObj.className = "gondul-is-private d-grid gap-0 row-gap-3"; + var device = nmsData.smanagement.switches[this.sw] + if(["eos64"].includes(device["platform"]) && device["serial"] != null && device["serial"] != "") { + var cap = document.createElement("a"); + cap.textContent = "Open in CVP"; + cap.href = "https://www.cv-prod-euwest-2.arista.io/cv/devices/overview/" + device["serial"]; + cap.target = "_blank"; + cap.className = "my-4 btn btn-outline-primary"; + cap.role = "button"; + domObj.appendChild(cap); + } + this._render(domObj); + }; }; -nmsInfoBox.addPanelType("switchLatency",switchLatencyPanel); +nmsInfoBox.addPanelType("switchLinks", switchLinksPanel); /* * Panel type: Switch summary @@ -909,129 +936,83 @@ nmsInfoBox.addPanelType("switchLatency",switchLatencyPanel); * Display a live summary of key metrics * */ -var switchSummaryPanel = function() { - nmsInfoPanel.call(this,"switchSummary"); - var latencyChart; - this.init = function() { - this.addHandler("ticker"); - this.refresh(); - }; - this.refresh = function(reason) { - if (this.box) { - this.box.refresh(); - return; - } - this.box = new nmsSwitchSummary(this.sw); - this.box.attach(this.me) - this.box.show() - }; +var switchSummaryPanel = function () { + nmsInfoPanel.call(this, "switchSummary"); + this.init = function () { + this.addHandler("ticker"); + this.refresh(); + }; + this.refresh = function (reason) { + if (this.box) { + this.box.refresh(); + return; + } + this.box = new nmsSwitchSummary(this.sw); + this.box.attach(this.me); + this.box.show(); + }; }; -nmsInfoBox.setLegendPick = function(tag,id) { - if (nms.legendPick != undefined) { - if (nms.legendPick.handler == tag && nms.legendPick.idx == id) { - nms.legendPick = undefined; - return; - } - } - nms.legendPick = {handler: tag, idx: id}; -} - -nmsInfoBox.addPanelType("switchSummary",switchSummaryPanel); - -var copybuttonfunc = function(text) { - console.log('clickened', text); - navigator.clipboard.writeText(text); -} -var switchLinks = function() { - nmsInfoPanel.call(this,"switchLinks"); - var latencyChart; - this.init = function() { - this.refresh(); - }; - this.refresh = function(reason) { - var content = []; - if (this.sw == false) { - console.log("ugh, cleanup failed?"); - return; - } - var sw = this.sw; - - var topp = document.createElement("div") - var urls = [ "http://gondul.tg23.gathering.org/api/templates/magic.conf/switch=" + sw, - "http://185.110.148.105/api/templates/magic.conf/switch=" + sw, - "http://gondul.tg23.gathering.org/api/write/fap/" + sw - ]; - if (testTree(nmsData,['smanagement','switches',sw])) { - var mg = nmsData["smanagement"]["switches"][sw]; - urls.push("ssh://[" + mg.mgmt_v6_addr + "]"); - urls.push("ssh://" + mg.mgmt_v4_addr); - } - for (var x in urls) { - console.log("create link") - topp.appendChild(document.createElement("br")); - var container = document.createElement("div"); - var link = document.createElement("a"); - link.href = urls[x]; - link.textContent = urls[x]; - var copybutton = document.createElement("button"); - copybutton.setAttribute("onclick", "copybuttonfunc('"+urls[x]+"')"); - copybutton.type = "button"; - var btnText = document.createTextNode("copy url"); - copybutton.className = "btn btn-primary"; - copybutton.appendChild(btnText); - container.appendChild(link); - container.appendChild(copybutton); - topp.appendChild(container); - } - this._render(topp); - }; +nmsInfoBox.setLegendPick = function (tag, id) { + if (nms.legendPick != undefined) { + if (nms.legendPick.handler == tag && nms.legendPick.idx == id) { + nms.legendPick = undefined; + return; + } + } + nms.legendPick = { handler: tag, idx: id }; }; -nmsInfoBox.addPanelType("switchLinks",switchLinks); + +nmsInfoBox.addPanelType("switchSummary", switchSummaryPanel); /* -* List networks -* -* Shows all networks -* -*/ -var networkListPanel = function() { - nmsInfoPanel.call(this,"listNetworks"); - this.refresh = function(reason) { - var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'}); - var networks = nmsData.networks.networks; - var table = document.createElement('table'); - table.className = "table table-condensed"; - table.id = "searchResults-table" - for (var net in networks) { - var row = table.insertRow(net); - var cell1 = row.insertCell(0); - var cell2 = row.insertCell(1); - var cell3 = row.insertCell(2); - cell1.innerHTML = "<a href='#' onclick='nmsInfoBox.showWindow(\"networkInfo\",\""+net+"\");'>"+net+ '</a>'; - cell2.innerHTML = networks[net].vlan; - cell3.innerHTML = networks[net].router; - } - this._render(table); - - }; + * List networks + * + * Shows all networks + * + */ +var networkListPanel = function () { + nmsInfoPanel.call(this, "listNetworks"); + this.refresh = function (reason) { + var collator = new Intl.Collator(undefined, { + numeric: true, + sensitivity: "base", + }); + var networks = nmsData.networks.networks; + var table = document.createElement("table"); + table.className = "table table-condensed"; + table.id = "searchResults-table"; + for (var net in networks) { + var row = table.insertRow(net); + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + var cell3 = row.insertCell(2); + cell1.innerHTML = + "<a href='#' onclick='nmsInfoBox.showWindow(\"networkInfo\",\"" + + net + + "\");'>" + + net + + "</a>"; + cell2.innerHTML = networks[net].vlan; + cell3.innerHTML = networks[net].router; + } + this._render(table); + }; }; -nmsInfoBox.addPanelType("listNetworks",networkListPanel); +nmsInfoBox.addPanelType("listNetworks", networkListPanel); /* -* Panel type: Network summary -* -* Display a summary -* -*/ -var networkSummaryPanel = function() { - nmsInfoPanel.call(this,"networkSummary"); - this.refresh = function(reason) { - var network = this.sw; - - }; -} -nmsInfoBox.addPanelType("networkSummary",networkSummaryPanel); - + * Panel type: Network summary + * + * Display a summary + * + */ +var networkSummaryPanel = function () { + nmsInfoPanel.call(this, "networkSummary"); + this.refresh = function (reason) { + var network = this.sw; + }; +}; +nmsInfoBox.addPanelType("networkSummary", networkSummaryPanel); /* * Panel type: Edit network @@ -1040,50 +1021,76 @@ nmsInfoBox.addPanelType("networkSummary",networkSummaryPanel); * */ var networkEditPanel = function () { - nmsInfoPanel.call(this,"networkEdit"); - this.refresh = function (reason) { - if (this.box) { return; } - this.box = new nmsModNet(this.sw); - this.box.attach(this.me) - this.box.show() - }; + nmsInfoPanel.call(this, "networkEdit"); + this.refresh = function (reason) { + if (this.box) { + return; + } + this.box = new nmsModNet(this.sw); + this.box.attach(this.me); + this.box.show(); + }; +}; +nmsInfoBox.addPanelType("networkEdit", networkEditPanel); + +/* + * Debug Panel + * + * Show debug information + * + */ +var debugStatsPanel = function () { + nmsInfoPanel.call(this, "debugStatsPanel"); + this.init = function () { + this.addHandler("ticker"); + this.refresh(); + }; + this.refresh = function (reason) { + var table = document.createElement("table"); + table.className = "table table-condensed"; + table.id = "searchResults-table"; + var stats = Object.fromEntries( + Object.entries(nmsData.stats).sort((a, b) => a[0].localeCompare(b[0])) + ); + for (var stat in stats) { + var row = table.insertRow(stat); + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + cell1.innerHTML = stat; + cell2.innerHTML = nmsData.stats[stat]; + } + this._render(table); + }; }; -nmsInfoBox.addPanelType("networkEdit",networkEditPanel); +nmsInfoBox.addPanelType("debugStats", debugStatsPanel); /* - * Provide common defaults for graph renders. + * Debug Panel + * + * Show debug information * - * Kept on the URL to avoid having to manage templates since we need to - * manage night mode anyway for now. */ -nmsInfoBox._graphZoom = function() { - if (nmsInfoBox._graphFrom == "-60min") { - nmsInfoBox._graphFrom = "-6h"; - } else if (nmsInfoBox._graphFrom == "-6h") { - nmsInfoBox._graphFrom = "-24h"; - } else if (nmsInfoBox._graphFrom == "-24h") { - nmsInfoBox._graphFrom = "-7days"; - } else { - nmsInfoBox._graphFrom = "-60min"; - } - - -} -nmsInfoBox._graphFrom = "-60min"; -nmsInfoBox._graphUntil = "now"; -nmsInfoBox._graphNormalize = function(f) { - return f.replace(/[^a-z0-9]/gi,"_"); -} -nmsInfoBox._graphDefaults = function(title) { - if (title != undefined) { - title = "From " + nmsInfoBox._graphFrom + " until " + nmsInfoBox._graphUntil + " (" + title + ")"; - } else { - title = "From " + nmsInfoBox._graphFrom + " until " + nmsInfoBox._graphUntil; - } - var base = "&yMinLeft=0&yMinRight=0&yMin=0&bgcolor=%23ffffff00&fontName=courier&width=600&height=240&yUnitSystem=binary&format=svg&from=" + nmsInfoBox._graphFrom + "&until=" + nmsInfoBox._graphUntil + '&title=' + title + "&lolBuster=" + Math.floor(new Date().getTime() / 30000); - if (nms.nightMode) { - return "&fgcolor=%23dddddd&minorGridLineColor=%233d3d3d&majorGridLineColor=%23666666" + base; - } else { - return base; - } -} +var debugPanel = function () { + nmsInfoPanel.call(this, "debugInfo"); + this.init = function () { + this.addHandler("ticker"); + this.refresh(); + }; + this.refresh = function (reason) { + var table = document.createElement("table"); + table.className = "table table-condensed"; + table.id = "searchResults-table"; + var stats = Object.fromEntries( + Object.entries(nmsData.stats).sort((a, b) => a[0].localeCompare(b[0])) + ); + for (var stat in stats) { + var row = table.insertRow(stat); + var cell1 = row.insertCell(0); + var cell2 = row.insertCell(1); + cell1.innerHTML = stat; + cell2.innerHTML = nmsData.stats[stat]; + } + this._render(table); + }; +}; +nmsInfoBox.addPanelType("debugInfo", debugPanel); diff --git a/web/js/nms-map-handlers.js b/web/js/nms-map-handlers.js index 0097586..27139d8 100644 --- a/web/js/nms-map-handlers.js +++ b/web/js/nms-map-handlers.js @@ -14,335 +14,341 @@ */ var handler_uplinks = { - init:uplinkInit, - getInfo:uplinkInfo, - tag:"uplink", - name:"Uplink" + init: uplinkInit, + getInfo: uplinkInfo, + tag: "uplink", + name: "Uplink", }; var handler_temp = { - init:tempInit, - getInfo:tempInfo, - tag:"temp", - name:"Temperature" + init: tempInit, + getInfo: tempInfo, + tag: "temp", + name: "Temperature", }; var handler_ping = { - init:pingInit, - getInfo:pingInfo, - tag:"ping", - name:"Ping" + init: pingInit, + getInfo: pingInfo, + tag: "ping", + name: "Ping", }; var handler_traffic = { - init:trafficInit, - tag:"traffic", - name:"Uplink traffic" + init: trafficInit, + tag: "traffic", + name: "Uplink traffic", }; var handler_traffic_tot = { - init:trafficTotInit, - tag:"traffictot", - name:"Switch traffic" + init: trafficTotInit, + tag: "traffictot", + name: "Switch traffic", }; var handler_dhcp = { - init:dhcpInit, - getInfo:dhcpInfo, - tag:"dhcp", - name:"DHCP" + init: dhcpInit, + getInfo: dhcpInfo, + tag: "dhcp", + name: "DHCP", }; var handler_disco = { - init:discoInit, - tag:"disco", - name:"Disco fever" + init: discoInit, + tag: "disco", + name: "Disco fever", }; var handler_snmp = { - init:snmpInit, - getInfo:snmpInfo, - tag:"snmp", - name:"SNMP state" + init: snmpInit, + getInfo: snmpInfo, + tag: "snmp", + name: "SNMP state", }; var handler_cpu = { - init:cpuInit, - getInfo:cpuInfo, - tag:"cpu", - name:"CPU utilization" + init: cpuInit, + getInfo: cpuInfo, + tag: "cpu", + name: "CPU utilization", }; var handler_memory = { - init:memoryInit, - getInfo:memoryInfo, - tag:"memory", - name:"Memory utilization" + init: memoryInit, + getInfo: memoryInfo, + tag: "memory", + name: "Memory utilization", }; var handler_health = { - init:healthInit, - getInfo:healthInfo, - tag:"health", - name:"Health" + init: healthInit, + getInfo: healthInfo, + tag: "health", + name: "Health", }; var handler_mgmt = { - getInfo:mgmtInfo, - tag:"mgmt", - name:"Management info" + getInfo: mgmtInfo, + tag: "mgmt", + name: "Management info", }; var handler_net = { - getInfo:networkInfo, - tag:"net", - name:"Network info" + getInfo: networkInfo, + tag: "net", + name: "Network info", }; var handler_snmpup = { - getInfo:snmpUpInfo, - tag:"snmpup", - name:"SNMP Uplink state" + getInfo: snmpUpInfo, + tag: "snmpup", + name: "SNMP Uplink state", }; -var handlerInfo = function(tag,desc) { - /* - * Short name, typically matching the url anchor. - */ - this.tag = tag; - this.description = desc || "Unknown"; - this.data = [ - { - value: undefined, - description: desc || "Generic info" - }]; - /* - * 0: all good. - * 1000: messed up. - * - * This can be "intelligent". E.g.: pingInfo() takes latency and - * the age of the reply into account in addition to having a - * special handling of lack of a result. - */ - this.score = 0; - /* - * Why the score is what it is. E.g.: If you have multiple - * conditions that set the score, what is the final value based on? - */ - this.why = "0 score is the default"; +var handlerInfo = function (tag, desc) { + /* + * Short name, typically matching the url anchor. + */ + this.tag = tag; + this.description = desc || "Unknown"; + this.data = [ + { + value: undefined, + description: desc || "Generic info", + }, + ]; + /* + * 0: all good. + * 1000: messed up. + * + * This can be "intelligent". E.g.: pingInfo() takes latency and + * the age of the reply into account in addition to having a + * special handling of lack of a result. + */ + this.score = 0; + /* + * Why the score is what it is. E.g.: If you have multiple + * conditions that set the score, what is the final value based on? + */ + this.why = "0 score is the default"; }; /* * Order matches what's seen in the infobox */ var handlers = [ - handler_health, - handler_mgmt, - handler_net, - handler_uplinks, - handler_temp, - handler_ping, - handler_traffic, - handler_disco, - handler_traffic_tot, - handler_dhcp, - handler_snmp, - handler_cpu, - handler_memory, - handler_snmpup - ]; - -function uplinkInfo(sw) -{ - var ret = new handlerInfo("snmpup","Uplinks"); - ret.why = "Uplinks"; - ret.score = 0; - var u = 0; - var t = 0; - var known_t = 0; - if (testTree(nmsData,['switchstate','switches',sw,'uplinks','live'])) { - u = parseInt(nmsData.switchstate.switches[sw].uplinks.live); - t = parseInt(nmsData.switchstate.switches[sw].uplinks.total); - known_t = t; - ret.data[0].value = u + " / " + t; - ret.data[0].description = "Uplinks (live/configured)"; - if (nmsData.switches.switches[sw].subnet4 == undefined || - nmsData.switches.switches[sw].subnet4 == null) { - if (tagged(sw,'3up')) { - known_t = 3; - } else if (tagged(sw,'2up')) { - known_t = 2; - } else if (tagged(sw, '1up')) { - known_t = 1; - } else if (tagged(sw,'4up')) { - known_t = 4; - } - if (known_t != t) { - ret.data[0].value += "(Overridden: " + known_t + ")"; - } - if (u == known_t) { - ret.score = 0; - ret.why = "All uplinks up"; - } else if (u == 1) { - ret.score = 800; - ret.why = "Only 1 of " + known_t + " uplinks alive"; - } else if (u < known_t && !(t >= 10 && u <5)) { - ret.score = 450; - ret.why = u + " of " + known_t + " uplinks alive"; - } else if (u > known_t) { - ret.score = 350; - ret.why = u + " of " + known_t + " uplinks alive"; - } else if (u < known_t && (t >= 10 && u < 5)) { - ret.score = 150; - ret.why = u + " of " + known_t + " uplinks alive (huge diff suggests WIP - downgrading)"; - } - } - } - if (testTree(nmsData,['switchstate','switches',sw,'clients','total'])) { - var tu = parseInt(nmsData.switchstate.switches[sw].clients.live); - var tt = parseInt(nmsData.switchstate.switches[sw].clients.total); - ret.data[1] = {}; - ret.data[1].value = tt ? (tu) + " / " + (tt) : "None configured"; - ret.data[1].description = "Client ports (live/total)"; - } - if (testTree(nmsData,['switchstate','switches',sw,'totals','live'])) { - var tu = parseInt(nmsData.switchstate.switches[sw].totals.live); - var tt = parseInt(nmsData.switchstate.switches[sw].totals.total); - ret.data[2] = {}; - ret.data[2].value = (tu-u) + " / " + (tt-t); - ret.data[2].description = "Non-uplink ports (live/total)"; - } - return ret; + handler_health, + handler_mgmt, + handler_net, + handler_uplinks, + handler_temp, + handler_ping, + handler_traffic, + handler_disco, + handler_traffic_tot, + handler_dhcp, + handler_snmp, + handler_cpu, + handler_memory, + handler_snmpup, +]; + +function uplinkInfo(sw) { + var ret = new handlerInfo("snmpup", "Uplinks"); + ret.why = "Uplinks"; + ret.score = 0; + var u = 0; + var t = 0; + var known_t = 0; + if (testTree(nmsData, ["switchstate", "switches", sw, "uplinks", "live"])) { + u = parseInt(nmsData.switchstate.switches[sw].uplinks.live); + t = parseInt(nmsData.switchstate.switches[sw].uplinks.total); + known_t = t; + ret.data[0].value = u + " / " + t; + ret.data[0].description = "Uplinks (live/configured)"; + if ( + nmsData.switches.switches[sw].subnet4 == undefined || + nmsData.switches.switches[sw].subnet4 == null + ) { + if (tagged(sw, "3up")) { + known_t = 3; + } else if (tagged(sw, "2up")) { + known_t = 2; + } else if (tagged(sw, "1up")) { + known_t = 1; + } else if (tagged(sw, "4up")) { + known_t = 4; + } + if (known_t != t) { + ret.data[0].value += "(Overridden: " + known_t + ")"; + } + if (u == known_t) { + ret.score = 0; + ret.why = "All uplinks up"; + } else if (u == 1) { + ret.score = 800; + ret.why = "Only 1 of " + known_t + " uplinks alive"; + } else if (u < known_t && !(t >= 10 && u < 5)) { + ret.score = 450; + ret.why = u + " of " + known_t + " uplinks alive"; + } else if (u > known_t) { + ret.score = 350; + ret.why = u + " of " + known_t + " uplinks alive"; + } else if (u < known_t && t >= 10 && u < 5) { + ret.score = 150; + ret.why = + u + + " of " + + known_t + + " uplinks alive (huge diff suggests WIP - downgrading)"; + } + } + } + if (testTree(nmsData, ["switchstate", "switches", sw, "clients", "total"])) { + var tu = parseInt(nmsData.switchstate.switches[sw].clients.live); + var tt = parseInt(nmsData.switchstate.switches[sw].clients.total); + ret.data[1] = {}; + ret.data[1].value = tt ? tu + " / " + tt : "None configured"; + ret.data[1].description = "Client ports (live/total)"; + } + if (testTree(nmsData, ["switchstate", "switches", sw, "totals", "live"])) { + var tu = parseInt(nmsData.switchstate.switches[sw].totals.live); + var tt = parseInt(nmsData.switchstate.switches[sw].totals.total); + ret.data[2] = {}; + ret.data[2].value = tu - u + " / " + (tt - t); + ret.data[2].description = "Non-uplink ports (live/total)"; + } + return ret; } /* * Update function for uplink map */ -function uplinkUpdater() -{ - if (!nmsData.switches) - return; - if (!nmsData.switches.switches) - return; - if (!nmsData.switchstate) - return; - if (!nmsData.switchstate.switches) - return; - for (var sw in nmsData.switches.switches) { - var uplinks=0; - if (nmsData.switchstate.switches[sw] == undefined || nmsData.switchstate.switches[sw].uplinks == undefined) { - uplinks=0; - } else { - uplinks = nmsData.switchstate.switches[sw].uplinks.live; - nuplinks = nmsData.switchstate.switches[sw].uplinks.total; - } - - if (uplinks == 0) { - nmsMap.setSwitchColor(sw,"white"); - } else if (uplinks == 1) { - nmsMap. setSwitchColor(sw, nmsColor.red); - } else if (uplinks == 2) { - nmsMap.setSwitchColor(sw, nmsColor.green); - } else if (uplinks == 3) { - nmsMap.setSwitchColor(sw, nmsColor.orange); - } else if (uplinks > 3) { - nmsMap.setSwitchColor(sw, nmsColor.blue); - } - } +function uplinkUpdater() { + if (!nmsData.switches) return; + if (!nmsData.switches.switches) return; + if (!nmsData.switchstate) return; + if (!nmsData.switchstate.switches) return; + for (var sw in nmsData.switches.switches) { + var uplinks = 0; + if ( + nmsData.switchstate.switches[sw] == undefined || + nmsData.switchstate.switches[sw].uplinks == undefined + ) { + uplinks = 0; + } else { + uplinks = nmsData.switchstate.switches[sw].uplinks.live; + nuplinks = nmsData.switchstate.switches[sw].uplinks.total; + } + + if (uplinks == 0) { + nmsMap.setSwitchColor(sw, "white"); + } else if (uplinks == 1) { + nmsMap.setSwitchColor(sw, nmsColor.red); + } else if (uplinks == 2) { + nmsMap.setSwitchColor(sw, nmsColor.green); + } else if (uplinks == 3) { + nmsMap.setSwitchColor(sw, nmsColor.orange); + } else if (uplinks > 3) { + nmsMap.setSwitchColor(sw, nmsColor.blue); + } + } } - /* * Init-function for uplink map */ -function uplinkInit() -{ - nmsData.addHandler("switches","mapHandler",uplinkUpdater); - nmsData.addHandler("switchstate","mapHandler",uplinkUpdater); - setLegend(1,"white","0 uplinks"); - setLegend(2,nmsColor.red,"1 uplink"); - setLegend(3,nmsColor.green,"2 uplinks"); - setLegend(4,nmsColor.orange,"3 uplinks"); - setLegend(5,nmsColor.blue,"4 uplinks"); +function uplinkInit() { + nmsData.addHandler("switches", "mapHandler", uplinkUpdater); + nmsData.addHandler("switchstate", "mapHandler", uplinkUpdater); + setLegend(1, "white", "0 uplinks"); + setLegend(2, nmsColor.red, "1 uplink"); + setLegend(3, nmsColor.green, "2 uplinks"); + setLegend(4, nmsColor.orange, "3 uplinks"); + setLegend(5, nmsColor.blue, "4 uplinks"); } /* * Init-function for uplink map */ -function trafficInit() -{ - nmsData.addHandler("switches","mapHandler",trafficUpdater); - nmsData.addHandler("switchstate","mapHandler",trafficUpdater); - var m = 1024 * 1024 / 8; - nmsColor.drawGradient([nmsColor.lightgreen, nmsColor.green, nmsColor.orange, nmsColor.red]); - setLegend(1,colorFromSpeed(0),"0 (N/A)"); - setLegend(5,colorFromSpeed(1100 * m) , "1100Mb/s"); - setLegend(4,colorFromSpeed(600 * m),"600Mb/s"); - setLegend(3,colorFromSpeed(300 * m),"300Mb/s"); - setLegend(2,colorFromSpeed(10 * m),"10Mb/s"); +function trafficInit() { + nmsData.addHandler("switches", "mapHandler", trafficUpdater); + nmsData.addHandler("switchstate", "mapHandler", trafficUpdater); + var m = (1024 * 1024) / 8; + nmsColor.drawGradient([ + nmsColor.teal, + nmsColor.green, + nmsColor.orange, + nmsColor.red, + ]); + setLegend(1, colorFromSpeed(0), "0 (N/A)"); + setLegend(5, colorFromSpeed(1100 * m), "1100Mb/s"); + setLegend(4, colorFromSpeed(600 * m), "600Mb/s"); + setLegend(3, colorFromSpeed(300 * m), "300Mb/s"); + setLegend(2, colorFromSpeed(10 * m), "10Mb/s"); } -function trafficUpdater() -{ - if (!nmsData.switchstate.switches || !nmsData.switchstate.then) - return; - for (var sw in nmsData.switchstate.switches) { - var speed = 0; - try { - var t = parseInt(nmsData.switchstate.then[sw].uplinks.ifHCOutOctets); - var n = parseInt(nmsData.switchstate.switches[sw].uplinks.ifHCOutOctets); - var tt = parseInt(nmsData.switchstate.then[sw].time); - var nt = parseInt(nmsData.switchstate.switches[sw].time); - } catch (e) { continue;}; - var tdiff = nt - tt; - var diff = n - t; - speed = diff / tdiff; - if(!isNaN(speed)) { - nmsMap.setSwitchColor(sw,colorFromSpeed(speed)); - nmsMap.setSwitchInfo(sw,byteCount(speed*8,0)); - } - } +function trafficUpdater() { + if (!nmsData.switchstate.switches || !nmsData.switchstate.then) return; + for (var sw in nmsData.switchstate.switches) { + var speed = 0; + try { + var t = parseInt(nmsData.switchstate.then[sw].uplinks.ifHCOutOctets); + var n = parseInt(nmsData.switchstate.switches[sw].uplinks.ifHCOutOctets); + var tt = parseInt(nmsData.switchstate.then[sw].time); + var nt = parseInt(nmsData.switchstate.switches[sw].time); + } catch (e) { + continue; + } + var tdiff = nt - tt; + var diff = n - t; + speed = diff / tdiff; + if (!isNaN(speed)) { + nmsMap.setSwitchColor(sw, colorFromSpeed(speed)); + nmsMap.setSwitchInfo(sw, byteCount(speed * 8, 0)); + } + } } -function trafficTotInit() -{ - nmsData.addHandler("switches","mapHandler",trafficTotUpdater); - nmsData.addHandler("switchstate","mapHandler",trafficTotUpdater); - var m = 1024 * 1024 / 8; - nmsColor.drawGradient([nmsColor.lightgreen, nmsColor.green, nmsColor.orange, nmsColor.red]); - setLegend(1,colorFromSpeed(0),"0 (N/A)"); - setLegend(5,colorFromSpeed(5000 * m,5) , "5000Mb/s"); - setLegend(4,colorFromSpeed(3000 * m,5),"3000Mb/s"); - setLegend(3,colorFromSpeed(1000 * m,5),"1000Mb/s"); - setLegend(2,colorFromSpeed(100 * m,5),"100Mb/s"); +function trafficTotInit() { + nmsData.addHandler("switches", "mapHandler", trafficTotUpdater); + nmsData.addHandler("switchstate", "mapHandler", trafficTotUpdater); + var m = (1024 * 1024) / 8; + nmsColor.drawGradient([ + nmsColor.teal, + nmsColor.green, + nmsColor.orange, + nmsColor.red, + ]); + setLegend(1, colorFromSpeed(0), "0 (N/A)"); + setLegend(5, colorFromSpeed(5000 * m, 5), "5000Mb/s"); + setLegend(4, colorFromSpeed(3000 * m, 5), "3000Mb/s"); + setLegend(3, colorFromSpeed(1000 * m, 5), "1000Mb/s"); + setLegend(2, colorFromSpeed(100 * m, 5), "100Mb/s"); } -function trafficTotUpdater() -{ - if (!nmsData.switchstate.switches || !nmsData.switchstate.then) - return; - for (var sw in nmsData.switchstate.switches) { - var speed = 0; - try { - var t = parseInt(nmsData.switchstate.then[sw].totals.ifHCOutOctets); - var n = parseInt(nmsData.switchstate.switches[sw].totals.ifHCOutOctets); - var tt = parseInt(nmsData.switchstate.then[sw].time); - var nt = parseInt(nmsData.switchstate.switches[sw].time); - } catch (e) { continue;}; - var tdiff = nt - tt; - var diff = n - t; - speed = diff / tdiff; - if(!isNaN(speed)) - nmsMap.setSwitchColor(sw,colorFromSpeed(speed)); - } +function trafficTotUpdater() { + if (!nmsData.switchstate.switches || !nmsData.switchstate.then) return; + for (var sw in nmsData.switchstate.switches) { + var speed = 0; + try { + var t = parseInt(nmsData.switchstate.then[sw].totals.ifHCOutOctets); + var n = parseInt(nmsData.switchstate.switches[sw].totals.ifHCOutOctets); + var tt = parseInt(nmsData.switchstate.then[sw].time); + var nt = parseInt(nmsData.switchstate.switches[sw].time); + } catch (e) { + continue; + } + var tdiff = nt - tt; + var diff = n - t; + speed = diff / tdiff; + if (!isNaN(speed)) nmsMap.setSwitchColor(sw, colorFromSpeed(speed)); + } } -function colorFromSpeed(speed,factor) -{ - var m = 1024 * 1024 / 8; - if (factor == undefined) - factor = 1.1; - if (speed == 0) - return nmsColor.blue; - speed = speed < 0 ? 0 : speed; - return nmsColor.getColorStop( 1000 * (speed / (factor * (1000 * m)))); +function colorFromSpeed(speed, factor) { + var m = (1024 * 1024) / 8; + if (factor == undefined) factor = 1.1; + if (speed == 0) return nmsColor.blue; + speed = speed < 0 ? 0 : speed; + return nmsColor.getColorStop(1000 * (speed / (factor * (1000 * m)))); } /* @@ -350,825 +356,954 @@ function colorFromSpeed(speed,factor) * thing (e.g., "0" is 20 and "15" is 35 by the time we pass it to * rgb_from_max()); */ -function temp_color(t) -{ - if (t == undefined) { - console.log("Temp_color, but temp is undefined"); - return nmsColor.blue; - } - t = parseInt(t) - 12; - t = Math.floor((t / 23) * 1000); - return nmsColor.getColorStop(t); +function temp_color(t) { + if (t == undefined) { + console.log("Temp_color, but temp is undefined"); + return nmsColor.blue; + } + t = parseInt(t) - 12; + t = Math.floor((t / 23) * 1000); + return nmsColor.getColorStop(t); } -function tempUpdater() -{ - if(!nmsData.switches) - return; - - for ( var sw in nmsData.switches["switches"]) { - var t = "white"; - var temp = ""; - - if(!nmsData.switchstate || !nmsData.switchstate.switches || !nmsData.switchstate.switches[sw] || !nmsData.switchstate.switches[sw].temp) - continue; - - var t = nmsData.switchstate.switches[sw].temp; - temp = t + "°C"; - t = temp_color(temp); - nmsMap.setSwitchColor(sw, t); - nmsMap.setSwitchInfo(sw, temp); - - } +function tempUpdater() { + if (!nmsData.switches) return; + + for (var sw in nmsData.switches["switches"]) { + var t = "white"; + var temp = ""; + + if ( + !nmsData.switchstate || + !nmsData.switchstate.switches || + !nmsData.switchstate.switches[sw] || + !nmsData.switchstate.switches[sw].temp + ) + continue; + + var t = nmsData.switchstate.switches[sw].temp; + temp = t + "°C"; + t = temp_color(temp); + nmsMap.setSwitchColor(sw, t); + nmsMap.setSwitchInfo(sw, temp); + } } -function tempInfo(sw) -{ - var ret = new handlerInfo("temp","Temperature"); - ret.why = "Temp"; - ret.score = 0; - ret.data[0].value = undefined; - if (testTree(nmsData,['switchstate','switches',sw,'temp'])) { - var temp = nmsData.switchstate.switches[sw].temp; - if (temp == undefined) { - ret.data[0].value = undefined; - } else { - temp = parseInt(temp); - ret.data[0].value = temp + "°C"; - } - if (temp > 30 && temp < 50) { - ret.score = temp; - } else if (temp > 50 && temp < 100) { - ret.score = temp * 5; - ret.why = "Very high temperature"; - } - } - return ret; +function tempInfo(sw) { + var ret = new handlerInfo("temp", "Temperature"); + ret.why = "Temp"; + ret.score = 0; + ret.data[0].value = undefined; + if (testTree(nmsData, ["switchstate", "switches", sw, "temp"])) { + var temp = nmsData.switchstate.switches[sw].temp; + if (temp == undefined) { + ret.data[0].value = undefined; + } else { + temp = parseInt(temp); + ret.data[0].value = temp + "°C"; + } + if (temp > 30 && temp < 50) { + ret.score = temp; + } else if (temp > 50 && temp < 100) { + ret.score = temp * 5; + ret.why = "Very high temperature"; + } + } + return ret; } -function tempInit() -{ - //Padded the gradient with extra colors for the upper unused values - nmsColor.drawGradient(["black", nmsColor.blue, nmsColor.lightblue, nmsColor.lightgreen, nmsColor.green, nmsColor.orange, nmsColor.red]); - setLegend(1,temp_color(15),"15 °C"); - setLegend(2,temp_color(20),"20 °C"); - setLegend(3,temp_color(25),"25 °C"); - setLegend(4,temp_color(30),"30 °C"); - setLegend(5,temp_color(35),"35 °C"); - nmsData.addHandler("switchstate","mapHandler",tempUpdater); - tempUpdater(); +function tempInit() { + //Padded the gradient with extra colors for the upper unused values + nmsColor.drawGradient([ + "black", + nmsColor.blue, + nmsColor.cyan, + nmsColor.teal, + nmsColor.green, + nmsColor.orange, + nmsColor.red, + ]); + setLegend(1, temp_color(15), "15 °C"); + setLegend(2, temp_color(20), "20 °C"); + setLegend(3, temp_color(25), "25 °C"); + setLegend(4, temp_color(30), "30 °C"); + setLegend(5, temp_color(35), "35 °C"); + nmsData.addHandler("switchstate", "mapHandler", tempUpdater); + tempUpdater(); } -function pingUpdater() -{ - if (nmsData.switches == undefined || nmsData.switches.switches == undefined) { - return; - } - for (var sw in nmsData.switches.switches) { - var c = nmsColor.getColorStop(pingInfo(sw).score); - if (c == 1000) { - nmsMap.setSwitchColor(sw, nmsColor.blue); - } else { - nmsMap.setSwitchColor(sw, c); - } - } +function pingUpdater() { + if (nmsData.switches == undefined || nmsData.switches.switches == undefined) { + return; + } + for (var sw in nmsData.switches.switches) { + var c = nmsColor.getColorStop(pingInfo(sw).score); + if (c == 1000) { + nmsMap.setSwitchColor(sw, nmsColor.blue); + } else { + nmsMap.setSwitchColor(sw, c); + } + } } -function printDiff(t) -{ - var str = ""; - if (t.d > 1) - str = t.d + " days"; - else if (t.d == 1) - str = t.d + " day"; - - if (t.h > 1) - str += " " + t.h + " hours"; - else if (t.h == 1) - str += " " + t.h + " hour"; - else if (t.d > 0) - str += " 0 hours"; - - if (t.m > 1) - str += " " + t.m + " minutes"; - else if (t.m == 1) - str += " " + t.m + " minute"; - else if (t.d > 0 || t.h > 0) - str += " 0 minutes"; - - if (t.s > 1) - str += " " + t.s + " seconds"; - else if (t.s == 1) - str += " " + t.s + " second"; - else if (t.d > 0 || t.h > 0 || t.m > 0) - str += " 0 seconds"; - return str; +function printDiff(t) { + var str = ""; + if (t.d > 1) str = t.d + " days"; + else if (t.d == 1) str = t.d + " day"; + + if (t.h > 1) str += " " + t.h + " hours"; + else if (t.h == 1) str += " " + t.h + " hour"; + else if (t.d > 0) str += " 0 hours"; + + if (t.m > 1) str += " " + t.m + " minutes"; + else if (t.m == 1) str += " " + t.m + " minute"; + else if (t.d > 0 || t.h > 0) str += " 0 minutes"; + + if (t.s > 1) str += " " + t.s + " seconds"; + else if (t.s == 1) str += " " + t.s + " second"; + else if (t.d > 0 || t.h > 0 || t.m > 0) str += " 0 seconds"; + return str; } -function pingInfo(sw) -{ - var ret = new handlerInfo("ping","Latency(ms)"); - ret.why = "Latency (?)"; - ret.score =0; - if (testTree(nmsData,['ping','switches',sw])) { - var v4 = nmsData.ping.switches[sw].latency4; - var v6 = nmsData.ping.switches[sw].latency6; - if (v4 == undefined || v4 == null || isNaN(v4)) - v4 = undefined; - if (v6 == undefined || v6 == null || isNaN(v6)) - v6 = undefined; - ret.data[0].value = v6 + " (v4: " + v4 + " )"; - ret.data[0].description = "Latency(ms)"; - if (v4 == undefined && v6 == undefined) { - ret.score = 1000; - ret.why = "No IPv4 or IPv6 ping reply"; - } else if(v6 == undefined && !tagged(sw,'ignorev6')) { - ret.score = 450; - ret.why = "No IPv6 ping reply"; - } else if (v4 == undefined) { - ret.score = 800; - ret.why = "No IPv4 ping reply"; - } - - v4 = parseFloat(v4) ; - v6 = parseFloat(v6) ; - if (tagged(sw,'ignorev6')) { - v6 = 0; - } - if (v4 > ret.score || v6 > ret.score) { - ret.why = "Latency"; - ret.score = parseInt(v4 > v6 ? v4 : v6); - } - if (nmsData.ping.switches[sw].age4 > 10 || nmsData.ping.switches[sw].age6 > 10) { - ret.why = "Old ping"; - ret.score = 900; - } - } else { - ret.data[0].value = "No ping replies"; - ret.why = "No ping replies"; - ret.score = 999; - } - - if (testTree(nmsData,['smanagement','switches',sw])) { - try { - var distro = nmsData['smanagement']['switches'][sw]['distro_name']; - var phy = nmsData['smanagement']['switches'][sw]['distro_phy_port']; - if (!(distro == "" || phy == "" || distro == undefined || phy == undefined)) { - ret.data[3] = {}; - ret.data[3].description = "Distro-port"; - ret.data[3].value = distro + " " + phy; - if (testTree(nmsData,['snmp','snmp',distro, 'ports',phy,'ifOperStatus'])) { - var x = nmsData['snmp']['snmp'][distro]['ports'][phy]['ifOperStatus']; - var ping = "no"; - var ping6 = "no "; - try { - ping = parseFloat(nmsData["ping"]["switches"][sw]["latency4"]); - ping6 = parseFloat(nmsData["ping"]["switches"][sw]["latency6"]); - } catch(e) {} - if (x == "up") { - ret.data[3].value += " (😇 up!)"; - if (isNaN(ping) && isNaN(ping6)) { - ret.score = 700; - ret.why = "Distro port is alive, but no IPv4/IPv6 ping."; - if (testTree(nmsData,['snmp','snmp',distro, 'ports',phy,'ifLastChange'])) { - if (testTree(nmsData,['snmp','snmp',distro, 'misc','sysUpTimeInstance'])) { - ret.data[4] = {}; - ret.data[4].description = 'Distro port changed'; - diff = (parseInt(nmsData['snmp']['snmp'][distro]['misc']['sysUpTimeInstance']['']) - parseInt(nmsData['snmp']['snmp'][distro]['ports'][phy]['ifLastChange'])) / 100; - var diff2 = { - d:parseInt((diff/60/60/24)), - h:parseInt((diff/60/60)%24), - m:parseInt((diff/60)%60), - s:parseInt(diff%60) - } - - - - ret.data[4].value = printDiff(diff2); - } - } - } - } else { - ret.data[3].value += " (👺down)"; - } - } - } - } catch(e) { - console.log("Lazy about errors...."); - console.log(e); - } - } - return ret; +function pingInfo(sw) { + var ret = new handlerInfo("ping", "Latency"); + ret.why = "Latency (?)"; + ret.score = 0; + if (testTree(nmsData, ["ping", "switches", sw])) { + var v4 = nmsData.ping.switches[sw].latency4; + var v6 = nmsData.ping.switches[sw].latency6; + if (v4 == undefined || v4 == null || isNaN(v4)) v4 = undefined; + if (v6 == undefined || v6 == null || isNaN(v6)) v6 = undefined; + ret.data[0].value = v6 + " ms (v4: " + v4 + " ms)"; + ret.data[0].description = "Latency(ms)"; + if (v4 == undefined && v6 == undefined) { + ret.score = 1000; + ret.why = "No IPv4 or IPv6 ping reply"; + } else if (v6 == undefined && !tagged(sw, "ignorev6")) { + ret.score = 450; + ret.why = "No IPv6 ping reply"; + } else if (v4 == undefined) { + ret.score = 800; + ret.why = "No IPv4 ping reply"; + } + + v4 = parseFloat(v4); + v6 = parseFloat(v6); + if (tagged(sw, "ignorev6")) { + v6 = 0; + } + if (v4 > ret.score || v6 > ret.score) { + ret.why = "Latency"; + ret.score = parseInt(v4 > v6 ? v4 : v6); + } + if ( + nmsData.ping.switches[sw].age4 > 10 || + nmsData.ping.switches[sw].age6 > 10 + ) { + ret.why = "Old ping"; + ret.score = 900; + } + } else { + ret.data[0].value = "No ping replies"; + ret.why = "No ping replies"; + ret.score = 999; + } + + if (testTree(nmsData, ["smanagement", "switches", sw])) { + try { + var distro = nmsData["smanagement"]["switches"][sw]["distro_name"]; + var phy = nmsData["smanagement"]["switches"][sw]["distro_phy_port"]; + if ( + !(distro == "" || phy == "" || distro == undefined || phy == undefined) + ) { + ret.data[3] = {}; + ret.data[3].description = "Distro-port"; + ret.data[3].value = distro + " " + phy; + if ( + testTree(nmsData, [ + "snmp", + "snmp", + distro, + "ports", + phy, + "ifOperStatus", + ]) + ) { + var x = nmsData["snmp"]["snmp"][distro]["ports"][phy]["ifOperStatus"]; + var ping = "no"; + var ping6 = "no "; + try { + ping = parseFloat(nmsData["ping"]["switches"][sw]["latency4"]); + ping6 = parseFloat(nmsData["ping"]["switches"][sw]["latency6"]); + } catch (e) {} + if (x == "up") { + ret.data[3].value += " (😇 up!)"; + if (isNaN(ping) && isNaN(ping6)) { + ret.score = 700; + ret.why = "Distro port is alive, but no IPv4/IPv6 ping."; + if ( + testTree(nmsData, [ + "snmp", + "snmp", + distro, + "ports", + phy, + "ifLastChange", + ]) + ) { + if ( + testTree(nmsData, [ + "snmp", + "snmp", + distro, + "misc", + "sysUpTimeInstance", + ]) + ) { + ret.data[4] = {}; + ret.data[4].description = "Distro port changed"; + diff = + (parseInt( + nmsData["snmp"]["snmp"][distro]["misc"][ + "sysUpTimeInstance" + ][""] + ) - + parseInt( + nmsData["snmp"]["snmp"][distro]["ports"][phy][ + "ifLastChange" + ] + )) / + 100; + var diff2 = { + d: parseInt(diff / 60 / 60 / 24), + h: parseInt((diff / 60 / 60) % 24), + m: parseInt((diff / 60) % 60), + s: parseInt(diff % 60), + }; + + ret.data[4].value = printDiff(diff2); + } + } + } + } else { + ret.data[3].value += " (👺down)"; + } + } + } + } catch (e) { + console.log("Lazy about errors...."); + console.log(e); + } + } + return ret; } -function pingInit() -{ - nmsColor.drawGradient([nmsColor.green,nmsColor.lightgreen, nmsColor.orange, nmsColor.red]); - setLegend(1,nmsColor.getColorStop(10),"1ms"); - setLegend(2,nmsColor.getColorStop(300),"30ms"); - setLegend(3,nmsColor.getColorStop(600),"60ms"); - setLegend(4,nmsColor.getColorStop(1000),"100ms"); - setLegend(5,nmsColor.blue,"No response"); - nmsData.addHandler("ping","mapHandler",pingUpdater); - pingUpdater(); +function pingInit() { + nmsColor.drawGradient([ + nmsColor.green, + nmsColor.teal, + nmsColor.orange, + nmsColor.red, + ]); + setLegend(1, nmsColor.getColorStop(10), "1ms"); + setLegend(2, nmsColor.getColorStop(300), "30ms"); + setLegend(3, nmsColor.getColorStop(600), "60ms"); + setLegend(4, nmsColor.getColorStop(1000), "100ms"); + setLegend(5, nmsColor.blue, "No response"); + nmsData.addHandler("ping", "mapHandler", pingUpdater); + pingUpdater(); } -function getDhcpColor(stop) -{ - stop = parseInt(stop); - stop = stop * 0.85; - if (stop < 0) - stop = 1000; - if (stop > 1000) - stop = 1000; - return nmsColor.getColorStop(stop); +function getDhcpColor(stop) { + stop = parseInt(stop); + stop = stop * 0.85; + if (stop < 0) stop = 1000; + if (stop > 1000) stop = 1000; + return nmsColor.getColorStop(stop); } -function dhcpUpdater() -{ - if (!testTree(nmsData,['dhcp','dhcp4']) || !testTree(nmsData,['dhcp','dhcp6']) || !testTree(nmsData,['switches','switches']) || !testTree(nmsData,['smanagement','switches'])) { - return; - } - var now = nmsData.dhcp.time; - for (var sw in nmsData.switches.switches) { - var c = nmsColor.blue; - var sv4 = nmsData.dhcp.dhcp4[nmsData.smanagement.switches[sw].traffic_vlan]; - var sv6 = nmsData.dhcp.dhcp6[nmsData.smanagement.switches[sw].traffic_vlan]; - if (sv4 == undefined && sv6 == undefined) { - nmsMap.setSwitchColor(sw,c); - continue; - } - var thenv4 = parseInt(sv4); - var thenv6 = parseInt(sv6); - var then = Math.max(thenv4, thenv6) - c = getDhcpColor(now - then); - nmsMap.setSwitchColor(sw, c); - } +function dhcpUpdater() { + if ( + !testTree(nmsData, ["dhcp", "dhcp4"]) || + !testTree(nmsData, ["dhcp", "dhcp6"]) || + !testTree(nmsData, ["switches", "switches"]) || + !testTree(nmsData, ["smanagement", "switches"]) + ) { + return; + } + var now = nmsData.dhcp.time; + for (var sw in nmsData.switches.switches) { + var c = nmsColor.blue; + var sv4 = nmsData.dhcp.dhcp4[nmsData.smanagement.switches[sw].traffic_vlan]; + var sv6 = nmsData.dhcp.dhcp6[nmsData.smanagement.switches[sw].traffic_vlan]; + if (sv4 == undefined && sv6 == undefined) { + nmsMap.setSwitchColor(sw, c); + continue; + } + var thenv4 = parseInt(sv4); + var thenv6 = parseInt(sv6); + var then = Math.max(thenv4, thenv6); + c = getDhcpColor(now - then); + nmsMap.setSwitchColor(sw, c); + } } function dhcpInfo(sw) { - var ret = new handlerInfo("dhcp","DHCP state"); - ret.why = "No DHCP data"; - ret.data[0].description = "DHCPv4 age"; - - ret.data[1] = {}; - ret.data[1].description = "DHCPv6 age"; - - if (!testTree(nmsData,['dhcp','dhcp4']) || !testTree(nmsData,['dhcp','dhcp6']) || !testTree(nmsData,['switches','switches']) || !testTree(nmsData,['smanagement','switches'])) { - return ret.data[1] = {}; + var ret = new handlerInfo("dhcp", "DHCP state"); + ret.why = "No DHCP data"; + ret.data[0].description = "DHCPv4 age"; + + ret.data[1] = {}; + ret.data[1].description = "DHCPv6 age"; + + if ( + !testTree(nmsData, ["dhcp", "dhcp4"]) || + !testTree(nmsData, ["dhcp", "dhcp6"]) || + !testTree(nmsData, ["switches", "switches"]) || + !testTree(nmsData, ["smanagement", "switches"]) + ) { + return (ret.data[1] = {}); + } + var dhcpClients = 0; + var clientPortsUp = 0; + var clientPortsUp = setTree( + nmsData, + ["switchstate", "switches", sw, "clients", "live"], + 0 + ); + var clientPortsTotal = setTree( + nmsData, + ["switchstate", "switches", sw, "clients", "total"], + 0 + ); + if (testTree(nmsData, ["smanagement", "switches", sw, "traffic_vlan"])) { + if ( + testTree(nmsData, [ + "dhcp", + "networks", + nmsData.smanagement.switches[sw].traffic_vlan, + "clients", + ]) + ) { + dhcpClients = + nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan] + .clients; + } + } + if ( + testTree(nmsData, [ + "dhcp", + "dhcp4", + nmsData.smanagement.switches[sw].traffic_vlan, + ]) + ) { + var now = nmsData.dhcp.time; + var then = + nmsData.dhcp.dhcp4[nmsData.smanagement.switches[sw].traffic_vlan]; + var diff = now - then; + var divider = 10; + if (dhcpClients < 10) { + divider = 12; + } + if (tagged(sw, "slowdhcp")) { + divider = 12; + } + + ret.data[0].value = secondsToTime(diff); + ret.why = "DHCP freshness"; + ret.score = diff / divider > 350 ? 350 : parseInt(diff / divider); + } else { + ret.data[0].value = "No DHCPv4 data"; + if (testTree(nmsData, ["smanagement", "switches", sw])) { + if ( + nmsData.smanagement.switches[sw].traffic_vlan == undefined || + nmsData.smanagement.switches[sw].traffic_vlan == "" + ) { + ret.data[0].value = "No associated networks"; + ret.score = 0; + ret.why = "No network associated"; + } else { + if (!(clientPortsUp < 2 && clientPortsTotal > 20)) { + ret.score = 350; + ret.why = "No DHCPv4 data"; + } else { + ret.data[0].value = "No DHCPv4 data, but too few clients anyway"; } - var dhcpClients = 0; - var clientPortsUp = 0; - var clientPortsUp = setTree(nmsData,['switchstate','switches',sw,'clients','live'],0); - var clientPortsTotal = setTree(nmsData,['switchstate','switches',sw,'clients','total'],0); - if (testTree(nmsData,['smanagement','switches',sw,'traffic_vlan'])) { - if (testTree(nmsData,['dhcp','networks',nmsData.smanagement.switches[sw].traffic_vlan,'clients'])) { - dhcpClients = nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan].clients; - } - } - if (testTree(nmsData,['dhcp','dhcp4',nmsData.smanagement.switches[sw].traffic_vlan])) { - var now = nmsData.dhcp.time; - var then = nmsData.dhcp.dhcp4[nmsData.smanagement.switches[sw].traffic_vlan]; - var diff = now - then; - var divider = 10; - if (dhcpClients < 10) { - divider = 12; - } - if(tagged(sw,'slowdhcp')) { - divider = 12; - } - - ret.data[0].value = secondsToTime(diff); - ret.why = "DHCP freshness"; - ret.score = diff/divider> 350 ? 350 : parseInt(diff/divider); - } else { - ret.data[0].value = "No DHCPv4 data"; - if (testTree(nmsData,['smanagement','switches',sw])) { - if (nmsData.smanagement.switches[sw].traffic_vlan == undefined || - nmsData.smanagement.switches[sw].traffic_vlan == "") { - ret.data[0].value = "No associated networks"; - ret.score = 0; - ret.why = "No network associated"; - } else { - if (!(clientPortsUp < 2 && clientPortsTotal > 20)) { - ret.score = 350; - ret.why = "No DHCPv4 data"; - } else { - ret.data[0].value = "No DHCPv4 data, but too few clients anyway"; - } - } - } else { - ret.score = 100; - ret.why = "No management data for DHCP"; - } - } - if (testTree(nmsData,['dhcp','dhcp6',nmsData.smanagement.switches[sw].traffic_vlan])) { - var now = nmsData.dhcp.time; - var then = nmsData.dhcp.dhcp6[nmsData.smanagement.switches[sw].traffic_vlan]; - var diff = now - then; - var divider = 10; - if (dhcpClients < 10) { - divider = 12; - } - if(tagged(sw,'slowdhcp')) { - divider = 12; - } - - ret.data[1].value = secondsToTime(diff); - ret.why = "DHCP freshness"; - ret.score = diff/divider> 350 ? 350 : parseInt(diff/divider); + } + } else { + ret.score = 100; + ret.why = "No management data for DHCP"; + } + } + if ( + testTree(nmsData, [ + "dhcp", + "dhcp6", + nmsData.smanagement.switches[sw].traffic_vlan, + ]) + ) { + var now = nmsData.dhcp.time; + var then = + nmsData.dhcp.dhcp6[nmsData.smanagement.switches[sw].traffic_vlan]; + var diff = now - then; + var divider = 10; + if (dhcpClients < 10) { + divider = 12; + } + if (tagged(sw, "slowdhcp")) { + divider = 12; + } + + ret.data[1].value = secondsToTime(diff); + ret.why = "DHCP freshness"; + ret.score = diff / divider > 350 ? 350 : parseInt(diff / divider); + } else { + ret.data[1].value = "No DHCPv6 data"; + if (testTree(nmsData, ["smanagement", "switches", sw])) { + if ( + nmsData.smanagement.switches[sw].traffic_vlan == undefined || + nmsData.smanagement.switches[sw].traffic_vlan == "" + ) { + ret.data[1].value = "No associated networks"; + ret.score = 0; + ret.why = "No network associated"; + } else { + if (!(clientPortsUp < 2 && clientPortsTotal > 20)) { + ret.score = 350; + ret.why = "No DHCPv6 data"; } else { - ret.data[1].value = "No DHCPv6 data"; - if (testTree(nmsData,['smanagement','switches',sw])) { - if (nmsData.smanagement.switches[sw].traffic_vlan == undefined || - nmsData.smanagement.switches[sw].traffic_vlan == "") { - ret.data[1].value = "No associated networks"; - ret.score = 0; - ret.why = "No network associated"; - } else { - if (!(clientPortsUp < 2 && clientPortsTotal > 20)) { - ret.score = 350; - ret.why = "No DHCPv6 data"; - } else { - ret.data[1].value = "No DHCPv6 data, but too few clients anyway"; - } - } - } else { - ret.score = 100; - ret.why = "No management data for DHCP"; - } + ret.data[1].value = "No DHCPv6 data, but too few clients anyway"; } - if (testTree(nmsData,['dhcp','networks',nmsData.smanagement.switches[sw].traffic_vlan,'clients'])) { - var dhcpClients = nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan].clients; - ret.data[2] = {}; - ret.data[2].value = nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan].clients; - ret.data[2].description = "DHCP clients"; - if (testTree(nmsData,['switchstate','switches',sw,'clients','live'])) { - var tu = parseInt(nmsData.switchstate.switches[sw].clients.live); - var tt = parseInt(nmsData.switchstate.switches[sw].clients.total); - if (tu - dhcpClients > 12) { - if (ret.score < 450) { - ret.score = 450; - ret.why = "Far more client ports than dhcp clients"; - } - } - } - } - if (testTree(nmsData,['switches','switches',sw, 'tags'])) { - if (tagged(sw,'ignoredhcp')) { - ret.score = 0; - ret.why += "(Ignored)"; - ret.data[0].value += "(Ignored)"; - } - } - return ret; + } + } else { + ret.score = 100; + ret.why = "No management data for DHCP"; + } + } + if ( + testTree(nmsData, [ + "dhcp", + "networks", + nmsData.smanagement.switches[sw].traffic_vlan, + "clients", + ]) + ) { + var dhcpClients = + nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan] + .clients; + ret.data[2] = {}; + ret.data[2].value = + nmsData.dhcp.networks[ + nmsData.smanagement.switches[sw].traffic_vlan + ].clients; + ret.data[2].description = "DHCP clients"; + if (testTree(nmsData, ["switchstate", "switches", sw, "clients", "live"])) { + var tu = parseInt(nmsData.switchstate.switches[sw].clients.live); + var tt = parseInt(nmsData.switchstate.switches[sw].clients.total); + if (tu - dhcpClients > 12) { + if (ret.score < 450) { + ret.score = 450; + ret.why = "Far more client ports than dhcp clients"; + } + } + } + } + if (testTree(nmsData, ["switches", "switches", sw, "tags"])) { + if (tagged(sw, "ignoredhcp")) { + ret.score = 0; + ret.why += "(Ignored)"; + ret.data[0].value += "(Ignored)"; + } + } + return ret; } -function dhcpInit() -{ - nmsColor.drawGradient([nmsColor.green, nmsColor.lightgreen, nmsColor.orange, nmsColor.red]); - nmsData.addHandler("dhcp","mapHandler",dhcpUpdater); - setLegend(1,"white","Undefined"); - setLegend(2,getDhcpColor(1),"1 Second old"); - setLegend(3,getDhcpColor(300),"300 Seconds old"); - setLegend(4,getDhcpColor(900),"900 Seconds old"); - setLegend(5,getDhcpColor(1200),"1200 Seconds old"); - dhcpUpdater(); +function dhcpInit() { + nmsColor.drawGradient([ + nmsColor.green, + nmsColor.teal, + nmsColor.orange, + nmsColor.red, + ]); + nmsData.addHandler("dhcp", "mapHandler", dhcpUpdater); + setLegend(1, "white", "Undefined"); + setLegend(2, getDhcpColor(1), "1 Second old"); + setLegend(3, getDhcpColor(300), "300 Seconds old"); + setLegend(4, getDhcpColor(900), "900 Seconds old"); + setLegend(5, getDhcpColor(1200), "1200 Seconds old"); + dhcpUpdater(); } /* * Testing-function to randomize colors of linknets and switches */ -function randomizeColors() -{ -/* for (var i in nms.switches_now.linknets) { +function randomizeColors() { + /* for (var i in nms.switches_now.linknets) { setLinknetColors(i, getRandomColor(), getRandomColor()); } */ - if (nmsData.switches == undefined || nmsData.switches.switches == undefined) { - return; - } - for (var sw in nmsData.switches.switches) { - nmsMap.setSwitchColor(sw, nmsColor.random()); - } + if (nmsData.switches == undefined || nmsData.switches.switches == undefined) { + return; + } + for (var sw in nmsData.switches.switches) { + nmsMap.setSwitchColor(sw, nmsColor.random()); + } } function discoDo() { - randomizeColors(); + randomizeColors(); } -function discoInit() -{ - nmsData.addHandler("ticker", "mapHandler", discoDo); - - setNightMode(true); - setLegend(1,nmsColor.blue,"Y"); - setLegend(2,nmsColor.red, "M"); - setLegend(3,nmsColor.orange,"C"); - setLegend(4,nmsColor.green, "A"); - setLegend(5,"white","!"); - discoDo(); +function discoInit() { + nmsData.addHandler("ticker", "mapHandler", discoDo); + + setNightMode(true); + setLegend(1, nmsColor.blue, "Y"); + setLegend(2, nmsColor.red, "M"); + setLegend(3, nmsColor.orange, "C"); + setLegend(4, nmsColor.green, "A"); + setLegend(5, "white", "!"); + discoDo(); } function snmpUpdater() { - for (var sw in nmsData.switches.switches) { - if (nmsData.snmp.snmp[sw] == undefined || nmsData.snmp.snmp[sw].misc == undefined) { - nmsMap.setSwitchColor(sw, nmsColor.red); - } else if (nmsData.snmp.snmp[sw].misc.sysName[0] != sw) { - nmsMap.setSwitchColor(sw, nmsColor.orange); - } else { - nmsMap.setSwitchColor(sw, nmsColor.green); - } - } + for (var sw in nmsData.switches.switches) { + if ( + nmsData.snmp.snmp[sw] == undefined || + nmsData.snmp.snmp[sw].misc == undefined + ) { + nmsMap.setSwitchColor(sw, nmsColor.red); + } else if (nmsData.snmp.snmp[sw].misc.sysName[0] != sw) { + nmsMap.setSwitchColor(sw, nmsColor.orange); + } else { + nmsMap.setSwitchColor(sw, nmsColor.green); + } + } } function secondsToTime(input) { - var d, h, m, s; - d = Math.floor(input / 60 / 60 / 24); - h = Math.floor((input - (d * 24 * 3600)) / 60 / 60); - m = Math.floor((input%3600)/60); - s = Math.floor(input%60); - var string = ""; - if (d > 0) - string = d + " days "; - if (h > 0) - string += h + " hours "; - if (h > 0 || m > 0) - string += m + " minutes "; - if (string == "") - string += s + " seconds"; - return string; + var d, h, m, s; + d = Math.floor(input / 60 / 60 / 24); + h = Math.floor((input - d * 24 * 3600) / 60 / 60); + m = Math.floor((input % 3600) / 60); + s = Math.floor(input % 60); + var string = ""; + if (d > 0) string = d + " days "; + if (h > 0) string += h + " hours "; + if (h > 0 || m > 0) string += m + " minutes "; + if (string == "") string += s + " seconds"; + return string; } function snmpInfo(sw) { - var ret = new handlerInfo("snmp","SNMP data"); - ret.why = "No SNMP data"; - if (tagged(sw,'ignore-snmp')) { - ret.score = 0; - ret.why += "(Ignored)"; - ret.data[0].value += "(Ignored)"; - } - else if (!testTree(nmsData,['snmp','snmp',sw,'misc'])) { - ret.score = 500; - ret.why = "No SNMP data"; - ret.data[0].value = "No data"; - if (testTree(nmsData,['smanagement','switches',sw])) { - if (nmsData.smanagement.switches[sw].community == undefined || - nmsData.smanagement.switches[sw].community == "disable") { - ret.score = 0; - ret.why = "SNMP disabled"; - ret.data[0].value = "SNMP disabled"; - } - } - } else if (nmsData.snmp.snmp[sw].misc.sysName[0].indexOf(sw) != 0) { - ret.score = 200; - ret.why = "SNMP sysName doesn't match Gondul sysname"; - ret.data[0].value = ret.why; - ret.data[1] = { description: "SNMP sysName", value: nmsData.snmp.snmp[sw].misc.sysName[0] }; - } else { - ret.score = 0; - ret.data[0].value = "Available"; - ret.why = "SNMP all good"; - } - if (testTree(nmsData,['snmp','snmp',sw,'misc','sysUpTimeInstance',''])) { - var uptime = parseInt(nmsData.snmp.snmp[sw]["misc"]["sysUpTimeInstance"][""]) / 100; - var upstring = secondsToTime(uptime); - ret.data.push({value: upstring, description: "System uptime"}); - if (uptime < 60*5 && ret.score < 300) { - ret.score = 300; - ret.why = "System rebooted last 5 minutes"; - } - if (uptime < 60*15 && ret.score < 250) { - ret.score = 250; - ret.why = "System rebooted last 15 minutes"; - } - } - if (testTree(nmsData,['snmp','snmp',sw,'misc','sysDescr','0'])) { - ret.data[1].description = "Description"; - lol = nmsData['snmp']['snmp'][sw]['misc']['sysDescr']['0']; - re1 = /Juniper Networks, Inc./ - re2 = /, Build date.*$/ - lol = lol.replace(re1,"") - lol = lol.replace(re2,"") - ret.data[1].value = lol - } - return ret; + var ret = new handlerInfo("snmp", "SNMP data"); + ret.why = "No SNMP data"; + if (tagged(sw, "ignore-snmp")) { + ret.score = 0; + ret.why += "(Ignored)"; + ret.data[0].value += "(Ignored)"; + } else if (!testTree(nmsData, ["snmp", "snmp", sw, "misc"])) { + ret.score = 500; + ret.why = "No SNMP data"; + ret.data[0].value = "No data"; + if (testTree(nmsData, ["smanagement", "switches", sw])) { + if ( + nmsData.smanagement.switches[sw].community == undefined || + nmsData.smanagement.switches[sw].community == "disable" + ) { + ret.score = 0; + ret.why = "SNMP disabled"; + ret.data[0].value = "SNMP disabled"; + } + } + } else if (nmsData.snmp.snmp[sw].misc.sysName[0].indexOf(sw) != 0) { + ret.score = 200; + ret.why = "SNMP sysName doesn't match Gondul sysname"; + ret.data[0].value = ret.why; + ret.data[1] = { + description: "SNMP sysName", + value: nmsData.snmp.snmp[sw].misc.sysName[0], + }; + } else { + ret.score = 0; + ret.data[0].value = "Available"; + ret.why = "SNMP all good"; + } + if ( + testTree(nmsData, ["snmp", "snmp", sw, "misc", "sysUpTimeInstance", ""]) + ) { + var uptime = + parseInt(nmsData.snmp.snmp[sw]["misc"]["sysUpTimeInstance"][""]) / 100; + var upstring = secondsToTime(uptime); + ret.data.push({ value: upstring, description: "System uptime" }); + if (uptime < 60 * 5 && ret.score < 300) { + ret.score = 300; + ret.why = "System rebooted last 5 minutes"; + } + if (uptime < 60 * 15 && ret.score < 250) { + ret.score = 250; + ret.why = "System rebooted last 15 minutes"; + } + } + if (testTree(nmsData, ["snmp", "snmp", sw, "misc", "sysDescr", "0"])) { + lol = nmsData["snmp"]["snmp"][sw]["misc"]["sysDescr"]["0"]; + re1 = /Juniper Networks, Inc./; + re2 = /, Build date.*$/; + re3 = /Arista Networks./; + lol = lol.replace(re1, ""); + lol = lol.replace(re2, ""); + lol = lol.replace(re3, ""); + ret.data.push({ value: lol, description: "Description" }); + } + return ret; } - function snmpInit() { - nmsData.addHandler("snmp", "mapHandler", snmpUpdater); - - setLegend(1,nmsColor.green,"OK"); - setLegend(2,nmsColor.orange, "Sysname mismatch"); - setLegend(3,nmsColor.red,"No SNMP data"); - setLegend(4,nmsColor.green, ""); - setLegend(5,nmsColor.green,""); - snmpUpdater(); + nmsData.addHandler("snmp", "mapHandler", snmpUpdater); + + setLegend(1, nmsColor.green, "OK"); + setLegend(2, nmsColor.orange, "Sysname mismatch"); + setLegend(3, nmsColor.red, "No SNMP data"); + setLegend(4, nmsColor.green, ""); + setLegend(5, nmsColor.green, ""); + snmpUpdater(); } function snmpUpInfo(sw) { - var ret = new handlerInfo("uplink","SNMP uplink data"); - ret.why = "No SNMP data"; - ret.score = 0; - - if (testTree(nmsData,['snmp','snmp',sw, 'ports'])) { - var total_up = 0; - var seen_up = 0; - for (var port in nmsData.snmp.snmp[sw].ports) { - var x = nmsData.snmp.snmp[sw].ports[port]; - if(x["ifAlias"] != null) { - if (x["ifAlias"].match(/B:/i) && x["ifOperStatus"] == "up") { - total_up += parseInt(x["ifHighSpeed"]); - } - if (x["ifAlias"].match(/G:/i) && x["ifOperStatus"] == "up") { - seen_up += parseInt(x["ifHighSpeed"]); - } - } - } - ret.data[0].value = "LAG member speed and total speed is " + seen_up; - if (total_up != seen_up) { - ret.score = 500; - if (tagged(sw,'ignoreuplink')) { - ret.score = 0; - } - - ret.why = "LAG member (ge/mge/xe/et) speed is " + seen_up + " but logical (ae) is " + total_up; - ret.data[0].value = ret.why; - } - } - return ret; + var ret = new handlerInfo("uplink", "SNMP uplink data"); + ret.why = "No SNMP uplink data"; + ret.score = 0; + + if (testTree(nmsData, ["snmp", "snmp", sw, "ports"])) { + var total_up = 0; + var seen_up = 0; + for (var port in nmsData.snmp.snmp[sw].ports) { + var x = nmsData.snmp.snmp[sw].ports[port]; + if (x["ifAlias"] != null) { + if (x["ifAlias"].match(/B:/i) && x["ifOperStatus"] == "up") { + total_up += parseInt(x["ifHighSpeed"]); + } + if (x["ifAlias"].match(/G:/i) && x["ifOperStatus"] == "up") { + seen_up += parseInt(x["ifHighSpeed"]); + } + } + } + ret.data[0].value = "LAG member speed and total speed is " + seen_up; + if (total_up != seen_up) { + ret.score = 500; + if (tagged(sw, "ignoreuplink")) { + ret.score = 0; + } + + ret.why = + "LAG member (ge/mge/xe/et) speed is " + + seen_up + + " but logical (ae) is " + + total_up; + ret.data[0].value = ret.why; + } + } + return ret; } function cpuInfo(sw) { - var ret = new handlerInfo("cpu","CPU utilization"); - ret.why = "No CPU info"; - ret.score = 0; - - if (testTree(nmsData,['snmp','snmp',sw, 'misc','jnxOperatingCPU'])) { - var cpu = 0; - for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingCPU) { - var local = nmsData.snmp.snmp[sw].misc['jnxOperatingCPU'][u]; - cpu = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingCPU[u],cpu); - } - if (cpu < 40) { - ret.score = 0; - } else if (cpu < 50) { - ret.score = 100; - } else if (cpu < 85 ) { - ret.score = cpu * 3; - } else { - ret.score = cpu * 7; - } - ret.why = "CPU utilization: " + cpu + "%"; - ret.data[0].value = cpu + "%"; - } - return ret; + var ret = new handlerInfo("cpu", "CPU utilization"); + ret.why = "No CPU info"; + ret.score = 0; + + if (testTree(nmsData, ["snmp", "snmp", sw, "misc", "jnxOperatingCPU"])) { + var cpu = 0; + for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingCPU) { + var local = nmsData.snmp.snmp[sw].misc["jnxOperatingCPU"][u]; + cpu = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingCPU[u], cpu); + } + if (cpu < 40) { + ret.score = 0; + } else if (cpu < 50) { + ret.score = 100; + } else if (cpu < 85) { + ret.score = cpu * 3; + } else { + ret.score = cpu * 7; + } + ret.why = "CPU utilization: " + cpu + "%"; + ret.data[0].value = cpu + "%"; + } + return ret; } function cpuUpdater() { - for (var sw in nmsData.switches.switches) { - try { - var cpu = 0; - for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingCPU) { - var local = nmsData.snmp.snmp[sw].misc['jnxOperatingCPU'][u]; - cpu = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingCPU[u],cpu); - } - nmsMap.setSwitchColor(sw, nmsColor.getColorStop(cpu * 10)); - nmsMap.setSwitchInfo(sw, cpu + " % "); - } catch (e) { - nmsMap.setSwitchColor(sw, "white"); - nmsMap.setSwitchInfo(sw, "N/A"); - } - } + for (var sw in nmsData.switches.switches) { + try { + var cpu = 0; + for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingCPU) { + var local = nmsData.snmp.snmp[sw].misc["jnxOperatingCPU"][u]; + cpu = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingCPU[u], cpu); + } + nmsMap.setSwitchColor(sw, nmsColor.getColorStop(cpu * 10)); + nmsMap.setSwitchInfo(sw, cpu + " % "); + } catch (e) { + nmsMap.setSwitchColor(sw, "white"); + nmsMap.setSwitchInfo(sw, "N/A"); + } + } } function memoryUpdater() { - for (var sw in nmsData.switches.switches) { - try { - var buffer = 0; - for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer) { - var local = nmsData.snmp.snmp[sw].misc['jnxOperatingBuffer'][u]; - buffer = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer[u],buffer); - } - nmsMap.setSwitchColor(sw, nmsColor.getColorStop(buffer * 10)); - nmsMap.setSwitchInfo(sw, buffer + " % "); - } catch (e) { - nmsMap.setSwitchColor(sw, "white"); - nmsMap.setSwitchInfo(sw, "N/A"); - } - } + for (var sw in nmsData.switches.switches) { + try { + var buffer = 0; + for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer) { + var local = nmsData.snmp.snmp[sw].misc["jnxOperatingBuffer"][u]; + buffer = Math.max( + nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer[u], + buffer + ); + } + nmsMap.setSwitchColor(sw, nmsColor.getColorStop(buffer * 10)); + nmsMap.setSwitchInfo(sw, buffer + " % "); + } catch (e) { + nmsMap.setSwitchColor(sw, "white"); + nmsMap.setSwitchInfo(sw, "N/A"); + } + } } function memoryInfo(sw) { - var ret = new handlerInfo("memory","Memory utilization"); - ret.why = "No Memory info"; - ret.score = 0; - - if (testTree(nmsData,['snmp','snmp',sw, 'misc','jnxOperatingBuffer'])) { - var memory = 0; - for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer) { - var local = nmsData.snmp.snmp[sw].misc['jnxOperatingBuffer'][u]; - memory = Math.max(nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer[u],memory); - } - if (memory < 70) { - ret.score = 0; - } else if (memory < 80) { - ret.score = 100; - } else if (memory < 90) { - ret.score = memory * 2; - } else { - ret.score = memory * 6; - } - ret.why = "Memory utilization: " + memory + "%"; - ret.data[0].value = memory + "%"; - } - return ret; + var ret = new handlerInfo("memory", "Memory utilization"); + ret.why = "No Memory info"; + ret.score = 0; + + if (testTree(nmsData, ["snmp", "snmp", sw, "misc", "jnxOperatingBuffer"])) { + var memory = 0; + for (var u in nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer) { + var local = nmsData.snmp.snmp[sw].misc["jnxOperatingBuffer"][u]; + memory = Math.max( + nmsData.snmp.snmp[sw].misc.jnxOperatingBuffer[u], + memory + ); + } + if (memory < 70) { + ret.score = 0; + } else if (memory < 80) { + ret.score = 100; + } else if (memory < 90) { + ret.score = memory * 2; + } else { + ret.score = memory * 6; + } + ret.why = "Memory utilization: " + memory + "%"; + ret.data[0].value = memory + "%"; + } + return ret; } function tagged(sw, tag) { - try { - if (testTree(nmsData,['switches','switches',sw, 'tags'])) { - if (nmsData.switches.switches[sw].tags.includes(tag)) { - return true; - } - } - } catch(e) { - console.log("Tried to find tags for " + sw + "but tags-datastructure is probably not an array?"); - } - return false; + try { + if (testTree(nmsData, ["switches", "switches", sw, "tags"])) { + if (nmsData.switches.switches[sw].tags.includes(tag)) { + return true; + } + } + } catch (e) { + console.log( + "Tried to find tags for " + + sw + + "but tags-datastructure is probably not an array?" + ); + } + return false; } function networkInfo(sw) { - var ret = new handlerInfo("net","Network info"); - ret.score = 0; - ret.why = "All good"; - if (testTree(nmsData,['smanagement','switches',sw])) { - var i = 0; - var mg = nmsData.smanagement.switches[sw]; - var objs = [{ - d: "Management", - v: setTree(nmsData,['networks','networks',mg.mgmt_vlan],undefined) - },{ - d: "Traffic", - v: setTree(nmsData,['networks','networks',mg.traffic_vlan],undefined) - } - ]; - for (var x in objs) { - a = objs[x]; - if (a.v == undefined) { - ret.data[i++] = { - value: 'Not set', - description: a.d + ' network' - }; - continue; - } - - ret.data[i++] = { - value: (a.v.name || "Not set") + " " + "vlan: " + (a.v.vlan || "Not set"), - description: a.d + " network" - } - ret.data[i++] = { - value: a.v.subnet4 || "Not set", - description: a.d + " subnet IPv4" - } - ret.data[i++] = { - value: a.v.subnet6 || "Not set", - description: a.d + " subnet IPv6" - } - ret.data[i++] = { - value: a.v.router || "Not set", - description: a.d + " net router" - } - } - } - return ret; + var ret = new handlerInfo("net", "Network info"); + ret.score = 0; + ret.why = "All good"; + if (testTree(nmsData, ["smanagement", "switches", sw])) { + var i = 0; + var mg = nmsData.smanagement.switches[sw]; + var objs = [ + { + d: "Management", + v: setTree(nmsData, ["networks", "networks", mg.mgmt_vlan], undefined), + }, + { + d: "Traffic", + v: setTree( + nmsData, + ["networks", "networks", mg.traffic_vlan], + undefined + ), + }, + ]; + for (var x in objs) { + a = objs[x]; + if (a.v == undefined) { + ret.data[i++] = { + value: "Not set", + description: a.d + " network", + }; + continue; + } + + ret.data[i++] = { + value: + (a.v.name || "Not set") + " " + "vlan: " + (a.v.vlan || "Not set"), + description: a.d + " network", + }; + ret.data[i++] = { + value: a.v.subnet4 || "Not set", + description: a.d + " subnet IPv4", + }; + ret.data[i++] = { + value: a.v.subnet6 || "Not set", + description: a.d + " subnet IPv6", + }; + ret.data[i++] = { + value: a.v.router || "Not set", + description: a.d + " net router", + }; + } + } + return ret; } function mgmtInfo(sw) { - var ret = new handlerInfo("mgmt","Management info"); - ret.score = 0; - ret.why = "All good"; - if (testTree(nmsData,['smanagement','switches',sw])) { - var mg = nmsData.smanagement.switches[sw]; - ret.data = - [{ - value: (mg.mgmt_v4_addr || "N/A") + " / " + (mg.mgmt_v6_addr || "N/A"), - description: "Management IP" - } - ]; - if ((mg.mgmt_v4_addr == undefined || mg.mgmt_v4_addr == "") && (mg.mgmt_v6_addr == undefined || mg.mgmt_v6_addr == "")) { - ret.why = "No IPv4 or IPv6 management IP"; - ret.score = 1000; - } else if (mg.mgmt_v4_addr == undefined || mg.mgmt_v4_addr == "") { - ret.why = "No IPv4 management IP"; - ret.score = 550; - } else if (mg.mgmt_v6_addr == undefined || mg.mgmt_v6_addr == "") { - ret.why = "No IPv6 management IP"; - ret.score = 560; - if (tagged(sw,'ignorev6')) { - ret.score = 0; - } - } - } else { - ret.score = 1000; - ret.why = "No management info"; - ret.data = [{}]; - ret.data[0].value = "N/A"; - ret.data[0].description = "Management info"; - }; - if (tagged(sw,'maint')) { - ret.score = 1337; - ret.why = "Maintenance mode: maint tag"; - } - return ret; + var ret = new handlerInfo("mgmt", "Management info"); + ret.score = 0; + ret.why = "All good"; + if (testTree(nmsData, ["smanagement", "switches", sw])) { + var mg = nmsData.smanagement.switches[sw]; + ret.data = [ + { + value: (mg.mgmt_v4_addr || "N/A") + " / " + (mg.mgmt_v6_addr || "N/A"), + description: "Management IP", + }, + ]; + if ( + (mg.mgmt_v4_addr == undefined || mg.mgmt_v4_addr == "") && + (mg.mgmt_v6_addr == undefined || mg.mgmt_v6_addr == "") + ) { + ret.why = "No IPv4 or IPv6 management IP"; + ret.score = 1000; + } else if (mg.mgmt_v4_addr == undefined || mg.mgmt_v4_addr == "") { + ret.why = "No IPv4 management IP"; + ret.score = 550; + } else if (mg.mgmt_v6_addr == undefined || mg.mgmt_v6_addr == "") { + ret.why = "No IPv6 management IP"; + ret.score = 560; + if (tagged(sw, "ignorev6")) { + ret.score = 0; + } + } + } else { + ret.score = 1000; + ret.why = "No management info"; + ret.data = [{}]; + ret.data[0].value = "N/A"; + ret.data[0].description = "Management info"; + } + if (tagged(sw, "maint")) { + ret.score = 1337; + ret.why = "Maintenance mode: maint tag"; + } + return ret; } function cpuInit() { - nmsData.addHandler("snmp", "mapHandler", cpuUpdater); - nmsColor.drawGradient([nmsColor.green,nmsColor.orange,nmsColor.red]); - setLegend(1,getColorStop(0),"0 %"); - setLegend(2,getColorStop(250),"25 %"); - setLegend(3,getColorStop(600),"60 %"); - setLegend(4,getColorStop(1000),"100 %"); - setLegend(5,"white","N/A"); - cpuUpdater(); + nmsData.addHandler("snmp", "mapHandler", cpuUpdater); + nmsColor.drawGradient([nmsColor.green, nmsColor.orange, nmsColor.red]); + setLegend(1, getColorStop(0), "0 %"); + setLegend(2, getColorStop(250), "25 %"); + setLegend(3, getColorStop(600), "60 %"); + setLegend(4, getColorStop(1000), "100 %"); + setLegend(5, "white", "N/A"); + cpuUpdater(); } function memoryInit() { - nmsData.addHandler("snmp", "mapHandler", memoryUpdater); - nmsColor.drawGradient([nmsColor.green,nmsColor.orange,nmsColor.red]); - setLegend(1,getColorStop(0),"0 %"); - setLegend(2,getColorStop(250),"25 %"); - setLegend(3,getColorStop(600),"60 %"); - setLegend(4,getColorStop(1000),"100 %"); - setLegend(5,"white","N/A"); - memoryUpdater(); + nmsData.addHandler("snmp", "mapHandler", memoryUpdater); + nmsColor.drawGradient([nmsColor.green, nmsColor.orange, nmsColor.red]); + setLegend(1, getColorStop(0), "0 %"); + setLegend(2, getColorStop(250), "25 %"); + setLegend(3, getColorStop(600), "60 %"); + setLegend(4, getColorStop(1000), "100 %"); + setLegend(5, "white", "N/A"); + memoryUpdater(); } function healthInfo(sw) { - var worst = new handlerInfo("health", "Health"); - var realdata = {}; - worst.score = 0; - worst.why = "All good"; - for (var h in handlers) { - if (handlers[h].tag== "health") - continue; - if (handlers[h].getInfo == undefined) - continue; - var ret = handlers[h].getInfo(sw); - realdata[handlers[h].tag] = ret.data; - if (ret.score > worst.score) { - worst = ret; - } - } - worst.data = [{ - description: "Health (lower is better)", - value: worst.score + " (" + worst.why + ")" - }]; - realdata['health'] = worst.data; - worst.realdata = realdata; - return worst; + var worst = new handlerInfo("health", "Health"); + var realdata = {}; + worst.score = 0; + worst.why = "All good"; + for (var h in handlers) { + if (handlers[h].tag == "health") continue; + if (handlers[h].getInfo == undefined) continue; + var ret = handlers[h].getInfo(sw); + realdata[handlers[h].tag] = ret.data; + if (ret.score > worst.score) { + worst = ret; + } + } + worst.data = [ + { + description: "Health (lower is better)", + value: worst.score + " (" + worst.why + ")", + }, + ]; + realdata["health"] = worst.data; + worst.realdata = realdata; + return worst; } -var nmsBlink = [] +var nmsBlink = []; function healthUpdater() { - if (nmsData.switches == undefined || nmsData.switches.switches == undefined) - return; - for (var sw in nmsData.switches.switches) { - var worst = healthInfo(sw); - color = nmsColor.getColorStop(worst.score); - // maint - if (worst.score == 1337) { - nmsMap.setSwitchColor(sw, "#89cff0"); - nmsMap.setSwitchInfo(sw, "maint"); - continue; - } - rigge = true; - // blinkenlights - if (rigge == false && worst.score > 650) { - if (nmsBlink[sw] == true) { - nmsMap.setSwitchColor(sw, "rebeccapurple"); - nmsBlink[sw] = false; - } else { - nmsMap.setSwitchColor(sw, nmsColor.getColorStop(worst.score)); - nmsBlink[sw] = true; - } - } else { - nmsMap.setSwitchColor(sw, nmsColor.getColorStop(worst.score)); - } - if (worst.score > 200) - nmsMap.setSwitchInfo(sw, worst.tag); - else { - if (nms.legendPick != undefined && - testTree(worst.realdata,[nms.legendPick.handler,nms.legendPick.idx])) { - nmsMap.setSwitchInfo(sw,worst.realdata[nms.legendPick.handler][nms.legendPick.idx].value); - } else { - nmsMap.setSwitchInfo(sw, undefined); - } - } - } + if (nmsData.switches == undefined || nmsData.switches.switches == undefined) + return; + for (var sw in nmsData.switches.switches) { + var worst = healthInfo(sw); + color = nmsColor.getColorStop(worst.score); + // maint + if (worst.score == 1337) { + nmsMap.setSwitchColor(sw, "#89cff0"); + nmsMap.setSwitchInfo(sw, "maint"); + continue; + } + rigge = true; + // blinkenlights + if (rigge == false && worst.score > 650) { + if (nmsBlink[sw] == true) { + nmsMap.setSwitchColor(sw, "rebeccapurple"); + nmsBlink[sw] = false; + } else { + nmsMap.setSwitchColor(sw, nmsColor.getColorStop(worst.score)); + nmsBlink[sw] = true; + } + } else { + nmsMap.setSwitchColor(sw, nmsColor.getColorStop(worst.score)); + } + if (worst.score > 200) nmsMap.setSwitchInfo(sw, worst.tag); + else { + if ( + nms.legendPick != undefined && + testTree(worst.realdata, [nms.legendPick.handler, nms.legendPick.idx]) + ) { + nmsMap.setSwitchInfo( + sw, + worst.realdata[nms.legendPick.handler][nms.legendPick.idx].value + ); + } else { + nmsMap.setSwitchInfo(sw, undefined); + } + } + } } function healthInit() { - nmsData.addHandler("ticker", "mapHandler", healthUpdater); - nmsColor.drawGradient([nmsColor.green,nmsColor.lightgreen, nmsColor.orange,nmsColor.red]); - setLegend(1,nmsColor.getColorStop(0),"All good"); - setLegend(2,nmsColor.getColorStop(250),"Ok-ish"); - setLegend(3,nmsColor.getColorStop(600),"Ick-ish"); - setLegend(4,nmsColor.getColorStop(800),"Nasty"); - setLegend(5,nmsColor.getColorStop(1000),"WTF?"); - healthUpdater(); + nmsData.addHandler("ticker", "mapHandler", healthUpdater); + nmsColor.drawGradient([ + nmsColor.green, + nmsColor.teal, + nmsColor.orange, + nmsColor.red, + ]); + setLegend(1, nmsColor.getColorStop(0), "All good"); + setLegend(2, nmsColor.getColorStop(250), "Ok-ish"); + setLegend(3, nmsColor.getColorStop(600), "Ick-ish"); + setLegend(4, nmsColor.getColorStop(900), "Nasty"); + setLegend(5, nmsColor.getColorStop(1000), "WTF?"); + healthUpdater(); } diff --git a/web/js/nms-map.js b/web/js/nms-map.js index bd88d1d..a658925 100644 --- a/web/js/nms-map.js +++ b/web/js/nms-map.js @@ -14,136 +14,149 @@ * nmsMap.disableHighlights() */ - var nmsMap = nmsMap || { - _moveInProgress: false, - stats: { - colorChange:0, - colorSame:0, - earlyDrawAll:0, - nowDups:0, - nows:0, - resizeEvents:0, - switchInfoSame:0, - switchInfoUpdate:0, - highlightChange:0, - textSwitchDraws:0, - textInfoDraws:0, - textInfoClears:0 - }, - contexts: ["bg","link","blur","switch","text","textInfo","top","input","hidden"], - _info: {}, - _settings: { - fontLineFactor: 2, - textMargin: 4, - xMargin: 10, - yMargin: 20, - fontSize: 14, - fontFace: "sans-serif" - }, - scale: 1, - _init: true, - _orig: { width:1920, height:1032 }, - _canvas: { - get width() { return nmsMap.scale * nmsMap._orig.width; }, - get height() { return nmsMap.scale * nmsMap._orig.height; } - }, - - _color: { }, - _linknets: {} , - _highlight: { }, - _highlightActive: false, - _c: {}, - _lastName: {}, - _lastInfo: {} -}; - -nmsMap._loadEvent = function(e) { - nmsMap._init = false; - nmsMap._drawAllSwitches(); -}; - -nmsMap.init = function() { - this._initContexts(); - this._init = true; - nmsData.addHandler("switches","nmsMap",function(){nmsMap._resizeEvent();}); - window.addEventListener('resize',nmsMap._resizeEvent,true); - window.addEventListener('load',nmsMap._loadEvent,true); -}; - -nmsMap.setSwitchColor = function(sw, color) { - /* - * NEED TO LOCATE? YAS. + _moveInProgress: false, + stats: { + colorChange: 0, + colorSame: 0, + earlyDrawAll: 0, + nowDups: 0, + nows: 0, + resizeEvents: 0, + switchInfoSame: 0, + switchInfoUpdate: 0, + highlightChange: 0, + textSwitchDraws: 0, + textInfoDraws: 0, + textInfoClears: 0, + }, + contexts: [ + "bg", + "link", + "blur", + "switch", + "text", + "textInfo", + "top", + "input", + "hidden", + ], + _info: {}, + _settings: { + fontLineFactor: 2, + textMargin: 4, + xMargin: 10, + yMargin: 20, + fontSize: 14, + fontFace: "sans-serif", + }, + scale: 1, + _init: true, + _orig: { width: 1920, height: 1032 }, + _canvas: { + get width() { + return nmsMap.scale * nmsMap._orig.width; + }, + get height() { + return nmsMap.scale * nmsMap._orig.height; + }, + }, + + _color: {}, + _linknets: {}, + _highlight: {}, + _highlightActive: false, + _c: {}, + _lastName: {}, + _lastInfo: {}, +}; + +nmsMap._loadEvent = function (e) { + nmsMap._init = false; + nmsMap._drawAllSwitches(); +}; + +nmsMap.init = function () { + this._initContexts(); + this._init = true; + nmsData.addHandler("switches", "nmsMap", function () { + nmsMap._resizeEvent(); + }); + window.addEventListener("resize", nmsMap._resizeEvent, true); + if (document.readyState === "complete") { + nmsMap._loadEvent(); + } else { + window.addEventListener("load", nmsMap._loadEvent, true); + } +}; + +nmsMap.setSwitchColor = function (sw, color) { + /* + * NEED TO LOCATE? YAS. if (nmsData.switches.switches[sw] && nmsData.switches.switches[sw].tags.includes("locating") && this._color[sw] != "purple") { color = "purple"; } */ - if (this._color[sw] != color) { - this._color[sw] = color; - this._drawSwitch(sw); - this.stats.colorChange++; - } else { - this.stats.colorSame++; - } -}; - - -nmsMap.setSwitchHighlight = function(sw, highlight) { - if( highlight ) - highlight = true; - if ( this._highlight[sw] != highlight ) { - this.stats.highlightChange++; - this._highlight[sw] = highlight; - } + if (this._color[sw] != color) { + this._color[sw] = color; this._drawSwitch(sw); + this.stats.colorChange++; + } else { + this.stats.colorSame++; + } }; - -nmsMap.enableHighlights = function() { - this._highlightActive = true; +nmsMap.setSwitchHighlight = function (sw, highlight) { + if (highlight) highlight = true; + if (this._highlight[sw] != highlight) { + this.stats.highlightChange++; + this._highlight[sw] = highlight; + } + this._drawSwitch(sw); }; - -nmsMap.disableHighlights = function() { - this._highlightActive = false; - this._drawAllSwitches(); +nmsMap.enableHighlights = function () { + this._highlightActive = true; }; +nmsMap.disableHighlights = function () { + this._highlightActive = false; + this._drawAllSwitches(); +}; -nmsMap.reset = function() { - for (var sw in this._color) { - nmsMap.setSwitchColor(sw, undefined); - } - for (var sw in this._info) { - nmsMap.setSwitchInfo(sw, undefined); - } +nmsMap.reset = function () { + for (var sw in this._color) { + nmsMap.setSwitchColor(sw, undefined); + } + for (var sw in this._info) { + nmsMap.setSwitchInfo(sw, undefined); + } }; -nmsMap.setSwitchInfo = function(sw,info) { - if (info != undefined) { - var textl = info.length; - if (textl > 15) - info = info.slice(0,15); - } - if (this._info[sw] != info) { - this._info[sw] = info; - this._drawSwitchInfo(sw); - this.stats.switchInfoUpdate++; - } else { - this.stats.switchInfoSame++; - } +nmsMap.setSwitchInfo = function (sw, info) { + if (info != undefined) { + var textl = info.length; + if (textl > 15) info = info.slice(0, 15); + } + if (this._info[sw] != info) { + this._info[sw] = info; + this._drawSwitchInfo(sw); + this.stats.switchInfoUpdate++; + } else { + this.stats.switchInfoSame++; + } }; -nmsMap._initContext = function(name) { - this._c[name] = {}; - this._c[name].c = document.getElementById(name + "Canvas"); - this._c[name].ctx = this._c[name].c.getContext('2d'); +nmsMap._initContext = function (name) { + this._c[name] = {}; + this._c[name].c = document.getElementById(name + "Canvas"); + this._c[name].ctx = this._c[name].c.getContext("2d"); }; -nmsMap._initContexts = function() { - for (var context in this.contexts) { - this._initContext(this.contexts[context]); - } +nmsMap._initContexts = function () { + for (var context in this.contexts) { + this._initContext(this.contexts[context]); + } }; /* @@ -152,56 +165,54 @@ nmsMap._initContexts = function() { * changed. Example: The menu is toggled. So far this is the same as * _resizeEvent, but there is no guarantee that will stay true. */ -nmsMap.forceResize = function() { - if (this._init == true) { - return; - } - nmsMap._resizeEvent(); -} - - -nmsMap._resizeEvent = function() { - var width = window.innerWidth - nmsMap._c.bg.c.offsetLeft; - var height = window.innerHeight - nmsMap._c.bg.c.offsetTop; - - var xScale = (width / (nmsMap._orig.width + nmsMap._settings.xMargin)); - var yScale = (height / (nmsMap._orig.height + nmsMap._settings.yMargin)); - - /* - * We need to forget this. Because the rescale will blank the text - * anyway it is safe to set it to undefined here. This is a special - * case, if you set it to 'undefined' anywhere else to "reset" or - * force a redraw of the text you will introduce a bug if a handler - * then tries to _unset_ the text (which you do by setting the text - * to undefined) - */ - nmsMap._lastName = {}; - nmsMap._lastInfo = {}; - if (xScale > yScale) { - nmsMap.scale = yScale; - } else { - nmsMap.scale = xScale; - } - for (var a in nmsMap._c) { - /* - * Resizing this to a too small size breaks gradients on smaller screens. - */ - if (a == 'hidden' && a != 'blur') - continue; - nmsMap._c[a].c.height = nmsMap._canvas.height; - nmsMap._c[a].c.width = nmsMap._canvas.width; - if(a == 'bg') { - nmsMap._drawBG(); - } - } - if (nmsMap._init != true) { - nmsMap._blurDrawn = false; - nmsMap._drawBG(); - nmsMap._drawAllSwitches(); - nmsMap._drawAllLinknets(); - nmsMap.drawNow(); - nmsMap.stats.resizeEvents++; - } +nmsMap.forceResize = function () { + if (this._init == true) { + return; + } + nmsMap._resizeEvent(); +}; + +nmsMap._resizeEvent = function () { + var width = window.innerWidth - nmsMap._c.bg.c.offsetLeft; + var height = window.innerHeight - nmsMap._c.bg.c.offsetTop; + + var xScale = width / (nmsMap._orig.width + nmsMap._settings.xMargin); + var yScale = height / (nmsMap._orig.height + nmsMap._settings.yMargin); + + /* + * We need to forget this. Because the rescale will blank the text + * anyway it is safe to set it to undefined here. This is a special + * case, if you set it to 'undefined' anywhere else to "reset" or + * force a redraw of the text you will introduce a bug if a handler + * then tries to _unset_ the text (which you do by setting the text + * to undefined) + */ + nmsMap._lastName = {}; + nmsMap._lastInfo = {}; + if (xScale > yScale) { + nmsMap.scale = yScale; + } else { + nmsMap.scale = xScale; + } + for (var a in nmsMap._c) { + /* + * Resizing this to a too small size breaks gradients on smaller screens. + */ + if (a == "hidden" && a != "blur") continue; + nmsMap._c[a].c.height = nmsMap._canvas.height; + nmsMap._c[a].c.width = nmsMap._canvas.width; + if (a == "bg") { + nmsMap._drawBG(); + } + } + if (nmsMap._init != true) { + nmsMap._blurDrawn = false; + nmsMap._drawBG(); + nmsMap._drawAllSwitches(); + nmsMap._drawAllLinknets(); + nmsMap.drawNow(); + nmsMap.stats.resizeEvents++; + } }; /* @@ -217,320 +228,341 @@ nmsMap._resizeEvent = function() { * local time zone with js. Should find a more robust solution. * */ -nmsMap.drawNow = function () -{ - var now = nmsData.now; - var ctx = nmsMap._c.top.ctx; - if (nmsTime.isRealTime()) { - if (!nmsMap._nowCleared) { - ctx.save(); - ctx.scale(this.scale, this.scale); - ctx.clearRect(0,0,800,100); - ctx.restore(); - nmsMap._nowCleared = true; - nmsMap._lastNow = undefined; - } - return true; - } - nmsMap._nowCleared = false; - if(String(now).indexOf('T') == -1) { //If now does not contain 'T' we assume its in epoch format - now = new Date(nmsData.now * 1000); - } else { - now = new Date(nmsData.now); //Date assumes UTC - } - now = now.toString().split(' ').splice(0,5).join(' '); //Date returns local time - if (nmsMap._lastNow == now) { - nmsMap.stats.nowDups++; - return; - } - nmsMap.stats.nows++; - - ctx.save(); - ctx.scale(this.scale, this.scale); - ctx.font = (2 * this._settings.fontSize) + "px " + this._settings.fontFace; - ctx.clearRect(0,0,800,100); - ctx.fillStyle = "white"; - ctx.strokeStyle = "black"; - ctx.translate(200,0); - ctx.lineWidth = nms.fontLineFactor; - ctx.strokeText(now, this._settings.textMargin, 25); - ctx.fillText(now, this._settings.textMargin, 25); - ctx.restore(); -}; - -nmsMap.setNightMode = function(toggle) { - if (this._nightmode == toggle) - return; - this._nightmode = toggle; - if (this._init == true) { - return; - } - if (!toggle) - this._c.blur.c.style.display = "none"; - else { - this._drawAllBlur(); - this._c.blur.c.style.display = ""; - } - nmsMap._drawBG(); -}; - -nmsMap._drawBG = function() { - var imageObj = document.getElementById('source'); - this._c.bg.ctx.drawImage(imageObj, 0, 0, nmsMap._canvas.width, nmsMap._canvas.height); - if(this._nightmode) - nmsMap._invertBG(); -}; - -nmsMap._invertBG = function() { - var imageData = this._c.bg.ctx.getImageData(0, 0, nmsMap._canvas.width, nmsMap._canvas.height); - var data = imageData.data; - - for(var i = 0; i < data.length; i += 4) { - data[i] = 255 - data[i]; - data[i + 1] = 255 - data[i + 1]; - data[i + 2] = 255 - data[i + 2]; - } - this._c.bg.ctx.putImageData(imageData, 0, 0); -}; - -nmsMap._getBox = function(sw) { - var box = nmsData.switches.switches[sw]['placement']; - box.x = parseInt(box.x); - box.y = parseInt(box.y); - box.width = parseInt(box.width); - box.height = parseInt(box.height); - return box; -}; - -nmsMap._drawSwitchBlur = function(sw) -{ - if (nmsData.switches == undefined || nmsData.switches.switches == undefined) - return; - var box = this._getBox(sw); - this._c.blur.ctx.save(); - this._c.blur.ctx.fillStyle = "red"; - this._c.blur.ctx.shadowBlur = 30; - this._c.blur.ctx.shadowColor = "white"; - this._c.blur.ctx.scale(this.scale, this.scale); // FIXME <- fix what?! - this._c.blur.ctx.fillRect(box['x'],box['y'],box['width'],box['height']); - this._c.blur.ctx.restore(); -}; - -nmsMap._drawSwitch = function(sw) -{ - // XXX: If a handler sets a color before switches are loaded... The - // color will get set fine so this isn't a problem. - if (nmsData.switches == undefined || nmsData.switches.switches == undefined) - return; - var box = this._getBox(sw); - var color = nmsMap._color[sw]; - if(this._highlightActive) { - if(nmsMap._highlight[sw]) { - color = nmsColor.green; - } else { - color = nmsColor.white; - } - } - if (color == undefined) { - color = nmsColor.blue; - } - this._c.switch.ctx.fillStyle = color; - this._drawBox(this._c.switch.ctx, box['x'],box['y'],box['width'],box['height']); - this._c.switch.ctx.shadowBlur = 0; - var switchtext = sw; - var textl = switchtext.length; - // Cut switch name if longer than this - var text_cut_l = 14; - // Cut switch name by more if we have a status indicator - if (this._info[sw]) { - text_cut_l -= this._info[sw].length - } - if (textl > text_cut_l) { - var rhs_text = this._info[sw]; - - switchtext = switchtext.slice(0,text_cut_l - 5) + ".." + switchtext.slice(textl-2,textl); - } - // Don't display AP name - if (switchtext[0] == "a" && switchtext[1] == "p") { - switchtext = "ap"; - } - - if (this._lastName[sw] != switchtext) { - nmsMap.stats.textSwitchDraws++; - this._drawText(this._c.text.ctx, switchtext,box); - this._lastName[sw] = switchtext; - } - - if(this._info[sw]) - this._drawSwitchInfo(sw); -}; - -nmsMap._drawSwitchInfo = function(sw) { - var box = this._getBox(sw); - if (this._lastInfo[sw] == this._info[sw]) - return; - // Skip info on APs - if (sw[0] == "a" && sw[1] == "p") { - return; - } - this._clearBox(this._c.textInfo.ctx, box, 3); - nmsMap.stats.textInfoClears++; - if (this._info[sw] != undefined) { - this._drawText(this._c.textInfo.ctx, this._info[sw], box, "right"); - nmsMap.stats.textInfoDraws++; - } - this._lastInfo[sw] = this._info[sw]; -}; - -nmsMap._clearBox = function(ctx,box,margin) { - if (margin == undefined) - margin = 0; - ctx.save(); - margin = Math.floor(margin * this.scale ); - ctx.scale(this.scale,this.scale); - ctx.clearRect(box['x'] - margin, box['y'] - margin, box['width'] + margin*2, box['height'] + margin*2); - ctx.restore(); -}; - -nmsMap._drawText = function(ctx, text, box, align) { - var rotate = false; - - if ((box['width'] + 10 )< box['height']) - rotate = true; - - this._clearBox(ctx,box, 1); - ctx.save(); - ctx.scale(this.scale, this.scale); - ctx.font = "bold " + this._settings.fontSize + "px " + this._settings.fontFace; - ctx.lineWidth = nmsMap._settings.fontLineFactor; - ctx.fillStyle = "white"; - ctx.strokeStyle = "black"; - ctx.translate(box.x + this._settings.textMargin, box.y + box.height - this._settings.textMargin); - - if (rotate) { - ctx.translate(box.width - this._settings.textMargin * 2,0); - ctx.rotate(Math.PI * 3/2); - } - - if (align == "right") { - ctx.textAlign = "right"; - /* - * Margin*2 is to compensate for the margin above. - */ - if (rotate) - ctx.translate(box.height - this._settings.textMargin*2,0); - else - ctx.translate(box.width - this._settings.textMargin*2,0); - } - - ctx.strokeText(text, 0, 0); - ctx.fillText(text, 0, 0); - ctx.restore(); -}; - -nmsMap._setLinknetColor = function(l, color1, color2) -{ - var oldcolor1; - var oldcolor2; - try { - oldcolor1 = nmsMap._linknets[l].sysname1; - oldcolor2 = nmsMap._linknets[l].sysname2; - if (oldcolor1 == color1 && oldcolor2 == color2) { - return ; - } - } catch (e) {} - nmsMap._linknets[l] = {}; - nmsMap._linknets[l].sysname1 = color1; - nmsMap._linknets[l].sysname2 = color2; - nmsMap._drawLinknet(l) -} - -nmsMap._drawLinknet = function(l) { - try { - var color1 = nmsColor.blue; - var color2 = nmsColor.blue; - try { - color1 = nmsMap._linknets[l].sysname1; - color2 = nmsMap._linknets[l].sysname2; - } catch(e) { } - nmsMap._connectSwitches(nmsData.switches.linknets[l].sysname1, nmsData.switches.linknets[l].sysname2, color1, color2); - } catch(e) { } -} - -nmsMap._drawAllLinknets = function() { - for (var l in nmsData.switches.linknets) { - nmsMap._drawLinknet(l); - } -} -nmsMap._drawAllSwitches = function() { - if (nmsData.switches == undefined) { - this.stats.earlyDrawAll++; - return; - } - for (var sw in nmsData.switches.switches) { - this._drawSwitch(sw); - } - if (this._nightmode) - this._drawAllBlur(); +nmsMap.drawNow = function () { + var now = nmsData.now; + var ctx = nmsMap._c.top.ctx; + if (nmsTime.isRealTime()) { + if (!nmsMap._nowCleared) { + ctx.save(); + ctx.scale(this.scale, this.scale); + ctx.clearRect(0, 0, 800, 100); + ctx.restore(); + nmsMap._nowCleared = true; + nmsMap._lastNow = undefined; + } + return true; + } + nmsMap._nowCleared = false; + if (String(now).indexOf("T") == -1) { + //If now does not contain 'T' we assume its in epoch format + now = new Date(nmsData.now * 1000); + } else { + now = new Date(nmsData.now); //Date assumes UTC + } + now = now.toString().split(" ").splice(0, 5).join(" "); //Date returns local time + if (nmsMap._lastNow == now) { + nmsMap.stats.nowDups++; + return; + } + nmsMap.stats.nows++; + + ctx.save(); + ctx.scale(this.scale, this.scale); + ctx.font = 2 * this._settings.fontSize + "px " + this._settings.fontFace; + ctx.clearRect(0, 0, 800, 100); + ctx.fillStyle = "white"; + ctx.strokeStyle = "black"; + ctx.translate(200, 0); + ctx.lineWidth = nms.fontLineFactor; + ctx.strokeText(now, this._settings.textMargin, 25); + ctx.fillText(now, this._settings.textMargin, 25); + ctx.restore(); +}; + +nmsMap.setNightMode = function (toggle) { + if (this._nightmode == toggle) return; + this._nightmode = toggle; + if (this._init == true) { + return; + } + if (!toggle) this._c.blur.c.style.display = "none"; + else { + this._drawAllBlur(); + this._c.blur.c.style.display = ""; + } + nmsMap._drawBG(); +}; + +nmsMap._drawBG = function () { + var imageObj = document.getElementById("source"); + this._c.bg.ctx.drawImage( + imageObj, + 0, + 0, + nmsMap._canvas.width, + nmsMap._canvas.height + ); + if (this._nightmode) nmsMap._invertBG(); +}; + +nmsMap._invertBG = function () { + var imageData = this._c.bg.ctx.getImageData( + 0, + 0, + nmsMap._canvas.width, + nmsMap._canvas.height + ); + var data = imageData.data; + + for (var i = 0; i < data.length; i += 4) { + data[i] = 255 - data[i]; + data[i + 1] = 255 - data[i + 1]; + data[i + 2] = 255 - data[i + 2]; + } + this._c.bg.ctx.putImageData(imageData, 0, 0); +}; + +nmsMap._getBox = function (sw) { + var box = nmsData.switches.switches[sw]["placement"]; + box.x = parseInt(box.x); + box.y = parseInt(box.y); + box.width = parseInt(box.width); + box.height = parseInt(box.height); + return box; +}; + +nmsMap._drawSwitchBlur = function (sw) { + if (nmsData.switches == undefined || nmsData.switches.switches == undefined) + return; + var box = this._getBox(sw); + this._c.blur.ctx.save(); + this._c.blur.ctx.fillStyle = "red"; + this._c.blur.ctx.shadowBlur = 30; + this._c.blur.ctx.shadowColor = "white"; + this._c.blur.ctx.scale(this.scale, this.scale); // FIXME <- fix what?! + this._c.blur.ctx.fillRect(box["x"], box["y"], box["width"], box["height"]); + this._c.blur.ctx.restore(); +}; + +nmsMap._drawSwitch = function (sw) { + // XXX: If a handler sets a color before switches are loaded... The + // color will get set fine so this isn't a problem. + if (nmsData.switches == undefined || nmsData.switches.switches == undefined) + return; + var box = this._getBox(sw); + var color = nmsMap._color[sw]; + if (this._highlightActive) { + if (nmsMap._highlight[sw]) { + color = nmsColor.green; + } else { + color = nmsColor.white; + } + } + if (color == undefined) { + color = nmsColor.blue; + } + this._c.switch.ctx.fillStyle = color; + this._drawBox( + this._c.switch.ctx, + box["x"], + box["y"], + box["width"], + box["height"] + ); + this._c.switch.ctx.shadowBlur = 0; + var switchtext = sw; + var textl = switchtext.length; + // Cut switch name if longer than this + var text_cut_l = 18; + // Cut switch name by more if we have a status indicator + if (this._info[sw]) { + text_cut_l -= this._info[sw].length; + } + if (textl > text_cut_l) { + var rhs_text = this._info[sw]; + + switchtext = + switchtext.slice(0, text_cut_l - 5) + + ".." + + switchtext.slice(textl - 2, textl); + } + // Don't display AP name + if (switchtext[0] == "a" && switchtext[1] == "p") { + switchtext = "ap"; + } + + if (this._lastName[sw] != switchtext) { + nmsMap.stats.textSwitchDraws++; + this._drawText(this._c.text.ctx, switchtext, box); + this._lastName[sw] = switchtext; + } + + if (this._info[sw]) this._drawSwitchInfo(sw); +}; + +nmsMap._drawSwitchInfo = function (sw) { + var box = this._getBox(sw); + if (this._lastInfo[sw] == this._info[sw]) return; + // Skip info on APs + if (sw[0] == "a" && sw[1] == "p") { + return; + } + this._clearBox(this._c.textInfo.ctx, box, 3); + nmsMap.stats.textInfoClears++; + if (this._info[sw] != undefined) { + this._drawText(this._c.textInfo.ctx, this._info[sw], box, "right"); + nmsMap.stats.textInfoDraws++; + } + this._lastInfo[sw] = this._info[sw]; +}; + +nmsMap._clearBox = function (ctx, box, margin) { + if (margin == undefined) margin = 0; + ctx.save(); + margin = Math.floor(margin * this.scale); + ctx.scale(this.scale, this.scale); + ctx.clearRect( + box["x"] - margin, + box["y"] - margin, + box["width"] + margin * 2, + box["height"] + margin * 2 + ); + ctx.restore(); +}; + +nmsMap._drawText = function (ctx, text, box, align) { + var rotate = false; + + if (box["width"] + 10 < box["height"]) rotate = true; + + this._clearBox(ctx, box, 1); + ctx.save(); + ctx.scale(this.scale, this.scale); + ctx.font = + "bold " + this._settings.fontSize + "px " + this._settings.fontFace; + ctx.lineWidth = nmsMap._settings.fontLineFactor; + ctx.fillStyle = "white"; + ctx.strokeStyle = "black"; + ctx.translate( + box.x + this._settings.textMargin, + box.y + box.height - this._settings.textMargin + ); + + if (rotate) { + ctx.translate(box.width - this._settings.textMargin * 2, 0); + ctx.rotate((Math.PI * 3) / 2); + } + + if (align == "right") { + ctx.textAlign = "right"; + /* + * Margin*2 is to compensate for the margin above. + */ + if (rotate) ctx.translate(box.height - this._settings.textMargin * 2, 0); + else ctx.translate(box.width - this._settings.textMargin * 2, 0); + } + + ctx.strokeText(text, 0, 0); + ctx.fillText(text, 0, 0); + ctx.restore(); +}; + +nmsMap._setLinknetColor = function (l, color1, color2) { + var oldcolor1; + var oldcolor2; + try { + oldcolor1 = nmsMap._linknets[l].sysname1; + oldcolor2 = nmsMap._linknets[l].sysname2; + if (oldcolor1 == color1 && oldcolor2 == color2) { + return; + } + } catch (e) {} + nmsMap._linknets[l] = {}; + nmsMap._linknets[l].sysname1 = color1; + nmsMap._linknets[l].sysname2 = color2; + nmsMap._drawLinknet(l); +}; + +nmsMap._drawLinknet = function (l) { + try { + var color1 = nmsColor.blue; + var color2 = nmsColor.blue; + try { + color1 = nmsMap._linknets[l].sysname1; + color2 = nmsMap._linknets[l].sysname2; + } catch (e) {} + nmsMap._connectSwitches( + nmsData.switches.linknets[l].sysname1, + nmsData.switches.linknets[l].sysname2, + color1, + color2 + ); + } catch (e) {} +}; + +nmsMap._drawAllLinknets = function () { + for (var l in nmsData.switches.linknets) { + nmsMap._drawLinknet(l); + } +}; +nmsMap._drawAllSwitches = function () { + if (nmsData.switches == undefined) { + this.stats.earlyDrawAll++; + return; + } + for (var sw in nmsData.switches.switches) { + this._drawSwitch(sw); + } + if (this._nightmode) this._drawAllBlur(); }; -nmsMap._drawAllBlur = function() { - if (nmsMap._blurDrawn == true) - return; - nmsMap._blurDrawn = true; - for (var sw in nmsData.switches.switches) { - nmsMap._drawSwitchBlur(sw); - } +nmsMap._drawAllBlur = function () { + if (nmsMap._blurDrawn == true) return; + nmsMap._blurDrawn = true; + for (var sw in nmsData.switches.switches) { + nmsMap._drawSwitchBlur(sw); + } }; -nmsMap._drawBox = function(ctx, x, y, boxw, boxh) { - ctx.save(); - ctx.scale(this.scale, this.scale); // FIXME <- what?! - ctx.fillRect(x,y, boxw, boxh); - ctx.lineWidth = 1; - ctx.strokeStyle = "#000000"; - ctx.strokeRect(x,y, boxw, boxh); - ctx.restore(); +nmsMap._drawBox = function (ctx, x, y, boxw, boxh) { + ctx.save(); + ctx.scale(this.scale, this.scale); // FIXME <- what?! + ctx.fillRect(x, y, boxw, boxh); + ctx.lineWidth = 1; + ctx.strokeStyle = "#000000"; + ctx.strokeRect(x, y, boxw, boxh); + ctx.restore(); }; -nmsMap._connectSwitches = function(sw1, sw2, color1, color2) { - nmsMap._connectBoxes(nmsMap._getBox(sw1), nmsMap._getBox(sw2), - color1, color2); +nmsMap._connectSwitches = function (sw1, sw2, color1, color2) { + nmsMap._connectBoxes( + nmsMap._getBox(sw1), + nmsMap._getBox(sw2), + color1, + color2 + ); }; /* * Draw a line between two boxes, with a gradient going from color1 to * color2. */ -nmsMap._connectBoxes = function(box1, box2,color1, color2) { - var ctx = nmsMap._c.link.ctx; - if (color1 == undefined) - color1 = nmsColor.blue; - if (color2 == undefined) - color2 = nmsColor.blue; - var x0 = Math.floor(box1.x + box1.width/2); - var y0 = Math.floor(box1.y + box1.height/2); - var x1 = Math.floor(box2.x + box2.width/2); - var y1 = Math.floor(box2.y + box2.height/2); - ctx.save(); - ctx.scale(nmsMap.scale, nmsMap.scale); - var gradient = ctx.createLinearGradient(x1,y1,x0,y0); - gradient.addColorStop(0, color1); - gradient.addColorStop(1, color2); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(x0,y0); - ctx.lineTo(x1,y1); - ctx.lineWidth = 5; - ctx.stroke(); - ctx.closePath(); - ctx.restore(); -}; - -nmsMap.moveSet = function(toggle) { - nmsMap._moveInProgress = toggle; - if (!toggle) - nmsMap._moveStopListen(); +nmsMap._connectBoxes = function (box1, box2, color1, color2) { + var ctx = nmsMap._c.link.ctx; + if (color1 == undefined) color1 = nmsColor.blue; + if (color2 == undefined) color2 = nmsColor.blue; + var x0 = Math.floor(box1.x + box1.width / 2); + var y0 = Math.floor(box1.y + box1.height / 2); + var x1 = Math.floor(box2.x + box2.width / 2); + var y1 = Math.floor(box2.y + box2.height / 2); + ctx.save(); + ctx.scale(nmsMap.scale, nmsMap.scale); + var gradient = ctx.createLinearGradient(x1, y1, x0, y0); + gradient.addColorStop(0, color1); + gradient.addColorStop(1, color2); + ctx.strokeStyle = gradient; + ctx.beginPath(); + ctx.moveTo(x0, y0); + ctx.lineTo(x1, y1); + ctx.lineWidth = 5; + ctx.stroke(); + ctx.closePath(); + ctx.restore(); +}; + +nmsMap.moveSet = function (toggle) { + nmsMap._moveInProgress = toggle; + if (!toggle) nmsMap._moveStopListen(); }; /* @@ -538,91 +570,92 @@ nmsMap.moveSet = function(toggle) { * * Currently just shows info for a switch. */ -nmsMap.canvasClick = function(e) -{ - var sw = findSwitch(e.pageX - e.target.offsetLeft, e.pageY - e.target.offsetTop); - if (sw != undefined) { - if (nmsMap._moveInProgress) { - nmsMap._moveStart(sw, e); - } else { - nmsInfoBox.click(sw); - } - } else { - nmsInfoBox.hide(); - } -}; - -nmsMap._clearOld = function(box) { - if (box) { - nmsMap._c.top.ctx.save(); - nmsMap._c.top.ctx.fillStyle = "#000000"; - nmsMap._c.top.ctx.scale(nmsMap.scale, nmsMap.scale); // FIXME - nmsMap._c.top.ctx.clearRect(box['x'] - 5, box['y'] - 5, box['width'] + 10, box['height'] + 10); - nmsMap._c.top.ctx.restore(); - } -}; - -nmsMap._moveMove = function(e) { - nmsMap._moveX = (e.pageX - e.target.offsetLeft) / nmsMap.scale; - nmsMap._moveY = (e.pageY - e.target.offsetTop) / nmsMap.scale; - var diffx = nmsMap._moveX - nmsMap._moveXstart; - var diffy = nmsMap._moveY - nmsMap._moveYstart; - var box = {}; - nmsMap._clearOld(nmsMap._moveOldBox); - box['x'] = nmsMap._moveBox['x'] + diffx; - box['y'] = nmsMap._moveBox['y'] + diffy; - box['height'] = nmsMap._moveBox['height']; - box['width'] = nmsMap._moveBox['width']; - nmsMap._moveOldBox = box; - nmsMap._c.top.ctx.save(); - nmsMap._c.top.ctx.fillStyle = "red"; - nmsMap._drawBox(nmsMap._c.top.ctx, box['x'], box['y'], box['width'], box['height']); - nmsMap._c.top.ctx.restore(); -}; - -nmsMap._moveSubmit = function() { - var data = { - sysname: nmsMap._moving, - placement: nmsMap._moveOldBox - }; - var myData = JSON.stringify([data]); - $.ajax({ - type: "POST", - url: "/api/write/switches", - dataType: "text", - data:myData, - success: function (data, textStatus, jqXHR) { - nmsData.invalidate("switches"); - } - }); -}; - -nmsMap._moveStopListen = function() { - nmsMap._c.input.c.removeEventListener('mousemove',nmsMap._moveMove, true); - nmsMap._c.input.c.removeEventListener('mouseup',nmsMap._moveDone, true); -}; - -nmsMap._moveDone = function(e) { - nmsMap._moveStopListen(); - if(nmsMap._moveOldBox == false) { - return; - } - nmsMap._moveSubmit(); - nmsMap._clearOld(nmsMap._moveOldBox); -}; - -nmsMap._moveStart = function(sw, e) -{ - nmsMap._moving = sw; - nmsMap._moveOldBox = false; - nmsMap._moveXstart = (e.pageX - e.target.offsetLeft) / nmsMap.scale; - nmsMap._moveYstart = (e.pageY - e.target.offsetTop) / nmsMap.scale; - nmsMap._moveBox = nmsData.switches.switches[sw].placement; - nmsMap._c.input.c.addEventListener('mousemove',nmsMap._moveMove,true); - nmsMap._c.input.c.addEventListener('mouseup',nmsMap._moveDone,true); +nmsMap.canvasClick = function (e) { + var sw = findSwitch( + e.pageX - e.target.offsetLeft, + e.pageY - e.target.offsetTop + ); + if (sw != undefined) { + if (nmsMap._moveInProgress) { + nmsMap._moveStart(sw, e); + } else { + nmsInfoBox.click(sw); + } + } else { + nmsInfoBox.hide(); + } +}; + +nmsMap._clearOld = function (box) { + if (box) { + nmsMap._c.top.ctx.save(); + nmsMap._c.top.ctx.fillStyle = "#000000"; + nmsMap._c.top.ctx.scale(nmsMap.scale, nmsMap.scale); // FIXME + nmsMap._c.top.ctx.clearRect( + box["x"] - 5, + box["y"] - 5, + box["width"] + 10, + box["height"] + 10 + ); + nmsMap._c.top.ctx.restore(); + } +}; + +nmsMap._moveMove = function (e) { + nmsMap._moveX = (e.pageX - e.target.offsetLeft) / nmsMap.scale; + nmsMap._moveY = (e.pageY - e.target.offsetTop) / nmsMap.scale; + var diffx = nmsMap._moveX - nmsMap._moveXstart; + var diffy = nmsMap._moveY - nmsMap._moveYstart; + var box = {}; + nmsMap._clearOld(nmsMap._moveOldBox); + box["x"] = parseInt(nmsMap._moveBox["x"] + diffx); + box["y"] = parseInt(nmsMap._moveBox["y"] + diffy); + box["height"] = parseInt(nmsMap._moveBox["height"]); + box["width"] = parseInt(nmsMap._moveBox["width"]); + nmsMap._moveOldBox = box; + nmsMap._c.top.ctx.save(); + nmsMap._c.top.ctx.fillStyle = "red"; + nmsMap._drawBox( + nmsMap._c.top.ctx, + box["x"], + box["y"], + box["width"], + box["height"] + ); + nmsMap._c.top.ctx.restore(); +}; + +nmsMap._moveSubmit = function () { + var sysname = nmsMap._moving; + var placement = nmsMap._moveOldBox; + const data = postData(`/api/v2/devices/${sysname}/placement`, placement); + console.log(data); +}; + +nmsMap._moveStopListen = function () { + nmsMap._c.input.c.removeEventListener("mousemove", nmsMap._moveMove, true); + nmsMap._c.input.c.removeEventListener("mouseup", nmsMap._moveDone, true); +}; + +nmsMap._moveDone = function (e) { + nmsMap._moveStopListen(); + if (nmsMap._moveOldBox == false) { + return; + } + nmsMap._moveSubmit(); + nmsMap._clearOld(nmsMap._moveOldBox); +}; + +nmsMap._moveStart = function (sw, e) { + nmsMap._moving = sw; + nmsMap._moveOldBox = false; + nmsMap._moveXstart = (e.pageX - e.target.offsetLeft) / nmsMap.scale; + nmsMap._moveYstart = (e.pageY - e.target.offsetTop) / nmsMap.scale; + nmsMap._moveBox = nmsData.switches.switches[sw].placement; + nmsMap._c.input.c.addEventListener("mousemove", nmsMap._moveMove, true); + nmsMap._c.input.c.addEventListener("mouseup", nmsMap._moveDone, true); }; - /* * STUFF NOT YET INTEGRATED, BUT MOVED AWAY FROM nms.js TO TIDY. * @@ -634,25 +667,37 @@ nmsMap._moveStart = function(sw, e) * * XXX: Might have to change the index here to match backend */ -function drawLinknet(i) -{ - var c1 = nms.linknet_color[i] && nms.linknet_color[i].c1 ? nms.linknet_color[i].c1 : blue; - var c2 = nms.linknet_color[i] && nms.linknet_color[i].c2 ? nms.linknet_color[i].c2 : blue; - if (nmsData.switches.switches[nmsData.switches.linknets[i].sysname1] && nmsData.switches.switches[nmsData.switches.linknets[i].sysname2]) { - connectSwitches(nmsData.switches.linknets[i].sysname1,nmsData.switches.linknets[i].sysname2, c1, c2); - } +function drawLinknet(i) { + var c1 = + nms.linknet_color[i] && nms.linknet_color[i].c1 + ? nms.linknet_color[i].c1 + : blue; + var c2 = + nms.linknet_color[i] && nms.linknet_color[i].c2 + ? nms.linknet_color[i].c2 + : blue; + if ( + nmsData.switches.switches[nmsData.switches.linknets[i].sysname1] && + nmsData.switches.switches[nmsData.switches.linknets[i].sysname2] + ) { + connectSwitches( + nmsData.switches.linknets[i].sysname1, + nmsData.switches.linknets[i].sysname2, + c1, + c2 + ); + } } /* * Draw all linknets */ -function drawLinknets() -{ - if (nmsData.switches && nmsData.switches.linknets) { - for (var i in nmsData.switches.linknets) { - drawLinknet(i); - } - } +function drawLinknets() { + if (nmsData.switches && nmsData.switches.linknets) { + for (var i in nmsData.switches.linknets) { + drawLinknet(i); + } + } } /* @@ -660,17 +705,15 @@ function drawLinknets() * * XXX: Probably have to change this to better match the backend data */ -function setLinknetColors(i,c1,c2) -{ - if (!nms.linknet_color[i] || - nms.linknet_color[i].c1 != c1 || - nms.linknet_color[i].c2 != c2) { - if (!nms.linknet_color[i]) - nms.linknet_color[i] = {}; - nms.linknet_color[i]['c1'] = c1; - nms.linknet_color[i]['c2'] = c2; - drawLinknet(i); - } +function setLinknetColors(i, c1, c2) { + if ( + !nms.linknet_color[i] || + nms.linknet_color[i].c1 != c1 || + nms.linknet_color[i].c2 != c2 + ) { + if (!nms.linknet_color[i]) nms.linknet_color[i] = {}; + nms.linknet_color[i]["c1"] = c1; + nms.linknet_color[i]["c2"] = c2; + drawLinknet(i); + } } - - diff --git a/web/js/nms-nightmode.js b/web/js/nms-nightmode.js index 0246e88..511cdd8 100644 --- a/web/js/nms-nightmode.js +++ b/web/js/nms-nightmode.js @@ -1,23 +1,23 @@ "use strict"; -var nmsNightMode = nmsNightMode || { - -} +var nmsNightMode = nmsNightMode || {}; var prefersColorSchemeMediaQuery = "(prefers-color-scheme: dark)"; -nmsNightMode.toggle = function() { - if (nms.nightMode) { - console.log("nightmode already set, not following system (remove cookies & url param to re-enable system following)"); - return - } +nmsNightMode.toggle = function () { + if (nms.nightMode) { + console.log( + "nightmode already set, not following system (remove cookies & url param to re-enable system following)" + ); + return; + } - var active = window.matchMedia(prefersColorSchemeMediaQuery).matches; - nms.nightMode = active; -} + var active = window.matchMedia(prefersColorSchemeMediaQuery).matches; + nms.nightMode = active; +}; -nmsNightMode.init = function() { - var preferColorScheme = window.matchMedia(prefersColorSchemeMediaQuery); - preferColorScheme.addListener(() => nmsNightMode.toggle()); - nmsNightMode.toggle(); // trigger initial -} +nmsNightMode.init = function () { + var preferColorScheme = window.matchMedia(prefersColorSchemeMediaQuery); + preferColorScheme.addListener(() => nmsNightMode.toggle()); + nmsNightMode.toggle(); // trigger initial +}; diff --git a/web/js/nms-oplog.js b/web/js/nms-oplog.js index 33b2c00..7fc10c3 100644 --- a/web/js/nms-oplog.js +++ b/web/js/nms-oplog.js @@ -1,281 +1,292 @@ "use strict"; -/* +/* * Please note: I've started moving this to a new and better way of doing * things and it is by no means a finished move. This means that this file is a * mess of two different styles at the time of this writing. Fix incomming. */ var nmsOplog = nmsOplog || { - table: {} -} -nmsOplog.init = function() { - nms.oplog = new nmsOplog2() -} -nmsOplog.getSwitchLogs = function(sw) { - var logs = []; - if (nmsData.oplog == undefined || nmsData['oplog']['oplog'] == undefined) - return []; - for (var v in nmsData['oplog']['oplog']) { - var log = nmsData['oplog']['oplog'][v]; - if (log['systems'] != "" && log['systems'] != undefined) { - if (nmsSearch.searchTest(log['systems'],sw)) { - logs.push(log); - } - } - } - return logs; -} + table: {}, +}; +nmsOplog.init = function () { + nms.oplog = new nmsOplog2(); +}; +nmsOplog.getSwitchLogs = function (sw) { + var logs = []; + if (nmsData.oplog == undefined || nmsData["oplog"]["oplog"] == undefined) + return []; + for (var v in nmsData["oplog"]["oplog"]) { + var log = nmsData["oplog"]["oplog"][v]; + if (log["systems"] != "" && log["systems"] != undefined) { + if (nmsSearch.searchTest(log["systems"], sw)) { + logs.push(log); + } + } + } + return logs; +}; // New-style-work-in-progress follows class nmsOplog2 { - constructor() { - this.logger = new nmsOplogInput() - this.logger.attach("navbar") - this.logger.show() - this.mini = new nmsLogTable() - this.full = new nmsLogTable("full", "large",0,0); - this.mini.attach("oplog-parent-mini") - this.full.attach("oplog-parent") - this.mini.show() - this.full.show() - this._username = new nmsBox("p", {html:{className: "navbar-text navbar-right"}}); - if (nms.user) { - this._username.html.textContent = nms.user - } - this._username.attach("navbar"); - this._username.show() - nmsData.addHandler("oplog", "nmsOplogHandler", this.updateComments,this); - } - updateComments(x) { - if (nms.user && x._username.user != nms.user) { - x._username.user = nms.user; - x._username.html.textContent = nms.user - } - x.mini.update() - x.full.update() - } + constructor() { + this._username = new nmsBox("span", { + html: { className: "navbar-text me-2" }, + }); + if (nms.user) { + this._username.html.textContent = nms.user; + } + this._username.attach("navbar"); + this._username.show(); + this.logger = new nmsOplogInput(); + this.logger.attach("navbar"); + this.logger.show(); + this.mini = new nmsLogTable(); + this.full = new nmsLogTable("full", "large", 0, 0); + this.mini.attach("oplog-parent-mini"); + this.full.attach("oplog-parent"); + this.mini.show(); + this.full.show(); + nmsData.addHandler("oplog", "nmsOplogHandler", this.updateComments, this); + } + updateComments(x) { + if (nms.user && x._username.user != nms.user) { + x._username.user = nms.user; + x._username.html.textContent = nms.user; + } + x.mini.update(); + x.full.update(); + } } + class nmsOplogInput extends nmsBox { - constructor() { - super("div",{html:{className:"navbar-form form-inline navbar-right gondul-is-private"}}) - this._systems = new nmsBox("input", {html:{className:"form-control",type:"text",size:"8",placeholder:"System(s)"}}); - this._systems.searchbox = document.getElementById("searchbox") - this._systems.html.oninput = function(e) { - this.nmsBox.searchbox.value = this.value; - this.nmsBox.searchbox.oninput(); - } - this.add(this._systems) - this._entry = new nmsBox("input", {html:{className:"form-control",type:"text",size:"30",placeholder:"Log entry"}}); - this.add(this._entry) - var button = new nmsBox("button",{html:{className:"btn btn-default",type:"button"}}); - button.html.textContent = "Log"; - button.container = this; - button.html.onclick = function(element) { - this.nmsBox.container.commit(element) - } - this.add(button); - } - /* Should be moved to nms.user probably */ - get user() { - if (nms.user) { - return nms.user; - } - var user = prompt("Who are you? Short nick for the record."); - if (user == null || user == undefined || user == "") { - console.log("empty prompt"); - alert("No cake for you."); - return false; - } - nms.user = user; - saveSettings(); - return nms.user; - } - _empty(input) { - if (input == undefined || input == null || input == "") { - return ""; - } - return input; - } - get entry() { - return this._empty(this._entry.html.value) - } - get systems() { - return this._empty(this._systems.html.value) - } - commit(element) { - if (!this.user) { - console.log("need a user...") - return false; - } - if (this.entry == "") { - return false; - } - var myData = {"user": this.user, "systems": this.systems, "log": this.entry}; - myData = JSON.stringify(myData); - $.ajax({ - type: "POST", - url: "/api/write/oplog", - dataType: "text", - data:myData, - success: function (data, textStatus, jqXHR) { - nmsData.invalidate("oplog"); - } - }); - this.blank() - } - blank() { - this._entry.html.value = ""; - this._systems.html.value = ""; - this._systems.searchbox.value = ""; - this._systems.searchbox.oninput() - } + constructor() { + super("div", { + html: { + className: "input-group input-group-sm w-25 me-4 gondul-is-private", + }, + }); + this._systems = new nmsBox("input", { + html: { + className: "form-control", + type: "text", + placeholder: "System(s)", + }, + }); + this._systems.searchbox = document.getElementById("searchbox"); + this._systems.html.oninput = function (e) { + this.nmsBox.searchbox.value = this.value; + this.nmsBox.searchbox.oninput(); + }; + this.add(this._systems); + this._entry = new nmsBox("input", { + html: { + className: "form-control", + type: "text", + placeholder: "Log entry", + }, + }); + this.add(this._entry); + var button = new nmsBox("button", { + html: { className: "btn btn-outline-secondary", type: "button" }, + }); + button.html.textContent = "Log"; + button.container = this; + button.html.onclick = function (element) { + this.nmsBox.container.commit(element); + }; + this.add(button); + } + /* Should be moved to nms.user probably */ + get user() { + if (nms.user) { + return nms.user; + } + var user = prompt("Who are you? Short nick for the record."); + if (user == null || user == undefined || user == "") { + console.log("empty prompt"); + alert("No cake for you."); + return false; + } + nms.user = user; + saveSettings(); + return nms.user; + } + _empty(input) { + if (input == undefined || input == null || input == "") { + return ""; + } + return input; + } + get entry() { + return this._empty(this._entry.html.value); + } + get systems() { + return this._empty(this._systems.html.value); + } + commit(element) { + if (!this.user) { + console.log("need a user..."); + return false; + } + if (this.entry == "") { + return false; + } + var myData = { username: this.user, systems: this.systems, message: this.entry }; + postData("/api/v2/oplog/", myData); + nmsData.invalidate("oplog"); + // $.ajax({ + // type: "POST", + // url: "/api/v2/oplog", + // dataType: "text", + // data: myData, + // success: function (data, textStatus, jqXHR) { + // nmsData.invalidate("oplog"); + // }, + // }); + this.blank(); + } + blank() { + this._entry.html.value = ""; + this._systems.html.value = ""; + this._systems.searchbox.value = ""; + this._systems.searchbox.oninput(); + } } - /* * This can be re-written now that it uses nmsBox... That rewrite was just a short * test of nmsBox... */ class nmsLogTable extends nmsTable { - constructor(mode = "small", timestyle = "small", cutoff = 100, limit = 10) { - super([]); - this.mode = mode; - this.timestyle = timestyle; - this.cutoff = cutoff; - this.limit = limit; - this.entries = {} - this.first = true; - } - /* This is a horrible implementation. BUT THAT'S WHAT YOU GET - */ - syncToTable() { - var i = 1; - var pastCut = false; - var indexes = []; - for (var idx in this.entries) { - indexes.push(parseInt(idx)) - } - // Testint to see what browsers I can break with exciting new - // syntax - indexes.sort((x,y) => y-x) - for (var idx in indexes) { - var entry = this.entries[indexes[idx]]; - if (!pastCut) { - if (entry == undefined) { - console.log("wtf, empty?") - console.log(entry) - } else { - entry.build(this.cutoff,this.timestyle) - if(!this.includes(entry)) { - // FIXME: This is dumb. It assumes we only get one update. - if (this.first) { - this.add(entry) - } else { - this.insert(entry) - } - } - } - } else { - if(this.includes(entry)) { - this.remove(entry) - } - } - if(this.limit > 0 && ++i > this.limit) { - pastCut = true; - } - } - this.first=false; - } - update() { - var candidates = nmsData['oplog']['oplog']; - for (var i in candidates) { - var candidate = candidates[i]; - if (this.entries[candidate.id] != undefined) { - continue; - } else { - this.entries[candidate.id] = new nmsOplogEntry(candidate); - } - } - this.syncToTable(); - } + constructor(mode = "small", timestyle = "small", cutoff = 100, limit = 10) { + super([]); + this.mode = mode; + this.timestyle = timestyle; + this.cutoff = cutoff; + this.limit = limit; + this.entries = {}; + this.first = true; + } + /* This is a horrible implementation. BUT THAT'S WHAT YOU GET + */ + syncToTable() { + var i = 1; + var pastCut = false; + var indexes = []; + for (var idx in this.entries) { + indexes.push(parseInt(idx)); + } + // Testint to see what browsers I can break with exciting new + // syntax + indexes.sort((x, y) => y - x); + for (var idx in indexes) { + var entry = this.entries[indexes[idx]]; + if (!pastCut) { + if (entry == undefined) { + console.log("wtf, empty?"); + console.log(entry); + } else { + entry.build(this.cutoff, this.timestyle); + if (!this.includes(entry)) { + // FIXME: This is dumb. It assumes we only get one update. + if (this.first) { + this.add(entry); + } else { + this.insert(entry); + } + } + } + } else { + if (this.includes(entry)) { + this.remove(entry); + } + } + if (this.limit > 0 && ++i > this.limit) { + pastCut = true; + } + } + this.first = false; + } + update() { + var candidates = nmsData["oplog"]["oplog"]; + for (var i in candidates) { + var candidate = candidates[i]; + if (this.entries[candidate.id] != undefined) { + continue; + } else { + this.entries[candidate.id] = new nmsOplogEntry(candidate); + } + } + this.syncToTable(); + } } -class nmsOplogEntry extends nmsBox { - build(cutoff,timestyle) { - if (this.built) { - return true; - } - var td1 = new nmsBox("td") - var td2 = new nmsBox("td") - if(timestyle == "small") { - td1.add(new nmsString(this.shortTime())) - } else { - td1.add(new nmsString(this.longTime())) - } - var col2 = new nmsString(this.systems + " [" + this.username + "] " + this.getData(cutoff)); - if (this.title != null) { - col2.html.title = this.title; - } - col2.searchbox = document.getElementById("searchbox") - col2.entry = this; - if (this.systems != undefined && this.systems != null && this.systems != "") { - col2.html.onclick = function(e) { - this.nmsBox.searchbox.value = this.nmsBox.entry.systems; - this.nmsBox.searchbox.oninput() - this.nmsBox.clicked = true; - setTimeout(function(e){e.clicked = false;},3000,this.nmsBox) - } - col2.html.onmouseover = function(e) { - this.nmsBox.over = true; - if (this.nmsBox.timer) { - clearTimeout(this.nmsBox.timer) - } - this.nmsBox.searchbox.value = this.nmsBox.entry.systems; - this.nmsBox.searchbox.hoverSource = this.nmsBox; - this.nmsBox.searchbox.oninput() - } - col2.html.onmouseleave = function(e) { - this.nmsBox.over = false; - if (this.nmsBox.clicked) { return; } - if (this.nmsBox.timer) { - clearTimeout(this.nmsBox.timer) - } - this.nmsBox.timer = setTimeout(function(e){ - if (e.over == false && e.entry.systems == e.searchbox.value && e.searchbox.hoverSource == e) { - e.searchbox.value = ""; - e.searchbox.oninput() - } - },2000,this.nmsBox) - } - } - this.add(td1) - td2.add(col2) - this.add(td2) - this.built = true; - } +class nmsOplogEntry extends nmsBox { + build(cutoff, timestyle) { + if (this.built) { + return true; + } + var td1 = new nmsBox("td"); + var td2 = new nmsBox("td"); + if (timestyle == "small") { + td1.add(new nmsString(this.shortTime())); + } else { + td1.add(new nmsString(this.longTime())); + } + var col2 = new nmsString( + this.systems + " [" + this.username + "] " + this.getData(cutoff) + ); + if (this.title != null) { + col2.html.title = this.title; + } + col2.searchbox = document.getElementById("searchbox"); + col2.entry = this; + if ( + this.systems != undefined && + this.systems != null && + this.systems != "" + ) { + col2.html.onclick = function (e) { + this.nmsBox.searchbox.value = this.nmsBox.entry.systems; + this.nmsBox.searchbox.oninput(); + this.nmsBox.clicked = true; + setTimeout( + function (e) { + e.clicked = false; + }, + 3000, + this.nmsBox + ); + }; + } + this.add(td1); + td2.add(col2); + this.add(td2); + this.built = true; + } - constructor(entry) { - super("tr") - this.td1 = null; - this.td2 = null; - this.time = new Date(entry.timestamp.replace(" ","T")) - this.id = entry.id; - this.data = entry.log; - this.title = null; - this.systems = entry.systems; - this.username = entry.username; - } - longTime() { - return this.time.toISOString(); - } - shortTime() { - return this.time.toTimeString().replace(/:\d\d .*$/,""); - } - getData(cutoff = 0) { - if (cutoff && this.data.length > cutoff) { - this.title = this.data; - return this.data.slice(0,cutoff) + "(...)"; - } - return this.data; - } + constructor(entry) { + super("tr"); + this.td1 = null; + this.td2 = null; + this.time = new Date(entry.time * 1000); + this.id = entry.id; + this.data = entry.message; + this.title = null; + this.systems = entry.systems; + this.username = entry.username; + } + longTime() { + return this.time.toISOString(); + } + shortTime() { + return this.time.toTimeString().replace(/:\d\d .*$/, ""); + } + getData(cutoff = 0) { + if (cutoff && this.data.length > cutoff) { + this.title = this.data; + return this.data.slice(0, cutoff) + "(...)"; + } + return this.data; + } } diff --git a/web/js/nms-search.js b/web/js/nms-search.js index 0726bb4..5f141bf 100644 --- a/web/js/nms-search.js +++ b/web/js/nms-search.js @@ -1,19 +1,20 @@ "use strict"; var nmsSearch = nmsSearch || { - _handler: false, - _lastId: false + _handler: false, + _lastId: false, }; -nmsSearch.helpText = [ - "The search box can be used to identify switches in several ways. The simplest is by name.", - "Searching by name can be done by just entering text, or if you want to match \"foobar1\" but not \"foobar15\" you can enclose the name in quotation marks. E.g.: foobar1 matches foobar1 and foobar1123123123, while \"foobar1\" only matches exactly foobar1.", - "All text-oriented searches are regular expressions. ^row\\d-2$ matches row1-2, row2-2, etc, but not row13-2 or rowx-2.", - "If you are using the non-public version of Gondul, you can also perform smart searches.", - "Distro search: Type the name of a distro-switch and all access switches registered to that distro switch will also be hilighted.", - 'Active ports: Type "active>x", "active<x" or "active=x" to identify switch with "x" amount of active gigabit ethernet (ge) ports. E.g.: "active>30".', - 'IP search: Start typing an IP and any switch with that IP registered either as management IP or part of its subnet will be identified', - 'SNMP search: Type anything found in the "sysDescr" SNMP OID to hilight a switch matching that. Practical examples include version numbers for firmware (e.g.: "JUNOS 12." vs "JUNOS 14.").']; +nmsSearch.helpText = [ + "The search box can be used to identify switches in several ways. The simplest is by name.", + 'Searching by name can be done by just entering text, or if you want to match "foobar1" but not "foobar15" you can enclose the name in quotation marks. E.g.: foobar1 matches foobar1 and foobar1123123123, while "foobar1" only matches exactly foobar1.', + "All text-oriented searches are regular expressions. ^row\\d-2$ matches row1-2, row2-2, etc, but not row13-2 or rowx-2.", + "If you are using the non-public version of Gondul, you can also perform smart searches.", + "Distro search: Type the name of a distro-switch and all access switches registered to that distro switch will also be hilighted.", + 'Active ports: Type "active>x", "active<x" or "active=x" to identify switch with "x" amount of active gigabit ethernet (ge) ports. E.g.: "active>30".', + "IP search: Start typing an IP and any switch with that IP registered either as management IP or part of its subnet will be identified", + 'SNMP search: Type anything found in the "sysDescr" SNMP OID to hilight a switch matching that. Practical examples include version numbers for firmware (e.g.: "JUNOS 12." vs "JUNOS 14.").', +]; nmsSearch.matches = []; @@ -22,195 +23,201 @@ nmsSearch.matches = []; * * Return true if it does. */ -nmsSearch.searchTest = function(id, sw) { - try { - var re = new RegExp(id,"i"); - if(re.test(sw)) { - return true; - } - if (id[0] == "\"") { - if (("\"" + sw.toLowerCase() + "\"") == id.toLowerCase()) { - return true; - } else { - return false; - } - } - try { - if (re.test(nmsData.switches.switches[sw].distro_name)) { - return true; - } - } catch (e) {} - try { - if (id.match("active")) { - var limit = id; - limit = limit.replace("active>",""); - limit = limit.replace("active<",""); - limit = limit.replace("active=",""); - var operator = id.replace("active","")[0]; - if (limit == parseInt(limit)) { - var ports = parseInt(nmsData.switchstate.switches[sw].totals.live); - limit = parseInt(limit); - if (operator == ">" ) { - if (ports > limit) { - return true; - } - } else if (operator == "<") { - if (ports < limit) { - return true; - } - } else if (operator == "=") { - if (ports == limit) { - return true; - } - } - } - } - } catch (e) {} - try { - if (re.test(nmsData.smanagement.switches[sw].mgmt_v4_addr)) { - return true; - } - if (re.test(nmsData.smanagement.switches[sw].mgmt_v6_addr)) { - return true; - } - } catch (e) {} - try { - if (re.test(nmsData.smanagement.switches[sw].subnet4)) { - return true; - } - if (re.test(nmsData.smanagement.switches[sw].subnet6)) { - return true; - } - } catch (e) {} - try { - for (var x in nmsData.switches.switches[sw]['tags']) { - if(re.test(nmsData.switches.switches[sw]['tags'][x])){ - return true; - } - } - } catch (e) {} - try { - for (var x in nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum) { - if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == null) { - continue; - } - if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == undefined) { - continue; - } - if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == "") { - continue; - } - if (re.test("serial:" + nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x])) { - return true; - } - } - } catch (e) {} - try { - for (var x in nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo) { - if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == null) { - continue; - } - if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == undefined) { - continue; - } - if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == "") { - continue; - } - if (re.test(nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x])) { - return true; - } - } - } catch (e) {} - if (re.test(nmsData.snmp.snmp[sw].misc.sysDescr[0])) { - return true; - } - } catch (e) { - return false; - } - return false; +nmsSearch.searchTest = function (id, sw) { + try { + var re = new RegExp(id, "i"); + if (re.test(sw)) { + return true; + } + if (id[0] == '"') { + if ('"' + sw.toLowerCase() + '"' == id.toLowerCase()) { + return true; + } else { + return false; + } + } + try { + if (re.test(nmsData.switches.switches[sw].distro_name)) { + return true; + } + } catch (e) {} + try { + if (id.match("active")) { + var limit = id; + limit = limit.replace("active>", ""); + limit = limit.replace("active<", ""); + limit = limit.replace("active=", ""); + var operator = id.replace("active", "")[0]; + if (limit == parseInt(limit)) { + var ports = parseInt(nmsData.switchstate.switches[sw].totals.live); + limit = parseInt(limit); + if (operator == ">") { + if (ports > limit) { + return true; + } + } else if (operator == "<") { + if (ports < limit) { + return true; + } + } else if (operator == "=") { + if (ports == limit) { + return true; + } + } + } + } + } catch (e) {} + try { + if (re.test(nmsData.smanagement.switches[sw].mgmt_v4_addr)) { + return true; + } + if (re.test(nmsData.smanagement.switches[sw].mgmt_v6_addr)) { + return true; + } + } catch (e) {} + try { + if (re.test(nmsData.smanagement.switches[sw].subnet4)) { + return true; + } + if (re.test(nmsData.smanagement.switches[sw].subnet6)) { + return true; + } + } catch (e) {} + try { + for (var x in nmsData.switches.switches[sw]["tags"]) { + if (re.test(nmsData.switches.switches[sw]["tags"][x])) { + return true; + } + } + } catch (e) {} + try { + for (var x in nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum) { + if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == null) { + continue; + } + if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == undefined) { + continue; + } + if (nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] == "") { + continue; + } + if ( + re.test( + "serial:" + nmsData.snmp.snmp[sw].misc.entPhysicalSerialNum[x] + ) + ) { + return true; + } + } + } catch (e) {} + try { + for (var x in nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo) { + if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == null) { + continue; + } + if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == undefined) { + continue; + } + if (nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x] == "") { + continue; + } + if (re.test(nmsData.snmp.snmp[sw].misc.jnxBoxSerialNo[x])) { + return true; + } + } + } catch (e) {} + if (re.test(nmsData.snmp.snmp[sw].misc.sysDescr[0])) { + return true; + } + } catch (e) { + return false; + } + return false; }; -nmsSearch.reset = function() { - document.getElementById("searchbox").dataset.match = ''; - document.getElementById("searchbox").value = ''; - nmsSearch.search(); -} - -nmsSearch._enableTimer = function() { - if (nmsSearch._handler == false) { - nmsSearch._handler = setInterval(nmsSearch.search,1000); - } -} +nmsSearch.reset = function () { + document.getElementById("searchbox").dataset.match = ""; + document.getElementById("searchbox").value = ""; + nmsSearch.search(); +}; -nmsSearch._disableTimer = function() { - if (nmsSearch._handler != false) { - clearInterval(nmsSearch.search); - } -} +nmsSearch._enableTimer = function () { + if (nmsSearch._handler == false) { + nmsSearch._handler = setInterval(nmsSearch.search, 1000); + } +}; -nmsSearch.search = function() { - var el = document.getElementById("searchbox"); - var id = false; - nmsSearch.matches = []; - if (el) { - id = el.value.toLowerCase(); - } - if(id) { - nmsMap.enableHighlights(); - for(var sw in nmsData.switches.switches) { - if (nmsSearch.searchTest(id,sw)) { - nmsSearch.matches.push(sw); - nmsMap.setSwitchHighlight(sw,true); - } else { - nmsMap.setSwitchHighlight(sw,false); - } - } - nmsSearch._enableTimer(); - } else { - nmsSearch._disableTimer(); - nmsMap.disableHighlights(); - } - if(nmsSearch.matches.length == 0) { - document.getElementById("searchbox-submit").classList.remove("btn-success"); - document.getElementById("searchbox-submit").classList.remove("btn-primary"); - } - else if(nmsSearch.matches.length == 1) { - document.getElementById("searchbox-submit").classList.add("btn-success"); - document.getElementById("searchbox-submit").classList.remove("btn-primary"); - } - else { - document.getElementById("searchbox-submit").classList.add("btn-primary"); - document.getElementById("searchbox-submit").classList.remove("btn-success"); - } +nmsSearch._disableTimer = function () { + if (nmsSearch._handler != false) { + clearInterval(nmsSearch.search); + } +}; +nmsSearch.search = function () { + var el = document.getElementById("searchbox"); + var id = false; + nmsSearch.matches = []; + if (el) { + id = el.value.toLowerCase(); + } + if (id) { + nmsMap.enableHighlights(); + for (var sw in nmsData.switches.switches) { + if (nmsSearch.searchTest(id, sw)) { + nmsSearch.matches.push(sw); + nmsMap.setSwitchHighlight(sw, true); + } else { + nmsMap.setSwitchHighlight(sw, false); + } + } + nmsSearch._enableTimer(); + } else { + nmsSearch._disableTimer(); + nmsMap.disableHighlights(); + } + if (nmsSearch.matches.length == 0) { + document.getElementById("searchbox-submit").classList.remove("btn-primary"); + document.getElementById("searchbox-submit").classList.remove("btn-success"); + document.getElementById("searchbox-submit").classList.add("btn-secondary"); + } else if (nmsSearch.matches.length == 1) { + document.getElementById("searchbox-submit").classList.add("btn-success"); + document.getElementById("searchbox-submit").classList.remove("btn-primary"); + document + .getElementById("searchbox-submit") + .classList.remove("btn-secondary"); + } else { + document.getElementById("searchbox-submit").classList.add("btn-primary"); + document.getElementById("searchbox-submit").classList.remove("btn-success"); + document + .getElementById("searchbox-submit") + .classList.remove("btn-secondary"); + } }; -nmsSearch.runSearch = function() { - if(nmsSearch.matches.length == 1) { - nmsInfoBox.showWindow("switchInfo",nmsSearch.matches[0]); - } - else if(nmsSearch.matches.length > 1) { - nmsInfoBox.showWindow('searchResults',nmsSearch.matches.length); - } - else { - document.getElementById("searchbox-submit").classList.remove("btn-primary"); - document.getElementById("searchbox").dataset.match = ''; - } +nmsSearch.runSearch = function () { + if (nmsSearch.matches.length == 1) { + nmsInfoBox.showWindow("switchInfo", nmsSearch.matches[0]); + } else if (nmsSearch.matches.length > 1) { + nmsInfoBox.showWindow("searchResults", nmsSearch.matches.length); + } else { + document.getElementById("searchbox-submit").classList.remove("btn-primary"); + document.getElementById("searchbox").dataset.match = ""; + } }; -nmsSearch._searchKeyListener = function(e) { - switch (e.keyCode) { - case 13: - nmsSearch.runSearch(); - break; - case 27: - nmsSearch.reset(); - break; - } -} +nmsSearch._searchKeyListener = function (e) { + switch (e.keyCode) { + case 13: + nmsSearch.runSearch(); + break; + case 27: + nmsSearch.reset(); + break; + } +}; -nmsSearch.init = function() { - $("#searchbox").keyup(function(e) { - nmsSearch._searchKeyListener(e); - }); -} +nmsSearch.init = function () { + // $("#searchbox").keyup(function(e) { + // nmsSearch._searchKeyListener(e); + // }); +}; diff --git a/web/js/nms-template.js b/web/js/nms-template.js index 0f25367..1d2c0e5 100644 --- a/web/js/nms-template.js +++ b/web/js/nms-template.js @@ -1,55 +1,60 @@ "use strict"; -var nmsTemplate = nmsTemplate || { -} +var nmsTemplate = nmsTemplate || {}; -nmsTemplate.test = function() { - var input = document.getElementById("template-input"); - var output = document.getElementById("template-output"); - var qp = document.getElementById("template-query-params"); - $.ajax({ - type: "POST", - url: "/api/templates/test" + qp.value, - async: false, - data: input.value, - dataType: "text", - success: function (indata, textStatus, jqXHR) { - var output = document.getElementById("template-output"); - output.value = jqXHR.responseText; - }, - error: function (jqXHR, textStatus) { - var output = document.getElementById("template-output"); - output.value = jqXHR.responseText; - } - }); -} +nmsTemplate.test = function () { + var input = document.getElementById("template-input"); + var output = document.getElementById("template-output"); + var qp = document.getElementById("template-query-params"); + $.ajax({ + type: "POST", + url: "/api/templates/test" + qp.value, + async: false, + data: input.value, + dataType: "text", + success: function (indata, textStatus, jqXHR) { + var output = document.getElementById("template-output"); + output.value = jqXHR.responseText; + }, + error: function (jqXHR, textStatus) { + var output = document.getElementById("template-output"); + output.value = jqXHR.responseText; + }, + }); +}; -nmsTemplate.fromFile = function(template) { - if(template == '') { return; } - $.ajax({ - type: "GET", - url: "/templates/" + template, - async: false, - dataType: "text", - success: function (indata, textStatus, jqXHR) { - var output = document.getElementById("template-input"); - output.value = indata; - } - }); - nmsTemplate.test(); -} +nmsTemplate.fromFile = function (template) { + if (template == "") { + return; + } + $.ajax({ + type: "GET", + url: "/templates/" + template, + async: false, + dataType: "text", + success: function (indata, textStatus, jqXHR) { + var output = document.getElementById("template-input"); + output.value = indata; + }, + }); + nmsTemplate.test(); +}; -nmsTemplate.getTemplates = function() { - $.ajax({ - type: "GET", - url: "/api/read/template-list", - async: false, - dataType: "json", - success: function (indata, textStatus, jqXHR) { - $.each( indata['templates'], function( value ) { - $('#nmsTemplate-select').append($("<option></option>").attr("value",indata['templates'][value]['file']).text(indata['templates'][value]['file'])); - }); - } - }); -} +nmsTemplate.getTemplates = function () { + $.ajax({ + type: "GET", + url: "/api/read/template-list", + async: false, + dataType: "json", + success: function (indata, textStatus, jqXHR) { + $.each(indata["templates"], function (value) { + $("#nmsTemplate-select").append( + $("<option></option>") + .attr("value", indata["templates"][value]["file"]) + .text(indata["templates"][value]["file"]) + ); + }); + }, + }); +}; //nmsTemplate.getTemplates(); diff --git a/web/js/nms-time.js b/web/js/nms-time.js index d5b6379..6962fef 100644 --- a/web/js/nms-time.js +++ b/web/js/nms-time.js @@ -9,73 +9,80 @@ * The interface is a bit bloated at the moment, though. */ var nmsTime = nmsTime || { - _now: undefined, - _handle: undefined, - _stopTime: undefined -} + _now: undefined, + _handle: undefined, + _stopTime: undefined, +}; -nmsTime.replayEvent = function() { - var eStart = setTree(nmsData,["config","config","data","start"],"2018-03-23T00:00:00+0200"); - nmsTime._stopTime = new Date(setTree(nmsData,["config","config","data","end"],"2018-04-01T14:30:00+0200")); - nmsTime.setNow(eStart); - nmsTime.startPlayback(60); -} +nmsTime.replayEvent = function () { + var eStart = setTree( + nmsData, + ["config", "config", "data", "start"], + "2018-03-23T00:00:00+0200" + ); + nmsTime._stopTime = new Date( + setTree( + nmsData, + ["config", "config", "data", "end"], + "2018-04-01T14:30:00+0200" + ) + ); + nmsTime.setNow(eStart); + nmsTime.startPlayback(60); +}; -nmsTime.isRealTime = function() { - if (nmsTime._now == undefined && nmsTime._handle == undefined) - return true; - return false; -} +nmsTime.isRealTime = function () { + if (nmsTime._now == undefined && nmsTime._handle == undefined) return true; + return false; +}; nmsTime.startNowPicker = function () { - $.datetimepicker.setLocale('no'); - $('#nowPicker').datetimepicker('destroy'); - var now; - if (nmsTime._now == undefined) - now = new Date(); - else - now = nmsTime._now; - now.setSeconds(0); - now.setMilliseconds(0); - var datepicker = $('#nowPicker').datetimepicker({ - value: now, - step: 1, - mask:false, - inline:true, - todayButton: true, - validateOnBlur:false, - dayOfWeekStart:1, - maxDate:'+1970/01/01', - onSelectDate: function(ct,$i){ - document.getElementById('nowPicker').dataset.iso = new Date(ct.valueOf()); - }, - onSelectTime: function(ct,$i){ - document.getElementById('nowPicker').dataset.iso = new Date(ct.valueOf()); - }, - onGenerate: function(ct,$i){ - document.getElementById('nowPicker').dataset.iso = new Date(ct.valueOf()); - } - }); -} + $.datetimepicker.setLocale("no"); + $("#nowPicker").datetimepicker("destroy"); + var now; + if (nmsTime._now == undefined) now = new Date(); + else now = nmsTime._now; + now.setSeconds(0); + now.setMilliseconds(0); + var datepicker = $("#nowPicker").datetimepicker({ + value: now, + step: 1, + mask: false, + inline: true, + todayButton: true, + validateOnBlur: false, + dayOfWeekStart: 1, + maxDate: "+1970/01/01", + onSelectDate: function (ct, $i) { + document.getElementById("nowPicker").dataset.iso = new Date(ct.valueOf()); + }, + onSelectTime: function (ct, $i) { + document.getElementById("nowPicker").dataset.iso = new Date(ct.valueOf()); + }, + onGenerate: function (ct, $i) { + document.getElementById("nowPicker").dataset.iso = new Date(ct.valueOf()); + }, + }); +}; -nmsTime.setNow = function(now) { - var newDate = new Date(now); - newDate.setSeconds(0); - newDate.setMilliseconds(0); - newDate.setMinutes(newDate.getMinutes() - newDate.getMinutes()%1); - nmsTime._now = newDate; - nmsTime._updateData(); -} +nmsTime.setNow = function (now) { + var newDate = new Date(now); + newDate.setSeconds(0); + newDate.setMilliseconds(0); + newDate.setMinutes(newDate.getMinutes() - (newDate.getMinutes() % 1)); + nmsTime._now = newDate; + nmsTime._updateData(); +}; -nmsTime._updateData = function() { - nmsData.now = nmsTime._now.getTime() / 1000; -} +nmsTime._updateData = function () { + nmsData.now = nmsTime._now.getTime() / 1000; +}; -nmsTime.realTime = function() { - nmsTime.stopPlayback(); - nmsTime._now = undefined; - nmsData.now = undefined; -} +nmsTime.realTime = function () { + nmsTime.stopPlayback(); + nmsTime._now = undefined; + nmsData.now = undefined; +}; /* * Step a fixed amount of time, measured in minutes. @@ -84,41 +91,42 @@ nmsTime.realTime = function() { * backend versions to avoid bloating the cache and thus also stressing the * database */ -nmsTime.step = function(amount) { - if (nmsTime._now == null) - throw "Stepping without nmsTime._now"; - if (amount == 0 || amount == undefined) - throw "Invalid step"; - if (nmsTime._now.getTime() + (amount * 1000 * 60 ) > Date.now()) { - nmsTime.realTime(); - return; - } - if (nmsTime._stopTime != undefined && nmsTime._now.getTime() >= nmsTime._stopTime.getTime()) { - nmsTime.stopPlayback(); - nmsTime._stopTime = undefined; - } - nmsTime._now.setMinutes(nmsTime._now.getMinutes() + amount); - nmsTime._updateData(); -} +nmsTime.step = function (amount) { + if (nmsTime._now == null) throw "Stepping without nmsTime._now"; + if (amount == 0 || amount == undefined) throw "Invalid step"; + if (nmsTime._now.getTime() + amount * 1000 * 60 > Date.now()) { + nmsTime.realTime(); + return; + } + if ( + nmsTime._stopTime != undefined && + nmsTime._now.getTime() >= nmsTime._stopTime.getTime() + ) { + nmsTime.stopPlayback(); + nmsTime._stopTime = undefined; + } + nmsTime._now.setMinutes(nmsTime._now.getMinutes() + amount); + nmsTime._updateData(); +}; /* * Step based on key-press. Same as step() but stops playback if it's * active and allows you to rewind from a "live" map. */ -nmsTime.stepKey = function(amount) { - nmsTime.stopPlayback(); - if (nmsTime._now == undefined) { - nmsTime.setNow(Date.now()); - } - nmsTime.step(amount); -} +nmsTime.stepKey = function (amount) { + nmsTime.stopPlayback(); + if (nmsTime._now == undefined) { + nmsTime.setNow(Date.now()); + } + nmsTime.step(amount); +}; /* * Target of setInterval() when replaying. */ -nmsTime._tick = function() { - nmsTime.step(nmsTime._speed); -} +nmsTime._tick = function () { + nmsTime.step(nmsTime._speed); +}; /* * We now have a time (presumably), start playback. @@ -127,32 +135,29 @@ nmsTime._tick = function() { * * Gondul does not _yet_ support fast forwarding into the future. */ -nmsTime.startPlayback = function(speed) { - if (nmsTime._handle) - nmsTime.stopPlayback(); - if (nmsTime._now.getTime() > Date.now()) { - nmsTime.stopPlayback(); - return; - } - nmsTime._speed = speed; - nmsTime._handle = setInterval(nmsTime._tick,2000); -} +nmsTime.startPlayback = function (speed) { + if (nmsTime._handle) nmsTime.stopPlayback(); + if (nmsTime._now.getTime() > Date.now()) { + nmsTime.stopPlayback(); + return; + } + nmsTime._speed = speed; + nmsTime._handle = setInterval(nmsTime._tick, 2000); +}; -nmsTime.togglePause = function() { - if (nmsTime._handle) { - nmsTime.stopPlayback(); - } else { - if (nmsTime.isRealTime()) { - nmsTime.setNow(Date.now()); - } else { - nmsTime.startPlayback(nmsTime._speed ? nmsTime._speed : 60); - } - } -} +nmsTime.togglePause = function () { + if (nmsTime._handle) { + nmsTime.stopPlayback(); + } else { + if (nmsTime.isRealTime()) { + nmsTime.setNow(Date.now()); + } else { + nmsTime.startPlayback(nmsTime._speed ? nmsTime._speed : 60); + } + } +}; -nmsTime.stopPlayback = function() { - if (nmsTime._handle) - clearInterval(nmsTime._handle); - nmsTime._handle = undefined; -} - +nmsTime.stopPlayback = function () { + if (nmsTime._handle) clearInterval(nmsTime._handle); + nmsTime._handle = undefined; +}; diff --git a/web/js/nms-types.js b/web/js/nms-types.js index 4e7c24e..ee33f31 100644 --- a/web/js/nms-types.js +++ b/web/js/nms-types.js @@ -1,16 +1,16 @@ "use strict"; /* * Base type. All nmsType* classes represent a logical family of units. - * This is used to provide input validation on the class-level and + * This is used to provide input validation on the class-level and * is used to store the value and description of variables. * This is not bound to editing in theory. It is natural to think * that nms-map-handlers will leverage the same type-system to * verify that things are as they should. * * An example of future features outside the scope of simply editing stuff: - * verify that a nmsTypeIP is contained in nmsTypeNetwork + * verify that a nmsTypeIP is contained in nmsTypeNetwork * use nmsTypePlace for all placement-logic - * + * * Stuff that should be supported within an editor: * - Validation (duh) * - Hints (auto-complete, parse-error-feedback) @@ -22,213 +22,234 @@ * nms-info-box */ class nmsType { - constructor(description, priority) { - this._value = null; - this.description = description; - this.validationReason = ""; - this.ro = false; - if (priority == undefined) { - priority = this._defaultPriority; - } - this.priority = priority - } - // Override this to get free validation. Just return true or false. - validate(input) { - return true; - } - // Always return text-representation - // Should be matched by fromString() - toString() { - if (this._value == null || this._value == undefined) { - return "" - } else { - return this._value.toString(); - } - } - // Set value from string-input - fromString(input) { - if (this.validate(input)) { - this._value = input; - } else { - throw "Invalid input. Use .validate() before setting stuff please. I am " + this + " and my input is " + input - } - } - initial(v) { - this.value = v; - if(this.priority == nmsPriority.newOnly) { - this.ro = true; - } - } - get value() { - return this._value; - } - set value(input) { - this._value = input; - } - get _defaultPriority() { - return nmsPriority.optional; - } + constructor(description, priority) { + this._value = null; + this.description = description; + this.validationReason = ""; + this.ro = false; + if (priority == undefined) { + priority = this._defaultPriority; + } + this.priority = priority; + } + // Override this to get free validation. Just return true or false. + validate(input) { + return true; + } + // Always return text-representation + // Should be matched by fromString() + toString() { + if (this._value == null || this._value == undefined) { + return ""; + } else { + return this._value.toString(); + } + } + // Set value from string-input + fromString(input) { + if (this.validate(input)) { + this._value = input; + } else { + throw ( + "Invalid input. Use .validate() before setting stuff please. I am " + + this + + " and my input is " + + input + ); + } + } + initial(v) { + this.value = v; + if (this.priority == nmsPriority.newOnly) { + this.ro = true; + } + } + get value() { + return this._value; + } + set value(input) { + this._value = input; + } + get _defaultPriority() { + return nmsPriority.optional; + } } -class nmsTypeInterval extends nmsType { - validate(input) { - return !!(input.match(/^\d\d:\d\d:\d\d$/)) - } +class nmsTypeInterval extends nmsType { + validate(input) { + return !!input.match(/^\d\d:\d\d:\d\d$/); + } } -class nmsTypeIP extends nmsType { - get _defaultPriority() { - return nmsPriority.important; - } - _validateV4(input) { - var x = input.match(/^(\d+)\.(\d+).(\d+).(\d+)$/) - if (!x) { - this.validationReason = "Doesn't look like IPv4 address or IPv6"; - return false; - } - for (var i = 1; i < 5; i ++) { - if (x[i] < 0 || x[i] > 255) { - this.validationReason = "The " + i + "'th octet("+x[i]+") is outside of expected range (0-255)" - return false - } - } - this.validationReason = "OK" - return true; - } - /* It's so easy to check if IPv6 addresses are valid. - */ - _validateV6(input) { - if (!!input.match(/^[a-fA-F0-9:]+$/)) { - this.validationReason = "OK IPv6 address" - return true; - } else { - this.validationReason = "Doesn't parse as a IPv6 address despite :"; - return false; - } - } - validate(input) { - if (input.match(":")) { - return this._validateV6(input); - } else { - return this._validateV4(input); - } - } +class nmsTypeIP extends nmsType { + get _defaultPriority() { + return nmsPriority.important; + } + _validateV4(input) { + var x = input.match(/^(\d+)\.(\d+).(\d+).(\d+)$/); + if (!x) { + this.validationReason = "Doesn't look like IPv4 address or IPv6"; + return false; + } + for (var i = 1; i < 5; i++) { + if (x[i] < 0 || x[i] > 255) { + this.validationReason = + "The " + + i + + "'th octet(" + + x[i] + + ") is outside of expected range (0-255)"; + return false; + } + } + this.validationReason = "OK"; + return true; + } + /* It's so easy to check if IPv6 addresses are valid. + */ + _validateV6(input) { + if (!!input.match(/^[a-fA-F0-9:]+$/)) { + this.validationReason = "OK IPv6 address"; + return true; + } else { + this.validationReason = "Doesn't parse as a IPv6 address despite :"; + return false; + } + } + validate(input) { + if (input.match(":")) { + return this._validateV6(input); + } else { + return this._validateV4(input); + } + } } class nmsTypeCIDR extends nmsType { - get _defaultPriority() { - return nmsPriority.important; - } - _validateV4(input) { - var x = input.match(/^(\d+)\.(\d+).(\d+).(\d+)\/(\d+)$/) - if (!x) { - this.validationReason = "Doesn't look like IPv4 cidr or IPv6"; - return false; - } - for (var i = 1; i < 5; i ++) { - if (x[i] < 0 || x[i] > 255) { - this.validationReason = "The " + i + "'th octet("+x[i]+") is outside of expected range (0-255)"; - return false; - } - } - if (x[5] < 8 || x[5] > 32) { - this.validationReason = "/"+x[5]+" is outside of expected range (8-32)"; - return false; - } - this.validationReason = "OK"; - return true; - } - _validateV6(input) { - if (!!input.match(/^[a-fA-F0-9:]+\/(\d+)$/)) { - this.validationReason = "OK IPv6 cidr" - return true; - } else { - this.validationReason = "Doesn't parse as a IPv6 cidr despite :"; - return false; - } - } - validate(input) { - if (input.match(":")) { - return this._validateV6(input); - } else { - return this._validateV4(input); - } - } + get _defaultPriority() { + return nmsPriority.important; + } + _validateV4(input) { + var x = input.match(/^(\d+)\.(\d+).(\d+).(\d+)\/(\d+)$/); + if (!x) { + this.validationReason = "Doesn't look like IPv4 cidr or IPv6"; + return false; + } + for (var i = 1; i < 5; i++) { + if (x[i] < 0 || x[i] > 255) { + this.validationReason = + "The " + + i + + "'th octet(" + + x[i] + + ") is outside of expected range (0-255)"; + return false; + } + } + if (x[5] < 8 || x[5] > 32) { + this.validationReason = + "/" + x[5] + " is outside of expected range (8-32)"; + return false; + } + this.validationReason = "OK"; + return true; + } + _validateV6(input) { + if (!!input.match(/^[a-fA-F0-9:]+\/(\d+)$/)) { + this.validationReason = "OK IPv6 cidr"; + return true; + } else { + this.validationReason = "Doesn't parse as a IPv6 cidr despite :"; + return false; + } + } + validate(input) { + if (input.match(":")) { + return this._validateV6(input); + } else { + return this._validateV4(input); + } + } } -class nmsTypeNetwork extends nmsType { - get _defaultPriority() { - return nmsPriority.important; - } - validate(input) { - var x =testTree(nmsData,["networks","networks",input]) - if (x) { - this.validationReason = "OK" - } else { - this.validationReason = "No such network: " + input - } - return x; - } +class nmsTypeNetwork extends nmsType { + get _defaultPriority() { + return nmsPriority.important; + } + validate(input) { + var x = testTree(nmsData, ["networks", "networks", input]); + if (x) { + this.validationReason = "OK"; + } else { + this.validationReason = "No such network: " + input; + } + return x; + } } class nmsTypeJSON extends nmsType { - validate(input) { - try { - JSON.parse(input); - this.validationReason = "OK" - return true; - } catch(e) { - this.validationReason = e.message; - return false; - } - } - toString() { - return JSON.stringify(this._value); - } - fromString(input) { - try { - this.value = JSON.parse(input); - } catch(e) { - throw "Invalid input. Use .validate() before setting stuff please. I am " + this + " and my input is " + input - } - } + validate(input) { + try { + JSON.parse(input); + this.validationReason = "OK"; + return true; + } catch (e) { + this.validationReason = e.message; + return false; + } + } + toString() { + return JSON.stringify(this._value); + } + fromString(input) { + try { + this.value = JSON.parse(input); + } catch (e) { + throw ( + "Invalid input. Use .validate() before setting stuff please. I am " + + this + + " and my input is " + + input + ); + } + } } -class nmsTypePlace extends nmsTypeJSON { } -class nmsTypePort extends nmsType { } +class nmsTypePlace extends nmsTypeJSON {} +class nmsTypePort extends nmsType {} class nmsTypeSysname extends nmsType { - get _defaultPriority() { - return nmsPriority.newOnly; - } - validate(input) { - if (this.ro) { - throw "Trying to validate a r/o field" - } - var x = testTree(nmsData,["switches","switches",input]) - if (x) { - this.validationReason = "Switch already exists" - } else { - this.validationReason = "OK: " + input - } - return !x; - } + get _defaultPriority() { + return nmsPriority.newOnly; + } + validate(input) { + if (this.ro) { + throw "Trying to validate a r/o field"; + } + var x = testTree(nmsData, ["switches", "switches", input]); + if (x) { + this.validationReason = "Switch already exists"; + } else { + this.validationReason = "OK: " + input; + } + return !x; + } } class nmsTypeSysnameReference extends nmsType { - get _defaultPriority() { - return nmsPriority.important; - } - validate(input) { - var x = testTree(nmsData,["switches","switches",input]) - if (x) { - this.validationReason = "OK" - } else { - this.validationReason = "No such switch: " + input - } - return x; - } + get _defaultPriority() { + return nmsPriority.important; + } + validate(input) { + var x = testTree(nmsData, ["switches", "switches", input]); + if (x) { + this.validationReason = "OK"; + } else { + this.validationReason = "No such switch: " + input; + } + return x; + } } -class nmsTypeTags extends nmsTypeJSON { } -class nmsTypeSecret extends nmsType { } +class nmsTypeTags extends nmsTypeJSON {} +class nmsTypeSecret extends nmsType {} var nmsPriority = { - readOnly: 0, - required: 1, - important: 2, - optional: 3, - newOnly: 4 -} + readOnly: 0, + required: 1, + important: 2, + optional: 3, + newOnly: 4, +}; diff --git a/web/js/nms-ui-boxes.js b/web/js/nms-ui-boxes.js index ee4dc98..6a89fcd 100644 --- a/web/js/nms-ui-boxes.js +++ b/web/js/nms-ui-boxes.js @@ -5,10 +5,10 @@ * The idea is to retain the ability to fiddle with html, but solve common * problems such as "I need to show a box that looks good" and "I need to * update the content of this field in this box when something happens". - * + * * Seeing as how it's 2019, I figured I'd try to use this whole "class" * thing :D - * + * * Eventually, everything in nms-info-box.js should use this, but more over, * if a need to write some code that needs a UI element arises, the general * problem should be solved here, while the implementation: elsewhere. @@ -20,221 +20,220 @@ */ class nmsBox { - constructor(type,settings = null) { - this.type = type; - this._boxes = [] - this.html = document.createElement(type); - this.html.nmsBox = this; - if (settings) { - this.applySettings(settings); - } - } - get value() { - var values = []; - for (var x in this._boxes) { - var tmp = this._boxes[x].value; - if (tmp != undefined && !((tmp instanceof Array) && tmp.length == 0)) { - values.push(tmp) - } - } - return values; - } + constructor(type, settings = null) { + this.type = type; + this._boxes = []; + this.html = document.createElement(type); + this.html.nmsBox = this; + if (settings) { + this.applySettings(settings); + } + } + get value() { + var values = []; + for (var x in this._boxes) { + var tmp = this._boxes[x].value; + if (tmp != undefined && !(tmp instanceof Array && tmp.length == 0)) { + values.push(tmp); + } + } + return values; + } - applySettings(settings) { - /* - * This really should go deeper, but the problem is that - * I'm lazy. You can't just use Object.assign() either because - * stuff like html.style isn't just any element and we want - * to be able to do html:{style:{display:"none"}} instead - * of html:{style:new (style object thing with display:none)} - * - * So far this works. - * - * Note that this breaks forr classList: This is because - * classList is just an accessor for className, so you - * should set className instead initially. - */ - if (settings.html) { - for (var x in settings.html) { - if(settings.html[x] instanceof Object) { - Object.assign(this.html[x],settings.html[x]) - } else { - this.html[x] = settings.html[x]; - } - } - } - } - /* Should rename these to push() and unshift(), really, to be - * more consistent. - */ - add(box) { - this._boxes.push(box); - box.attach(this.html) - box.show() - } - insert(box) { - this._boxes.unshift(box) - box.attach(this.html) - box.show(true,-1) - } - - /* This is provided so as to allow attaching to non-nmsBox-objects. - * E.g.: attach the root to a HTML element directly. - * If you just use foo = document.getElement..., - * foo.appendChild(box.html), then .hide() will work fine, - * but there's no way to do .show() afterwards. - * - * Be aware: - * - we want to AVOID the child knowing too much about the parent - * - HTML elements can only ever be part of a single parent - * element. This means that it is safe to attach(root1), .show(), - * atach(root2), show() ... The DOM object wil be removed from root1. - * - Due to the above, we should probably actually adress that, since - * there are valid reasons for showing the same nmsBox twice (e.g.: - * showing a list of tons of stuff, and also a "top 5") - */ - attach(root) { - if (!(root instanceof HTMLElement)) { - root = document.getElementById(root) - } - console.assert(root instanceof HTMLElement) - this._root = root; - } - show(show = true,where=1) { - if (!show) { - this.hide() - return - } - if (this._root instanceof HTMLElement) { - if (where>0) { - this._root.appendChild(this.html); - } else { - this._root.insertBefore(this.html,this._root.firstElementChild) - } - } - } - _remove(source,box) { - source.html.removeChild(box.html) - if (box._root == source) { - box._root = undefined; - } - var x = source._boxes.indexOf(box) - delete source._boxes[x] - } - _includes(source,box) { - if (source._boxes.indexOf(box) >= 0) { - return true; - } else { - return false; - } - } - /* - * This redirect is to make it easier for subclasses that - * override add() to make it eaiser to add logical - * childs, e.g. adding to a table really adds to ._tbody, - * not the true top-element of the table. - */ - remove(box) { - this._remove(this,box) - } - includes(box) { - return this._includes(this,box); - } - hide() { - if (this.html.parentElement instanceof HTMLElement) { - this.html.parentElement.removeChild(this.html); - } - } - destroy() { - this.hide() - for (var i in this._boxes) { - var x = this._boxes[i]; - x.hide() - x.destroy() - delete this._boxes[i] - } - delete this.html; - delete this; - } - update() { - for (var x in this._boxes) { - this._boxes[x].update(); - } - } -}; + applySettings(settings) { + /* + * This really should go deeper, but the problem is that + * I'm lazy. You can't just use Object.assign() either because + * stuff like html.style isn't just any element and we want + * to be able to do html:{style:{display:"none"}} instead + * of html:{style:new (style object thing with display:none)} + * + * So far this works. + * + * Note that this breaks forr classList: This is because + * classList is just an accessor for className, so you + * should set className instead initially. + */ + if (settings.html) { + for (var x in settings.html) { + if (settings.html[x] instanceof Object) { + Object.assign(this.html[x], settings.html[x]); + } else { + this.html[x] = settings.html[x]; + } + } + } + } + /* Should rename these to push() and unshift(), really, to be + * more consistent. + */ + add(box) { + this._boxes.push(box); + box.attach(this.html); + box.show(); + } + insert(box) { + this._boxes.unshift(box); + box.attach(this.html); + box.show(true, -1); + } + /* This is provided so as to allow attaching to non-nmsBox-objects. + * E.g.: attach the root to a HTML element directly. + * If you just use foo = document.getElement..., + * foo.appendChild(box.html), then .hide() will work fine, + * but there's no way to do .show() afterwards. + * + * Be aware: + * - we want to AVOID the child knowing too much about the parent + * - HTML elements can only ever be part of a single parent + * element. This means that it is safe to attach(root1), .show(), + * atach(root2), show() ... The DOM object wil be removed from root1. + * - Due to the above, we should probably actually adress that, since + * there are valid reasons for showing the same nmsBox twice (e.g.: + * showing a list of tons of stuff, and also a "top 5") + */ + attach(root) { + if (!(root instanceof HTMLElement)) { + root = document.getElementById(root); + } + console.assert(root instanceof HTMLElement); + this._root = root; + } + show(show = true, where = 1) { + if (!show) { + this.hide(); + return; + } + if (this._root instanceof HTMLElement) { + if (where > 0) { + this._root.appendChild(this.html); + } else { + this._root.insertBefore(this.html, this._root.firstElementChild); + } + } + } + _remove(source, box) { + source.html.removeChild(box.html); + if (box._root == source) { + box._root = undefined; + } + var x = source._boxes.indexOf(box); + delete source._boxes[x]; + } + _includes(source, box) { + if (source._boxes.indexOf(box) >= 0) { + return true; + } else { + return false; + } + } + /* + * This redirect is to make it easier for subclasses that + * override add() to make it eaiser to add logical + * childs, e.g. adding to a table really adds to ._tbody, + * not the true top-element of the table. + */ + remove(box) { + this._remove(this, box); + } + includes(box) { + return this._includes(this, box); + } + hide() { + if (this.html.parentElement instanceof HTMLElement) { + this.html.parentElement.removeChild(this.html); + } + } + destroy() { + this.hide(); + for (var i in this._boxes) { + var x = this._boxes[i]; + x.hide(); + x.destroy(); + delete this._boxes[i]; + } + delete this.html; + delete this; + } + update() { + for (var x in this._boxes) { + this._boxes[x].update(); + } + } +} class nmsString extends nmsBox { - constructor(content,type) { - type = type ? type : "p"; - super(type,{ html: { textContent: content }}) - } - set value(input) { - this.html.textContent = input; - } - get value() { - return this.html.textContent; - } + constructor(content, type) { + type = type ? type : "p"; + super(type, { html: { textContent: content } }); + } + set value(input) { + this.html.textContent = input; + } + get value() { + return this.html.textContent; + } } class nmsButton extends nmsBox { - constructor(text,type = "btn-default") { - super("button",{html:{textContent:text,className:"btn "+type,type:"button"}}) - } + constructor(text, type = "btn-default") { + super("button", { + html: { textContent: text, className: "btn " + type, type: "button" }, + }); + } } /* * A general-purpose table. It can be created in one go, or - * as-you-go. + * as-you-go. */ class nmsTable extends nmsBox { - constructor(content, caption) { - super("table",{html:{className:"table table-condensed"}}); - if (caption != undefined) { - var cap = new nmsBox("caption"); - cap.html.textContent = caption; - super.add(cap); - } - this._tbody = new nmsBox("tbody"); - super.add(this._tbody); - for (var v in content) { - this.add(content[v]); - } - } - remove(box) { - this._remove(this._tbody,box) - } - includes(box) { - return this._tbody.includes(box) - } - _makeBox(content) { - if (content instanceof nmsBox) { - return content; - } - var tr; - var td1; - var td2; - tr = new nmsBox("tr"); - for (var x in content) { - var td = new nmsBox("td"); - var child = content[x]; - if (child instanceof nmsBox) { - td.add(child); - } else { - td.add(new nmsString(child)); - } - tr.add(td); - } - return tr; - } - /* Can take either a single nmsBox-object that will be added as-is, - * or an array of items that will be added as individual cells - */ - add(content) { - this._tbody.add(this._makeBox(content)); - } - insert(box) { - this._tbody.insert(this._makeBox(box)); - } + constructor(content, caption) { + super("table", { html: { className: "table table-sm table-transparent" } }); + if (caption != undefined) { + var cap = new nmsBox("caption"); + cap.html.textContent = caption; + super.add(cap); + } + this._tbody = new nmsBox("tbody"); + super.add(this._tbody); + for (var v in content) { + this.add(content[v]); + } + } + remove(box) { + this._remove(this._tbody, box); + } + includes(box) { + return this._tbody.includes(box); + } + _makeBox(content) { + if (content instanceof nmsBox) { + return content; + } + var tr; + tr = new nmsBox("tr"); + for (var x in content) { + var td = new nmsBox("td"); + var child = content[x]; + if (child instanceof nmsBox) { + td.add(child); + } else { + td.add(new nmsString(child)); + } + tr.add(td); + } + return tr; + } + /* Can take either a single nmsBox-object that will be added as-is, + * or an array of items that will be added as individual cells + */ + add(content) { + this._tbody.add(this._makeBox(content)); + } + insert(box) { + this._tbody.insert(this._makeBox(box)); + } } /* @@ -245,54 +244,57 @@ class nmsTable extends nmsBox { * myThing.add(nmsString("whatever")) * myThing.title = "blah...." */ -class nmsPanel extends nmsBox{ - constructor(title){ - super("div",{html:{style:{gridColumn: 2}}}); - this._topBox = new nmsBox("div",{ html: { className: "panel panel-default"}}); - this._body = new nmsBox("div",{html:{className: "panel-body"}}); - this.nav = new nmsBox("div",{html:{className: "panel-body"}}); - this._topBox.add(this.makeHeading(title)); - this._topBox.add(this.nav); - this._topBox.add(this._body); - super.add(this._topBox); - } - attach(root = document.getElementById("genericPanelContainer")) { - try { - var x = parseInt(root.lastElementChild.style.gridColumnStart); - this.html.style.gridColumnStart = x+1; - } catch(e) { - } - super.attach(root) - } - show() { - if (!this._root) { - this.attach() - } - super.show() - } - /* Mainly just to make the constructor more readable. */ - makeHeading(title) { - var titleObject = new nmsBox("div",{html:{className: "panel-heading"}}); - this._titleText = new nmsBox("h4",{html:{textContent: title}}); - var closeButton = new nmsBox("button"); - closeButton.html.className = "close"; - closeButton.panel = this; - closeButton.html.onclick = function() { - this.nmsBox.panel.destroy(); - } - closeButton.html.style = "float: right;"; - closeButton.add(new nmsString("X","span")); - titleObject.add(closeButton); - titleObject.add(this._titleText); - return titleObject; - } - add(item) { - this._body.add(item) - } - set title(input) { - this._titleText.html.textContent = input; - } - get title() { - this._titleText.html.textContent; - } +class nmsPanel extends nmsBox { + constructor(title) { + super("div", { html: { style: { gridColumn: 2 } } }); + this._topBox = new nmsBox("div", { + html: { className: "panel panel-default" }, + }); + this._body = new nmsBox("div", { html: { className: "panel-body" } }); + this.nav = new nmsBox("div", { html: { className: "panel-body" } }); + this._topBox.add(this.makeHeading(title)); + this._topBox.add(this.nav); + this._topBox.add(this._body); + super.add(this._topBox); + } + attach(root = document.getElementById("genericPanelContainer")) { + try { + var x = parseInt(root.lastElementChild.style.gridColumnStart); + this.html.style.gridColumnStart = x + 1; + } catch (e) {} + super.attach(root); + } + show() { + if (!this._root) { + this.attach(); + } + super.show(); + } + /* Mainly just to make the constructor more readable. */ + makeHeading(title) { + var titleObject = new nmsBox("div", { + html: { className: "panel-heading" }, + }); + this._titleText = new nmsBox("h4", { html: { textContent: title } }); + var closeButton = new nmsBox("button"); + closeButton.html.className = "close"; + closeButton.panel = this; + closeButton.html.onclick = function () { + this.nmsBox.panel.destroy(); + }; + closeButton.html.style = "float: right;"; + closeButton.add(new nmsString("X", "span")); + titleObject.add(closeButton); + titleObject.add(this._titleText); + return titleObject; + } + add(item) { + this._body.add(item); + } + set title(input) { + this._titleText.html.textContent = input; + } + get title() { + this._titleText.html.textContent; + } } diff --git a/web/js/nms-ui-switch-summary.js b/web/js/nms-ui-switch-summary.js index 9b63b24..edc6921 100644 --- a/web/js/nms-ui-switch-summary.js +++ b/web/js/nms-ui-switch-summary.js @@ -1,58 +1,63 @@ "user strict"; class nmsSwitchSummary extends nmsTable { - constructor(sw) { - super() - this._sw = sw; - this._data = {} - this.refresh() - } - - refresh() { - for (var h in handlers ) { - if (handlers[h].getInfo != undefined) { - var tmp = handlers[h].getInfo(this._sw); - if (!tmp) { continue; } - if (this._data[h] == undefined) { - this._data[h] = {} - } - for (var x in tmp.data) { - if (this._data[h][x] == undefined) { - this._data[h][x] = new nmsSwitchItem(tmp.data[x].description,handlers[h]) - this.add(this._data[h][x]) - } - this._data[h][x].refresh(tmp.data[x]) - } - } - } - } + constructor(sw) { + super(); + this._sw = sw; + this._data = {}; + this.refresh(); + } + + refresh() { + for (var h in handlers) { + if (handlers[h].getInfo != undefined) { + var tmp = handlers[h].getInfo(this._sw); + if (!tmp) { + continue; + } + if (this._data[h] == undefined) { + this._data[h] = {}; + } + for (var x in tmp.data) { + if (this._data[h][x] == undefined) { + this._data[h][x] = new nmsSwitchItem( + tmp.data[x].description, + handlers[h] + ); + this.add(this._data[h][x]); + } + this._data[h][x].refresh(tmp.data[x]); + } + } + } + } } class nmsSwitchItem extends nmsBox { - constructor(description,handler) { - super("tr") - this.add(new nmsBox("td",{html:{textContent:description}})); - this.html.title = handler.tag; - this._value = new nmsBox("td") - this.add(this._value) - } - refresh(item) { - if (item.value == null || item.value == undefined || item.value == "") { - if (this._hidden == true) { - return; - } - this._value_content = undefined; - this._hidden = true; - this.hide() - return; - } - if (this._value_content != item.value) { - this._value.html.textContent = item.value; - this._value_content = item.value; - } - if (this._hidden == true) { - this.show() - this._hidden = false; - } - } + constructor(description, handler) { + super("tr"); + this.add(new nmsBox("td", { html: { textContent: description } })); + this.html.title = handler.tag; + this._value = new nmsBox("td"); + this.add(this._value); + } + refresh(item) { + if (item.value == null || item.value == undefined || item.value == "") { + if (this._hidden == true) { + return; + } + this._value_content = undefined; + this._hidden = true; + this.hide(); + return; + } + if (this._value_content != item.value) { + this._value.html.textContent = item.value; + this._value_content = item.value; + } + if (this._hidden == true) { + this.show(); + this._hidden = false; + } + } } diff --git a/web/js/nms-ui-switch.js b/web/js/nms-ui-switch.js index 825ecd9..e2663d4 100644 --- a/web/js/nms-ui-switch.js +++ b/web/js/nms-ui-switch.js @@ -3,318 +3,352 @@ /* Basic editor for switches, and possibly networks and whatever. * This is the first real use of both the nmsBox and nmsType, so * expect changes as the need(s) arise. - * + * * The general idea is simple, though: Editing and adding is to be treated * as similar as possible, and there should be no hard-coding anywhere. If * we need a "one-off" for whatever, we should find a genric way of solving - * it to avoid complicating things. - * + * it to avoid complicating things. + * */ class nmsNewSwitch extends nmsPanel { - constructor() { - super("Add new switch") - this.add(new nmsModSwitch(undefined)) - this.nav.add(new nmsString("The only required field for adding a switch is the sysname, everything else will be filled in by the backend if you do not provide it. However, you should PROBABLY fill in managemnt IP and a few other fields.")); - } + constructor() { + super("Add new switch"); + this.add(new nmsModSwitch(undefined)); + this.nav.add( + new nmsString( + "The only required field for adding a switch is the sysname, everything else will be filled in by the backend if you do not provide it. However, you should PROBABLY fill in managemnt IP and a few other fields." + ) + ); + } } class nmsNewNet extends nmsPanel { - constructor() { - super("Add new network") - this.add(new nmsModNet(undefined)) - this.nav.add(new nmsString("Only the name is required, but you should probably fill in more.")); - } + constructor() { + super("Add new network"); + this.add(new nmsModNet(undefined)); + this.nav.add( + new nmsString( + "Only the name is required, but you should probably fill in more." + ) + ); + } } class nmsModThing extends nmsBox { - constructor(data) { - super("div"); - this.identifier = data.identifier; - this.invalidate = data.invalidate; - this.api = data.api; - this.item = data.item; - this.generateBaseTemplate() - this.populate() - var save = new nmsButton("Save","btn-primary"); - save.panel = this; - save.html.onclick = this.save; - this.add(save) - var del = new nmsButton("Delete","btn btn-danger"); - del.panel = this - del.html.onclick = this.del; - this.add(del) - } - commit(data) { - $.ajax({ - type: "POST", - url: this.api, - dataType: "text", - nmsBox:this, - data:JSON.stringify(data), - success: function (data, textStatus, jqXHR) { - var msg = new nmsString("Changed..."); - msg.attach(this.nmsBox._root); - msg.show() - this.nmsBox.destroy() - //nmsInfoBox.hide(); - for (var x of this.nmsBox.invalidate) { - nmsData.invalidate(x); - } - } - }); - } + constructor(data) { + super("div"); + this.identifier = data.identifier; + this.invalidate = data.invalidate; + this.api = data.api; + this.item = data.item; + this.generateBaseTemplate(); + this.populate(); + } + commit(data) { + $.ajax({ + type: "POST", + url: this.api, + dataType: "text", + nmsBox: this, + data: JSON.stringify(data), + success: function (data, textStatus, jqXHR) { + var msg = new nmsString("Changed..."); + msg.attach(this.nmsBox._root); + msg.show(); + this.nmsBox.destroy(); + //nmsInfoBox.hide(); + for (var x of this.nmsBox.invalidate) { + nmsData.invalidate(x); + } + }, + }); + } - del(e) { - if(confirm("This will delete the " + this.typeName + ":" + this.nmsBox.panel.item)) { - this.nmsBox.panel.commit([{'sysname': this.nmsBox.panel.item, 'deleted': true}]); - }; - } - save(e) { - var diff = this.nmsBox.panel.diff() - if (diff != undefined) { - this.nmsBox.panel.commit([diff]) - } - } - /* Pretty sure that the type-thing is OK, but what I want is to - * generate a nmsTemplate or something that can be used to get/set - * variables generically, and replaces nmsEditRow. Since right now, - * both the template and the row is fiddling with values, luckily - * all through the same actual object, but still.... - * This is because I wrote nmsEditRow before I added a type-system. - * - * The fundamental problem is that the row-rendering is obviously - * affected by the type, and the overall "template"/parent - * (nmsModSwitch right now) is also obviously affected by changes to - * the individual rows. - * - * Right now a change in a value means nmsEditRow will get the - * event, it will use the nmsType to validate, and ultimately set, - * but it ALSO has to store a text-representation of the value if it - * changes from other sources (e.g.: auto-complete), and we need to - * alert nmsModSwitch that a change has occurred so it can act - * approrpiately (e.g.: Enabling/disabling a save button). - * - * This means that nmsType instances, nmsEditRow instances and - * nmsModSwitch instance is tightly coupled in non-obvious ways. - * - * Which means bugs. - */ - populate() { - if (this.item != undefined) { - this._populateTemplate(this.item); - } - this.table = new nmsTable(); - this.rows = {} - for (var v in this._template) { - this.rows[v] = new nmsEditRow(v, this._template[v]); - this.rows[v].parent = this; - this.table.add(this.rows[v]); - } - this.add(this.table); - } - changed(row) { - this.title = "saw row change on " + row.name + " to " + row.value; - } - get value() { - var ret = {}; - for (var idx in this.rows) { - ret[idx] = this.rows[idx].value; - } - return ret; - } - diff() { - var ret = {}; - var changed = 0; - for (var idx in this.rows) { - if (this.rows[idx].value.toString() != this.rows[idx].original) { - ret[idx] = this.rows[idx].value.value; - changed++; - } - } - if (!changed) { - return undefined; - } - ret[this.identifier] = this.rows[this.identifier].value.value; - return ret; - } + del(e) { + if ( + confirm( + "This will delete the " + this.typeName + ":" + this.nmsBox.panel.item + ) + ) { + this.nmsBox.panel.commit([ + { sysname: this.nmsBox.panel.item, deleted: true }, + ]); + } + } + save(e) { + var diff = this.nmsBox.panel.diff(); + if (diff != undefined) { + this.nmsBox.panel.commit([diff]); + } + } + /* Pretty sure that the type-thing is OK, but what I want is to + * generate a nmsTemplate or something that can be used to get/set + * variables generically, and replaces nmsEditRow. Since right now, + * both the template and the row is fiddling with values, luckily + * all through the same actual object, but still.... + * This is because I wrote nmsEditRow before I added a type-system. + * + * The fundamental problem is that the row-rendering is obviously + * affected by the type, and the overall "template"/parent + * (nmsModSwitch right now) is also obviously affected by changes to + * the individual rows. + * + * Right now a change in a value means nmsEditRow will get the + * event, it will use the nmsType to validate, and ultimately set, + * but it ALSO has to store a text-representation of the value if it + * changes from other sources (e.g.: auto-complete), and we need to + * alert nmsModSwitch that a change has occurred so it can act + * approrpiately (e.g.: Enabling/disabling a save button). + * + * This means that nmsType instances, nmsEditRow instances and + * nmsModSwitch instance is tightly coupled in non-obvious ways. + * + * Which means bugs. + */ + populate() { + if (this.item != undefined) { + this._populateTemplate(this.item); + } + this.table = new nmsTable(); + this.rows = {}; + for (var v in this._template) { + this.rows[v] = new nmsEditRow(v, this._template[v]); + this.rows[v].parent = this; + this.table.add(this.rows[v]); + } + this.add(this.table); + } + changed(row) { + this.title = "saw row change on " + row.name + " to " + row.value; + } + get value() { + var ret = {}; + for (var idx in this.rows) { + ret[idx] = this.rows[idx].value; + } + return ret; + } + diff() { + var ret = {}; + var changed = 0; + for (var idx in this.rows) { + if (this.rows[idx].value.toString() != this.rows[idx].original) { + ret[idx] = this.rows[idx].value.value; + changed++; + } + } + if (!changed) { + return undefined; + } + ret[this.identifier] = this.rows[this.identifier].value.value; + return ret; + } } class nmsEditRow extends nmsBox { - constructor(text,value) { - super("tr") - // This should/could be smarter in the future. - console.assert(value instanceof nmsType) - this.name = text; - this._value = value; - this.original = value.toString(); - var td1 = new nmsBox("td") - var name = new nmsString(text+" "); - name.html.title = value.description; - td1.add(name) - this.add(td1); - td1.html.width="50%" - this._state = new nmsBox("span",{html:{className:"label label-default",textContent:"Original"}}) - this._valid = new nmsBox("span",{html:{className:"label label-default",textContent:"Not verified"}}) - name.add(this._state) - name.add(this._valid) - this._valid.hide() - this.changed(false) - var content = new nmsBox("td") - var input = new nmsBox("input") - input.html.value = value.toString(); - input.html.className = "form-control"; - input.html.type = "text"; - input.row = this; - if (value.ro) { - input.html.disabled = true; - input.html.title = "Read/only attribute"; - } - if (value instanceof nmsTypeSecret) { - input.html.type = "password" - input.html.autocomplete = "off" - input.html.onfocus = function f() { this.type = "text" } - input.html.oninput = function f() { this.type = "text" } - input.html.onblur = function f() { this.type = "password" } - } - input.html.onchange = function() { - this.nmsBox.row.value = this.value - } - input.html.oninput = function() { - this.nmsBox.row.value = this.value - } - this._input = input; - this._content = content; - content.add(input) - this.add(content) - } - get value() { - return this._value; - } - changed(val) { - if (val) { - this._state.show() - this._state.html.textContent = "Changed" - this._state.html.classList.remove("label-default") - this._state.html.classList.add("label-warning") - } else { - this._state.hide() - } - } - valid(val) { - this._valid.html.classList.remove("label-default") - this._valid.show() - if (val) { - this._valid.html.textContent = "Valid" - this._valid.html.classList.remove("label-danger") - this._valid.html.classList.add("label-success") - } else { - this._valid.html.textContent = "Invalid" - this._valid.html.classList.add("label-danger") - this._valid.html.classList.remove("label-success") - } - } + constructor(text, value) { + super("tr"); + // This should/could be smarter in the future. + console.assert(value instanceof nmsType); + this.name = text; + this._value = value; + this.original = value.toString(); + var td1 = new nmsBox("td"); + var name = new nmsString(text + " "); + name.html.title = value.description; + td1.add(name); + this.add(td1); + td1.html.width = "50%"; + this._state = new nmsBox("span", { + html: { className: "label label-default", textContent: "Original" }, + }); + this._valid = new nmsBox("span", { + html: { className: "label label-default", textContent: "Not verified" }, + }); + name.add(this._state); + name.add(this._valid); + this._valid.hide(); + this.changed(false); + var content = new nmsBox("td"); + var input = new nmsBox("input"); + input.html.value = value.toString(); + input.html.className = "form-control"; + input.html.type = "text"; + input.row = this; + input.html.disabled = true; + if (value instanceof nmsTypeSecret) { + input.html.type = "password"; + input.html.autocomplete = "off"; + input.html.onfocus = function f() { + this.type = "text"; + }; + input.html.oninput = function f() { + this.type = "text"; + }; + input.html.onblur = function f() { + this.type = "password"; + }; + } + input.html.onchange = function () { + this.nmsBox.row.value = this.value; + }; + input.html.oninput = function () { + this.nmsBox.row.value = this.value; + }; + this._input = input; + this._content = content; + content.add(input); + this.add(content); + } + get value() { + return this._value; + } + changed(val) { + if (val) { + this._state.show(); + this._state.html.textContent = "Changed"; + this._state.html.classList.remove("label-default"); + this._state.html.classList.add("label-warning"); + } else { + this._state.hide(); + } + } + valid(val) { + this._valid.html.classList.remove("label-default"); + this._valid.show(); + if (val) { + this._valid.html.textContent = "Valid"; + this._valid.html.classList.remove("label-danger"); + this._valid.html.classList.add("label-success"); + } else { + this._valid.html.textContent = "Invalid"; + this._valid.html.classList.add("label-danger"); + this._valid.html.classList.remove("label-success"); + } + } - - /* THIS IS A MESS */ - set value(value) { - if (!this._value.validate(value)) { - this.valid(false) - this._content.html.classList.add("has-error"); - return; - } else { - this.valid(true) - this._content.html.classList.remove("has-error"); - this._value.fromString(value); - } - if (this._input.html.value != this._value.toString()) { - this._input.html.value = this._value.toString() - } - if (this._value.toString() != this.original) { - this.changed(true) - this._content.html.classList.add("has-success"); - } else { - this.changed(false) - this._content.html.classList.remove("has-success"); - } - this.parent.changed(this) - } + /* THIS IS A MESS */ + set value(value) { + if (!this._value.validate(value)) { + this.valid(false); + this._content.html.classList.add("has-error"); + return; + } else { + this.valid(true); + this._content.html.classList.remove("has-error"); + this._value.fromString(value); + } + if (this._input.html.value != this._value.toString()) { + this._input.html.value = this._value.toString(); + } + if (this._value.toString() != this.original) { + this.changed(true); + this._content.html.classList.add("has-success"); + } else { + this.changed(false); + this._content.html.classList.remove("has-success"); + } + this.parent.changed(this); + } } class nmsModSwitch extends nmsModThing { - constructor(sw) { - super({item: sw, identifier: "sysname", invalidate: ["switches","smanagement"], api: "/api/write/switches"}) - } - generateBaseTemplate() { - this._template = { - sysname: new nmsTypeSysname("Unique systemname/switch name. Only required field. Read/only on existing equipment." ), - mgmt_v4_addr: new nmsTypeIP("Management address IPv4"), - mgmt_v6_addr: new nmsTypeIP("Management address IPv6"), - mgmt_vlan: new nmsTypeNetwork("Management VLAN"), - traffic_vlan: new nmsTypeNetwork("Traffic VLAN"), - distro_name: new nmsTypeSysnameReference("Distro switch upstream of this system. Required for provisioning."), - distro_phy_port: new nmsTypePort("Name of port we connect to at the distro switch. Used for provisioning, among other things."), - poll_frequency: new nmsTypeInterval("Poll frequency for SNMP (will use default from backend)"), - community: new nmsTypeSecret("SNMP community (will use default from backend)"), - placement: new nmsTypePlace("Map placement (If following a regular naming scheme, the backend will place it poperly, otherwise a random place will be chose)"), - tags: new nmsTypeTags("Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems.") - } - } - _populateTemplate(sw) { - var swi = []; - var swm = []; - try { - swi = nmsData.switches["switches"][sw]; - swm = nmsData.smanagement.switches[sw]; - } catch(e) {} + constructor(sw) { + super({ + item: sw, + identifier: "sysname", + invalidate: ["switches", "smanagement"], + api: "/api/write/switches", + }); + } + generateBaseTemplate() { + this._template = { + sysname: new nmsTypeSysname( + "Unique systemname/switch name. Only required field. Read/only on existing equipment." + ), + mgmt_v4_addr: new nmsTypeIP("Management address IPv4"), + mgmt_v6_addr: new nmsTypeIP("Management address IPv6"), + mgmt_vlan: new nmsTypeNetwork("Management VLAN"), + traffic_vlan: new nmsTypeNetwork("Traffic VLAN"), + distro_name: new nmsTypeSysnameReference( + "Distro switch upstream of this system. Required for provisioning." + ), + distro_phy_port: new nmsTypePort( + "Name of port we connect to at the distro switch. Used for provisioning, among other things." + ), + placement: new nmsTypePlace( + "Map placement (If following a regular naming scheme, the backend will place it poperly, otherwise a random place will be chose)" + ), + tags: new nmsTypeTags( + "Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems." + ), + }; + } + _populateTemplate(sw) { + var swi = []; + var swm = []; + try { + swi = nmsData.switches["switches"][sw]; + swm = nmsData.smanagement.switches[sw]; + } catch (e) {} - var template = {} - for (var v in swi) { - console.assert(this._template[v] instanceof nmsType) - if (swi[v] != null) { - this._template[v].initial(swi[v]); - } - } - for (var v in swm) { - if (v == "last_updated") { - continue; - } - console.assert(this._template[v] instanceof nmsType) - if (swm[v] != null) { - this._template[v].initial(swm[v]); - } - } - } + var template = {}; + for (var v in swi) { + console.assert(this._template[v] instanceof nmsType); + if (swi[v] != null) { + this._template[v].initial(swi[v]); + } + } + for (var v in swm) { + if (v == "last_updated") { + continue; + } + console.assert(this._template[v] instanceof nmsType); + if (swm[v] != null && this._template[v]) { + this._template[v].initial(swm[v]); + } + } + } } class nmsModNet extends nmsModThing { - constructor(net) { - super({item: net, identifier: "name", invalidate: ["networks","smanagement"], api: "/api/write/networks"}) - } - generateBaseTemplate() { - this._template = { - name: new nmsType("Unique networkname. Only required field. Read/only on existing nets."), - vlan: new nmsType("VLAN ID"), - gw4: new nmsTypeIP("Gateway address, IPv4"), - gw6: new nmsTypeIP("Gateway address, IPv6"), - subnet4: new nmsTypeCIDR("Subnet, IPv4"), - subnet6: new nmsTypeCIDR("Subnet, IPv6"), - router: new nmsTypeSysnameReference("Router where net is terminated. E.g.: r1.noc for floor traffic nets"), - tags: new nmsTypeTags("Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems.") - } - } - _populateTemplate(net) { - var nets = []; - try { - nets = nmsData.networks["networks"][net]; - } catch(e) {} + constructor(net) { + super({ + item: net, + identifier: "name", + invalidate: ["networks", "smanagement"], + api: "/api/write/networks", + }); + } + generateBaseTemplate() { + this._template = { + name: new nmsType( + "Unique networkname. Only required field. Read/only on existing nets." + ), + vlan: new nmsType("VLAN ID"), + gw4: new nmsTypeIP("Gateway address, IPv4"), + gw6: new nmsTypeIP("Gateway address, IPv6"), + subnet4: new nmsTypeCIDR("Subnet, IPv4"), + subnet6: new nmsTypeCIDR("Subnet, IPv6"), + router: new nmsTypeSysnameReference( + "Router where net is terminated. E.g.: r1.noc for floor traffic nets" + ), + tags: new nmsTypeTags( + "Additional tags in JSON text array format. Can be anything. Used to provide a simple escape hatch mechanism to tag systems." + ), + }; + } + _populateTemplate(net) { + var nets = []; + try { + nets = nmsData.networks["networks"][net]; + } catch (e) {} - var template = {} - for (var v in nets) { - console.assert(this._template[v] instanceof nmsType) - if (nets[v] != null) { - this._template[v].initial(nets[v]); - } - } - } + var template = {}; + for (var v in nets) { + console.assert(this._template[v] instanceof nmsType); + if (nets[v] != null) { + this._template[v].initial(nets[v]); + } + } + } } - - diff --git a/web/js/nms-ui.js b/web/js/nms-ui.js index 48865c4..efbeeec 100644 --- a/web/js/nms-ui.js +++ b/web/js/nms-ui.js @@ -1,27 +1,26 @@ "use strict"; - /* * The idea is to gradually move pure UI stuff into nmsUi. */ var nmsUi = nmsUi || { - _active: "map" + _active: "map", }; -nmsUi.setActive = function(pane) { - var old = document.getElementById(nmsUi._active); - var newp = document.getElementById(pane); - old.style.display = "none"; - newp.style.display = "block"; - - var oldlink = document.getElementById(nmsUi._active + "-link"); - var newlink = document.getElementById(pane + "-link"); - oldlink.classList.remove("active"); - newlink.classList.add("active"); +nmsUi.setActive = function (pane) { + var old = document.getElementById(nmsUi._active); + var newp = document.getElementById(pane); + old.style.display = "none"; + newp.style.display = "block"; + + var oldlink = document.getElementById(nmsUi._active + "-link"); + var newlink = document.getElementById(pane + "-link"); + oldlink.classList.remove("active"); + newlink.classList.add("active"); - nmsUi._active = pane; -} + nmsUi._active = pane; +}; -nmsUi.toggleVertical = function(x) { - nms.vertical = !nms.vertical; -} +nmsUi.toggleVertical = function (x) { + nms.vertical = !nms.vertical; +}; diff --git a/web/js/nms.js b/web/js/nms.js index f0b82a7..c699726 100644 --- a/web/js/nms.js +++ b/web/js/nms.js @@ -15,87 +15,96 @@ * now it's just leftovers. */ var nms = { - stats:{}, // Various internal stats - get nightMode() { return this._nightMode; }, - set nightMode(val) { if (val != this._nightMode) { this._nightMode = val; setNightMode(val); } }, - /* - * Various setInterval() handlers. See nmsTimer() for how they are - * used. - * - * FIXME: Should just stop using these. - */ - timers: { - tvmode: false - }, - - menuShowing:true, - oplogShowing:true, - get uptime() { - return (Date.now() - this._startTime)/1000; - }, - _vertical: 0, - get vertical() { return this._vertical }, - set vertical(v) { - this._vertical = v; - if(v) - document.body.classList.add("vertical"); - else - document.body.classList.remove("vertical"); - saveSettings(); - }, - - interval: 10, - _user: undefined, - get user() { return this._user; }, - set user(u) { - this._user = u; - saveSettings(); - }, - /* - * This is a list of nms[x] variables that we store in our - * settings-cookie when altered and restore on load. - */ - settingsList:[ - 'nightMode', - 'menuShowing', - 'vertical', - 'interval', - 'oplogShowing', - 'user' - ], - keyBindings:{ - '-':toggleMenu, - 'n':toggleNightMode, - '1':setMapModeFromN, - '2':setMapModeFromN, - '3':setMapModeFromN, - '4':setMapModeFromN, - '5':setMapModeFromN, - '6':setMapModeFromN, - '7':setMapModeFromN, - '8':setMapModeFromN, - '9':setMapModeFromN, - '0':setMapModeFromN, - 'c':toggleConnect, - 'H':moveTimeFromKey, - 'h':moveTimeFromKey, - 'j':moveTimeFromKey, - 'k':moveTimeFromKey, - 'l':moveTimeFromKey, - 'L':moveTimeFromKey, - 'p':moveTimeFromKey, - 'r':moveTimeFromKey, - 'o':toggleOplog, - 'Escape':hideWindow, - '?':toggleHelp - }, - tvmode: { - handlers: [], - currentIndex: 0, - interval: 20000, - active: false, - vertical: false - } + stats: {}, // Various internal stats + get nightMode() { + return this._nightMode; + }, + set nightMode(val) { + if (val != this._nightMode) { + this._nightMode = val; + setNightMode(val); + } + }, + /* + * Various setInterval() handlers. See nmsTimer() for how they are + * used. + * + * FIXME: Should just stop using these. + */ + timers: { + tvmode: false, + }, + + menuShowing: true, + oplogShowing: true, + get uptime() { + return (Date.now() - this._startTime) / 1000; + }, + _vertical: 0, + get vertical() { + return this._vertical; + }, + set vertical(v) { + this._vertical = v; + if (v) document.body.classList.add("vertical"); + else document.body.classList.remove("vertical"); + saveSettings(); + }, + + interval: 10, + _user: undefined, + get user() { + return this._user; + }, + set user(u) { + this._user = u; + saveSettings(); + }, + /* + * This is a list of nms[x] variables that we store in our + * settings-cookie when altered and restore on load. + */ + settingsList: [ + "nightMode", + "menuShowing", + "vertical", + "interval", + "oplogShowing", + "user", + ], + keyBindings: { + "-": toggleMenu, + n: toggleNightMode, + 1: setMapModeFromN, + 2: setMapModeFromN, + 3: setMapModeFromN, + 4: setMapModeFromN, + 5: setMapModeFromN, + 6: setMapModeFromN, + 7: setMapModeFromN, + 8: setMapModeFromN, + 9: setMapModeFromN, + 0: setMapModeFromN, + c: toggleConnect, + H: moveTimeFromKey, + h: moveTimeFromKey, + j: moveTimeFromKey, + k: moveTimeFromKey, + l: moveTimeFromKey, + L: moveTimeFromKey, + p: moveTimeFromKey, + r: moveTimeFromKey, + o: toggleOplog, + Escape: hideWindow, + "?": toggleHelp, + }, + tvmode: { + handlers: [], + currentIndex: 0, + interval: 20000, + active: false, + vertical: false, + }, }; /* @@ -105,76 +114,69 @@ var nms = { * new code. */ function nmsTimer(handler, interval, name, description) { - this.handler = handler; - this.handle = false; - this.interval = parseInt(interval); - this.name = name; - this.description = description; - this.start = function() { - if (this.handle) { - this.stop(); - } - this.handle = setInterval(this.handler,this.interval); - }; - this.stop = function() { - if (this.handle) - clearInterval(this.handle); - this.handle = false; - }; - - this.setInterval = function(interval) { - var started = this.handle != false; - this.stop(); - this.interval = parseInt(interval); - if (started) - this.start(); - }; + this.handler = handler; + this.handle = false; + this.interval = parseInt(interval); + this.name = name; + this.description = description; + this.start = function () { + if (this.handle) { + this.stop(); + } + this.handle = setInterval(this.handler, this.interval); + }; + this.stop = function () { + if (this.handle) clearInterval(this.handle); + this.handle = false; + }; + + this.setInterval = function (interval) { + var started = this.handle != false; + this.stop(); + this.interval = parseInt(interval); + if (started) this.start(); + }; } - /* * Convenience function that doesn't support huge numbers, and it's easier * to comment than to fix. But not really, but I'm not fixing it anyway. */ -function byteCount(bytes,precision) { - if (precision ==undefined) - precision = 1; - var units = ['', 'K', 'M', 'G', 'T', 'P', 'E','Z']; - var i = 0; - while (bytes > 1024) { - bytes = bytes / 1024; - i++; - } - if (i == 0) - return bytes; - return bytes.toFixed(precision) + units[i]; +function byteCount(bytes, precision) { + if (precision == undefined) precision = 1; + var units = ["", "K", "M", "G", "T", "P", "E", "Z"]; + var i = 0; + while (bytes > 1024) { + bytes = bytes / 1024; + i++; + } + if (i == 0) return bytes; + return bytes.toFixed(precision) + units[i]; } /* * Definitely not a way to toggle night mode. Does something COMPLETELY * DIFFERENT. */ -function toggleNightMode() -{ - nms.nightMode = !nms.nightMode; - saveSettings(); +function toggleNightMode() { + nms.nightMode = !nms.nightMode; + saveSettings(); } /* * There are 4 legend-bars. This is a helper-function to set the color and * description/name for each one. Used from handler init-functions. */ -function setLegend(x,color,name) -{ - var el = document.getElementById("legend-" + x); - el.style.background = color; - el.title = name; - el.textContent = name; - if (name == "") { - el.style.display = 'none'; - } else { - el.style.display = ''; - } +function setLegend(x, color, name) { + var el = document.getElementById("legend-" + x); + el.style.background = color; + el.title = name; + el.textContent = name; + if (name == "") { + el.style.display = "none"; + } else { + el.style.display = ""; + } } /* @@ -186,37 +188,41 @@ function setLegend(x,color,name) * FIXME: this is getting gradually stripped down from the original, so far * we're not quite there yet with merging it with the regular code paths. */ -nms.tvmode.start = function(views,interval) { - nms.tvmode.handlers = []; - for(var view in views) { - for(var handler in handlers) { - if(views[view] == handlers[handler].tag) { - nms.tvmode.handlers.push(handlers[handler]); - } - } - } - if (nms.tvmode.handlers.length > 1) { - if(interval > 0) - nms.tvmode.interval = interval * 1000; - nms.timers.tvmode = new nmsTimer(nms.tvmode.tick, nms.tvmode.interval, "TV-mode ticker", "Handler used to advance tv-mode"); - nms.timers.tvmode.start(); - nms.tvmode.tick(); - nms.tvmode.active = true; - } -} -nms.tvmode.tick = function() { - if(nms.tvmode.currentIndex > nms.tvmode.handlers.length - 1) { - nms.tvmode.currentIndex = 0; - } - setUpdater(nms.tvmode.handlers[nms.tvmode.currentIndex],false); - nms.tvmode.currentIndex++; -} -nms.tvmode.stop = function() { - if (nms.tvmode.active) { - nms.timers.tvmode.stop(); - nms.tvmode.active = false; - } -} +nms.tvmode.start = function (views, interval) { + nms.tvmode.handlers = []; + for (var view in views) { + for (var handler in handlers) { + if (views[view] == handlers[handler].tag) { + nms.tvmode.handlers.push(handlers[handler]); + } + } + } + if (nms.tvmode.handlers.length > 1) { + if (interval > 0) nms.tvmode.interval = interval * 1000; + nms.timers.tvmode = new nmsTimer( + nms.tvmode.tick, + nms.tvmode.interval, + "TV-mode ticker", + "Handler used to advance tv-mode" + ); + nms.timers.tvmode.start(); + nms.tvmode.tick(); + nms.tvmode.active = true; + } +}; +nms.tvmode.tick = function () { + if (nms.tvmode.currentIndex > nms.tvmode.handlers.length - 1) { + nms.tvmode.currentIndex = 0; + } + setUpdater(nms.tvmode.handlers[nms.tvmode.currentIndex], false); + nms.tvmode.currentIndex++; +}; +nms.tvmode.stop = function () { + if (nms.tvmode.active) { + nms.timers.tvmode.stop(); + nms.tvmode.active = false; + } +}; /* * Used when changing handler to ensure that the new handler is listed in @@ -224,15 +230,15 @@ nms.tvmode.stop = function() { * we only overwrite it if the new view isn't present. */ function ensureAnchorHas(view) { - try { - var views = document.location.hash.slice(1); - views = views.split(","); - if (views.includes(view)) { - return true; - } - } catch(e) { } - document.location.hash = view; - return false; + try { + var views = document.location.hash.slice(1); + views = views.split(","); + if (views.includes(view)) { + return true; + } + } catch (e) {} + document.location.hash = view; + return false; } /* @@ -241,56 +247,63 @@ function ensureAnchorHas(view) { * stopTv esnures that we don't conflict with the tvmode thing. If a * user-initiated map is selected, tvmode is disabled. */ -function setUpdater(fo, stopTv ) -{ - if (stopTv == undefined) { - stopTv = true; - } - if (stopTv) - nms.tvmode.stop(); - nmsMap.reset(); - nmsData.unregisterHandlerWildcard("mapHandler"); - try { - fo.init(); - } catch (e) { - /* - * This can happen typically on initial load where the data - * hasn't been retrieved yet. Instead of breaking the - * entire init-process, just bail out here. - */ - console.log("Possibly broken handler: " + fo.name); - console.log(e); - } - var foo = document.getElementById("map-mode-title"); - foo.innerHTML = fo.name; - ensureAnchorHas(fo.tag); +function setUpdater(fo, stopTv) { + if (stopTv == undefined) { + stopTv = true; + } + if (stopTv) nms.tvmode.stop(); + nmsMap.reset(); + nmsData.unregisterHandlerWildcard("mapHandler"); + try { + fo.init(); + } catch (e) { + /* + * This can happen typically on initial load where the data + * hasn't been retrieved yet. Instead of breaking the + * entire init-process, just bail out here. + */ + console.log("Possibly broken handler: " + fo.name); + console.log(e); + } + var foo = document.getElementById("map-mode-title"); + foo.innerHTML = fo.name; + ensureAnchorHas(fo.tag); } function toggleLayer(layer) { - var l = document.getElementById(layer); - if (l.style.display == 'none') - l.style.display = ''; - else - l.style.display = 'none'; + var l = document.getElementById(layer); + if (l.classList.contains("show")) { + // Hide + l.classList.remove("show"); + l.classList.add("d-none"); + } else { + // Show + l.classList.remove("d-none"); + l.classList.add("show"); + } } function hideLayer(layer) { - var l = document.getElementById(layer); - l.style.display = 'none'; + var l = document.getElementById(layer); + l.classList.remove("show"); + l.classList.add("d-none"); } - function toggleConnect() { - toggleLayer("linkCanvas"); + toggleLayer("linkCanvas"); } /* * Returns true if the coordinates (x,y) is inside the box defined by * box.{x,y,w.h} (e.g.: placement of a switch). */ -function isIn(box, x, y) -{ - return ((x >= box.x) && (x <= (box.x + box.width)) && (y >= box.y) && (y <= (box.y + box.height))); +function isIn(box, x, y) { + return ( + x >= box.x && + x <= box.x + box.width && + y >= box.y && + y <= box.y + box.height + ); } /* @@ -299,16 +312,16 @@ function isIn(box, x, y) * * FIXME: this belongs in nmsMap. */ -function findSwitch(x,y) { - x = parseInt(parseInt(x) / nmsMap.scale); - y = parseInt(parseInt(y) / nmsMap.scale); - - for (var v in nmsData.switches.switches) { - if(isIn(nmsData.switches.switches[v]['placement'],x,y)) { - return v; - } - } - return undefined; +function findSwitch(x, y) { + x = parseInt(parseInt(x) / nmsMap.scale); + y = parseInt(parseInt(y) / nmsMap.scale); + + for (var v in nmsData.switches.switches) { + if (isIn(nmsData.switches.switches[v]["placement"], x, y)) { + return v; + } + } + return undefined; } /* @@ -317,19 +330,13 @@ function findSwitch(x,y) { * Changes background and nav-bar, then leaves the rest to nmsMap. */ function setNightMode(toggle) { - nms.nightMode = toggle; - var body = document.getElementById("body"); - body.style.background = toggle ? "black" : "white"; - var nav = document.getElementsByTagName("nav")[0]; - if (toggle) { - nav.classList.add('navbar-inverse'); - document.body.classList.add("nightmode"); - } else { - nav.classList.remove('navbar-inverse'); - document.body.classList.remove("nightmode"); - } - nmsMap.setNightMode(toggle); - setNightModeChart(toggle); + nms.nightMode = toggle; + if (toggle) { + document.documentElement.setAttribute("data-bs-theme", "dark"); + } else { + document.documentElement.setAttribute("data-bs-theme", "light"); + } + nmsMap.setNightMode(toggle); } /* @@ -348,23 +355,15 @@ function setNightMode(toggle) { * just silencing them or by moving this off the main thread, then go * ahead and fix it. I don't consider it a real problem, though. */ -function getInitialConfig() { - $.ajax({ - type: "GET", - url: "/api/public/config", - async: false, - dataType: "json", - success: function (data, textStatus, jqXHR) { - if (data["config"]["public"] == "true") { - nms._public = true; - document.body.classList.add("gondul-public"); - } else { - nms._public = false; - document.body.classList.add("gondul-private"); - nmsTemplate.getTemplates(); - } - } - }); +async function getInitialConfig() { + nms._public = false; + document.body.classList.add("gondul-private"); + + const data = await getData("/api/public/config"); + if (data["config"]["public"] == "true") { + nms._public = true; + document.body.classList.add("gondul-public"); + } } /* @@ -374,230 +373,222 @@ function getInitialConfig() { * the same framework. Or rather: that's the goal. We're not quite there * yet. */ -function initNMS() { - // Only used for dev-purposes now. Accessible through nms.uptime. - nms._startTime = Date.now(); - - // Public - nmsData.registerSource("config","/api/public/config"); - nmsData.registerSource("ping", "/api/public/ping"); - nmsData.registerSource("switches","/api/public/switches"); - nmsData.registerSource("switchstate","/api/public/switch-state"); - nmsData.registerSource("dhcpsummary","/api/public/dhcp-summary"); - nmsData.registerSource("dhcp","/api/public/dhcp"); - - // Fetch initial config. Basically just populates nms._public. - // All other settings are kept in nmsData['config']. - getInitialConfig(); - - // This is a magic dummy-source, it's purpose is to give a unified - // way to get ticks every second. It is mainly meant to allow map - // handlers to register for ticks so they will execute without data - // (and thus notice stale data instead of showing a green ping-map - // despite no pings) - nmsData.registerSource("ticker","bananabananbanana"); - - if (!nms._public) { - // Private - nmsData.registerSource("snmp","/api/read/snmp"); - nmsData.registerSource("smanagement","/api/read/switches-management"); - nmsData.registerSource("oplog", "/api/read/oplog"); - nmsData.registerSource("networks","/api/read/networks"); - nmsOplog.init(); - } - restoreSettings(); - nmsMap.init(); - detectHandler(); - setupKeyhandler(); - nmsSearch.init(); - nmsDhcp.init(); - nmsNightMode.init(); +async function initNMS() { + // Only used for dev-purposes now. Accessible through nms.uptime. + nms._startTime = Date.now(); + + // Public + nmsData.registerSource("config", "/api/public/config"); + nmsData.registerSource("ping", "/api/public/ping"); + nmsData.registerSource( + "switches", + "/api/public/switches" + ); + //nmsData.registerSource("switchstate", "/api/public/switch-state"); + //nmsData.registerSource("dhcpsummary","/api/public/dhcp-summary"); + //nmsData.registerSource("dhcp","/api/public/dhcp"); + + // Fetch initial config. Basically just populates nms._public. + // All other settings are kept in nmsData['config']. + await getInitialConfig(); + + // This is a magic dummy-source, it's purpose is to give a unified + // way to get ticks every second. It is mainly meant to allow map + // handlers to register for ticks so they will execute without data + // (and thus notice stale data instead of showing a green ping-map + // despite no pings) + nmsData.registerSource("ticker", "bananabananbanana"); + + if (!nms._public) { + // Private + nmsData.registerSource("snmp", "/api/read/snmp"); + nmsData.registerSource( + "smanagement", + "/api/read/switches-management" + ); + nmsData.registerSource("oplog", "/api/v2/oplog/"); + nmsData.registerSource( + "networks", + "/api/read/networks" + ); + nmsOplog.init(); + } + restoreSettings(); + nmsMap.init(); + detectHandler(); + setupKeyhandler(); + nmsSearch.init(); + //nmsDhcp.init(); + nmsNightMode.init(); } function detectHandler() { - var views = document.location.hash.slice(1); - var interval = nms.interval; - if (views == undefined || views == "") - views = "health"; - if (nms._public) - views = "ping"; - views = views.split(","); - - if (views.length > 1) { - nms.tvmode.start(views,interval); - return; - } else { - for (var i in handlers) { - if (handlers[i].tag == views[0]) { - setUpdater(handlers[i]); - return; - } - } - } - setUpdater(handler_health); + var views = document.location.hash.slice(1); + var interval = nms.interval; + if (views == undefined || views == "") views = "health"; + if (nms._public) views = "ping"; + views = views.split(","); + + if (views.length > 1) { + nms.tvmode.start(views, interval); + return; + } else { + for (var i in handlers) { + if (handlers[i].tag == views[0]) { + setUpdater(handlers[i]); + return; + } + } + } + setUpdater(handler_health); } function getUrlVars() { - var vars = {}; - var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&#]*)/gi, function(m,key,value) { - vars[key] = value; - }); - return vars; -} - -function setMenu() -{ - var nav = document.getElementsByTagName("nav")[0]; - nav.style.display = nms.menuShowing ? '' : 'none'; - nmsMap.forceResize(); -} - -function setOplog() -{ - if(nms._public == false) - nms.oplog.mini.show(nms.oplogShowing) -} - -function toggleMenu() -{ - nms.menuShowing = ! nms.menuShowing; - setMenu(); - saveSettings(); -} -function toggleOplog() -{ - nms.oplogShowing = ! nms.oplogShowing; - setOplog(); - saveSettings(); -} -function hideWindow(e,key) -{ - nmsInfoBox.hide(); -} -function toggleHelp(e,key) { - toggleLayer('aboutKeybindings'); -} - -function setMapModeFromN(e,key) -{ - switch(key) { - case '1': - setUpdater(handler_health); - break; - case '2': - setUpdater(handler_uplinks); - break; - case '3': - setUpdater(handler_dhcp); - break; - case '4': - setUpdater(handler_ping); - break; - case '5': - setUpdater(handler_temp); - break; - case '6': - setUpdater(handler_traffic); - break; - case '7': - setUpdater(handler_traffic_tot); - break; - case '8': - setUpdater(handler_snmp); - break; - case '9': - setUpdater(handler_cpu); - break; - case '0': - setUpdater(handler_disco); - break; - } - return true; -} - -function moveTimeFromKey(e,key) -{ - switch(key) { - case 'H': - nmsTime.stepKey(-1440); - break; - case 'h': - nmsTime.stepKey(-60); - break; - case 'j': - nmsTime.stepKey(-5); - break; - case 'k': - nmsTime.stepKey(5); - break; - case 'l': - nmsTime.stepKey(60); - break; - case 'L': - nmsTime.stepKey(1440); - break; - case 'p': - nmsTime.togglePause(); - break; - case 'r': - nmsTime.realTime(); - break; - } - return true; -} - -function keyPressed(e) -{ - if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") { - return false; - } - if(e.key) { - var key = e.key; - } else { - var key = e.keyCode; - switch(key) { - case 187: - key = '?'; - break; - case 189: - key = '-'; - break; - case 27: - key = 'Escape'; - break; - default: - key = String.fromCharCode(key); - key = key.toLowerCase(); - break; - } - } - if (nms.keyBindings[key]) - return nms.keyBindings[key](e,key); - if (nms.keyBindings['default']) - return nms.keyBindings['default'](e,key); - return false; -} - -function setupKeyhandler() -{ - var b = document.getElementsByTagName("body")[0]; - $( "body" ).keyup(function(e) { - keyPressed(e); - }); + var vars = {}; + var parts = window.location.href.replace( + /[?&]+([^=&]+)=([^&#]*)/gi, + function (m, key, value) { + vars[key] = value; + } + ); + return vars; +} + +function setMenu() { + var nav = document.getElementsByTagName("nav")[0]; + nav.style.display = nms.menuShowing ? "" : "none"; + nmsMap.forceResize(); +} + +function setOplog() { + if (nms._public == false) nms.oplog.mini.show(nms.oplogShowing); +} + +function toggleMenu() { + nms.menuShowing = !nms.menuShowing; + setMenu(); + saveSettings(); +} +function toggleOplog() { + nms.oplogShowing = !nms.oplogShowing; + setOplog(); + saveSettings(); +} +function hideWindow(e, key) { + nmsInfoBox.hide(); +} +function toggleHelp(e, key) { + toggleLayer("aboutKeybindings"); +} + +function setMapModeFromN(e, key) { + switch (key) { + case "1": + setUpdater(handler_health); + break; + case "2": + setUpdater(handler_uplinks); + break; + case "3": + setUpdater(handler_dhcp); + break; + case "4": + setUpdater(handler_ping); + break; + case "5": + setUpdater(handler_temp); + break; + case "6": + setUpdater(handler_traffic); + break; + case "7": + setUpdater(handler_traffic_tot); + break; + case "8": + setUpdater(handler_snmp); + break; + case "9": + setUpdater(handler_cpu); + break; + case "0": + setUpdater(handler_disco); + break; + } + return true; +} + +function moveTimeFromKey(e, key) { + switch (key) { + case "H": + nmsTime.stepKey(-1440); + break; + case "h": + nmsTime.stepKey(-60); + break; + case "j": + nmsTime.stepKey(-5); + break; + case "k": + nmsTime.stepKey(5); + break; + case "l": + nmsTime.stepKey(60); + break; + case "L": + nmsTime.stepKey(1440); + break; + case "p": + nmsTime.togglePause(); + break; + case "r": + nmsTime.realTime(); + break; + } + return true; +} + +function keyPressed(e) { + if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") { + return false; + } + if (e.key) { + var key = e.key; + } else { + var key = e.keyCode; + switch (key) { + case 187: + key = "?"; + break; + case 189: + key = "-"; + break; + case 27: + key = "Escape"; + break; + default: + key = String.fromCharCode(key); + key = key.toLowerCase(); + break; + } + } + if (nms.keyBindings[key]) return nms.keyBindings[key](e, key); + if (nms.keyBindings["default"]) return nms.keyBindings["default"](e, key); + return false; +} + +function setupKeyhandler() { + document.addEventListener("keydown", (event) => keyPressed(event), false); } - function getCookie(cname) { - var name = cname + "="; - var ca = document.cookie.split(';'); - for(var i=0; i<ca.length; i++) { - var c = ca[i]; - while (c.charAt(0)==' ') - c = c.substring(1); - if (c.indexOf(name) == 0) - return c.substring(name.length,c.length); - } - return ""; + var name = cname + "="; + var ca = document.cookie.split(";"); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == " ") c = c.substring(1); + if (c.indexOf(name) == 0) return c.substring(name.length, c.length); + } + return ""; } /* @@ -606,15 +597,14 @@ function getCookie(cname) { * Also prints the value of the cookie on the console. This can then be * used as part of the URL instead. */ -function saveSettings() -{ - var foo={}; - for ( var v in nms.settingsList ) { - foo[ nms.settingsList[v] ] = nms[ nms.settingsList[v] ]; - } - var string = btoa(JSON.stringify(foo)); - document.cookie = 'nms='+string; - console.log("Add this to the URL to use these settings: nms="+string); +function saveSettings() { + var foo = {}; + for (var v in nms.settingsList) { + foo[nms.settingsList[v]] = nms[nms.settingsList[v]]; + } + var string = btoa(JSON.stringify(foo)); + document.cookie = 'nms='+string; + //console.log("Add this to the URL to use these settings: nms="+string); } /* @@ -622,44 +612,25 @@ function saveSettings() * paramater" nms. * Url paramater overrides the cookie. */ -function restoreSettings() -{ - try { - var retrieve = JSON.parse(atob(getCookie("nms"))); - } catch(e) { - } - try { - var retrieve2 = getUrlVars()['nms']; - if (retrieve2 != "") { - retrieve = JSON.parse(atob(retrieve2)); - - } - } catch (e) { - } - - for (var v in retrieve) { - nms[v] = retrieve[v]; - } - setMenu(); - setOplog(); +function restoreSettings() { + try { + var retrieve = JSON.parse(atob(getCookie("nms"))); + } catch (e) {} + try { + var retrieve2 = getUrlVars()["nms"]; + if (retrieve2 != "") { + retrieve = JSON.parse(atob(retrieve2)); + } + } catch (e) {} + + for (var v in retrieve) { + nms[v] = retrieve[v]; + } + setMenu(); + setOplog(); } /* - * Updates a simple legend-free graph, located on the navbar. - * - * The idea is to give a general "feeling" of the event. And that it's - * neat. - * - * The timer-thing to bust a cache divides by 10 seconds, so updating more - * than once every 10 seconds is pointless. - */ -function nmsUpdateNavbarGraph() { - var img = document.getElementById("navbar-graph"); - var w = 200; - - img.src = "/render/?target=movingAverage(averageSeries(ping.*.*.ipv4),%225min%22)&target=secondYAxis(averageSeries(perSecond(snmp.*.*.ports.*.{ifHCInOctets,ifHCOutOctets})))&bgcolor=%23ffffff00&width=" + w + "&height=20&format=svg&from=-30min&until=now&graphOnly=true"; -} -/* * Test if the entire path specified in the arrary "ar" exists under the * specified root. * @@ -673,20 +644,18 @@ function nmsUpdateNavbarGraph() { * or the provided default. */ function setTree(root, ar, def) { - if (ar == undefined || root == undefined) { - return def; - } else { - for (var i in ar) { - root = root[ar[i]]; - if (root == undefined) - return def; - } - } - return root; + if (ar == undefined || root == undefined) { + return def; + } else { + for (var i in ar) { + root = root[ar[i]]; + if (root == undefined) return def; + } + } + return root; } + function testTree(root, ar) { - var x = setTree(root,ar,false); - if (x != false) - return true; + var x = setTree(root, ar, false); + if (x != false) return true; } - diff --git a/web/js/npm.js b/web/js/npm.js deleted file mode 100644 index bf6aa80..0000000 --- a/web/js/npm.js +++ /dev/null @@ -1,13 +0,0 @@ -// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. -require('../../js/transition.js') -require('../../js/alert.js') -require('../../js/button.js') -require('../../js/carousel.js') -require('../../js/collapse.js') -require('../../js/dropdown.js') -require('../../js/modal.js') -require('../../js/tooltip.js') -require('../../js/popover.js') -require('../../js/scrollspy.js') -require('../../js/tab.js') -require('../../js/affix.js')
\ No newline at end of file |