/* /web/static/lib/Chart/Chart.js */ (function(global,factory){typeof exports==='object'&&typeof module!=='undefined'?module.exports=factory():typeof define==='function'&&define.amd?define(factory):(global=typeof globalThis!=='undefined'?globalThis:global||self,global.Chart=factory());})(this,(function(){'use strict';var plugins=Object.freeze({__proto__:null,get Colors(){return plugin_colors;},get Decimation(){return plugin_decimation;},get Filler(){return index;},get Legend(){return plugin_legend;},get SubTitle(){return plugin_subtitle;},get Title(){return plugin_title;},get Tooltip(){return plugin_tooltip;}});function noop(){} const uid=(()=>{let id=0;return()=>id++;})();function isNullOrUndef(value){return value===null||typeof value==='undefined';} function isArray(value){if(Array.isArray&&Array.isArray(value)){return true;} const type=Object.prototype.toString.call(value);if(type.slice(0,7)==='[object'&&type.slice(-6)==='Array]'){return true;} return false;} function isObject(value){return value!==null&&Object.prototype.toString.call(value)==='[object Object]';} function isNumberFinite(value){return(typeof value==='number'||value instanceof Number)&&isFinite(+value);} function finiteOrDefault(value,defaultValue){return isNumberFinite(value)?value:defaultValue;} function valueOrDefault(value,defaultValue){return typeof value==='undefined'?defaultValue:value;} const toPercentage=(value,dimension)=>typeof value==='string'&&value.endsWith('%')?parseFloat(value)/100:+value/dimension;const toDimension=(value,dimension)=>typeof value==='string'&&value.endsWith('%')?parseFloat(value)/100*dimension:+value;function callback(fn,args,thisArg){if(fn&&typeof fn.call==='function'){return fn.apply(thisArg,args);}} function each(loopable,fn,thisArg,reverse){let i,len,keys;if(isArray(loopable)){len=loopable.length;if(reverse){for(i=len-1;i>=0;i--){fn.call(thisArg,loopable[i],i);}}else{for(i=0;iv,x:(o)=>o.x,y:(o)=>o.y};function _splitKey(key){const parts=key.split('.');const keys=[];let tmp='';for(const part of parts){tmp+=part;if(tmp.endsWith('\\')){tmp=tmp.slice(0,-1)+'.';}else{keys.push(tmp);tmp='';}} return keys;} function _getKeyResolver(key){const keys=_splitKey(key);return(obj)=>{for(const k of keys){if(k===''){break;} obj=obj&&obj[k];} return obj;};} function resolveObjectKey(obj,key){const resolver=keyResolvers[key]||(keyResolvers[key]=_getKeyResolver(key));return resolver(obj);} function _capitalize(str){return str.charAt(0).toUpperCase()+str.slice(1);} const defined=(value)=>typeof value!=='undefined';const isFunction=(value)=>typeof value==='function';const setsEqual=(a,b)=>{if(a.size!==b.size){return false;} for(const item of a){if(!b.has(item)){return false;}} return true;};function _isClickEvent(e){return e.type==='mouseup'||e.type==='click'||e.type==='contextmenu';} const PI=Math.PI;const TAU=2*PI;const PITAU=TAU+PI;const INFINITY=Number.POSITIVE_INFINITY;const RAD_PER_DEG=PI/180;const HALF_PI=PI/2;const QUARTER_PI=PI/4;const TWO_THIRDS_PI=PI*2/3;const log10=Math.log10;const sign=Math.sign;function almostEquals(x,y,epsilon){return Math.abs(x-y)a-b).pop();return result;} function isNumber(n){return!isNaN(parseFloat(n))&&isFinite(n);} function almostWhole(x,epsilon){const rounded=Math.round(x);return rounded-epsilon<=x&&rounded+epsilon>=x;} function _setMinAndMaxByKey(array,target,property){let i,ilen,value;for(i=0,ilen=array.length;iangleToEnd&&startToAngle=Math.min(start,end)-epsilon&&value<=Math.max(start,end)+epsilon;} function _lookup(table,value,cmp){cmp=cmp||((index)=>table[index]1){mid=lo+hi>>1;if(cmp(mid)){lo=mid;}else{hi=mid;}} return{lo,hi};} const _lookupByKey=(table,key,value,last)=>_lookup(table,value,last?(index)=>{const ti=table[index][key];return titable[index][key]_lookup(table,value,(index)=>table[index][key]>=value);function _filterBetween(values,min,max){let start=0;let end=values.length;while(startstart&&values[end-1]>max){end--;} return start>0||end{const method='_onData'+_capitalize(key);const base=array[key];Object.defineProperty(array,key,{configurable:true,enumerable:false,value(...args){const res=base.apply(this,args);array._chartjs.listeners.forEach((object)=>{if(typeof object[method]==='function'){object[method](...args);}});return res;}});});} function unlistenArrayEvents(array,listener){const stub=array._chartjs;if(!stub){return;} const listeners=stub.listeners;const index=listeners.indexOf(listener);if(index!==-1){listeners.splice(index,1);} if(listeners.length>0){return;} arrayEvents.forEach((key)=>{delete array[key];});delete array._chartjs;} function _arrayUnique(items){const set=new Set(items);if(set.size===items.length){return items;} return Array.from(set);} function fontString(pixelSize,fontStyle,fontFamily){return fontStyle+' '+pixelSize+'px '+fontFamily;} const requestAnimFrame=function(){if(typeof window==='undefined'){return function(callback){return callback();};} return window.requestAnimationFrame;}();function throttled(fn,thisArg){let argsToUse=[];let ticking=false;return function(...args){argsToUse=args;if(!ticking){ticking=true;requestAnimFrame.call(window,()=>{ticking=false;fn.apply(thisArg,argsToUse);});}};} function debounce(fn,delay){let timeout;return function(...args){if(delay){clearTimeout(timeout);timeout=setTimeout(fn,delay,args);}else{fn.apply(this,args);} return delay;};} const _toLeftRightCenter=(align)=>align==='start'?'left':align==='end'?'right':'center';const _alignStartEnd=(align,start,end)=>align==='start'?start:align==='end'?end:(start+end)/2;const _textX=(align,left,right,rtl)=>{const check=rtl?'left':'right';return align===check?right:align==='center'?(left+right)/2:left;};function _getStartAndCountOfVisiblePoints(meta,points,animationsDisabled){const pointCount=points.length;let start=0;let count=pointCount;if(meta._sorted){const{iScale,_parsed}=meta;const axis=iScale.axis;const{min,max,minDefined,maxDefined}=iScale.getUserBounds();if(minDefined){start=_limitValue(Math.min(_lookupByKey(_parsed,axis,min).lo,animationsDisabled?pointCount:_lookupByKey(points,axis,iScale.getPixelForValue(min)).lo),0,pointCount-1);} if(maxDefined){count=_limitValue(Math.max(_lookupByKey(_parsed,iScale.axis,max,true).hi+1,animationsDisabled?0:_lookupByKey(points,axis,iScale.getPixelForValue(max),true).hi+1),start,pointCount)-start;}else{count=pointCount-start;}} return{start,count};} function _scaleRangesChanged(meta){const{xScale,yScale,_scaleRanges}=meta;const newRanges={xmin:xScale.min,xmax:xScale.max,ymin:yScale.min,ymax:yScale.max};if(!_scaleRanges){meta._scaleRanges=newRanges;return true;} const changed=_scaleRanges.xmin!==xScale.min||_scaleRanges.xmax!==xScale.max||_scaleRanges.ymin!==yScale.min||_scaleRanges.ymax!==yScale.max;Object.assign(_scaleRanges,newRanges);return changed;} class Animator{constructor(){this._request=null;this._charts=new Map();this._running=false;this._lastDate=undefined;} _notify(chart,anims,date,type){const callbacks=anims.listeners[type];const numSteps=anims.duration;callbacks.forEach((fn)=>fn({chart,initial:anims.initial,numSteps,currentStep:Math.min(date-anims.start,numSteps)}));} _refresh(){if(this._request){return;} this._running=true;this._request=requestAnimFrame.call(window,()=>{this._update();this._request=null;if(this._running){this._refresh();}});} _update(date=Date.now()){let remaining=0;this._charts.forEach((anims,chart)=>{if(!anims.running||!anims.items.length){return;} const items=anims.items;let i=items.length-1;let draw=false;let item;for(;i>=0;--i){item=items[i];if(item._active){if(item._total>anims.duration){anims.duration=item._total;} item.tick(date);draw=true;}else{items[i]=items[items.length-1];items.pop();}} if(draw){chart.draw();this._notify(chart,anims,date,'progress');} if(!items.length){anims.running=false;this._notify(chart,anims,date,'complete');anims.initial=false;} remaining+=items.length;});this._lastDate=date;if(remaining===0){this._running=false;}} _getAnims(chart){const charts=this._charts;let anims=charts.get(chart);if(!anims){anims={running:false,initial:true,items:[],listeners:{complete:[],progress:[]}};charts.set(chart,anims);} return anims;} listen(chart,event,cb){this._getAnims(chart).listeners[event].push(cb);} add(chart,items){if(!items||!items.length){return;} this._getAnims(chart).items.push(...items);} has(chart){return this._getAnims(chart).items.length>0;} start(chart){const anims=this._charts.get(chart);if(!anims){return;} anims.running=true;anims.start=Date.now();anims.duration=anims.items.reduce((acc,cur)=>Math.max(acc,cur._duration),0);this._refresh();} running(chart){if(!this._running){return false;} const anims=this._charts.get(chart);if(!anims||!anims.running||!anims.items.length){return false;} return true;} stop(chart){const anims=this._charts.get(chart);if(!anims||!anims.items.length){return;} const items=anims.items;let i=items.length-1;for(;i>=0;--i){items[i].cancel();} anims.items=[];this._notify(chart,anims,Date.now(),'complete');} remove(chart){return this._charts.delete(chart);}} var animator=new Animator();function round(v){return v+0.5|0;} const lim=(v,l,h)=>Math.max(Math.min(v,h),l);function p2b(v){return lim(round(v*2.55),0,255);} function n2b(v){return lim(round(v*255),0,255);} function b2n(v){return lim(round(v/2.55)/100,0,1);} function n2p(v){return lim(round(v*100),0,100);} const map$1={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15};const hex=[...'0123456789ABCDEF'];const h1=b=>hex[b&0xF];const h2=b=>hex[(b&0xF0)>>4]+hex[b&0xF];const eq=b=>((b&0xF0)>>4)===(b&0xF);const isShort=v=>eq(v.r)&&eq(v.g)&&eq(v.b)&&eq(v.a);function hexParse(str){var len=str.length;var ret;if(str[0]==='#'){if(len===4||len===5){ret={r:255&map$1[str[1]]*17,g:255&map$1[str[2]]*17,b:255&map$1[str[3]]*17,a:len===5?map$1[str[4]]*17:255};}else if(len===7||len===9){ret={r:map$1[str[1]]<<4|map$1[str[2]],g:map$1[str[3]]<<4|map$1[str[4]],b:map$1[str[5]]<<4|map$1[str[6]],a:len===9?(map$1[str[7]]<<4|map$1[str[8]]):255};}} return ret;} const alpha=(a,f)=>a<255?f(a):'';function hexString(v){var f=isShort(v)?h1:h2;return v?'#'+f(v.r)+f(v.g)+f(v.b)+alpha(v.a,f):undefined;} const HUE_RE=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function hsl2rgbn(h,s,l){const a=s*Math.min(l,1-l);const f=(n,k=(n+h/30)%12)=>l-a*Math.max(Math.min(k-3,9-k,1),-1);return[f(0),f(8),f(4)];} function hsv2rgbn(h,s,v){const f=(n,k=(n+h/60)%6)=>v-v*s*Math.max(Math.min(k,4-k,1),0);return[f(5),f(3),f(1)];} function hwb2rgbn(h,w,b){const rgb=hsl2rgbn(h,1,0.5);let i;if(w+b>1){i=1/(w+b);w*=i;b*=i;} for(i=0;i<3;i++){rgb[i]*=1-w-b;rgb[i]+=w;} return rgb;} function hueValue(r,g,b,d,max){if(r===max){return((g-b)/d)+(g0.5?d/(2-max-min):d/(max+min);h=hueValue(r,g,b,d,max);h=h*60+0.5;} return[h|0,s||0,l];} function calln(f,a,b,c){return(Array.isArray(a)?f(a[0],a[1],a[2]):f(a,b,c)).map(n2b);} function hsl2rgb(h,s,l){return calln(hsl2rgbn,h,s,l);} function hwb2rgb(h,w,b){return calln(hwb2rgbn,h,w,b);} function hsv2rgb(h,s,v){return calln(hsv2rgbn,h,s,v);} function hue(h){return(h%360+360)%360;} function hueParse(str){const m=HUE_RE.exec(str);let a=255;let v;if(!m){return;} if(m[5]!==v){a=m[6]?p2b(+m[5]):n2b(+m[5]);} const h=hue(+m[2]);const p1=+m[3]/100;const p2=+m[4]/100;if(m[1]==='hwb'){v=hwb2rgb(h,p1,p2);}else if(m[1]==='hsv'){v=hsv2rgb(h,p1,p2);}else{v=hsl2rgb(h,p1,p2);} return{r:v[0],g:v[1],b:v[2],a:a};} function rotate(v,deg){var h=rgb2hsl(v);h[0]=hue(h[0]+deg);h=hsl2rgb(h);v.r=h[0];v.g=h[1];v.b=h[2];} function hslString(v){if(!v){return;} const a=rgb2hsl(v);const h=a[0];const s=n2p(a[1]);const l=n2p(a[2]);return v.a<255?`hsla(${h}, ${s}%, ${l}%, ${b2n(v.a)})`:`hsl(${h}, ${s}%, ${l}%)`;} const map$2={x:'dark',Z:'light',Y:'re',X:'blu',W:'gr',V:'medium',U:'slate',A:'ee',T:'ol',S:'or',B:'ra',C:'lateg',D:'ights',R:'in',Q:'turquois',E:'hi',P:'ro',O:'al',N:'le',M:'de',L:'yello',F:'en',K:'ch',G:'arks',H:'ea',I:'ightg',J:'wh'};const names$1={OiceXe:'f0f8ff',antiquewEte:'faebd7',aqua:'ffff',aquamarRe:'7fffd4',azuY:'f0ffff',beige:'f5f5dc',bisque:'ffe4c4',black:'0',blanKedOmond:'ffebcd',Xe:'ff',XeviTet:'8a2be2',bPwn:'a52a2a',burlywood:'deb887',caMtXe:'5f9ea0',KartYuse:'7fff00',KocTate:'d2691e',cSO:'ff7f50',cSnflowerXe:'6495ed',cSnsilk:'fff8dc',crimson:'dc143c',cyan:'ffff',xXe:'8b',xcyan:'8b8b',xgTMnPd:'b8860b',xWay:'a9a9a9',xgYF:'6400',xgYy:'a9a9a9',xkhaki:'bdb76b',xmagFta:'8b008b',xTivegYF:'556b2f',xSange:'ff8c00',xScEd:'9932cc',xYd:'8b0000',xsOmon:'e9967a',xsHgYF:'8fbc8f',xUXe:'483d8b',xUWay:'2f4f4f',xUgYy:'2f4f4f',xQe:'ced1',xviTet:'9400d3',dAppRk:'ff1493',dApskyXe:'bfff',dimWay:'696969',dimgYy:'696969',dodgerXe:'1e90ff',fiYbrick:'b22222',flSOwEte:'fffaf0',foYstWAn:'228b22',fuKsia:'ff00ff',gaRsbSo:'dcdcdc',ghostwEte:'f8f8ff',gTd:'ffd700',gTMnPd:'daa520',Way:'808080',gYF:'8000',gYFLw:'adff2f',gYy:'808080',honeyMw:'f0fff0',hotpRk:'ff69b4',RdianYd:'cd5c5c',Rdigo:'4b0082',ivSy:'fffff0',khaki:'f0e68c',lavFMr:'e6e6fa',lavFMrXsh:'fff0f5',lawngYF:'7cfc00',NmoncEffon:'fffacd',ZXe:'add8e6',ZcSO:'f08080',Zcyan:'e0ffff',ZgTMnPdLw:'fafad2',ZWay:'d3d3d3',ZgYF:'90ee90',ZgYy:'d3d3d3',ZpRk:'ffb6c1',ZsOmon:'ffa07a',ZsHgYF:'20b2aa',ZskyXe:'87cefa',ZUWay:'778899',ZUgYy:'778899',ZstAlXe:'b0c4de',ZLw:'ffffe0',lime:'ff00',limegYF:'32cd32',lRF:'faf0e6',magFta:'ff00ff',maPon:'800000',VaquamarRe:'66cdaa',VXe:'cd',VScEd:'ba55d3',VpurpN:'9370db',VsHgYF:'3cb371',VUXe:'7b68ee',VsprRggYF:'fa9a',VQe:'48d1cc',VviTetYd:'c71585',midnightXe:'191970',mRtcYam:'f5fffa',mistyPse:'ffe4e1',moccasR:'ffe4b5',navajowEte:'ffdead',navy:'80',Tdlace:'fdf5e6',Tive:'808000',TivedBb:'6b8e23',Sange:'ffa500',SangeYd:'ff4500',ScEd:'da70d6',pOegTMnPd:'eee8aa',pOegYF:'98fb98',pOeQe:'afeeee',pOeviTetYd:'db7093',papayawEp:'ffefd5',pHKpuff:'ffdab9',peru:'cd853f',pRk:'ffc0cb',plum:'dda0dd',powMrXe:'b0e0e6',purpN:'800080',YbeccapurpN:'663399',Yd:'ff0000',Psybrown:'bc8f8f',PyOXe:'4169e1',saddNbPwn:'8b4513',sOmon:'fa8072',sandybPwn:'f4a460',sHgYF:'2e8b57',sHshell:'fff5ee',siFna:'a0522d',silver:'c0c0c0',skyXe:'87ceeb',UXe:'6a5acd',UWay:'708090',UgYy:'708090',snow:'fffafa',sprRggYF:'ff7f',stAlXe:'4682b4',tan:'d2b48c',teO:'8080',tEstN:'d8bfd8',tomato:'ff6347',Qe:'40e0d0',viTet:'ee82ee',JHt:'f5deb3',wEte:'ffffff',wEtesmoke:'f5f5f5',Lw:'ffff00',LwgYF:'9acd32'};function unpack(){const unpacked={};const keys=Object.keys(names$1);const tkeys=Object.keys(map$2);let i,j,k,ok,nk;for(i=0;i>16&0xFF,k>>8&0xFF,k&0xFF];} return unpacked;} let names;function nameParse(str){if(!names){names=unpack();names.transparent=[0,0,0,0];} const a=names[str.toLowerCase()];return a&&{r:a[0],g:a[1],b:a[2],a:a.length===4?a[3]:255};} const RGB_RE=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;function rgbParse(str){const m=RGB_RE.exec(str);let a=255;let r,g,b;if(!m){return;} if(m[7]!==r){const v=+m[7];a=m[8]?p2b(v):lim(v*255,0,255);} r=+m[1];g=+m[3];b=+m[5];r=255&(m[2]?p2b(r):lim(r,0,255));g=255&(m[4]?p2b(g):lim(g,0,255));b=255&(m[6]?p2b(b):lim(b,0,255));return{r:r,g:g,b:b,a:a};} function rgbString(v){return v&&(v.a<255?`rgba(${v.r}, ${v.g}, ${v.b}, ${b2n(v.a)})`:`rgb(${v.r}, ${v.g}, ${v.b})`);} const to=v=>v<=0.0031308?v*12.92:Math.pow(v,1.0/2.4)*1.055-0.055;const from=v=>v<=0.04045?v/12.92:Math.pow((v+0.055)/1.055,2.4);function interpolate$1(rgb1,rgb2,t){const r=from(b2n(rgb1.r));const g=from(b2n(rgb1.g));const b=from(b2n(rgb1.b));return{r:n2b(to(r+t*(from(b2n(rgb2.r))-r))),g:n2b(to(g+t*(from(b2n(rgb2.g))-g))),b:n2b(to(b+t*(from(b2n(rgb2.b))-b))),a:rgb1.a+t*(rgb2.a-rgb1.a)};} function modHSL(v,i,ratio){if(v){let tmp=rgb2hsl(v);tmp[i]=Math.max(0,Math.min(tmp[i]+tmp[i]*ratio,i===0?360:1));tmp=hsl2rgb(tmp);v.r=tmp[0];v.g=tmp[1];v.b=tmp[2];}} function clone(v,proto){return v?Object.assign(proto||{},v):v;} function fromObject(input){var v={r:0,g:0,b:0,a:255};if(Array.isArray(input)){if(input.length>=3){v={r:input[0],g:input[1],b:input[2],a:255};if(input.length>3){v.a=n2b(input[3]);}}}else{v=clone(input,{r:0,g:0,b:0,a:1});v.a=n2b(v.a);} return v;} function functionParse(str){if(str.charAt(0)==='r'){return rgbParse(str);} return hueParse(str);} class Color{constructor(input){if(input instanceof Color){return input;} const type=typeof input;let v;if(type==='object'){v=fromObject(input);}else if(type==='string'){v=hexParse(input)||nameParse(input)||functionParse(input);} this._rgb=v;this._valid=!!v;} get valid(){return this._valid;} get rgb(){var v=clone(this._rgb);if(v){v.a=b2n(v.a);} return v;} set rgb(obj){this._rgb=fromObject(obj);} rgbString(){return this._valid?rgbString(this._rgb):undefined;} hexString(){return this._valid?hexString(this._rgb):undefined;} hslString(){return this._valid?hslString(this._rgb):undefined;} mix(color,weight){if(color){const c1=this.rgb;const c2=color.rgb;let w2;const p=weight===w2?0.5:weight;const w=2*p-1;const a=c1.a-c2.a;const w1=((w*a===-1?w:(w+a)/(1+w*a))+1)/2.0;w2=1-w1;c1.r=0xFF&w1*c1.r+w2*c2.r+0.5;c1.g=0xFF&w1*c1.g+w2*c2.g+0.5;c1.b=0xFF&w1*c1.b+w2*c2.b+0.5;c1.a=p*c1.a+(1-p)*c2.a;this.rgb=c1;} return this;} interpolate(color,t){if(color){this._rgb=interpolate$1(this._rgb,color._rgb,t);} return this;} clone(){return new Color(this.rgb);} alpha(a){this._rgb.a=n2b(a);return this;} clearer(ratio){const rgb=this._rgb;rgb.a*=1-ratio;return this;} greyscale(){const rgb=this._rgb;const val=round(rgb.r*0.3+rgb.g*0.59+rgb.b*0.11);rgb.r=rgb.g=rgb.b=val;return this;} opaquer(ratio){const rgb=this._rgb;rgb.a*=1+ratio;return this;} negate(){const v=this._rgb;v.r=255-v.r;v.g=255-v.g;v.b=255-v.b;return this;} lighten(ratio){modHSL(this._rgb,2,ratio);return this;} darken(ratio){modHSL(this._rgb,2,-ratio);return this;} saturate(ratio){modHSL(this._rgb,1,ratio);return this;} desaturate(ratio){modHSL(this._rgb,1,-ratio);return this;} rotate(deg){rotate(this._rgb,deg);return this;}} function isPatternOrGradient(value){if(value&&typeof value==='object'){const type=value.toString();return type==='[object CanvasPattern]'||type==='[object CanvasGradient]';} return false;} function color(value){return isPatternOrGradient(value)?value:new Color(value);} function getHoverColor(value){return isPatternOrGradient(value)?value:new Color(value).saturate(0.5).darken(0.1).hexString();} const numbers=['x','y','borderWidth','radius','tension'];const colors=['color','borderColor','backgroundColor'];function applyAnimationsDefaults(defaults){defaults.set('animation',{delay:undefined,duration:1000,easing:'easeOutQuart',fn:undefined,from:undefined,loop:undefined,to:undefined,type:undefined});defaults.describe('animation',{_fallback:false,_indexable:false,_scriptable:(name)=>name!=='onProgress'&&name!=='onComplete'&&name!=='fn'});defaults.set('animations',{colors:{type:'color',properties:colors},numbers:{type:'number',properties:numbers}});defaults.describe('animations',{_fallback:'animation'});defaults.set('transitions',{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:'transparent'},visible:{type:'boolean',duration:0}}},hide:{animations:{colors:{to:'transparent'},visible:{type:'boolean',easing:'linear',fn:(v)=>v|0}}}});} function applyLayoutsDefaults(defaults){defaults.set('layout',{autoPadding:true,padding:{top:0,right:0,bottom:0,left:0}});} const intlCache=new Map();function getNumberFormat(locale,options){options=options||{};const cacheKey=locale+JSON.stringify(options);let formatter=intlCache.get(cacheKey);if(!formatter){formatter=new Intl.NumberFormat(locale,options);intlCache.set(cacheKey,formatter);} return formatter;} function formatNumber(num,locale,options){return getNumberFormat(locale,options).format(num);} const formatters={values(value){return isArray(value)?value:''+value;},numeric(tickValue,index,ticks){if(tickValue===0){return'0';} const locale=this.chart.options.locale;let notation;let delta=tickValue;if(ticks.length>1){const maxTick=Math.max(Math.abs(ticks[0].value),Math.abs(ticks[ticks.length-1].value));if(maxTick<1e-4||maxTick>1e+15){notation='scientific';} delta=calculateDelta(tickValue,ticks);} const logDelta=log10(Math.abs(delta));const numDecimal=isNaN(logDelta)?1:Math.max(Math.min(-1*Math.floor(logDelta),20),0);const options={notation,minimumFractionDigits:numDecimal,maximumFractionDigits:numDecimal};Object.assign(options,this.options.ticks.format);return formatNumber(tickValue,locale,options);},logarithmic(tickValue,index,ticks){if(tickValue===0){return'0';} const remain=ticks[index].significand||tickValue/Math.pow(10,Math.floor(log10(tickValue)));if([1,2,3,5,10,15].includes(remain)||index>0.8*ticks.length){return formatters.numeric.call(this,tickValue,index,ticks);} return'';}};function calculateDelta(tickValue,ticks){let delta=ticks.length>3?ticks[2].value-ticks[1].value:ticks[1].value-ticks[0].value;if(Math.abs(delta)>=1&&tickValue!==Math.floor(tickValue)){delta=tickValue-Math.floor(tickValue);} return delta;} var Ticks={formatters};function applyScaleDefaults(defaults){defaults.set('scale',{display:true,offset:false,reverse:false,beginAtZero:false,bounds:'ticks',clip:true,grace:0,grid:{display:true,lineWidth:1,drawOnChartArea:true,drawTicks:true,tickLength:8,tickWidth:(_ctx,options)=>options.lineWidth,tickColor:(_ctx,options)=>options.color,offset:false},border:{display:true,dash:[],dashOffset:0.0,width:1},title:{display:false,text:'',padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:false,textStrokeWidth:0,textStrokeColor:'',padding:3,display:true,autoSkip:true,autoSkipPadding:3,labelOffset:0,callback:Ticks.formatters.values,minor:{},major:{},align:'center',crossAlign:'near',showLabelBackdrop:false,backdropColor:'rgba(255, 255, 255, 0.75)',backdropPadding:2}});defaults.route('scale.ticks','color','','color');defaults.route('scale.grid','color','','borderColor');defaults.route('scale.border','color','','borderColor');defaults.route('scale.title','color','','color');defaults.describe('scale',{_fallback:false,_scriptable:(name)=>!name.startsWith('before')&&!name.startsWith('after')&&name!=='callback'&&name!=='parser',_indexable:(name)=>name!=='borderDash'&&name!=='tickBorderDash'&&name!=='dash'});defaults.describe('scales',{_fallback:'scale'});defaults.describe('scale.ticks',{_scriptable:(name)=>name!=='backdropPadding'&&name!=='callback',_indexable:(name)=>name!=='backdropPadding'});} const overrides=Object.create(null);const descriptors=Object.create(null);function getScope$1(node,key){if(!key){return node;} const keys=key.split('.');for(let i=0,n=keys.length;icontext.chart.platform.getDevicePixelRatio();this.elements={};this.events=['mousemove','mouseout','click','touchstart','touchmove'];this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:'normal',lineHeight:1.2,weight:null};this.hover={};this.hoverBackgroundColor=(ctx,options)=>getHoverColor(options.backgroundColor);this.hoverBorderColor=(ctx,options)=>getHoverColor(options.borderColor);this.hoverColor=(ctx,options)=>getHoverColor(options.color);this.indexAxis='x';this.interaction={mode:'nearest',intersect:true,includeInvisible:false};this.maintainAspectRatio=true;this.onHover=null;this.onClick=null;this.parsing=true;this.plugins={};this.responsive=true;this.scale=undefined;this.scales={};this.showLine=true;this.drawActiveElementsOnTop=true;this.describe(_descriptors);this.apply(_appliers);} set(scope,values){return set(this,scope,values);} get(scope){return getScope$1(this,scope);} describe(scope,values){return set(descriptors,scope,values);} override(scope,values){return set(overrides,scope,values);} route(scope,name,targetScope,targetName){const scopeObject=getScope$1(this,scope);const targetScopeObject=getScope$1(this,targetScope);const privateName='_'+name;Object.defineProperties(scopeObject,{[privateName]:{value:scopeObject[name],writable:true},[name]:{enumerable:true,get(){const local=this[privateName];const target=targetScopeObject[targetName];if(isObject(local)){return Object.assign({},target,local);} return valueOrDefault(local,target);},set(value){this[privateName]=value;}}});} apply(appliers){appliers.forEach((apply)=>apply(this));}} var defaults=new Defaults({_scriptable:(name)=>!name.startsWith('on'),_indexable:(name)=>name!=='events',hover:{_fallback:'interaction'},interaction:{_scriptable:false,_indexable:false}},[applyAnimationsDefaults,applyLayoutsDefaults,applyScaleDefaults]);function _isDomSupported(){return typeof window!=='undefined'&&typeof document!=='undefined';} function _getParentNode(domNode){let parent=domNode.parentNode;if(parent&&parent.toString()==='[object ShadowRoot]'){parent=parent.host;} return parent;} function parseMaxStyle(styleValue,node,parentProperty){let valueInPixels;if(typeof styleValue==='string'){valueInPixels=parseInt(styleValue,10);if(styleValue.indexOf('%')!==-1){valueInPixels=valueInPixels/100*node.parentNode[parentProperty];}}else{valueInPixels=styleValue;} return valueInPixels;} const getComputedStyle=(element)=>element.ownerDocument.defaultView.getComputedStyle(element,null);function getStyle(el,property){return getComputedStyle(el).getPropertyValue(property);} const positions=['top','right','bottom','left'];function getPositionedStyle(styles,style,suffix){const result={};suffix=suffix?'-'+suffix:'';for(let i=0;i<4;i++){const pos=positions[i];result[pos]=parseFloat(styles[style+'-'+pos+suffix])||0;} result.width=result.left+result.right;result.height=result.top+result.bottom;return result;} const useOffsetPos=(x,y,target)=>(x>0||y>0)&&(!target||!target.shadowRoot);function getCanvasPosition(e,canvas){const touches=e.touches;const source=touches&&touches.length?touches[0]:e;const{offsetX,offsetY}=source;let box=false;let x,y;if(useOffsetPos(offsetX,offsetY,e.target)){x=offsetX;y=offsetY;}else{const rect=canvas.getBoundingClientRect();x=source.clientX-rect.left;y=source.clientY-rect.top;box=true;} return{x,y,box};} function getRelativePosition(event,chart){if('native'in event){return event;} const{canvas,currentDevicePixelRatio}=chart;const style=getComputedStyle(canvas);const borderBox=style.boxSizing==='border-box';const paddings=getPositionedStyle(style,'padding');const borders=getPositionedStyle(style,'border','width');const{x,y,box}=getCanvasPosition(event,canvas);const xOffset=paddings.left+(box&&borders.left);const yOffset=paddings.top+(box&&borders.top);let{width,height}=chart;if(borderBox){width-=paddings.width+borders.width;height-=paddings.height+borders.height;} return{x:Math.round((x-xOffset)/width*canvas.width/currentDevicePixelRatio),y:Math.round((y-yOffset)/height*canvas.height/currentDevicePixelRatio)};} function getContainerSize(canvas,width,height){let maxWidth,maxHeight;if(width===undefined||height===undefined){const container=canvas&&_getParentNode(canvas);if(!container){width=canvas.clientWidth;height=canvas.clientHeight;}else{const rect=container.getBoundingClientRect();const containerStyle=getComputedStyle(container);const containerBorder=getPositionedStyle(containerStyle,'border','width');const containerPadding=getPositionedStyle(containerStyle,'padding');width=rect.width-containerPadding.width-containerBorder.width;height=rect.height-containerPadding.height-containerBorder.height;maxWidth=parseMaxStyle(containerStyle.maxWidth,container,'clientWidth');maxHeight=parseMaxStyle(containerStyle.maxHeight,container,'clientHeight');}} return{width,height,maxWidth:maxWidth||INFINITY,maxHeight:maxHeight||INFINITY};} const round1=(v)=>Math.round(v*10)/10;function getMaximumSize(canvas,bbWidth,bbHeight,aspectRatio){const style=getComputedStyle(canvas);const margins=getPositionedStyle(style,'margin');const maxWidth=parseMaxStyle(style.maxWidth,canvas,'clientWidth')||INFINITY;const maxHeight=parseMaxStyle(style.maxHeight,canvas,'clientHeight')||INFINITY;const containerSize=getContainerSize(canvas,bbWidth,bbHeight);let{width,height}=containerSize;if(style.boxSizing==='content-box'){const borders=getPositionedStyle(style,'border','width');const paddings=getPositionedStyle(style,'padding');width-=paddings.width+borders.width;height-=paddings.height+borders.height;} width=Math.max(0,width-margins.width);height=Math.max(0,aspectRatio?width/aspectRatio:height-margins.height);width=round1(Math.min(width,maxWidth,containerSize.maxWidth));height=round1(Math.min(height,maxHeight,containerSize.maxHeight));if(width&&!height){height=round1(width/2);} const maintainHeight=bbWidth!==undefined||bbHeight!==undefined;if(maintainHeight&&aspectRatio&&containerSize.height&&height>containerSize.height){height=containerSize.height;width=round1(Math.floor(height*aspectRatio));} return{width,height};} function retinaScale(chart,forceRatio,forceStyle){const pixelRatio=forceRatio||1;const deviceHeight=Math.floor(chart.height*pixelRatio);const deviceWidth=Math.floor(chart.width*pixelRatio);chart.height=Math.floor(chart.height);chart.width=Math.floor(chart.width);const canvas=chart.canvas;if(canvas.style&&(forceStyle||!canvas.style.height&&!canvas.style.width)){canvas.style.height=`${chart.height}px`;canvas.style.width=`${chart.width}px`;} if(chart.currentDevicePixelRatio!==pixelRatio||canvas.height!==deviceHeight||canvas.width!==deviceWidth){chart.currentDevicePixelRatio=pixelRatio;canvas.height=deviceHeight;canvas.width=deviceWidth;chart.ctx.setTransform(pixelRatio,0,0,pixelRatio,0,0);return true;} return false;} const supportsEventListenerOptions=function(){let passiveSupported=false;try{const options={get passive(){passiveSupported=true;return false;}};if(_isDomSupported()){window.addEventListener('test',null,options);window.removeEventListener('test',null,options);}}catch(e){} return passiveSupported;}();function readUsedSize(element,property){const value=getStyle(element,property);const matches=value&&value.match(/^(\d+)(\.\d+)?px$/);return matches?+matches[1]:undefined;} function toFontString(font){if(!font||isNullOrUndef(font.size)||isNullOrUndef(font.family)){return null;} return(font.style?font.style+' ':'')+(font.weight?font.weight+' ':'')+font.size+'px '+font.family;} function _measureText(ctx,data,gc,longest,string){let textWidth=data[string];if(!textWidth){textWidth=data[string]=ctx.measureText(string).width;gc.push(string);} if(textWidth>longest){longest=textWidth;} return longest;} function _longestText(ctx,font,arrayOfThings,cache){cache=cache||{};let data=cache.data=cache.data||{};let gc=cache.garbageCollect=cache.garbageCollect||[];if(cache.font!==font){data=cache.data={};gc=cache.garbageCollect=[];cache.font=font;} ctx.save();ctx.font=font;let longest=0;const ilen=arrayOfThings.length;let i,j,jlen,thing,nestedThing;for(i=0;iarrayOfThings.length){for(i=0;i0){ctx.stroke();}} function _isPointInArea(point,area,margin){margin=margin||0.5;return!area||point&&point.x>area.left-margin&&point.xarea.top-margin&&point.y0&&opts.strokeColor!=='';let i,line;ctx.save();ctx.font=font.string;setRenderOpts(ctx,opts);for(i=0;iscopes[0]){const finalRootScopes=rootScopes||scopes;if(typeof fallback==='undefined'){fallback=_resolve('_fallback',scopes);} const cache={[Symbol.toStringTag]:'Object',_cacheable:true,_scopes:scopes,_rootScopes:finalRootScopes,_fallback:fallback,_getTarget:getTarget,override:(scope)=>_createResolver([scope,...scopes],prefixes,finalRootScopes,fallback)};return new Proxy(cache,{deleteProperty(target,prop){delete target[prop];delete target._keys;delete scopes[0][prop];return true;},get(target,prop){return _cached(target,prop,()=>_resolveWithPrefixes(prop,prefixes,scopes,target));},getOwnPropertyDescriptor(target,prop){return Reflect.getOwnPropertyDescriptor(target._scopes[0],prop);},getPrototypeOf(){return Reflect.getPrototypeOf(scopes[0]);},has(target,prop){return getKeysFromAllScopes(target).includes(prop);},ownKeys(target){return getKeysFromAllScopes(target);},set(target,prop,value){const storage=target._storage||(target._storage=getTarget());target[prop]=storage[prop]=value;delete target._keys;return true;}});} function _attachContext(proxy,context,subProxy,descriptorDefaults){const cache={_cacheable:false,_proxy:proxy,_context:context,_subProxy:subProxy,_stack:new Set(),_descriptors:_descriptors(proxy,descriptorDefaults),setContext:(ctx)=>_attachContext(proxy,ctx,subProxy,descriptorDefaults),override:(scope)=>_attachContext(proxy.override(scope),context,subProxy,descriptorDefaults)};return new Proxy(cache,{deleteProperty(target,prop){delete target[prop];delete proxy[prop];return true;},get(target,prop,receiver){return _cached(target,prop,()=>_resolveWithContext(target,prop,receiver));},getOwnPropertyDescriptor(target,prop){return target._descriptors.allKeys?Reflect.has(proxy,prop)?{enumerable:true,configurable:true}:undefined:Reflect.getOwnPropertyDescriptor(proxy,prop);},getPrototypeOf(){return Reflect.getPrototypeOf(proxy);},has(target,prop){return Reflect.has(proxy,prop);},ownKeys(){return Reflect.ownKeys(proxy);},set(target,prop,value){proxy[prop]=value;delete target[prop];return true;}});} function _descriptors(proxy,defaults={scriptable:true,indexable:true}){const{_scriptable=defaults.scriptable,_indexable=defaults.indexable,_allKeys=defaults.allKeys}=proxy;return{allKeys:_allKeys,scriptable:_scriptable,indexable:_indexable,isScriptable:isFunction(_scriptable)?_scriptable:()=>_scriptable,isIndexable:isFunction(_indexable)?_indexable:()=>_indexable};} const readKey=(prefix,name)=>prefix?prefix+_capitalize(name):name;const needsSubResolver=(prop,value)=>isObject(value)&&prop!=='adapters'&&(Object.getPrototypeOf(value)===null||value.constructor===Object);function _cached(target,prop,resolve){if(Object.prototype.hasOwnProperty.call(target,prop)||prop==='constructor'){return target[prop];} const value=resolve();target[prop]=value;return value;} function _resolveWithContext(target,prop,receiver){const{_proxy,_context,_subProxy,_descriptors:descriptors}=target;let value=_proxy[prop];if(isFunction(value)&&descriptors.isScriptable(prop)){value=_resolveScriptable(prop,value,target,receiver);} if(isArray(value)&&value.length){value=_resolveArray(prop,value,target,descriptors.isIndexable);} if(needsSubResolver(prop,value)){value=_attachContext(value,_context,_subProxy&&_subProxy[prop],descriptors);} return value;} function _resolveScriptable(prop,getValue,target,receiver){const{_proxy,_context,_subProxy,_stack}=target;if(_stack.has(prop)){throw new Error('Recursion detected: '+Array.from(_stack).join('->')+'->'+prop);} _stack.add(prop);let value=getValue(_context,_subProxy||receiver);_stack.delete(prop);if(needsSubResolver(prop,value)){value=createSubResolver(_proxy._scopes,_proxy,prop,value);} return value;} function _resolveArray(prop,value,target,isIndexable){const{_proxy,_context,_subProxy,_descriptors:descriptors}=target;if(typeof _context.index!=='undefined'&&isIndexable(prop)){return value[_context.index%value.length];}else if(isObject(value[0])){const arr=value;const scopes=_proxy._scopes.filter((s)=>s!==arr);value=[];for(const item of arr){const resolver=createSubResolver(scopes,_proxy,prop,item);value.push(_attachContext(resolver,_context,_subProxy&&_subProxy[prop],descriptors));}} return value;} function resolveFallback(fallback,prop,value){return isFunction(fallback)?fallback(prop,value):fallback;} const getScope=(key,parent)=>key===true?parent:typeof key==='string'?resolveObjectKey(parent,key):undefined;function addScopes(set,parentScopes,key,parentFallback,value){for(const parent of parentScopes){const scope=getScope(key,parent);if(scope){set.add(scope);const fallback=resolveFallback(scope._fallback,key,value);if(typeof fallback!=='undefined'&&fallback!==key&&fallback!==parentFallback){return fallback;}}else if(scope===false&&typeof parentFallback!=='undefined'&&key!==parentFallback){return null;}} return false;} function createSubResolver(parentScopes,resolver,prop,value){const rootScopes=resolver._rootScopes;const fallback=resolveFallback(resolver._fallback,prop,value);const allScopes=[...parentScopes,...rootScopes];const set=new Set();set.add(value);let key=addScopesFromKey(set,allScopes,prop,fallback||prop,value);if(key===null){return false;} if(typeof fallback!=='undefined'&&fallback!==prop){key=addScopesFromKey(set,allScopes,fallback,key,value);if(key===null){return false;}} return _createResolver(Array.from(set),[''],rootScopes,fallback,()=>subGetTarget(resolver,prop,value));} function addScopesFromKey(set,allScopes,key,fallback,item){while(key){key=addScopes(set,allScopes,key,fallback,item);} return key;} function subGetTarget(resolver,prop,value){const parent=resolver._getTarget();if(!(prop in parent)){parent[prop]={};} const target=parent[prop];if(isArray(target)&&isObject(value)){return value;} return target||{};} function _resolveWithPrefixes(prop,prefixes,scopes,proxy){let value;for(const prefix of prefixes){value=_resolve(readKey(prefix,prop),scopes);if(typeof value!=='undefined'){return needsSubResolver(prop,value)?createSubResolver(scopes,proxy,prop,value):value;}}} function _resolve(key,scopes){for(const scope of scopes){if(!scope){continue;} const value=scope[key];if(typeof value!=='undefined'){return value;}}} function getKeysFromAllScopes(target){let keys=target._keys;if(!keys){keys=target._keys=resolveKeysFromAllScopes(target._scopes);} return keys;} function resolveKeysFromAllScopes(scopes){const set=new Set();for(const scope of scopes){for(const key of Object.keys(scope).filter((k)=>!k.startsWith('_'))){set.add(key);}} return Array.from(set);} function _parseObjectDataRadialScale(meta,data,start,count){const{iScale}=meta;const{key='r'}=this._parsing;const parsed=new Array(count);let i,ilen,index,item;for(i=0,ilen=count;iiindexAxis==='x'?'y':'x';function splineCurve(firstPoint,middlePoint,afterPoint,t){const previous=firstPoint.skip?middlePoint:firstPoint;const current=middlePoint;const next=afterPoint.skip?middlePoint:afterPoint;const d01=distanceBetweenPoints(current,previous);const d12=distanceBetweenPoints(next,current);let s01=d01/(d01+d12);let s12=d12/(d01+d12);s01=isNaN(s01)?0:s01;s12=isNaN(s12)?0:s12;const fa=t*s01;const fb=t*s12;return{previous:{x:current.x-fa*(next.x-previous.x),y:current.y-fa*(next.y-previous.y)},next:{x:current.x+fb*(next.x-previous.x),y:current.y+fb*(next.y-previous.y)}};} function monotoneAdjust(points,deltaK,mK){const pointsLen=points.length;let alphaK,betaK,tauK,squaredMagnitude,pointCurrent;let pointAfter=getPoint(points,0);for(let i=0;i!pt.skip);} if(options.cubicInterpolationMode==='monotone'){splineCurveMonotone(points,indexAxis);}else{let prev=loop?points[points.length-1]:points[0];for(i=0,ilen=points.length;it===0||t===1;const elasticIn=(t,s,p)=>-(Math.pow(2,10*(t-=1))*Math.sin((t-s)*TAU/p));const elasticOut=(t,s,p)=>Math.pow(2,-10*t)*Math.sin((t-s)*TAU/p)+1;const effects={linear:(t)=>t,easeInQuad:(t)=>t*t,easeOutQuad:(t)=>-t*(t-2),easeInOutQuad:(t)=>(t/=0.5)<1?0.5*t*t:-0.5*(--t*(t-2)-1),easeInCubic:(t)=>t*t*t,easeOutCubic:(t)=>(t-=1)*t*t+1,easeInOutCubic:(t)=>(t/=0.5)<1?0.5*t*t*t:0.5*((t-=2)*t*t+2),easeInQuart:(t)=>t*t*t*t,easeOutQuart:(t)=>-((t-=1)*t*t*t-1),easeInOutQuart:(t)=>(t/=0.5)<1?0.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2),easeInQuint:(t)=>t*t*t*t*t,easeOutQuint:(t)=>(t-=1)*t*t*t*t+1,easeInOutQuint:(t)=>(t/=0.5)<1?0.5*t*t*t*t*t:0.5*((t-=2)*t*t*t*t+2),easeInSine:(t)=>-Math.cos(t*HALF_PI)+1,easeOutSine:(t)=>Math.sin(t*HALF_PI),easeInOutSine:(t)=>-0.5*(Math.cos(PI*t)-1),easeInExpo:(t)=>t===0?0:Math.pow(2,10*(t-1)),easeOutExpo:(t)=>t===1?1:-Math.pow(2,-10*t)+1,easeInOutExpo:(t)=>atEdge(t)?t:t<0.5?0.5*Math.pow(2,10*(t*2-1)):0.5*(-Math.pow(2,-10*(t*2-1))+2),easeInCirc:(t)=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:(t)=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:(t)=>(t/=0.5)<1?-0.5*(Math.sqrt(1-t*t)-1):0.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:(t)=>atEdge(t)?t:elasticIn(t,0.075,0.3),easeOutElastic:(t)=>atEdge(t)?t:elasticOut(t,0.075,0.3),easeInOutElastic(t){const s=0.1125;const p=0.45;return atEdge(t)?t:t<0.5?0.5*elasticIn(t*2,s,p):0.5+0.5*elasticOut(t*2-1,s,p);},easeInBack(t){const s=1.70158;return t*t*((s+1)*t-s);},easeOutBack(t){const s=1.70158;return(t-=1)*t*((s+1)*t+s)+1;},easeInOutBack(t){let s=1.70158;if((t/=0.5)<1){return 0.5*(t*t*(((s*=1.525)+1)*t-s));} return 0.5*((t-=2)*t*(((s*=1.525)+1)*t+s)+2);},easeInBounce:(t)=>1-effects.easeOutBounce(1-t),easeOutBounce(t){const m=7.5625;const d=2.75;if(t<1/d){return m*t*t;} if(t<2/d){return m*(t-=1.5/d)*t+0.75;} if(t<2.5/d){return m*(t-=2.25/d)*t+0.9375;} return m*(t-=2.625/d)*t+0.984375;},easeInOutBounce:(t)=>t<0.5?effects.easeInBounce(t*2)*0.5:effects.easeOutBounce(t*2-1)*0.5+0.5};function _pointInLine(p1,p2,t,mode){return{x:p1.x+t*(p2.x-p1.x),y:p1.y+t*(p2.y-p1.y)};} function _steppedInterpolation(p1,p2,t,mode){return{x:p1.x+t*(p2.x-p1.x),y:mode==='middle'?t<0.5?p1.y:p2.y:mode==='after'?t<1?p1.y:p2.y:t>0?p2.y:p1.y};} function _bezierInterpolation(p1,p2,t,mode){const cp1={x:p1.cp2x,y:p1.cp2y};const cp2={x:p2.cp1x,y:p2.cp1y};const a=_pointInLine(p1,cp1,t);const b=_pointInLine(cp1,cp2,t);const c=_pointInLine(cp2,p2,t);const d=_pointInLine(a,b,t);const e=_pointInLine(b,c,t);return _pointInLine(d,e,t);} const LINE_HEIGHT=/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/;const FONT_STYLE=/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/;function toLineHeight(value,size){const matches=(''+value).match(LINE_HEIGHT);if(!matches||matches[1]==='normal'){return size*1.2;} value=+matches[2];switch(matches[3]){case'px':return value;case'%':value/=100;break;} return size*value;} const numberOrZero=(v)=>+v||0;function _readValueToProps(value,props){const ret={};const objProps=isObject(props);const keys=objProps?Object.keys(props):props;const read=isObject(value)?objProps?(prop)=>valueOrDefault(value[prop],value[props[prop]]):(prop)=>value[prop]:()=>value;for(const prop of keys){ret[prop]=numberOrZero(read(prop));} return ret;} function toTRBL(value){return _readValueToProps(value,{top:'y',right:'x',bottom:'y',left:'x'});} function toTRBLCorners(value){return _readValueToProps(value,['topLeft','topRight','bottomLeft','bottomRight']);} function toPadding(value){const obj=toTRBL(value);obj.width=obj.left+obj.right;obj.height=obj.top+obj.bottom;return obj;} function toFont(options,fallback){options=options||{};fallback=fallback||defaults.font;let size=valueOrDefault(options.size,fallback.size);if(typeof size==='string'){size=parseInt(size,10);} let style=valueOrDefault(options.style,fallback.style);if(style&&!(''+style).match(FONT_STYLE)){console.warn('Invalid font style specified: "'+style+'"');style=undefined;} const font={family:valueOrDefault(options.family,fallback.family),lineHeight:toLineHeight(valueOrDefault(options.lineHeight,fallback.lineHeight),size),size,style,weight:valueOrDefault(options.weight,fallback.weight),string:''};font.string=toFontString(font);return font;} function resolve(inputs,context,index,info){let cacheable=true;let i,ilen,value;for(i=0,ilen=inputs.length;ibeginAtZero&&value===0?0:value+add;return{min:keepZero(min,-Math.abs(change)),max:keepZero(max,change)};} function createContext(parentContext,context){return Object.assign(Object.create(parentContext),context);} const getRightToLeftAdapter=function(rectX,width){return{x(x){return rectX+rectX+width-x;},setWidth(w){width=w;},textAlign(align){if(align==='center'){return align;} return align==='right'?'left':'right';},xPlus(x,value){return x-value;},leftForLtr(x,itemWidth){return x-itemWidth;}};};const getLeftToRightAdapter=function(){return{x(x){return x;},setWidth(w){},textAlign(align){return align;},xPlus(x,value){return x+value;},leftForLtr(x,_itemWidth){return x;}};};function getRtlAdapter(rtl,rectX,width){return rtl?getRightToLeftAdapter(rectX,width):getLeftToRightAdapter();} function overrideTextDirection(ctx,direction){let style,original;if(direction==='ltr'||direction==='rtl'){style=ctx.canvas.style;original=[style.getPropertyValue('direction'),style.getPropertyPriority('direction')];style.setProperty('direction',direction,'important');ctx.prevTextDirection=original;}} function restoreTextDirection(ctx,original){if(original!==undefined){delete ctx.prevTextDirection;ctx.canvas.style.setProperty('direction',original[0],original[1]);}} function propertyFn(property){if(property==='angle'){return{between:_angleBetween,compare:_angleDiff,normalize:_normalizeAngle};} return{between:_isBetween,compare:(a,b)=>a-b,normalize:(x)=>x};} function normalizeSegment({start,end,count,loop,style}){return{start:start%count,end:end%count,loop:loop&&(end-start+1)%count===0,style};} function getSegment(segment,points,bounds){const{property,start:startBound,end:endBound}=bounds;const{between,normalize}=propertyFn(property);const count=points.length;let{start,end,loop}=segment;let i,ilen;if(loop){start+=count;end+=count;for(i=0,ilen=count;ibetween(startBound,prevValue,value)&&compare(startBound,prevValue)!==0;const endIsBefore=()=>compare(endBound,value)===0||between(endBound,prevValue,value);const shouldStart=()=>inside||startIsBefore();const shouldStop=()=>!inside||endIsBefore();for(let i=start,prev=start;i<=end;++i){point=points[i%count];if(point.skip){continue;} value=normalize(point[property]);if(value===prevValue){continue;} inside=between(value,startBound,endBound);if(subStart===null&&shouldStart()){subStart=compare(value,startBound)===0?i:prev;} if(subStart!==null&&shouldStop()){result.push(normalizeSegment({start:subStart,end:i,loop,count,style}));subStart=null;} prev=i;prevValue=value;} if(subStart!==null){result.push(normalizeSegment({start:subStart,end,loop,count,style}));} return result;} function _boundSegments(line,bounds){const result=[];const segments=line.segments;for(let i=0;istart&&points[end%count].skip){end--;} end%=count;return{start,end};} function solidSegments(points,start,max,loop){const count=points.length;const result=[];let last=start;let prev=points[start];let end;for(end=start+1;end<=max;++end){const cur=points[end%count];if(cur.skip||cur.stop){if(!prev.skip){loop=false;result.push({start:start%count,end:(end-1)%count,loop});start=last=cur.stop?end:null;}}else{last=end;if(prev.skip){start=end;}} prev=cur;} if(last!==null){result.push({start:start%count,end:last%count,loop});} return result;} function _computeSegments(line,segmentOptions){const points=line.points;const spanGaps=line.options.spanGaps;const count=points.length;if(!count){return[];} const loop=!!line._loop;const{start,end}=findStartAndEnd(points,count,loop,spanGaps);if(spanGaps===true){return splitByStyles(line,[{start,end,loop}],points,segmentOptions);} const max=end{if(element[rangeMethod]&&element[rangeMethod](position[axis],useFinalPosition)){items.push({element,datasetIndex,index});intersectsItem=intersectsItem||element.inRange(position.x,position.y,useFinalPosition);}});if(intersect&&!intersectsItem){return[];} return items;} var Interaction={evaluateInteractionItems,modes:{index(chart,e,options,useFinalPosition){const position=getRelativePosition(e,chart);const axis=options.axis||'x';const includeInvisible=options.includeInvisible||false;const items=options.intersect?getIntersectItems(chart,position,axis,useFinalPosition,includeInvisible):getNearestItems(chart,position,axis,false,useFinalPosition,includeInvisible);const elements=[];if(!items.length){return[];} chart.getSortedVisibleDatasetMetas().forEach((meta)=>{const index=items[0].index;const element=meta.data[index];if(element&&!element.skip){elements.push({element,datasetIndex:meta.index,index});}});return elements;},dataset(chart,e,options,useFinalPosition){const position=getRelativePosition(e,chart);const axis=options.axis||'xy';const includeInvisible=options.includeInvisible||false;let items=options.intersect?getIntersectItems(chart,position,axis,useFinalPosition,includeInvisible):getNearestItems(chart,position,axis,false,useFinalPosition,includeInvisible);if(items.length>0){const datasetIndex=items[0].datasetIndex;const data=chart.getDatasetMeta(datasetIndex).data;items=[];for(let i=0;iv.pos===position);} function filterDynamicPositionByAxis(array,axis){return array.filter((v)=>STATIC_POSITIONS.indexOf(v.pos)===-1&&v.box.axis===axis);} function sortByWeight(array,reverse){return array.sort((a,b)=>{const v0=reverse?b:a;const v1=reverse?a:b;return v0.weight===v1.weight?v0.index-v1.index:v0.weight-v1.weight;});} function wrapBoxes(boxes){const layoutBoxes=[];let i,ilen,box,pos,stack,stackWeight;for(i=0,ilen=(boxes||[]).length;iwrap.box.fullSize),true);const left=sortByWeight(filterByPosition(layoutBoxes,'left'),true);const right=sortByWeight(filterByPosition(layoutBoxes,'right'));const top=sortByWeight(filterByPosition(layoutBoxes,'top'),true);const bottom=sortByWeight(filterByPosition(layoutBoxes,'bottom'));const centerHorizontal=filterDynamicPositionByAxis(layoutBoxes,'x');const centerVertical=filterDynamicPositionByAxis(layoutBoxes,'y');return{fullSize,leftAndTop:left.concat(top),rightAndBottom:right.concat(centerVertical).concat(bottom).concat(centerHorizontal),chartArea:filterByPosition(layoutBoxes,'chartArea'),vertical:left.concat(right).concat(centerVertical),horizontal:top.concat(bottom).concat(centerHorizontal)};} function getCombinedMax(maxPadding,chartArea,a,b){return Math.max(maxPadding[a],chartArea[a])+Math.max(maxPadding[b],chartArea[b]);} function updateMaxPadding(maxPadding,boxPadding){maxPadding.top=Math.max(maxPadding.top,boxPadding.top);maxPadding.left=Math.max(maxPadding.left,boxPadding.left);maxPadding.bottom=Math.max(maxPadding.bottom,boxPadding.bottom);maxPadding.right=Math.max(maxPadding.right,boxPadding.right);} function updateDims(chartArea,params,layout,stacks){const{pos,box}=layout;const maxPadding=chartArea.maxPadding;if(!isObject(pos)){if(layout.size){chartArea[pos]-=layout.size;} const stack=stacks[layout.stack]||{size:0,count:1};stack.size=Math.max(stack.size,layout.horizontal?box.height:box.width);layout.size=stack.size/stack.count;chartArea[pos]+=layout.size;} if(box.getPadding){updateMaxPadding(maxPadding,box.getPadding());} const newWidth=Math.max(0,params.outerWidth-getCombinedMax(maxPadding,chartArea,'left','right'));const newHeight=Math.max(0,params.outerHeight-getCombinedMax(maxPadding,chartArea,'top','bottom'));const widthChanged=newWidth!==chartArea.w;const heightChanged=newHeight!==chartArea.h;chartArea.w=newWidth;chartArea.h=newHeight;return layout.horizontal?{same:widthChanged,other:heightChanged}:{same:heightChanged,other:widthChanged};} function handleMaxPadding(chartArea){const maxPadding=chartArea.maxPadding;function updatePos(pos){const change=Math.max(maxPadding[pos]-chartArea[pos],0);chartArea[pos]+=change;return change;} chartArea.y+=updatePos('top');chartArea.x+=updatePos('left');updatePos('right');updatePos('bottom');} function getMargins(horizontal,chartArea){const maxPadding=chartArea.maxPadding;function marginForPositions(positions){const margin={left:0,top:0,right:0,bottom:0};positions.forEach((pos)=>{margin[pos]=Math.max(chartArea[pos],maxPadding[pos]);});return margin;} return horizontal?marginForPositions(['left','right']):marginForPositions(['top','bottom']);} function fitBoxes(boxes,chartArea,params,stacks){const refitBoxes=[];let i,ilen,layout,box,refit,changed;for(i=0,ilen=boxes.length,refit=0;i{if(typeof box.beforeLayout==='function'){box.beforeLayout();}});const visibleVerticalBoxCount=verticalBoxes.reduce((total,wrap)=>wrap.box.options&&wrap.box.options.display===false?total:total+1,0)||1;const params=Object.freeze({outerWidth:width,outerHeight:height,padding,availableWidth,availableHeight,vBoxMaxWidth:availableWidth/2/visibleVerticalBoxCount,hBoxMaxHeight:availableHeight/2});const maxPadding=Object.assign({},padding);updateMaxPadding(maxPadding,toPadding(minPadding));const chartArea=Object.assign({maxPadding,w:availableWidth,h:availableHeight,x:padding.left,y:padding.top},padding);const stacks=setLayoutDims(verticalBoxes.concat(horizontalBoxes),params);fitBoxes(boxes.fullSize,chartArea,params,stacks);fitBoxes(verticalBoxes,chartArea,params,stacks);if(fitBoxes(horizontalBoxes,chartArea,params,stacks)){fitBoxes(verticalBoxes,chartArea,params,stacks);} handleMaxPadding(chartArea);placeBoxes(boxes.leftAndTop,chartArea,params,stacks);chartArea.x+=chartArea.w;chartArea.y+=chartArea.h;placeBoxes(boxes.rightAndBottom,chartArea,params,stacks);chart.chartArea={left:chartArea.left,top:chartArea.top,right:chartArea.left+chartArea.w,bottom:chartArea.top+chartArea.h,height:chartArea.h,width:chartArea.w};each(boxes.chartArea,(layout)=>{const box=layout.box;Object.assign(box,chart.chartArea);box.update(chartArea.w,chartArea.h,{left:0,top:0,right:0,bottom:0});});}};class BasePlatform{acquireContext(canvas,aspectRatio){} releaseContext(context){return false;} addEventListener(chart,type,listener){} removeEventListener(chart,type,listener){} getDevicePixelRatio(){return 1;} getMaximumSize(element,width,height,aspectRatio){width=Math.max(0,width||element.width);height=height||element.height;return{width,height:Math.max(0,aspectRatio?Math.floor(width/aspectRatio):height)};} isAttached(canvas){return true;} updateConfig(config){}} class BasicPlatform extends BasePlatform{acquireContext(item){return item&&item.getContext&&item.getContext('2d')||null;} updateConfig(config){config.options.animation=false;}} const EXPANDO_KEY='$chartjs';const EVENT_TYPES={touchstart:'mousedown',touchmove:'mousemove',touchend:'mouseup',pointerenter:'mouseenter',pointerdown:'mousedown',pointermove:'mousemove',pointerup:'mouseup',pointerleave:'mouseout',pointerout:'mouseout'};const isNullOrEmpty=(value)=>value===null||value==='';function initCanvas(canvas,aspectRatio){const style=canvas.style;const renderHeight=canvas.getAttribute('height');const renderWidth=canvas.getAttribute('width');canvas[EXPANDO_KEY]={initial:{height:renderHeight,width:renderWidth,style:{display:style.display,height:style.height,width:style.width}}};style.display=style.display||'block';style.boxSizing=style.boxSizing||'border-box';if(isNullOrEmpty(renderWidth)){const displayWidth=readUsedSize(canvas,'width');if(displayWidth!==undefined){canvas.width=displayWidth;}} if(isNullOrEmpty(renderHeight)){if(canvas.style.height===''){canvas.height=canvas.width/(aspectRatio||2);}else{const displayHeight=readUsedSize(canvas,'height');if(displayHeight!==undefined){canvas.height=displayHeight;}}} return canvas;} const eventListenerOptions=supportsEventListenerOptions?{passive:true}:false;function addListener(node,type,listener){if(node){node.addEventListener(type,listener,eventListenerOptions);}} function removeListener(chart,type,listener){if(chart&&chart.canvas){chart.canvas.removeEventListener(type,listener,eventListenerOptions);}} function fromNativeEvent(event,chart){const type=EVENT_TYPES[event.type]||event.type;const{x,y}=getRelativePosition(event,chart);return{type,chart,native:event,x:x!==undefined?x:null,y:y!==undefined?y:null};} function nodeListContains(nodeList,canvas){for(const node of nodeList){if(node===canvas||node.contains(canvas)){return true;}}} function createAttachObserver(chart,type,listener){const canvas=chart.canvas;const observer=new MutationObserver((entries)=>{let trigger=false;for(const entry of entries){trigger=trigger||nodeListContains(entry.addedNodes,canvas);trigger=trigger&&!nodeListContains(entry.removedNodes,canvas);} if(trigger){listener();}});observer.observe(document,{childList:true,subtree:true});return observer;} function createDetachObserver(chart,type,listener){const canvas=chart.canvas;const observer=new MutationObserver((entries)=>{let trigger=false;for(const entry of entries){trigger=trigger||nodeListContains(entry.removedNodes,canvas);trigger=trigger&&!nodeListContains(entry.addedNodes,canvas);} if(trigger){listener();}});observer.observe(document,{childList:true,subtree:true});return observer;} const drpListeningCharts=new Map();let oldDevicePixelRatio=0;function onWindowResize(){const dpr=window.devicePixelRatio;if(dpr===oldDevicePixelRatio){return;} oldDevicePixelRatio=dpr;drpListeningCharts.forEach((resize,chart)=>{if(chart.currentDevicePixelRatio!==dpr){resize();}});} function listenDevicePixelRatioChanges(chart,resize){if(!drpListeningCharts.size){window.addEventListener('resize',onWindowResize);} drpListeningCharts.set(chart,resize);} function unlistenDevicePixelRatioChanges(chart){drpListeningCharts.delete(chart);if(!drpListeningCharts.size){window.removeEventListener('resize',onWindowResize);}} function createResizeObserver(chart,type,listener){const canvas=chart.canvas;const container=canvas&&_getParentNode(canvas);if(!container){return;} const resize=throttled((width,height)=>{const w=container.clientWidth;listener(width,height);if(w{const entry=entries[0];const width=entry.contentRect.width;const height=entry.contentRect.height;if(width===0&&height===0){return;} resize(width,height);});observer.observe(container);listenDevicePixelRatioChanges(chart,resize);return observer;} function releaseObserver(chart,type,observer){if(observer){observer.disconnect();} if(type==='resize'){unlistenDevicePixelRatioChanges(chart);}} function createProxyAndListen(chart,type,listener){const canvas=chart.canvas;const proxy=throttled((event)=>{if(chart.ctx!==null){listener(fromNativeEvent(event,chart));}},chart);addListener(canvas,type,proxy);return proxy;} class DomPlatform extends BasePlatform{acquireContext(canvas,aspectRatio){const context=canvas&&canvas.getContext&&canvas.getContext('2d');if(context&&context.canvas===canvas){initCanvas(canvas,aspectRatio);return context;} return null;} releaseContext(context){const canvas=context.canvas;if(!canvas[EXPANDO_KEY]){return false;} const initial=canvas[EXPANDO_KEY].initial;['height','width'].forEach((prop)=>{const value=initial[prop];if(isNullOrUndef(value)){canvas.removeAttribute(prop);}else{canvas.setAttribute(prop,value);}});const style=initial.style||{};Object.keys(style).forEach((key)=>{canvas.style[key]=style[key];});canvas.width=canvas.width;delete canvas[EXPANDO_KEY];return true;} addEventListener(chart,type,listener){this.removeEventListener(chart,type);const proxies=chart.$proxies||(chart.$proxies={});const handlers={attach:createAttachObserver,detach:createDetachObserver,resize:createResizeObserver};const handler=handlers[type]||createProxyAndListen;proxies[type]=handler(chart,type,listener);} removeEventListener(chart,type){const proxies=chart.$proxies||(chart.$proxies={});const proxy=proxies[type];if(!proxy){return;} const handlers={attach:releaseObserver,detach:releaseObserver,resize:releaseObserver};const handler=handlers[type]||removeListener;handler(chart,type,proxy);proxies[type]=undefined;} getDevicePixelRatio(){return window.devicePixelRatio;} getMaximumSize(canvas,width,height,aspectRatio){return getMaximumSize(canvas,width,height,aspectRatio);} isAttached(canvas){const container=canvas&&_getParentNode(canvas);return!!(container&&container.isConnected);}} function _detectPlatform(canvas){if(!_isDomSupported()||typeof OffscreenCanvas!=='undefined'&&canvas instanceof OffscreenCanvas){return BasicPlatform;} return DomPlatform;} var platforms=Object.freeze({__proto__:null,BasePlatform:BasePlatform,BasicPlatform:BasicPlatform,DomPlatform:DomPlatform,_detectPlatform:_detectPlatform});const transparent='transparent';const interpolators={boolean(from,to,factor){return factor>0.5?to:from;},color(from,to,factor){const c0=color(from||transparent);const c1=c0.valid&&color(to||transparent);return c1&&c1.valid?c1.mix(c0,factor).hexString():to;},number(from,to,factor){return from+(to-from)*factor;}};class Animation{constructor(cfg,target,prop,to){const currentValue=target[prop];to=resolve([cfg.to,to,currentValue,cfg.from]);const from=resolve([cfg.from,currentValue,to]);this._active=true;this._fn=cfg.fn||interpolators[cfg.type||typeof from];this._easing=effects[cfg.easing]||effects.linear;this._start=Math.floor(Date.now()+(cfg.delay||0));this._duration=this._total=Math.floor(cfg.duration);this._loop=!!cfg.loop;this._target=target;this._prop=prop;this._from=from;this._to=to;this._promises=undefined;} active(){return this._active;} update(cfg,to,date){if(this._active){this._notify(false);const currentValue=this._target[this._prop];const elapsed=date-this._start;const remain=this._duration-elapsed;this._start=date;this._duration=Math.floor(Math.max(remain,cfg.duration));this._total+=elapsed;this._loop=!!cfg.loop;this._to=resolve([cfg.to,to,currentValue,cfg.from]);this._from=resolve([cfg.from,currentValue,to]);}} cancel(){if(this._active){this.tick(Date.now());this._active=false;this._notify(false);}} tick(date){const elapsed=date-this._start;const duration=this._duration;const prop=this._prop;const from=this._from;const loop=this._loop;const to=this._to;let factor;this._active=from!==to&&(loop||elapsed1?2-factor:factor;factor=this._easing(Math.min(1,Math.max(0,factor)));this._target[prop]=this._fn(from,to,factor);} wait(){const promises=this._promises||(this._promises=[]);return new Promise((res,rej)=>{promises.push({res,rej});});} _notify(resolved){const method=resolved?'res':'rej';const promises=this._promises||[];for(let i=0;i{const cfg=config[key];if(!isObject(cfg)){return;} const resolved={};for(const option of animationOptions){resolved[option]=cfg[option];} (isArray(cfg.properties)&&cfg.properties||[key]).forEach((prop)=>{if(prop===key||!animatedProps.has(prop)){animatedProps.set(prop,resolved);}});});} _animateOptions(target,values){const newOptions=values.options;const options=resolveTargetOptions(target,newOptions);if(!options){return[];} const animations=this._createAnimations(options,newOptions);if(newOptions.$shared){awaitAll(target.options.$animations,newOptions).then(()=>{target.options=newOptions;},()=>{});} return animations;} _createAnimations(target,values){const animatedProps=this._properties;const animations=[];const running=target.$animations||(target.$animations={});const props=Object.keys(values);const date=Date.now();let i;for(i=props.length-1;i>=0;--i){const prop=props[i];if(prop.charAt(0)==='$'){continue;} if(prop==='options'){animations.push(...this._animateOptions(target,values));continue;} const value=values[prop];let animation=running[prop];const cfg=animatedProps.get(prop);if(animation){if(cfg&&animation.active()){animation.update(cfg,value,date);continue;}else{animation.cancel();}} if(!cfg||!cfg.duration){target[prop]=value;continue;} running[prop]=animation=new Animation(cfg,target,prop,value);animations.push(animation);} return animations;} update(target,values){if(this._properties.size===0){Object.assign(target,values);return;} const animations=this._createAnimations(target,values);if(animations.length){animator.add(this._chart,animations);return true;}}} function awaitAll(animations,properties){const running=[];const keys=Object.keys(properties);for(let i=0;i0||!positive&&value<0){return meta.index;}} return null;} function updateStacks(controller,parsed){const{chart,_cachedMeta:meta}=controller;const stacks=chart._stacks||(chart._stacks={});const{iScale,vScale,index:datasetIndex}=meta;const iAxis=iScale.axis;const vAxis=vScale.axis;const key=getStackKey(iScale,vScale,meta);const ilen=parsed.length;let stack;for(let i=0;iscales[key].axis===axis).shift();} function createDatasetContext(parent,index){return createContext(parent,{active:false,dataset:undefined,datasetIndex:index,index,mode:'default',type:'dataset'});} function createDataContext(parent,index,element){return createContext(parent,{active:false,dataIndex:index,parsed:undefined,raw:undefined,element,index,mode:'default',type:'data'});} function clearStacks(meta,items){const datasetIndex=meta.controller.index;const axis=meta.vScale&&meta.vScale.axis;if(!axis){return;} items=items||meta._parsed;for(const parsed of items){const stacks=parsed._stacks;if(!stacks||stacks[axis]===undefined||stacks[axis][datasetIndex]===undefined){return;} delete stacks[axis][datasetIndex];if(stacks[axis]._visualValues!==undefined&&stacks[axis]._visualValues[datasetIndex]!==undefined){delete stacks[axis]._visualValues[datasetIndex];}}} const isDirectUpdateMode=(mode)=>mode==='reset'||mode==='none';const cloneIfNotShared=(cached,shared)=>shared?cached:Object.assign({},cached);const createStack=(canStack,meta,chart)=>canStack&&!meta.hidden&&meta._stacked&&{keys:getSortedDatasetIndices(chart,true),values:null};class DatasetController{static defaults={};static datasetElementType=null;static dataElementType=null;constructor(chart,datasetIndex){this.chart=chart;this._ctx=chart.ctx;this.index=datasetIndex;this._cachedDataOpts={};this._cachedMeta=this.getMeta();this._type=this._cachedMeta.type;this.options=undefined;this._parsing=false;this._data=undefined;this._objectData=undefined;this._sharedOptions=undefined;this._drawStart=undefined;this._drawCount=undefined;this.enableOptionSharing=false;this.supportsDecimation=false;this.$context=undefined;this._syncList=[];this.datasetElementType=new.target.datasetElementType;this.dataElementType=new.target.dataElementType;this.initialize();} initialize(){const meta=this._cachedMeta;this.configure();this.linkScales();meta._stacked=isStacked(meta.vScale,meta);this.addElements();if(this.options.fill&&!this.chart.isPluginEnabled('filler')){console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options");}} updateIndex(datasetIndex){if(this.index!==datasetIndex){clearStacks(this._cachedMeta);} this.index=datasetIndex;} linkScales(){const chart=this.chart;const meta=this._cachedMeta;const dataset=this.getDataset();const chooseId=(axis,x,y,r)=>axis==='x'?x:axis==='r'?r:y;const xid=meta.xAxisID=valueOrDefault(dataset.xAxisID,getFirstScaleId(chart,'x'));const yid=meta.yAxisID=valueOrDefault(dataset.yAxisID,getFirstScaleId(chart,'y'));const rid=meta.rAxisID=valueOrDefault(dataset.rAxisID,getFirstScaleId(chart,'r'));const indexAxis=meta.indexAxis;const iid=meta.iAxisID=chooseId(indexAxis,xid,yid,rid);const vid=meta.vAxisID=chooseId(indexAxis,yid,xid,rid);meta.xScale=this.getScaleForId(xid);meta.yScale=this.getScaleForId(yid);meta.rScale=this.getScaleForId(rid);meta.iScale=this.getScaleForId(iid);meta.vScale=this.getScaleForId(vid);} getDataset(){return this.chart.data.datasets[this.index];} getMeta(){return this.chart.getDatasetMeta(this.index);} getScaleForId(scaleID){return this.chart.scales[scaleID];} _getOtherScale(scale){const meta=this._cachedMeta;return scale===meta.iScale?meta.vScale:meta.iScale;} reset(){this._update('reset');} _destroy(){const meta=this._cachedMeta;if(this._data){unlistenArrayEvents(this._data,this);} if(meta._stacked){clearStacks(meta);}} _dataCheck(){const dataset=this.getDataset();const data=dataset.data||(dataset.data=[]);const _data=this._data;if(isObject(data)){const meta=this._cachedMeta;this._data=convertObjectDataToArray(data,meta);}else if(_data!==data){if(_data){unlistenArrayEvents(_data,this);const meta=this._cachedMeta;clearStacks(meta);meta._parsed=[];} if(data&&Object.isExtensible(data)){listenArrayEvents(data,this);} this._syncList=[];this._data=data;}} addElements(){const meta=this._cachedMeta;this._dataCheck();if(this.datasetElementType){meta.dataset=new this.datasetElementType();}} buildOrUpdateElements(resetNewElements){const meta=this._cachedMeta;const dataset=this.getDataset();let stackChanged=false;this._dataCheck();const oldStacked=meta._stacked;meta._stacked=isStacked(meta.vScale,meta);if(meta.stack!==dataset.stack){stackChanged=true;clearStacks(meta);meta.stack=dataset.stack;} this._resyncElements(resetNewElements);if(stackChanged||oldStacked!==meta._stacked){updateStacks(this,meta._parsed);meta._stacked=isStacked(meta.vScale,meta);}} configure(){const config=this.chart.config;const scopeKeys=config.datasetScopeKeys(this._type);const scopes=config.getOptionScopes(this.getDataset(),scopeKeys,true);this.options=config.createResolver(scopes,this.getContext());this._parsing=this.options.parsing;this._cachedDataOpts={};} parse(start,count){const{_cachedMeta:meta,_data:data}=this;const{iScale,_stacked}=meta;const iAxis=iScale.axis;let sorted=start===0&&count===data.length?true:meta._sorted;let prev=start>0&&meta._parsed[start-1];let i,cur,parsed;if(this._parsing===false){meta._parsed=data;meta._sorted=true;parsed=data;}else{if(isArray(data[start])){parsed=this.parseArrayData(meta,data,start,count);}else if(isObject(data[start])){parsed=this.parseObjectData(meta,data,start,count);}else{parsed=this.parsePrimitiveData(meta,data,start,count);} const isNotInOrderComparedToPrev=()=>cur[iAxis]===null||prev&&cur[iAxis]otherValue||otherMax=0;--i){if(_skip()){continue;} this.updateRangeFromParsed(range,scale,parsed,stack);break;}} return range;} getAllParsedValues(scale){const parsed=this._cachedMeta._parsed;const values=[];let i,ilen,value;for(i=0,ilen=parsed.length;i=0&&indexthis.getContext(index,active,mode);const values=config.resolveNamedOptions(scopes,names,context,prefixes);if(values.$shared){values.$shared=sharing;cache[cacheKey]=Object.freeze(cloneIfNotShared(values,sharing));} return values;} _resolveAnimations(index,transition,active){const chart=this.chart;const cache=this._cachedDataOpts;const cacheKey=`animation-${transition}`;const cached=cache[cacheKey];if(cached){return cached;} let options;if(chart.options.animation!==false){const config=this.chart.config;const scopeKeys=config.datasetAnimationScopeKeys(this._type,transition);const scopes=config.getOptionScopes(this.getDataset(),scopeKeys);options=config.createResolver(scopes,this.getContext(index,active,transition));} const animations=new Animations(chart,options&&options.animations);if(options&&options._cacheable){cache[cacheKey]=Object.freeze(animations);} return animations;} getSharedOptions(options){if(!options.$shared){return;} return this._sharedOptions||(this._sharedOptions=Object.assign({},options));} includeOptions(mode,sharedOptions){return!sharedOptions||isDirectUpdateMode(mode)||this.chart._animationsDisabled;} _getSharedOptions(start,mode){const firstOpts=this.resolveDataElementOptions(start,mode);const previouslySharedOptions=this._sharedOptions;const sharedOptions=this.getSharedOptions(firstOpts);const includeOptions=this.includeOptions(mode,sharedOptions)||sharedOptions!==previouslySharedOptions;this.updateSharedOptions(sharedOptions,mode,firstOpts);return{sharedOptions,includeOptions};} updateElement(element,index,properties,mode){if(isDirectUpdateMode(mode)){Object.assign(element,properties);}else{this._resolveAnimations(index,mode).update(element,properties);}} updateSharedOptions(sharedOptions,mode,newOptions){if(sharedOptions&&!isDirectUpdateMode(mode)){this._resolveAnimations(undefined,mode).update(sharedOptions,newOptions);}} _setStyle(element,index,mode,active){element.active=active;const options=this.getStyle(index,active);this._resolveAnimations(index,mode,active).update(element,{options:!active&&this.getSharedOptions(options)||options});} removeHoverStyle(element,datasetIndex,index){this._setStyle(element,index,'active',false);} setHoverStyle(element,datasetIndex,index){this._setStyle(element,index,'active',true);} _removeDatasetHoverStyle(){const element=this._cachedMeta.dataset;if(element){this._setStyle(element,undefined,'active',false);}} _setDatasetHoverStyle(){const element=this._cachedMeta.dataset;if(element){this._setStyle(element,undefined,'active',true);}} _resyncElements(resetNewElements){const data=this._data;const elements=this._cachedMeta.data;for(const[method,arg1,arg2]of this._syncList){this[method](arg1,arg2);} this._syncList=[];const numMeta=elements.length;const numData=data.length;const count=Math.min(numData,numMeta);if(count){this.parse(0,count);} if(numData>numMeta){this._insertElements(numMeta,numData-numMeta,resetNewElements);}else if(numData{arr.length+=count;for(i=arr.length-1;i>=end;i--){arr[i]=arr[i-count];}};move(data);for(i=start;i{ret[prop]=anims[prop]&&anims[prop].active()?anims[prop]._to:this[prop];});return ret;}} function autoSkip(scale,ticks){const tickOpts=scale.options.ticks;const determinedMaxTicks=determineMaxTicks(scale);const ticksLimit=Math.min(tickOpts.maxTicksLimit||determinedMaxTicks,determinedMaxTicks);const majorIndices=tickOpts.major.enabled?getMajorIndices(ticks):[];const numMajorIndices=majorIndices.length;const first=majorIndices[0];const last=majorIndices[numMajorIndices-1];const newTicks=[];if(numMajorIndices>ticksLimit){skipMajors(ticks,newTicks,majorIndices,numMajorIndices/ticksLimit);return newTicks;} const spacing=calculateSpacing(majorIndices,ticks,ticksLimit);if(numMajorIndices>0){let i,ilen;const avgMajorSpacing=numMajorIndices>1?Math.round((last-first)/(numMajorIndices-1)):null;skip(ticks,newTicks,spacing,isNullOrUndef(avgMajorSpacing)?0:first-avgMajorSpacing,first);for(i=0,ilen=numMajorIndices-1;ispacing){return factor;}} return Math.max(spacing,1);} function getMajorIndices(ticks){const result=[];let i,ilen;for(i=0,ilen=ticks.length;ialign==='left'?'right':align==='right'?'left':align;const offsetFromEdge=(scale,edge,offset)=>edge==='top'||edge==='left'?scale[edge]+offset:scale[edge]-offset;const getTicksLimit=(ticksLength,maxTicksLimit)=>Math.min(maxTicksLimit||ticksLength,ticksLength);function sample(arr,numItems){const result=[];const increment=arr.length/numItems;const len=arr.length;let i=0;for(;iend+epsilon){return;}} return lineValue;} function garbageCollect(caches,length){each(caches,(cache)=>{const gc=cache.gc;const gcLen=gc.length/2;let i;if(gcLen>length){for(i=0;imax?max:min;max=minDefined&&min>max?min:max;return{min:finiteOrDefault(min,finiteOrDefault(max,min)),max:finiteOrDefault(max,finiteOrDefault(min,max))};} getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0};} getTicks(){return this.ticks;} getLabels(){const data=this.chart.data;return this.options.labels||(this.isHorizontal()?data.xLabels:data.yLabels)||data.labels||[];} getLabelItems(chartArea=this.chart.chartArea){const items=this._labelItems||(this._labelItems=this._computeLabelItems(chartArea));return items;} beforeLayout(){this._cache={};this._dataLimitsCached=false;} beforeUpdate(){callback(this.options.beforeUpdate,[this]);} update(maxWidth,maxHeight,margins){const{beginAtZero,grace,ticks:tickOpts}=this.options;const sampleSize=tickOpts.sampleSize;this.beforeUpdate();this.maxWidth=maxWidth;this.maxHeight=maxHeight;this._margins=margins=Object.assign({left:0,right:0,top:0,bottom:0},margins);this.ticks=null;this._labelSizes=null;this._gridLineItems=null;this._labelItems=null;this.beforeSetDimensions();this.setDimensions();this.afterSetDimensions();this._maxLength=this.isHorizontal()?this.width+margins.left+margins.right:this.height+margins.top+margins.bottom;if(!this._dataLimitsCached){this.beforeDataLimits();this.determineDataLimits();this.afterDataLimits();this._range=_addGrace(this,grace,beginAtZero);this._dataLimitsCached=true;} this.beforeBuildTicks();this.ticks=this.buildTicks()||[];this.afterBuildTicks();const samplingEnabled=sampleSize=maxRotation||numTicks<=1||!this.isHorizontal()){this.labelRotation=minRotation;return;} const labelSizes=this._getLabelSizes();const maxLabelWidth=labelSizes.widest.width;const maxLabelHeight=labelSizes.highest.height;const maxWidth=_limitValue(this.chart.width-maxLabelWidth,0,this.maxWidth);tickWidth=options.offset?this.maxWidth/numTicks:maxWidth/(numTicks-1);if(maxLabelWidth+6>tickWidth){tickWidth=maxWidth/(numTicks-(options.offset?0.5:1));maxHeight=this.maxHeight-getTickMarkLength(options.grid)-tickOpts.padding-getTitleHeight(options.title,this.chart.options.font);maxLabelDiagonal=Math.sqrt(maxLabelWidth*maxLabelWidth+maxLabelHeight*maxLabelHeight);labelRotation=toDegrees(Math.min(Math.asin(_limitValue((labelSizes.highest.height+6)/tickWidth,-1,1)),Math.asin(_limitValue(maxHeight/maxLabelDiagonal,-1,1))-Math.asin(_limitValue(maxLabelHeight/maxLabelDiagonal,-1,1))));labelRotation=Math.max(minRotation,Math.min(maxRotation,labelRotation));} this.labelRotation=labelRotation;} afterCalculateLabelRotation(){callback(this.options.afterCalculateLabelRotation,[this]);} afterAutoSkip(){} beforeFit(){callback(this.options.beforeFit,[this]);} fit(){const minSize={width:0,height:0};const{chart,options:{ticks:tickOpts,title:titleOpts,grid:gridOpts}}=this;const display=this._isVisible();const isHorizontal=this.isHorizontal();if(display){const titleHeight=getTitleHeight(titleOpts,chart.options.font);if(isHorizontal){minSize.width=this.maxWidth;minSize.height=getTickMarkLength(gridOpts)+titleHeight;}else{minSize.height=this.maxHeight;minSize.width=getTickMarkLength(gridOpts)+titleHeight;} if(tickOpts.display&&this.ticks.length){const{first,last,widest,highest}=this._getLabelSizes();const tickPadding=tickOpts.padding*2;const angleRadians=toRadians(this.labelRotation);const cos=Math.cos(angleRadians);const sin=Math.sin(angleRadians);if(isHorizontal){const labelHeight=tickOpts.mirror?0:sin*widest.width+cos*highest.height;minSize.height=Math.min(this.maxHeight,minSize.height+labelHeight+tickPadding);}else{const labelWidth=tickOpts.mirror?0:cos*widest.width+sin*highest.height;minSize.width=Math.min(this.maxWidth,minSize.width+labelWidth+tickPadding);} this._calculatePadding(first,last,sin,cos);}} this._handleMargins();if(isHorizontal){this.width=this._length=chart.width-this._margins.left-this._margins.right;this.height=minSize.height;}else{this.width=minSize.width;this.height=this._length=chart.height-this._margins.top-this._margins.bottom;}} _calculatePadding(first,last,sin,cos){const{ticks:{align,padding},position}=this.options;const isRotated=this.labelRotation!==0;const labelsBelowTicks=position!=='top'&&this.axis==='x';if(this.isHorizontal()){const offsetLeft=this.getPixelForTick(0)-this.left;const offsetRight=this.right-this.getPixelForTick(this.ticks.length-1);let paddingLeft=0;let paddingRight=0;if(isRotated){if(labelsBelowTicks){paddingLeft=cos*first.width;paddingRight=sin*last.height;}else{paddingLeft=sin*first.height;paddingRight=cos*last.width;}}else if(align==='start'){paddingRight=last.width;}else if(align==='end'){paddingLeft=first.width;}else if(align!=='inner'){paddingLeft=first.width/2;paddingRight=last.width/2;} this.paddingLeft=Math.max((paddingLeft-offsetLeft+padding)*this.width/(this.width-offsetLeft),0);this.paddingRight=Math.max((paddingRight-offsetRight+padding)*this.width/(this.width-offsetRight),0);}else{let paddingTop=last.height/2;let paddingBottom=first.height/2;if(align==='start'){paddingTop=0;paddingBottom=first.height;}else if(align==='end'){paddingTop=last.height;paddingBottom=0;} this.paddingTop=paddingTop+padding;this.paddingBottom=paddingBottom+padding;}} _handleMargins(){if(this._margins){this._margins.left=Math.max(this.paddingLeft,this._margins.left);this._margins.top=Math.max(this.paddingTop,this._margins.top);this._margins.right=Math.max(this.paddingRight,this._margins.right);this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom);}} afterFit(){callback(this.options.afterFit,[this]);} isHorizontal(){const{axis,position}=this.options;return position==='top'||position==='bottom'||axis==='x';} isFullSize(){return this.options.fullSize;} _convertTicksToLabels(ticks){this.beforeTickToLabelConversion();this.generateTickLabels(ticks);let i,ilen;for(i=0,ilen=ticks.length;i({width:widths[idx]||0,height:heights[idx]||0});return{first:valueAt(0),last:valueAt(length-1),widest:valueAt(widest),highest:valueAt(highest),widths,heights};} getLabelForValue(value){return value;} getPixelForValue(value,index){return NaN;} getValueForPixel(pixel){} getPixelForTick(index){const ticks=this.ticks;if(index<0||index>ticks.length-1){return null;} return this.getPixelForValue(ticks[index].value);} getPixelForDecimal(decimal){if(this._reversePixels){decimal=1-decimal;} const pixel=this._startPixel+decimal*this._length;return _int16Range(this._alignToPixels?_alignPixel(this.chart,pixel,0):pixel);} getDecimalForPixel(pixel){const decimal=(pixel-this._startPixel)/this._length;return this._reversePixels?1-decimal:decimal;} getBasePixel(){return this.getPixelForValue(this.getBaseValue());} getBaseValue(){const{min,max}=this;return min<0&&max<0?max:min>0&&max>0?min:0;} getContext(index){const ticks=this.ticks||[];if(index>=0&&indexw*sin?w/cos:h/sin:h*sin0;} _computeGridLineItems(chartArea){const axis=this.axis;const chart=this.chart;const options=this.options;const{grid,position,border}=options;const offset=grid.offset;const isHorizontal=this.isHorizontal();const ticks=this.ticks;const ticksLength=ticks.length+(offset?1:0);const tl=getTickMarkLength(grid);const items=[];const borderOpts=border.setContext(this.getContext());const axisWidth=borderOpts.display?borderOpts.width:0;const axisHalfWidth=axisWidth/2;const alignBorderValue=function(pixel){return _alignPixel(chart,pixel,axisWidth);};let borderValue,i,lineValue,alignedLineValue;let tx1,ty1,tx2,ty2,x1,y1,x2,y2;if(position==='top'){borderValue=alignBorderValue(this.bottom);ty1=this.bottom-tl;ty2=borderValue-axisHalfWidth;y1=alignBorderValue(chartArea.top)+axisHalfWidth;y2=chartArea.bottom;}else if(position==='bottom'){borderValue=alignBorderValue(this.top);y1=chartArea.top;y2=alignBorderValue(chartArea.bottom)-axisHalfWidth;ty1=borderValue+axisHalfWidth;ty2=this.top+tl;}else if(position==='left'){borderValue=alignBorderValue(this.right);tx1=this.right-tl;tx2=borderValue-axisHalfWidth;x1=alignBorderValue(chartArea.left)+axisHalfWidth;x2=chartArea.right;}else if(position==='right'){borderValue=alignBorderValue(this.left);x1=chartArea.left;x2=alignBorderValue(chartArea.right)-axisHalfWidth;tx1=borderValue+axisHalfWidth;tx2=this.left+tl;}else if(axis==='x'){if(position==='center'){borderValue=alignBorderValue((chartArea.top+chartArea.bottom)/2+0.5);}else if(isObject(position)){const positionAxisID=Object.keys(position)[0];const value=position[positionAxisID];borderValue=alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value));} y1=chartArea.top;y2=chartArea.bottom;ty1=borderValue+axisHalfWidth;ty2=ty1+tl;}else if(axis==='y'){if(position==='center'){borderValue=alignBorderValue((chartArea.left+chartArea.right)/2);}else if(isObject(position)){const positionAxisID=Object.keys(position)[0];const value=position[positionAxisID];borderValue=alignBorderValue(this.chart.scales[positionAxisID].getPixelForValue(value));} tx1=borderValue-axisHalfWidth;tx2=tx1-tl;x1=chartArea.left;x2=chartArea.right;} const limit=valueOrDefault(options.ticks.maxTicksLimit,ticksLength);const step=Math.max(1,Math.ceil(ticksLength/limit));for(i=0;i0){left-=width/2;} break;} backdrop={left,top,width:width+labelPadding.width,height:height+labelPadding.height,color:optsAtIndex.backdropColor};} items.push({label,font,textOffset,options:{rotation,color,strokeColor,strokeWidth,textAlign:tickTextAlign,textBaseline,translation:[x,y],backdrop}});} return items;} _getXAxisLabelAlignment(){const{position,ticks}=this.options;const rotation=-toRadians(this.labelRotation);if(rotation){return position==='top'?'left':'right';} let align='center';if(ticks.align==='start'){align='left';}else if(ticks.align==='end'){align='right';}else if(ticks.align==='inner'){align='inner';} return align;} _getYAxisLabelAlignment(tl){const{position,ticks:{crossAlign,mirror,padding}}=this.options;const labelSizes=this._getLabelSizes();const tickAndPadding=tl+padding;const widest=labelSizes.widest.width;let textAlign;let x;if(position==='left'){if(mirror){x=this.right+padding;if(crossAlign==='near'){textAlign='left';}else if(crossAlign==='center'){textAlign='center';x+=widest/2;}else{textAlign='right';x+=widest;}}else{x=this.right-tickAndPadding;if(crossAlign==='near'){textAlign='right';}else if(crossAlign==='center'){textAlign='center';x-=widest/2;}else{textAlign='left';x=this.left;}}}else if(position==='right'){if(mirror){x=this.left+padding;if(crossAlign==='near'){textAlign='right';}else if(crossAlign==='center'){textAlign='center';x-=widest/2;}else{textAlign='left';x-=widest;}}else{x=this.left+tickAndPadding;if(crossAlign==='near'){textAlign='left';}else if(crossAlign==='center'){textAlign='center';x+=widest/2;}else{textAlign='right';x=this.right;}}}else{textAlign='right';} return{textAlign,x};} _computeLabelArea(){if(this.options.ticks.mirror){return;} const chart=this.chart;const position=this.options.position;if(position==='left'||position==='right'){return{top:0,left:this.left,bottom:chart.height,right:this.right};} if(position==='top'||position==='bottom'){return{top:this.top,left:0,bottom:this.bottom,right:chart.width};}} drawBackground(){const{ctx,options:{backgroundColor},left,top,width,height}=this;if(backgroundColor){ctx.save();ctx.fillStyle=backgroundColor;ctx.fillRect(left,top,width,height);ctx.restore();}} getLineWidthForValue(value){const grid=this.options.grid;if(!this._isVisible()||!grid.display){return 0;} const ticks=this.ticks;const index=ticks.findIndex((t)=>t.value===value);if(index>=0){const opts=grid.setContext(this.getContext(index));return opts.lineWidth;} return 0;} drawGrid(chartArea){const grid=this.options.grid;const ctx=this.ctx;const items=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(chartArea));let i,ilen;const drawLine=(p1,p2,style)=>{if(!style.width||!style.color){return;} ctx.save();ctx.lineWidth=style.width;ctx.strokeStyle=style.color;ctx.setLineDash(style.borderDash||[]);ctx.lineDashOffset=style.borderDashOffset;ctx.beginPath();ctx.moveTo(p1.x,p1.y);ctx.lineTo(p2.x,p2.y);ctx.stroke();ctx.restore();};if(grid.display){for(i=0,ilen=items.length;i{this.draw(chartArea);}}];} return[{z:gz,draw:(chartArea)=>{this.drawBackground();this.drawGrid(chartArea);this.drawTitle();}},{z:bz,draw:()=>{this.drawBorder();}},{z:tz,draw:(chartArea)=>{this.drawLabels(chartArea);}}];} getMatchingVisibleMetas(type){const metas=this.chart.getSortedVisibleDatasetMetas();const axisID=this.axis+'AxisID';const result=[];let i,ilen;for(i=0,ilen=metas.length;i{const propertyParts=property.split('.');const sourceName=propertyParts.pop();const sourceScope=[scope].concat(propertyParts).join('.');const parts=routes[property].split('.');const targetName=parts.pop();const targetScope=parts.join('.');defaults.route(sourceScope,sourceName,targetScope,targetName);});} function isIChartComponent(proto){return'id'in proto&&'defaults'in proto;} class Registry{constructor(){this.controllers=new TypedRegistry(DatasetController,'datasets',true);this.elements=new TypedRegistry(Element,'elements');this.plugins=new TypedRegistry(Object,'plugins');this.scales=new TypedRegistry(Scale,'scales');this._typedRegistries=[this.controllers,this.scales,this.elements];} add(...args){this._each('register',args);} remove(...args){this._each('unregister',args);} addControllers(...args){this._each('register',args,this.controllers);} addElements(...args){this._each('register',args,this.elements);} addPlugins(...args){this._each('register',args,this.plugins);} addScales(...args){this._each('register',args,this.scales);} getController(id){return this._get(id,this.controllers,'controller');} getElement(id){return this._get(id,this.elements,'element');} getPlugin(id){return this._get(id,this.plugins,'plugin');} getScale(id){return this._get(id,this.scales,'scale');} removeControllers(...args){this._each('unregister',args,this.controllers);} removeElements(...args){this._each('unregister',args,this.elements);} removePlugins(...args){this._each('unregister',args,this.plugins);} removeScales(...args){this._each('unregister',args,this.scales);} _each(method,args,typedRegistry){[...args].forEach((arg)=>{const reg=typedRegistry||this._getRegistryForType(arg);if(typedRegistry||reg.isForType(arg)||reg===this.plugins&&arg.id){this._exec(method,reg,arg);}else{each(arg,(item)=>{const itemReg=typedRegistry||this._getRegistryForType(item);this._exec(method,itemReg,item);});}});} _exec(method,registry,component){const camelMethod=_capitalize(method);callback(component['before'+camelMethod],[],component);registry[method](component);callback(component['after'+camelMethod],[],component);} _getRegistryForType(type){for(let i=0;ia.filter((x)=>!b.some((y)=>x.plugin.id===y.plugin.id));this._notify(diff(previousDescriptors,descriptors),chart,'stop');this._notify(diff(descriptors,previousDescriptors),chart,'start');}} function allPlugins(config){const localIds={};const plugins=[];const keys=Object.keys(registry.plugins.items);for(let i=0;i1&&idMatchesAxis(id[0].toLowerCase());if(axis){return axis;}} throw new Error(`Cannot determine type of '${id}' axis. Please provide 'axis' or 'position' option.`);} function getAxisFromDataset(id,axis,dataset){if(dataset[axis+'AxisID']===id){return{axis};}} function retrieveAxisFromDatasets(id,config){if(config.data&&config.data.datasets){const boundDs=config.data.datasets.filter((d)=>d.xAxisID===id||d.yAxisID===id);if(boundDs.length){return getAxisFromDataset(id,'x',boundDs[0])||getAxisFromDataset(id,'y',boundDs[0]);}} return{};} function mergeScaleConfig(config,options){const chartDefaults=overrides[config.type]||{scales:{}};const configScales=options.scales||{};const chartIndexAxis=getIndexAxis(config.type,options);const scales=Object.create(null);Object.keys(configScales).forEach((id)=>{const scaleConf=configScales[id];if(!isObject(scaleConf)){return console.error(`Invalid scale configuration for scale: ${id}`);} if(scaleConf._proxy){return console.warn(`Ignoring resolver passed as options for scale: ${id}`);} const axis=determineAxis(id,scaleConf,retrieveAxisFromDatasets(id,config),defaults.scales[scaleConf.type]);const defaultId=getDefaultScaleIDFromAxis(axis,chartIndexAxis);const defaultScaleOptions=chartDefaults.scales||{};scales[id]=mergeIf(Object.create(null),[{axis},scaleConf,defaultScaleOptions[axis],defaultScaleOptions[defaultId]]);});config.data.datasets.forEach((dataset)=>{const type=dataset.type||config.type;const indexAxis=dataset.indexAxis||getIndexAxis(type,options);const datasetDefaults=overrides[type]||{};const defaultScaleOptions=datasetDefaults.scales||{};Object.keys(defaultScaleOptions).forEach((defaultID)=>{const axis=getAxisFromDefaultScaleID(defaultID,indexAxis);const id=dataset[axis+'AxisID']||axis;scales[id]=scales[id]||Object.create(null);mergeIf(scales[id],[{axis},configScales[id],defaultScaleOptions[defaultID]]);});});Object.keys(scales).forEach((key)=>{const scale=scales[key];mergeIf(scale,[defaults.scales[scale.type],defaults.scale]);});return scales;} function initOptions(config){const options=config.options||(config.options={});options.plugins=valueOrDefault(options.plugins,{});options.scales=mergeScaleConfig(config,options);} function initData(data){data=data||{};data.datasets=data.datasets||[];data.labels=data.labels||[];return data;} function initConfig(config){config=config||{};config.data=initData(config.data);initOptions(config);return config;} const keyCache=new Map();const keysCached=new Set();function cachedKeys(cacheKey,generate){let keys=keyCache.get(cacheKey);if(!keys){keys=generate();keyCache.set(cacheKey,keys);keysCached.add(keys);} return keys;} const addIfFound=(set,obj,key)=>{const opts=resolveObjectKey(obj,key);if(opts!==undefined){set.add(opts);}};class Config{constructor(config){this._config=initConfig(config);this._scopeCache=new Map();this._resolverCache=new Map();} get platform(){return this._config.platform;} get type(){return this._config.type;} set type(type){this._config.type=type;} get data(){return this._config.data;} set data(data){this._config.data=initData(data);} get options(){return this._config.options;} set options(options){this._config.options=options;} get plugins(){return this._config.plugins;} update(){const config=this._config;this.clearCache();initOptions(config);} clearCache(){this._scopeCache.clear();this._resolverCache.clear();} datasetScopeKeys(datasetType){return cachedKeys(datasetType,()=>[[`datasets.${datasetType}`,'']]);} datasetAnimationScopeKeys(datasetType,transition){return cachedKeys(`${datasetType}.transition.${transition}`,()=>[[`datasets.${datasetType}.transitions.${transition}`,`transitions.${transition}`],[`datasets.${datasetType}`,'']]);} datasetElementScopeKeys(datasetType,elementType){return cachedKeys(`${datasetType}-${elementType}`,()=>[[`datasets.${datasetType}.elements.${elementType}`,`datasets.${datasetType}`,`elements.${elementType}`,'']]);} pluginScopeKeys(plugin){const id=plugin.id;const type=this.type;return cachedKeys(`${type}-plugin-${id}`,()=>[[`plugins.${id}`,...plugin.additionalOptionScopes||[]]]);} _cachedScopes(mainScope,resetCache){const _scopeCache=this._scopeCache;let cache=_scopeCache.get(mainScope);if(!cache||resetCache){cache=new Map();_scopeCache.set(mainScope,cache);} return cache;} getOptionScopes(mainScope,keyLists,resetCache){const{options,type}=this;const cache=this._cachedScopes(mainScope,resetCache);const cached=cache.get(keyLists);if(cached){return cached;} const scopes=new Set();keyLists.forEach((keys)=>{if(mainScope){scopes.add(mainScope);keys.forEach((key)=>addIfFound(scopes,mainScope,key));} keys.forEach((key)=>addIfFound(scopes,options,key));keys.forEach((key)=>addIfFound(scopes,overrides[type]||{},key));keys.forEach((key)=>addIfFound(scopes,defaults,key));keys.forEach((key)=>addIfFound(scopes,descriptors,key));});const array=Array.from(scopes);if(array.length===0){array.push(Object.create(null));} if(keysCached.has(keyLists)){cache.set(keyLists,array);} return array;} chartOptionScopes(){const{options,type}=this;return[options,overrides[type]||{},defaults.datasets[type]||{},{type},defaults,descriptors];} resolveNamedOptions(scopes,names,context,prefixes=['']){const result={$shared:true};const{resolver,subPrefixes}=getResolver(this._resolverCache,scopes,prefixes);let options=resolver;if(needContext(resolver,names)){result.$shared=false;context=isFunction(context)?context():context;const subResolver=this.createResolver(scopes,context,subPrefixes);options=_attachContext(resolver,context,subResolver);} for(const prop of names){result[prop]=options[prop];} return result;} createResolver(scopes,context,prefixes=[''],descriptorDefaults){const{resolver}=getResolver(this._resolverCache,scopes,prefixes);return isObject(context)?_attachContext(resolver,context,undefined,descriptorDefaults):resolver;}} function getResolver(resolverCache,scopes,prefixes){let cache=resolverCache.get(scopes);if(!cache){cache=new Map();resolverCache.set(scopes,cache);} const cacheKey=prefixes.join();let cached=cache.get(cacheKey);if(!cached){const resolver=_createResolver(scopes,prefixes);cached={resolver,subPrefixes:prefixes.filter((p)=>!p.toLowerCase().includes('hover'))};cache.set(cacheKey,cached);} return cached;} const hasFunction=(value)=>isObject(value)&&Object.getOwnPropertyNames(value).some((key)=>isFunction(value[key]));function needContext(proxy,names){const{isScriptable,isIndexable}=_descriptors(proxy);for(const prop of names){const scriptable=isScriptable(prop);const indexable=isIndexable(prop);const value=(indexable||scriptable)&&proxy[prop];if(scriptable&&(isFunction(value)||hasFunction(value))||indexable&&isArray(value)){return true;}} return false;} var version="4.4.5";const KNOWN_POSITIONS=['top','bottom','left','right','chartArea'];function positionIsHorizontal(position,axis){return position==='top'||position==='bottom'||KNOWN_POSITIONS.indexOf(position)===-1&&axis==='x';} function compare2Level(l1,l2){return function(a,b){return a[l1]===b[l1]?a[l2]-b[l2]:a[l1]-b[l1];};} function onAnimationsComplete(context){const chart=context.chart;const animationOptions=chart.options.animation;chart.notifyPlugins('afterRender');callback(animationOptions&&animationOptions.onComplete,[context],chart);} function onAnimationProgress(context){const chart=context.chart;const animationOptions=chart.options.animation;callback(animationOptions&&animationOptions.onProgress,[context],chart);} function getCanvas(item){if(_isDomSupported()&&typeof item==='string'){item=document.getElementById(item);}else if(item&&item.length){item=item[0];} if(item&&item.canvas){item=item.canvas;} return item;} const instances={};const getChart=(key)=>{const canvas=getCanvas(key);return Object.values(instances).filter((c)=>c.canvas===canvas).pop();};function moveNumericKeys(obj,start,move){const keys=Object.keys(obj);for(const key of keys){const intKey=+key;if(intKey>=start){const value=obj[key];delete obj[key];if(move>0||intKey>start){obj[intKey+move]=value;}}}} function determineLastEvent(e,lastEvent,inChartArea,isClick){if(!inChartArea||e.type==='mouseout'){return null;} if(isClick){return lastEvent;} return e;} function getSizeForArea(scale,chartArea,field){return scale.options.clip?scale[field]:chartArea[field];} function getDatasetArea(meta,chartArea){const{xScale,yScale}=meta;if(xScale&&yScale){return{left:getSizeForArea(xScale,chartArea,'left'),right:getSizeForArea(xScale,chartArea,'right'),top:getSizeForArea(yScale,chartArea,'top'),bottom:getSizeForArea(yScale,chartArea,'bottom')};} return chartArea;} class Chart{static defaults=defaults;static instances=instances;static overrides=overrides;static registry=registry;static version=version;static getChart=getChart;static register(...items){registry.add(...items);invalidatePlugins();} static unregister(...items){registry.remove(...items);invalidatePlugins();} constructor(item,userConfig){const config=this.config=new Config(userConfig);const initialCanvas=getCanvas(item);const existingChart=getChart(initialCanvas);if(existingChart){throw new Error('Canvas is already in use. Chart with ID \''+existingChart.id+'\''+' must be destroyed before the canvas with ID \''+existingChart.canvas.id+'\' can be reused.');} const options=config.createResolver(config.chartOptionScopes(),this.getContext());this.platform=new(config.platform||_detectPlatform(initialCanvas))();this.platform.updateConfig(config);const context=this.platform.acquireContext(initialCanvas,options.aspectRatio);const canvas=context&&context.canvas;const height=canvas&&canvas.height;const width=canvas&&canvas.width;this.id=uid();this.ctx=context;this.canvas=canvas;this.width=width;this.height=height;this._options=options;this._aspectRatio=this.aspectRatio;this._layers=[];this._metasets=[];this._stacks=undefined;this.boxes=[];this.currentDevicePixelRatio=undefined;this.chartArea=undefined;this._active=[];this._lastEvent=undefined;this._listeners={};this._responsiveListeners=undefined;this._sortedMetasets=[];this.scales={};this._plugins=new PluginService();this.$proxies={};this._hiddenIndices={};this.attached=false;this._animationsDisabled=undefined;this.$context=undefined;this._doResize=debounce((mode)=>this.update(mode),options.resizeDelay||0);this._dataChanges=[];instances[this.id]=this;if(!context||!canvas){console.error("Failed to create chart: can't acquire context from the given item");return;} animator.listen(this,'complete',onAnimationsComplete);animator.listen(this,'progress',onAnimationProgress);this._initialize();if(this.attached){this.update();}} get aspectRatio(){const{options:{aspectRatio,maintainAspectRatio},width,height,_aspectRatio}=this;if(!isNullOrUndef(aspectRatio)){return aspectRatio;} if(maintainAspectRatio&&_aspectRatio){return _aspectRatio;} return height?width/height:null;} get data(){return this.config.data;} set data(data){this.config.data=data;} get options(){return this._options;} set options(options){this.config.options=options;} get registry(){return registry;} _initialize(){this.notifyPlugins('beforeInit');if(this.options.responsive){this.resize();}else{retinaScale(this,this.options.devicePixelRatio);} this.bindEvents();this.notifyPlugins('afterInit');return this;} clear(){clearCanvas(this.canvas,this.ctx);return this;} stop(){animator.stop(this);return this;} resize(width,height){if(!animator.running(this)){this._resize(width,height);}else{this._resizeBeforeDraw={width,height};}} _resize(width,height){const options=this.options;const canvas=this.canvas;const aspectRatio=options.maintainAspectRatio&&this.aspectRatio;const newSize=this.platform.getMaximumSize(canvas,width,height,aspectRatio);const newRatio=options.devicePixelRatio||this.platform.getDevicePixelRatio();const mode=this.width?'resize':'attach';this.width=newSize.width;this.height=newSize.height;this._aspectRatio=this.aspectRatio;if(!retinaScale(this,newRatio,true)){return;} this.notifyPlugins('resize',{size:newSize});callback(options.onResize,[this,newSize],this);if(this.attached){if(this._doResize(mode)){this.render();}}} ensureScalesHaveIDs(){const options=this.options;const scalesOptions=options.scales||{};each(scalesOptions,(axisOptions,axisID)=>{axisOptions.id=axisID;});} buildOrUpdateScales(){const options=this.options;const scaleOpts=options.scales;const scales=this.scales;const updated=Object.keys(scales).reduce((obj,id)=>{obj[id]=false;return obj;},{});let items=[];if(scaleOpts){items=items.concat(Object.keys(scaleOpts).map((id)=>{const scaleOptions=scaleOpts[id];const axis=determineAxis(id,scaleOptions);const isRadial=axis==='r';const isHorizontal=axis==='x';return{options:scaleOptions,dposition:isRadial?'chartArea':isHorizontal?'bottom':'left',dtype:isRadial?'radialLinear':isHorizontal?'category':'linear'};}));} each(items,(item)=>{const scaleOptions=item.options;const id=scaleOptions.id;const axis=determineAxis(id,scaleOptions);const scaleType=valueOrDefault(scaleOptions.type,item.dtype);if(scaleOptions.position===undefined||positionIsHorizontal(scaleOptions.position,axis)!==positionIsHorizontal(item.dposition)){scaleOptions.position=item.dposition;} updated[id]=true;let scale=null;if(id in scales&&scales[id].type===scaleType){scale=scales[id];}else{const scaleClass=registry.getScale(scaleType);scale=new scaleClass({id,type:scaleType,ctx:this.ctx,chart:this});scales[scale.id]=scale;} scale.init(scaleOptions,options);});each(updated,(hasUpdated,id)=>{if(!hasUpdated){delete scales[id];}});each(scales,(scale)=>{layouts.configure(this,scale,scale.options);layouts.addBox(this,scale);});} _updateMetasets(){const metasets=this._metasets;const numData=this.data.datasets.length;const numMeta=metasets.length;metasets.sort((a,b)=>a.index-b.index);if(numMeta>numData){for(let i=numData;idatasets.length){delete this._stacks;} metasets.forEach((meta,index)=>{if(datasets.filter((x)=>x===meta._dataset).length===0){this._destroyDatasetMeta(index);}});} buildOrUpdateControllers(){const newControllers=[];const datasets=this.data.datasets;let i,ilen;this._removeUnreferencedMetasets();for(i=0,ilen=datasets.length;i{this.getDatasetMeta(datasetIndex).controller.reset();},this);} reset(){this._resetElements();this.notifyPlugins('reset');} update(mode){const config=this.config;config.update();const options=this._options=config.createResolver(config.chartOptionScopes(),this.getContext());const animsDisabled=this._animationsDisabled=!options.animation;this._updateScales();this._checkEventBindings();this._updateHiddenIndices();this._plugins.invalidate();if(this.notifyPlugins('beforeUpdate',{mode,cancelable:true})===false){return;} const newControllers=this.buildOrUpdateControllers();this.notifyPlugins('beforeElementsUpdate');let minPadding=0;for(let i=0,ilen=this.data.datasets.length;i{controller.reset();});} this._updateDatasets(mode);this.notifyPlugins('afterUpdate',{mode});this._layers.sort(compare2Level('z','_idx'));const{_active,_lastEvent}=this;if(_lastEvent){this._eventHandler(_lastEvent,true);}else if(_active.length){this._updateHoverStyles(_active,_active,true);} this.render();} _updateScales(){each(this.scales,(scale)=>{layouts.removeBox(this,scale);});this.ensureScalesHaveIDs();this.buildOrUpdateScales();} _checkEventBindings(){const options=this.options;const existingEvents=new Set(Object.keys(this._listeners));const newEvents=new Set(options.events);if(!setsEqual(existingEvents,newEvents)||!!this._responsiveListeners!==options.responsive){this.unbindEvents();this.bindEvents();}} _updateHiddenIndices(){const{_hiddenIndices}=this;const changes=this._getUniformDataChanges()||[];for(const{method,start,count}of changes){const move=method==='_removeElements'?-count:count;moveNumericKeys(_hiddenIndices,start,move);}} _getUniformDataChanges(){const _dataChanges=this._dataChanges;if(!_dataChanges||!_dataChanges.length){return;} this._dataChanges=[];const datasetCount=this.data.datasets.length;const makeSet=(idx)=>new Set(_dataChanges.filter((c)=>c[0]===idx).map((c,i)=>i+','+c.splice(1).join(',')));const changeSet=makeSet(0);for(let i=1;ic.split(',')).map((a)=>({method:a[1],start:+a[2],count:+a[3]}));} _updateLayout(minPadding){if(this.notifyPlugins('beforeLayout',{cancelable:true})===false){return;} layouts.update(this,this.width,this.height,minPadding);const area=this.chartArea;const noArea=area.width<=0||area.height<=0;this._layers=[];each(this.boxes,(box)=>{if(noArea&&box.position==='chartArea'){return;} if(box.configure){box.configure();} this._layers.push(...box._layers());},this);this._layers.forEach((item,index)=>{item._idx=index;});this.notifyPlugins('afterLayout');} _updateDatasets(mode){if(this.notifyPlugins('beforeDatasetsUpdate',{mode,cancelable:true})===false){return;} for(let i=0,ilen=this.data.datasets.length;i=0;--i){this._drawDataset(metasets[i]);} this.notifyPlugins('afterDatasetsDraw');} _drawDataset(meta){const ctx=this.ctx;const clip=meta._clip;const useClip=!clip.disabled;const area=getDatasetArea(meta,this.chartArea);const args={meta,index:meta.index,cancelable:true};if(this.notifyPlugins('beforeDatasetDraw',args)===false){return;} if(useClip){clipArea(ctx,{left:clip.left===false?0:area.left-clip.left,right:clip.right===false?this.width:area.right+clip.right,top:clip.top===false?0:area.top-clip.top,bottom:clip.bottom===false?this.height:area.bottom+clip.bottom});} meta.controller.draw();if(useClip){unclipArea(ctx);} args.cancelable=false;this.notifyPlugins('afterDatasetDraw',args);} isPointInArea(point){return _isPointInArea(point,this.chartArea,this._minPadding);} getElementsAtEventForMode(e,mode,options,useFinalPosition){const method=Interaction.modes[mode];if(typeof method==='function'){return method(this,e,options,useFinalPosition);} return[];} getDatasetMeta(datasetIndex){const dataset=this.data.datasets[datasetIndex];const metasets=this._metasets;let meta=metasets.filter((x)=>x&&x._dataset===dataset).pop();if(!meta){meta={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:dataset&&dataset.order||0,index:datasetIndex,_dataset:dataset,_parsed:[],_sorted:false};metasets.push(meta);} return meta;} getContext(){return this.$context||(this.$context=createContext(null,{chart:this,type:'chart'}));} getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length;} isDatasetVisible(datasetIndex){const dataset=this.data.datasets[datasetIndex];if(!dataset){return false;} const meta=this.getDatasetMeta(datasetIndex);return typeof meta.hidden==='boolean'?!meta.hidden:!dataset.hidden;} setDatasetVisibility(datasetIndex,visible){const meta=this.getDatasetMeta(datasetIndex);meta.hidden=!visible;} toggleDataVisibility(index){this._hiddenIndices[index]=!this._hiddenIndices[index];} getDataVisibility(index){return!this._hiddenIndices[index];} _updateVisibility(datasetIndex,dataIndex,visible){const mode=visible?'show':'hide';const meta=this.getDatasetMeta(datasetIndex);const anims=meta.controller._resolveAnimations(undefined,mode);if(defined(dataIndex)){meta.data[dataIndex].hidden=!visible;this.update();}else{this.setDatasetVisibility(datasetIndex,visible);anims.update(meta,{visible});this.update((ctx)=>ctx.datasetIndex===datasetIndex?mode:undefined);}} hide(datasetIndex,dataIndex){this._updateVisibility(datasetIndex,dataIndex,false);} show(datasetIndex,dataIndex){this._updateVisibility(datasetIndex,dataIndex,true);} _destroyDatasetMeta(datasetIndex){const meta=this._metasets[datasetIndex];if(meta&&meta.controller){meta.controller._destroy();} delete this._metasets[datasetIndex];} _stop(){let i,ilen;this.stop();animator.remove(this);for(i=0,ilen=this.data.datasets.length;i{platform.addEventListener(this,type,listener);listeners[type]=listener;};const listener=(e,x,y)=>{e.offsetX=x;e.offsetY=y;this._eventHandler(e);};each(this.options.events,(type)=>_add(type,listener));} bindResponsiveEvents(){if(!this._responsiveListeners){this._responsiveListeners={};} const listeners=this._responsiveListeners;const platform=this.platform;const _add=(type,listener)=>{platform.addEventListener(this,type,listener);listeners[type]=listener;};const _remove=(type,listener)=>{if(listeners[type]){platform.removeEventListener(this,type,listener);delete listeners[type];}};const listener=(width,height)=>{if(this.canvas){this.resize(width,height);}};let detached;const attached=()=>{_remove('attach',attached);this.attached=true;this.resize();_add('resize',listener);_add('detach',detached);};detached=()=>{this.attached=false;_remove('resize',listener);this._stop();this._resize(0,0);_add('attach',attached);};if(platform.isAttached(this.canvas)){attached();}else{detached();}} unbindEvents(){each(this._listeners,(listener,type)=>{this.platform.removeEventListener(this,type,listener);});this._listeners={};each(this._responsiveListeners,(listener,type)=>{this.platform.removeEventListener(this,type,listener);});this._responsiveListeners=undefined;} updateHoverStyle(items,mode,enabled){const prefix=enabled?'set':'remove';let meta,item,i,ilen;if(mode==='dataset'){meta=this.getDatasetMeta(items[0].datasetIndex);meta.controller['_'+prefix+'DatasetHoverStyle']();} for(i=0,ilen=items.length;i{const meta=this.getDatasetMeta(datasetIndex);if(!meta){throw new Error('No dataset found at index '+datasetIndex);} return{datasetIndex,element:meta.data[index],index};});const changed=!_elementsEqual(active,lastActive);if(changed){this._active=active;this._lastEvent=null;this._updateHoverStyles(active,lastActive);}} notifyPlugins(hook,args,filter){return this._plugins.notify(this,hook,args,filter);} isPluginEnabled(pluginId){return this._plugins._cache.filter((p)=>p.plugin.id===pluginId).length===1;} _updateHoverStyles(active,lastActive,replay){const hoverOptions=this.options.hover;const diff=(a,b)=>a.filter((x)=>!b.some((y)=>x.datasetIndex===y.datasetIndex&&x.index===y.index));const deactivated=diff(lastActive,active);const activated=replay?active:diff(active,lastActive);if(deactivated.length){this.updateHoverStyle(deactivated,hoverOptions.mode,false);} if(activated.length&&hoverOptions.mode){this.updateHoverStyle(activated,hoverOptions.mode,true);}} _eventHandler(e,replay){const args={event:e,replay,cancelable:true,inChartArea:this.isPointInArea(e)};const eventFilter=(plugin)=>(plugin.options.events||this.options.events).includes(e.native.type);if(this.notifyPlugins('beforeEvent',args,eventFilter)===false){return;} const changed=this._handleEvent(e,replay,args.inChartArea);args.cancelable=false;this.notifyPlugins('afterEvent',args,eventFilter);if(changed||args.changed){this.render();} return this;} _handleEvent(e,replay,inChartArea){const{_active:lastActive=[],options}=this;const useFinalPosition=replay;const active=this._getActiveElements(e,lastActive,inChartArea,useFinalPosition);const isClick=_isClickEvent(e);const lastEvent=determineLastEvent(e,this._lastEvent,inChartArea,isClick);if(inChartArea){this._lastEvent=null;callback(options.onHover,[e,active,this],this);if(isClick){callback(options.onClick,[e,active,this],this);}} const changed=!_elementsEqual(active,lastActive);if(changed||replay){this._active=active;this._updateHoverStyles(active,lastActive,replay);} this._lastEvent=lastEvent;return changed;} _getActiveElements(e,lastActive,inChartArea,useFinalPosition){if(e.type==='mouseout'){return[];} if(!inChartArea){return lastActive;} const hoverOptions=this.options.hover;return this.getElementsAtEventForMode(e,hoverOptions.mode,hoverOptions,useFinalPosition);}} function invalidatePlugins(){return each(Chart.instances,(chart)=>chart._plugins.invalidate());} function abstract(){throw new Error('This method is not implemented: Check that a complete date adapter is provided.');} class DateAdapterBase{static override(members){Object.assign(DateAdapterBase.prototype,members);} options;constructor(options){this.options=options||{};} init(){} formats(){return abstract();} parse(){return abstract();} format(){return abstract();} add(){return abstract();} diff(){return abstract();} startOf(){return abstract();} endOf(){return abstract();}} var _adapters={_date:DateAdapterBase};function getAllScaleValues(scale,type){if(!scale._cache.$bar){const visibleMetas=scale.getMatchingVisibleMetas(type);let values=[];for(let i=0,ilen=visibleMetas.length;ia-b));} return scale._cache.$bar;} function computeMinSampleSize(meta){const scale=meta.iScale;const values=getAllScaleValues(scale,meta.type);let min=scale._length;let i,ilen,curr,prev;const updateMinAndPrev=()=>{if(curr===32767||curr===-32768){return;} if(defined(prev)){min=Math.min(min,Math.abs(curr-prev)||min);} prev=curr;};for(i=0,ilen=values.length;i0?pixels[index-1]:null;let next=indexMath.abs(max)){barStart=max;barEnd=min;} item[vScale.axis]=barEnd;item._custom={barStart,barEnd,start:startValue,end:endValue,min,max};} function parseValue(entry,item,vScale,i){if(isArray(entry)){parseFloatBar(entry,item,vScale,i);}else{item[vScale.axis]=vScale.parse(entry,i);} return item;} function parseArrayOrPrimitive(meta,data,start,count){const iScale=meta.iScale;const vScale=meta.vScale;const labels=iScale.getLabels();const singleScale=iScale===vScale;const parsed=[];let i,ilen,item,entry;for(i=start,ilen=start+count;i=actualBase?1:-1);} function borderProps(properties){let reverse,start,end,top,bottom;if(properties.horizontal){reverse=properties.base>properties.x;start='left';end='right';}else{reverse=properties.basemeta.controller.options.grouped);const stacked=iScale.options.stacked;const stacks=[];const currentParsed=this._cachedMeta.controller.getParsed(dataIndex);const iScaleValue=currentParsed&¤tParsed[iScale.axis];const skipNull=(meta)=>{const parsed=meta._parsed.find((item)=>item[iScale.axis]===iScaleValue);const val=parsed&&parsed[meta.vScale.axis];if(isNullOrUndef(val)||isNaN(val)){return true;}};for(const meta of metasets){if(dataIndex!==undefined&&skipNull(meta)){continue;} if(stacked===false||stacks.indexOf(meta.stack)===-1||stacked===undefined&&meta.stack===undefined){stacks.push(meta.stack);} if(meta.index===last){break;}} if(!stacks.length){stacks.push(undefined);} return stacks;} _getStackCount(index){return this._getStacks(undefined,index).length;} _getStackIndex(datasetIndex,name,dataIndex){const stacks=this._getStacks(datasetIndex,dataIndex);const index=name!==undefined?stacks.indexOf(name):-1;return index===-1?stacks.length-1:index;} _getRuler(){const opts=this.options;const meta=this._cachedMeta;const iScale=meta.iScale;const pixels=[];let i,ilen;for(i=0,ilen=meta.data.length;i=0;--i){max=Math.max(max,data[i].size(this.resolveDataElementOptions(i))/2);} return max>0&&max;} getLabelAndValue(index){const meta=this._cachedMeta;const labels=this.chart.data.labels||[];const{xScale,yScale}=meta;const parsed=this.getParsed(index);const x=xScale.getLabelForValue(parsed.x);const y=yScale.getLabelForValue(parsed.y);const r=parsed._custom;return{label:labels[index]||'',value:'('+x+', '+y+(r?', '+r:'')+')'};} update(mode){const points=this._cachedMeta.data;this.updateElements(points,0,points.length,mode);} updateElements(points,start,count,mode){const reset=mode==='reset';const{iScale,vScale}=this._cachedMeta;const{sharedOptions,includeOptions}=this._getSharedOptions(start,mode);const iAxis=iScale.axis;const vAxis=vScale.axis;for(let i=start;i_angleBetween(angle,startAngle,endAngle,true)?1:Math.max(a,a*cutout,b,b*cutout);const calcMin=(angle,a,b)=>_angleBetween(angle,startAngle,endAngle,true)?-1:Math.min(a,a*cutout,b,b*cutout);const maxX=calcMax(0,startX,endX);const maxY=calcMax(HALF_PI,startY,endY);const minX=calcMin(PI,startX,endX);const minY=calcMin(PI+HALF_PI,startY,endY);ratioX=(maxX-minX)/2;ratioY=(maxY-minY)/2;offsetX=-(maxX+minX)/2;offsetY=-(maxY+minY)/2;} return{ratioX,ratioY,offsetX,offsetY};} class DoughnutController extends DatasetController{static id='doughnut';static defaults={datasetElementType:false,dataElementType:'arc',animation:{animateRotate:true,animateScale:false},animations:{numbers:{type:'number',properties:['circumference','endAngle','innerRadius','outerRadius','startAngle','x','y','offset','borderWidth','spacing']}},cutout:'50%',rotation:0,circumference:360,radius:'100%',spacing:0,indexAxis:'r'};static descriptors={_scriptable:(name)=>name!=='spacing',_indexable:(name)=>name!=='spacing'&&!name.startsWith('borderDash')&&!name.startsWith('hoverBorderDash')};static overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(chart){const data=chart.data;if(data.labels.length&&data.datasets.length){const{labels:{pointStyle,color}}=chart.legend.options;return data.labels.map((label,i)=>{const meta=chart.getDatasetMeta(0);const style=meta.controller.getStyle(i);return{text:label,fillStyle:style.backgroundColor,strokeStyle:style.borderColor,fontColor:color,lineWidth:style.borderWidth,pointStyle:pointStyle,hidden:!chart.getDataVisibility(i),index:i};});} return[];}},onClick(e,legendItem,legend){legend.chart.toggleDataVisibility(legendItem.index);legend.chart.update();}}}};constructor(chart,datasetIndex){super(chart,datasetIndex);this.enableOptionSharing=true;this.innerRadius=undefined;this.outerRadius=undefined;this.offsetX=undefined;this.offsetY=undefined;} linkScales(){} parse(start,count){const data=this.getDataset().data;const meta=this._cachedMeta;if(this._parsing===false){meta._parsed=data;}else{let getter=(i)=>+data[i];if(isObject(data[start])){const{key='value'}=this._parsing;getter=(i)=>+resolveObjectKey(data[i],key);} let i,ilen;for(i=start,ilen=start+count;i0&&!isNaN(value)){return TAU*(Math.abs(value)/total);} return 0;} getLabelAndValue(index){const meta=this._cachedMeta;const chart=this.chart;const labels=chart.data.labels||[];const value=formatNumber(meta._parsed[index],chart.options.locale);return{label:labels[index]||'',value};} getMaxBorderWidth(arcs){let max=0;const chart=this.chart;let i,ilen,meta,controller,options;if(!arcs){for(i=0,ilen=chart.data.datasets.length;i0&&this.getParsed(start-1);for(let i=0;i=end){properties.skip=true;continue;} const parsed=this.getParsed(i);const nullData=isNullOrUndef(parsed[vAxis]);const iPixel=properties[iAxis]=iScale.getPixelForValue(parsed[iAxis],i);const vPixel=properties[vAxis]=reset||nullData?vScale.getBasePixel():vScale.getPixelForValue(_stacked?this.applyStack(vScale,parsed,_stacked):parsed[vAxis],i);properties.skip=isNaN(iPixel)||isNaN(vPixel)||nullData;properties.stop=i>0&&Math.abs(parsed[iAxis]-prevParsed[iAxis])>maxGapLength;if(segment){properties.parsed=parsed;properties.raw=_dataset.data[i];} if(includeOptions){properties.options=sharedOptions||this.resolveDataElementOptions(i,point.active?'active':mode);} if(!directUpdate){this.updateElement(point,i,properties,mode);} prevParsed=parsed;}} getMaxOverflow(){const meta=this._cachedMeta;const dataset=meta.dataset;const border=dataset.options&&dataset.options.borderWidth||0;const data=meta.data||[];if(!data.length){return border;} const firstPoint=data[0].size(this.resolveDataElementOptions(0));const lastPoint=data[data.length-1].size(this.resolveDataElementOptions(data.length-1));return Math.max(border,firstPoint,lastPoint)/2;} draw(){const meta=this._cachedMeta;meta.dataset.updateControlPoints(this.chart.chartArea,meta.iScale.axis);super.draw();}} class PolarAreaController extends DatasetController{static id='polarArea';static defaults={dataElementType:'arc',animation:{animateRotate:true,animateScale:true},animations:{numbers:{type:'number',properties:['x','y','startAngle','endAngle','innerRadius','outerRadius']}},indexAxis:'r',startAngle:0};static overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(chart){const data=chart.data;if(data.labels.length&&data.datasets.length){const{labels:{pointStyle,color}}=chart.legend.options;return data.labels.map((label,i)=>{const meta=chart.getDatasetMeta(0);const style=meta.controller.getStyle(i);return{text:label,fillStyle:style.backgroundColor,strokeStyle:style.borderColor,fontColor:color,lineWidth:style.borderWidth,pointStyle:pointStyle,hidden:!chart.getDataVisibility(i),index:i};});} return[];}},onClick(e,legendItem,legend){legend.chart.toggleDataVisibility(legendItem.index);legend.chart.update();}}},scales:{r:{type:'radialLinear',angleLines:{display:false},beginAtZero:true,grid:{circular:true},pointLabels:{display:false},startAngle:0}}};constructor(chart,datasetIndex){super(chart,datasetIndex);this.innerRadius=undefined;this.outerRadius=undefined;} getLabelAndValue(index){const meta=this._cachedMeta;const chart=this.chart;const labels=chart.data.labels||[];const value=formatNumber(meta._parsed[index].r,chart.options.locale);return{label:labels[index]||'',value};} parseObjectData(meta,data,start,count){return _parseObjectDataRadialScale.bind(this)(meta,data,start,count);} update(mode){const arcs=this._cachedMeta.data;this._updateRadius();this.updateElements(arcs,0,arcs.length,mode);} getMinMax(){const meta=this._cachedMeta;const range={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};meta.data.forEach((element,index)=>{const parsed=this.getParsed(index).r;if(!isNaN(parsed)&&this.chart.getDataVisibility(index)){if(parsedrange.max){range.max=parsed;}}});return range;} _updateRadius(){const chart=this.chart;const chartArea=chart.chartArea;const opts=chart.options;const minSize=Math.min(chartArea.right-chartArea.left,chartArea.bottom-chartArea.top);const outerRadius=Math.max(minSize/2,0);const innerRadius=Math.max(opts.cutoutPercentage?outerRadius/100*opts.cutoutPercentage:1,0);const radiusLength=(outerRadius-innerRadius)/chart.getVisibleDatasetCount();this.outerRadius=outerRadius-radiusLength*this.index;this.innerRadius=this.outerRadius-radiusLength;} updateElements(arcs,start,count,mode){const reset=mode==='reset';const chart=this.chart;const opts=chart.options;const animationOpts=opts.animation;const scale=this._cachedMeta.rScale;const centerX=scale.xCenter;const centerY=scale.yCenter;const datasetStartAngle=scale.getIndexAngle(0)-0.5*PI;let angle=datasetStartAngle;let i;const defaultAngle=360/this.countVisibleElements();for(i=0;i{if(!isNaN(this.getParsed(index).r)&&this.chart.getDataVisibility(index)){count++;}});return count;} _computeAngle(index,mode,defaultAngle){return this.chart.getDataVisibility(index)?toRadians(this.resolveDataElementOptions(index,mode).angle||defaultAngle):0;}} class PieController extends DoughnutController{static id='pie';static defaults={cutout:0,rotation:0,circumference:360,radius:'100%'};} class RadarController extends DatasetController{static id='radar';static defaults={datasetElementType:'line',dataElementType:'point',indexAxis:'r',showLine:true,elements:{line:{fill:'start'}}};static overrides={aspectRatio:1,scales:{r:{type:'radialLinear'}}};getLabelAndValue(index){const vScale=this._cachedMeta.vScale;const parsed=this.getParsed(index);return{label:vScale.getLabels()[index],value:''+vScale.getLabelForValue(parsed[vScale.axis])};} parseObjectData(meta,data,start,count){return _parseObjectDataRadialScale.bind(this)(meta,data,start,count);} update(mode){const meta=this._cachedMeta;const line=meta.dataset;const points=meta.data||[];const labels=meta.iScale.getLabels();line.points=points;if(mode!=='resize'){const options=this.resolveDatasetElementOptions(mode);if(!this.options.showLine){options.borderWidth=0;} const properties={_loop:true,_fullLoop:labels.length===points.length,options};this.updateElement(line,undefined,properties,mode);} this.updateElements(points,0,points.length,mode);} updateElements(points,start,count,mode){const scale=this._cachedMeta.rScale;const reset=mode==='reset';for(let i=start;i0&&this.getParsed(start-1);for(let i=start;i0&&Math.abs(parsed[iAxis]-prevParsed[iAxis])>maxGapLength;if(segment){properties.parsed=parsed;properties.raw=_dataset.data[i];} if(includeOptions){properties.options=sharedOptions||this.resolveDataElementOptions(i,point.active?'active':mode);} if(!directUpdate){this.updateElement(point,i,properties,mode);} prevParsed=parsed;} this.updateSharedOptions(sharedOptions,mode,firstOpts);} getMaxOverflow(){const meta=this._cachedMeta;const data=meta.data||[];if(!this.options.showLine){let max=0;for(let i=data.length-1;i>=0;--i){max=Math.max(max,data[i].size(this.resolveDataElementOptions(i))/2);} return max>0&&max;} const dataset=meta.dataset;const border=dataset.options&&dataset.options.borderWidth||0;if(!data.length){return border;} const firstPoint=data[0].size(this.resolveDataElementOptions(0));const lastPoint=data[data.length-1].size(this.resolveDataElementOptions(data.length-1));return Math.max(border,firstPoint,lastPoint)/2;}} var controllers=Object.freeze({__proto__:null,BarController:BarController,BubbleController:BubbleController,DoughnutController:DoughnutController,LineController:LineController,PieController:PieController,PolarAreaController:PolarAreaController,RadarController:RadarController,ScatterController:ScatterController});function clipArc(ctx,element,endAngle){const{startAngle,pixelMargin,x,y,outerRadius,innerRadius}=element;let angleMargin=pixelMargin/outerRadius;ctx.beginPath();ctx.arc(x,y,outerRadius,startAngle-angleMargin,endAngle+angleMargin);if(innerRadius>pixelMargin){angleMargin=pixelMargin/innerRadius;ctx.arc(x,y,innerRadius,endAngle+angleMargin,startAngle-angleMargin,true);}else{ctx.arc(x,y,pixelMargin,endAngle+HALF_PI,startAngle-HALF_PI);} ctx.closePath();ctx.clip();} function toRadiusCorners(value){return _readValueToProps(value,['outerStart','outerEnd','innerStart','innerEnd']);} function parseBorderRadius$1(arc,innerRadius,outerRadius,angleDelta){const o=toRadiusCorners(arc.options.borderRadius);const halfThickness=(outerRadius-innerRadius)/2;const innerLimit=Math.min(halfThickness,angleDelta*innerRadius/2);const computeOuterLimit=(val)=>{const outerArcLimit=(outerRadius-Math.min(halfThickness,val))*angleDelta/2;return _limitValue(val,0,Math.min(halfThickness,outerArcLimit));};return{outerStart:computeOuterLimit(o.outerStart),outerEnd:computeOuterLimit(o.outerEnd),innerStart:_limitValue(o.innerStart,0,innerLimit),innerEnd:_limitValue(o.innerEnd,0,innerLimit)};} function rThetaToXY(r,theta,x,y){return{x:x+r*Math.cos(theta),y:y+r*Math.sin(theta)};} function pathArc(ctx,element,offset,spacing,end,circular){const{x,y,startAngle:start,pixelMargin,innerRadius:innerR}=element;const outerRadius=Math.max(element.outerRadius+spacing+offset-pixelMargin,0);const innerRadius=innerR>0?innerR+spacing+offset+pixelMargin:0;let spacingOffset=0;const alpha=end-start;if(spacing){const noSpacingInnerRadius=innerR>0?innerR-spacing:0;const noSpacingOuterRadius=outerRadius>0?outerRadius-spacing:0;const avNogSpacingRadius=(noSpacingInnerRadius+noSpacingOuterRadius)/2;const adjustedAngle=avNogSpacingRadius!==0?alpha*avNogSpacingRadius/(avNogSpacingRadius+spacing):alpha;spacingOffset=(alpha-adjustedAngle)/2;} const beta=Math.max(0.001,alpha*outerRadius-offset/PI)/outerRadius;const angleOffset=(alpha-beta)/2;const startAngle=start+angleOffset+spacingOffset;const endAngle=end-angleOffset-spacingOffset;const{outerStart,outerEnd,innerStart,innerEnd}=parseBorderRadius$1(element,innerRadius,outerRadius,endAngle-startAngle);const outerStartAdjustedRadius=outerRadius-outerStart;const outerEndAdjustedRadius=outerRadius-outerEnd;const outerStartAdjustedAngle=startAngle+outerStart/outerStartAdjustedRadius;const outerEndAdjustedAngle=endAngle-outerEnd/outerEndAdjustedRadius;const innerStartAdjustedRadius=innerRadius+innerStart;const innerEndAdjustedRadius=innerRadius+innerEnd;const innerStartAdjustedAngle=startAngle+innerStart/innerStartAdjustedRadius;const innerEndAdjustedAngle=endAngle-innerEnd/innerEndAdjustedRadius;ctx.beginPath();if(circular){const outerMidAdjustedAngle=(outerStartAdjustedAngle+outerEndAdjustedAngle)/2;ctx.arc(x,y,outerRadius,outerStartAdjustedAngle,outerMidAdjustedAngle);ctx.arc(x,y,outerRadius,outerMidAdjustedAngle,outerEndAdjustedAngle);if(outerEnd>0){const pCenter=rThetaToXY(outerEndAdjustedRadius,outerEndAdjustedAngle,x,y);ctx.arc(pCenter.x,pCenter.y,outerEnd,outerEndAdjustedAngle,endAngle+HALF_PI);} const p4=rThetaToXY(innerEndAdjustedRadius,endAngle,x,y);ctx.lineTo(p4.x,p4.y);if(innerEnd>0){const pCenter=rThetaToXY(innerEndAdjustedRadius,innerEndAdjustedAngle,x,y);ctx.arc(pCenter.x,pCenter.y,innerEnd,endAngle+HALF_PI,innerEndAdjustedAngle+Math.PI);} const innerMidAdjustedAngle=(endAngle-innerEnd/innerRadius+(startAngle+innerStart/innerRadius))/2;ctx.arc(x,y,innerRadius,endAngle-innerEnd/innerRadius,innerMidAdjustedAngle,true);ctx.arc(x,y,innerRadius,innerMidAdjustedAngle,startAngle+innerStart/innerRadius,true);if(innerStart>0){const pCenter=rThetaToXY(innerStartAdjustedRadius,innerStartAdjustedAngle,x,y);ctx.arc(pCenter.x,pCenter.y,innerStart,innerStartAdjustedAngle+Math.PI,startAngle-HALF_PI);} const p8=rThetaToXY(outerStartAdjustedRadius,startAngle,x,y);ctx.lineTo(p8.x,p8.y);if(outerStart>0){const pCenter=rThetaToXY(outerStartAdjustedRadius,outerStartAdjustedAngle,x,y);ctx.arc(pCenter.x,pCenter.y,outerStart,startAngle-HALF_PI,outerStartAdjustedAngle);}}else{ctx.moveTo(x,y);const outerStartX=Math.cos(outerStartAdjustedAngle)*outerRadius+x;const outerStartY=Math.sin(outerStartAdjustedAngle)*outerRadius+y;ctx.lineTo(outerStartX,outerStartY);const outerEndX=Math.cos(outerEndAdjustedAngle)*outerRadius+x;const outerEndY=Math.sin(outerEndAdjustedAngle)*outerRadius+y;ctx.lineTo(outerEndX,outerEndY);} ctx.closePath();} function drawArc(ctx,element,offset,spacing,circular){const{fullCircles,startAngle,circumference}=element;let endAngle=element.endAngle;if(fullCircles){pathArc(ctx,element,offset,spacing,endAngle,circular);for(let i=0;iname!=='borderDash'};circumference;endAngle;fullCircles;innerRadius;outerRadius;pixelMargin;startAngle;constructor(cfg){super();this.options=undefined;this.circumference=undefined;this.startAngle=undefined;this.endAngle=undefined;this.innerRadius=undefined;this.outerRadius=undefined;this.pixelMargin=0;this.fullCircles=0;if(cfg){Object.assign(this,cfg);}} inRange(chartX,chartY,useFinalPosition){const point=this.getProps(['x','y'],useFinalPosition);const{angle,distance}=getAngleFromPoint(point,{x:chartX,y:chartY});const{startAngle,endAngle,innerRadius,outerRadius,circumference}=this.getProps(['startAngle','endAngle','innerRadius','outerRadius','circumference'],useFinalPosition);const rAdjust=(this.options.spacing+this.options.borderWidth)/2;const _circumference=valueOrDefault(circumference,endAngle-startAngle);const nonZeroBetween=_angleBetween(angle,startAngle,endAngle)&&startAngle!==endAngle;const betweenAngles=_circumference>=TAU||nonZeroBetween;const withinRadius=_isBetween(distance,innerRadius+rAdjust,outerRadius+rAdjust);return betweenAngles&&withinRadius;} getCenterPoint(useFinalPosition){const{x,y,startAngle,endAngle,innerRadius,outerRadius}=this.getProps(['x','y','startAngle','endAngle','innerRadius','outerRadius'],useFinalPosition);const{offset,spacing}=this.options;const halfAngle=(startAngle+endAngle)/2;const halfRadius=(innerRadius+outerRadius+spacing+offset)/2;return{x:x+Math.cos(halfAngle)*halfRadius,y:y+Math.sin(halfAngle)*halfRadius};} tooltipPosition(useFinalPosition){return this.getCenterPoint(useFinalPosition);} draw(ctx){const{options,circumference}=this;const offset=(options.offset||0)/4;const spacing=(options.spacing||0)/2;const circular=options.circular;this.pixelMargin=options.borderAlign==='inner'?0.33:0;this.fullCircles=circumference>TAU?Math.floor(circumference/TAU):0;if(circumference===0||this.innerRadius<0||this.outerRadius<0){return;} ctx.save();const halfAngle=(this.startAngle+this.endAngle)/2;ctx.translate(Math.cos(halfAngle)*offset,Math.sin(halfAngle)*offset);const fix=1-Math.sin(Math.min(PI,circumference||0));const radiusOffset=offset*fix;ctx.fillStyle=options.backgroundColor;ctx.strokeStyle=options.borderColor;drawArc(ctx,this,radiusOffset,spacing,circular);drawBorder(ctx,this,radiusOffset,spacing,circular);ctx.restore();}} function setStyle(ctx,options,style=options){ctx.lineCap=valueOrDefault(style.borderCapStyle,options.borderCapStyle);ctx.setLineDash(valueOrDefault(style.borderDash,options.borderDash));ctx.lineDashOffset=valueOrDefault(style.borderDashOffset,options.borderDashOffset);ctx.lineJoin=valueOrDefault(style.borderJoinStyle,options.borderJoinStyle);ctx.lineWidth=valueOrDefault(style.borderWidth,options.borderWidth);ctx.strokeStyle=valueOrDefault(style.borderColor,options.borderColor);} function lineTo(ctx,previous,target){ctx.lineTo(target.x,target.y);} function getLineMethod(options){if(options.stepped){return _steppedLineTo;} if(options.tension||options.cubicInterpolationMode==='monotone'){return _bezierCurveTo;} return lineTo;} function pathVars(points,segment,params={}){const count=points.length;const{start:paramsStart=0,end:paramsEnd=count-1}=params;const{start:segmentStart,end:segmentEnd}=segment;const start=Math.max(paramsStart,segmentStart);const end=Math.min(paramsEnd,segmentEnd);const outside=paramsStartsegmentEnd&¶msEnd>segmentEnd;return{count,start,loop:segment.loop,ilen:end(start+(reverse?ilen-index:index))%count;const drawX=()=>{if(minY!==maxY){ctx.lineTo(avgX,maxY);ctx.lineTo(avgX,minY);ctx.lineTo(avgX,lastY);}};if(move){point=points[pointIndex(0)];ctx.moveTo(point.x,point.y);} for(i=0;i<=ilen;++i){point=points[pointIndex(i)];if(point.skip){continue;} const x=point.x;const y=point.y;const truncX=x|0;if(truncX===prevX){if(ymaxY){maxY=y;} avgX=(countX*avgX+x)/++countX;}else{drawX();ctx.lineTo(x,y);prevX=truncX;countX=0;minY=maxY=y;} lastY=y;} drawX();} function _getSegmentMethod(line){const opts=line.options;const borderDash=opts.borderDash&&opts.borderDash.length;const useFastPath=!line._decimated&&!line._loop&&!opts.tension&&opts.cubicInterpolationMode!=='monotone'&&!opts.stepped&&!borderDash;return useFastPath?fastPathSegment:pathSegment;} function _getInterpolationMethod(options){if(options.stepped){return _steppedInterpolation;} if(options.tension||options.cubicInterpolationMode==='monotone'){return _bezierInterpolation;} return _pointInLine;} function strokePathWithCache(ctx,line,start,count){let path=line._path;if(!path){path=line._path=new Path2D();if(line.path(path,start,count)){path.closePath();}} setStyle(ctx,line.options);ctx.stroke(path);} function strokePathDirect(ctx,line,start,count){const{segments,options}=line;const segmentMethod=_getSegmentMethod(line);for(const segment of segments){setStyle(ctx,options,segment.style);ctx.beginPath();if(segmentMethod(ctx,line,segment,{start,end:start+count-1})){ctx.closePath();} ctx.stroke();}} const usePath2D=typeof Path2D==='function';function draw(ctx,line,start,count){if(usePath2D&&!line.options.segment){strokePathWithCache(ctx,line,start,count);}else{strokePathDirect(ctx,line,start,count);}} class LineElement extends Element{static id='line';static defaults={borderCapStyle:'butt',borderDash:[],borderDashOffset:0,borderJoinStyle:'miter',borderWidth:3,capBezierPoints:true,cubicInterpolationMode:'default',fill:false,spanGaps:false,stepped:false,tension:0};static defaultRoutes={backgroundColor:'backgroundColor',borderColor:'borderColor'};static descriptors={_scriptable:true,_indexable:(name)=>name!=='borderDash'&&name!=='fill'};constructor(cfg){super();this.animated=true;this.options=undefined;this._chart=undefined;this._loop=undefined;this._fullLoop=undefined;this._path=undefined;this._points=undefined;this._segments=undefined;this._decimated=false;this._pointsUpdated=false;this._datasetIndex=undefined;if(cfg){Object.assign(this,cfg);}} updateControlPoints(chartArea,indexAxis){const options=this.options;if((options.tension||options.cubicInterpolationMode==='monotone')&&!options.stepped&&!this._pointsUpdated){const loop=options.spanGaps?this._loop:this._fullLoop;_updateBezierControlPoints(this._points,options,chartArea,loop,indexAxis);this._pointsUpdated=true;}} set points(points){this._points=points;delete this._segments;delete this._path;this._pointsUpdated=false;} get points(){return this._points;} get segments(){return this._segments||(this._segments=_computeSegments(this,this.options.segment));} first(){const segments=this.segments;const points=this.points;return segments.length&&points[segments[0].start];} last(){const segments=this.segments;const points=this.points;const count=segments.length;return count&&points[segments[count-1].end];} interpolate(point,property){const options=this.options;const value=point[property];const points=this.points;const segments=_boundSegments(this,{property,start:value,end:value});if(!segments.length){return;} const result=[];const _interpolate=_getInterpolationMethod(options);let i,ilen;for(i=0,ilen=segments.length;i{if(typeof raw==='string'){index=labels.push(raw)-1;addedLabels.unshift({index,label:raw});}else if(isNaN(raw)){index=null;} return index;};function findOrAddLabel(labels,raw,index,addedLabels){const first=labels.indexOf(raw);if(first===-1){return addIfString(labels,raw,index,addedLabels);} const last=labels.lastIndexOf(raw);return first!==last?index:first;} const validIndex=(index,max)=>index===null?null:_limitValue(Math.round(index),0,max);function _getLabelForValue(value){const labels=this.getLabels();if(value>=0&&valueticks.length-1){return null;} return this.getPixelForValue(ticks[index].value);} getValueForPixel(pixel){return Math.round(this._startValue+this.getDecimalForPixel(pixel)*this._valueRange);} getBasePixel(){return this.bottom;}} function generateTicks$1(generationOptions,dataRange){const ticks=[];const MIN_SPACING=1e-14;const{bounds,step,min,max,precision,count,maxTicks,maxDigits,includeBounds}=generationOptions;const unit=step||1;const maxSpaces=maxTicks-1;const{min:rmin,max:rmax}=dataRange;const minDefined=!isNullOrUndef(min);const maxDefined=!isNullOrUndef(max);const countDefined=!isNullOrUndef(count);const minSpacing=(rmax-rmin)/(maxDigits+1);let spacing=niceNum((rmax-rmin)/maxSpaces/unit)*unit;let factor,niceMin,niceMax,numSpaces;if(spacingmaxSpaces){spacing=niceNum(numSpaces*spacing/maxSpaces/unit)*unit;} if(!isNullOrUndef(precision)){factor=Math.pow(10,precision);spacing=Math.ceil(spacing*factor)/factor;} if(bounds==='ticks'){niceMin=Math.floor(rmin/spacing)*spacing;niceMax=Math.ceil(rmax/spacing)*spacing;}else{niceMin=rmin;niceMax=rmax;} if(minDefined&&maxDefined&&step&&almostWhole((max-min)/step,spacing/1000)){numSpaces=Math.round(Math.min((max-min)/spacing,maxTicks));spacing=(max-min)/numSpaces;niceMin=min;niceMax=max;}else if(countDefined){niceMin=minDefined?min:niceMin;niceMax=maxDefined?max:niceMax;numSpaces=count-1;spacing=(niceMax-niceMin)/numSpaces;}else{numSpaces=(niceMax-niceMin)/spacing;if(almostEquals(numSpaces,Math.round(numSpaces),spacing/1000)){numSpaces=Math.round(numSpaces);}else{numSpaces=Math.ceil(numSpaces);}} const decimalPlaces=Math.max(_decimalPlaces(spacing),_decimalPlaces(niceMin));factor=Math.pow(10,isNullOrUndef(precision)?decimalPlaces:precision);niceMin=Math.round(niceMin*factor)/factor;niceMax=Math.round(niceMax*factor)/factor;let j=0;if(minDefined){if(includeBounds&&niceMin!==min){ticks.push({value:min});if(niceMinmax){break;} ticks.push({value:tickValue});} if(maxDefined&&includeBounds&&niceMax!==max){if(ticks.length&&almostEquals(ticks[ticks.length-1].value,max,relativeLabelSize(max,minSpacing,generationOptions))){ticks[ticks.length-1].value=max;}else{ticks.push({value:max});}}else if(!maxDefined||niceMax===max){ticks.push({value:niceMax});} return ticks;} function relativeLabelSize(value,minSpacing,{horizontal,minRotation}){const rad=toRadians(minRotation);const ratio=(horizontal?Math.sin(rad):Math.cos(rad))||0.001;const length=0.75*minSpacing*(''+value).length;return Math.min(minSpacing/ratio,length);} class LinearScaleBase extends Scale{constructor(cfg){super(cfg);this.start=undefined;this.end=undefined;this._startValue=undefined;this._endValue=undefined;this._valueRange=0;} parse(raw,index){if(isNullOrUndef(raw)){return null;} if((typeof raw==='number'||raw instanceof Number)&&!isFinite(+raw)){return null;} return+raw;} handleTickRangeOptions(){const{beginAtZero}=this.options;const{minDefined,maxDefined}=this.getUserBounds();let{min,max}=this;const setMin=(v)=>min=minDefined?min:v;const setMax=(v)=>max=maxDefined?max:v;if(beginAtZero){const minSign=sign(min);const maxSign=sign(max);if(minSign<0&&maxSign<0){setMax(0);}else if(minSign>0&&maxSign>0){setMin(0);}} if(min===max){let offset=max===0?1:Math.abs(max*0.05);setMax(max+offset);if(!beginAtZero){setMin(min-offset);}} this.min=min;this.max=max;} getTickLimit(){const tickOpts=this.options.ticks;let{maxTicksLimit,stepSize}=tickOpts;let maxTicks;if(stepSize){maxTicks=Math.ceil(this.max/stepSize)-Math.floor(this.min/stepSize)+1;if(maxTicks>1000){console.warn(`scales.${this.id}.ticks.stepSize: ${stepSize} would result generating up to ${maxTicks} ticks. Limiting to 1000.`);maxTicks=1000;}}else{maxTicks=this.computeTickLimit();maxTicksLimit=maxTicksLimit||11;} if(maxTicksLimit){maxTicks=Math.min(maxTicksLimit,maxTicks);} return maxTicks;} computeTickLimit(){return Number.POSITIVE_INFINITY;} buildTicks(){const opts=this.options;const tickOpts=opts.ticks;let maxTicks=this.getTickLimit();maxTicks=Math.max(2,maxTicks);const numericGeneratorOptions={maxTicks,bounds:opts.bounds,min:opts.min,max:opts.max,precision:tickOpts.precision,step:tickOpts.stepSize,count:tickOpts.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:tickOpts.minRotation||0,includeBounds:tickOpts.includeBounds!==false};const dataRange=this._range||this;const ticks=generateTicks$1(numericGeneratorOptions,dataRange);if(opts.bounds==='ticks'){_setMinAndMaxByKey(ticks,this,'value');} if(opts.reverse){ticks.reverse();this.start=this.max;this.end=this.min;}else{this.start=this.min;this.end=this.max;} return ticks;} configure(){const ticks=this.ticks;let start=this.min;let end=this.max;super.configure();if(this.options.offset&&ticks.length){const offset=(end-start)/Math.max(ticks.length-1,1)/2;start-=offset;end+=offset;} this._startValue=start;this._endValue=end;this._valueRange=end-start;} getLabelForValue(value){return formatNumber(value,this.chart.options.locale,this.options.ticks.format);}} class LinearScale extends LinearScaleBase{static id='linear';static defaults={ticks:{callback:Ticks.formatters.numeric}};determineDataLimits(){const{min,max}=this.getMinMax(true);this.min=isNumberFinite(min)?min:0;this.max=isNumberFinite(max)?max:1;this.handleTickRangeOptions();} computeTickLimit(){const horizontal=this.isHorizontal();const length=horizontal?this.width:this.height;const minRotation=toRadians(this.options.ticks.minRotation);const ratio=(horizontal?Math.sin(minRotation):Math.cos(minRotation))||0.001;const tickFont=this._resolveTickFontOptions(0);return Math.ceil(length/Math.min(40,tickFont.lineHeight/ratio));} getPixelForValue(value){return value===null?NaN:this.getPixelForDecimal((value-this._startValue)/this._valueRange);} getValueForPixel(pixel){return this._startValue+this.getDecimalForPixel(pixel)*this._valueRange;}} const log10Floor=(v)=>Math.floor(log10(v));const changeExponent=(v,m)=>Math.pow(10,log10Floor(v)+m);function isMajor(tickVal){const remain=tickVal/Math.pow(10,log10Floor(tickVal));return remain===1;} function steps(min,max,rangeExp){const rangeStep=Math.pow(10,rangeExp);const start=Math.floor(min/rangeStep);const end=Math.ceil(max/rangeStep);return end-start;} function startExp(min,max){const range=max-min;let rangeExp=log10Floor(range);while(steps(min,max,rangeExp)>10){rangeExp++;} while(steps(min,max,rangeExp)<10){rangeExp--;} return Math.min(rangeExp,log10Floor(min));} function generateTicks(generationOptions,{min,max}){min=finiteOrDefault(generationOptions.min,min);const ticks=[];const minExp=log10Floor(min);let exp=startExp(min,max);let precision=exp<0?Math.pow(10,Math.abs(exp)):1;const stepSize=Math.pow(10,exp);const base=minExp>exp?Math.pow(10,minExp):0;const start=Math.round((min-base)*precision)/precision;const offset=Math.floor((min-base)/stepSize/10)*stepSize*10;let significand=Math.floor((start-offset)/Math.pow(10,exp));let value=finiteOrDefault(generationOptions.min,Math.round((base+offset+significand*Math.pow(10,exp))*precision)/precision);while(value=10){significand=significand<15?15:20;}else{significand++;} if(significand>=20){exp++;significand=2;precision=exp>=0?1:precision;} value=Math.round((base+offset+significand*Math.pow(10,exp))*precision)/precision;} const lastTick=finiteOrDefault(generationOptions.max,value);ticks.push({value:lastTick,major:isMajor(lastTick),significand});return ticks;} class LogarithmicScale extends Scale{static id='logarithmic';static defaults={ticks:{callback:Ticks.formatters.logarithmic,major:{enabled:true}}};constructor(cfg){super(cfg);this.start=undefined;this.end=undefined;this._startValue=undefined;this._valueRange=0;} parse(raw,index){const value=LinearScaleBase.prototype.parse.apply(this,[raw,index]);if(value===0){this._zero=true;return undefined;} return isNumberFinite(value)&&value>0?value:null;} determineDataLimits(){const{min,max}=this.getMinMax(true);this.min=isNumberFinite(min)?Math.max(0,min):null;this.max=isNumberFinite(max)?Math.max(0,max):null;if(this.options.beginAtZero){this._zero=true;} if(this._zero&&this.min!==this._suggestedMin&&!isNumberFinite(this._userMin)){this.min=min===changeExponent(this.min,0)?changeExponent(this.min,-1):changeExponent(this.min,0);} this.handleTickRangeOptions();} handleTickRangeOptions(){const{minDefined,maxDefined}=this.getUserBounds();let min=this.min;let max=this.max;const setMin=(v)=>min=minDefined?min:v;const setMax=(v)=>max=maxDefined?max:v;if(min===max){if(min<=0){setMin(1);setMax(10);}else{setMin(changeExponent(min,-1));setMax(changeExponent(max,+1));}} if(min<=0){setMin(changeExponent(max,-1));} if(max<=0){setMax(changeExponent(min,+1));} this.min=min;this.max=max;} buildTicks(){const opts=this.options;const generationOptions={min:this._userMin,max:this._userMax};const ticks=generateTicks(generationOptions,this);if(opts.bounds==='ticks'){_setMinAndMaxByKey(ticks,this,'value');} if(opts.reverse){ticks.reverse();this.start=this.max;this.end=this.min;}else{this.start=this.min;this.end=this.max;} return ticks;} getLabelForValue(value){return value===undefined?'0':formatNumber(value,this.chart.options.locale,this.options.ticks.format);} configure(){const start=this.min;super.configure();this._startValue=log10(start);this._valueRange=log10(this.max)-log10(start);} getPixelForValue(value){if(value===undefined||value===0){value=this.min;} if(value===null||isNaN(value)){return NaN;} return this.getPixelForDecimal(value===this.min?0:(log10(value)-this._startValue)/this._valueRange);} getValueForPixel(pixel){const decimal=this.getDecimalForPixel(pixel);return Math.pow(10,this._startValue+decimal*this._valueRange);}} function getTickBackdropHeight(opts){const tickOpts=opts.ticks;if(tickOpts.display&&opts.display){const padding=toPadding(tickOpts.backdropPadding);return valueOrDefault(tickOpts.font&&tickOpts.font.size,defaults.font.size)+padding.height;} return 0;} function measureLabelSize(ctx,font,label){label=isArray(label)?label:[label];return{w:_longestText(ctx,font.string,label),h:label.length*font.lineHeight};} function determineLimits(angle,pos,size,min,max){if(angle===min||angle===max){return{start:pos-size/2,end:pos+size/2};}else if(anglemax){return{start:pos-size,end:pos};} return{start:pos,end:pos+size};} function fitWithPointLabels(scale){const orig={l:scale.left+scale._padding.left,r:scale.right-scale._padding.right,t:scale.top+scale._padding.top,b:scale.bottom-scale._padding.bottom};const limits=Object.assign({},orig);const labelSizes=[];const padding=[];const valueCount=scale._pointLabels.length;const pointLabelOpts=scale.options.pointLabels;const additionalAngle=pointLabelOpts.centerPointLabels?PI/valueCount:0;for(let i=0;iorig.r){x=(hLimits.end-orig.r)/sin;limits.r=Math.max(limits.r,orig.r+x);} if(vLimits.startorig.b){y=(vLimits.end-orig.b)/cos;limits.b=Math.max(limits.b,orig.b+y);}} function createPointLabelItem(scale,index,itemOpts){const outerDistance=scale.drawingArea;const{extra,additionalAngle,padding,size}=itemOpts;const pointLabelPosition=scale.getPointPosition(index,outerDistance+extra+padding,additionalAngle);const angle=Math.round(toDegrees(_normalizeAngle(pointLabelPosition.angle+HALF_PI)));const y=yForAngle(pointLabelPosition.y,size.h,angle);const textAlign=getTextAlignForAngle(angle);const left=leftForTextAlign(pointLabelPosition.x,size.w,textAlign);return{visible:true,x:pointLabelPosition.x,y,textAlign,left,top:y,right:left+size.w,bottom:y+size.h};} function isNotOverlapped(item,area){if(!area){return true;} const{left,top,right,bottom}=item;const apexesInArea=_isPointInArea({x:left,y:top},area)||_isPointInArea({x:left,y:bottom},area)||_isPointInArea({x:right,y:top},area)||_isPointInArea({x:right,y:bottom},area);return!apexesInArea;} function buildPointLabelItems(scale,labelSizes,padding){const items=[];const valueCount=scale._pointLabels.length;const opts=scale.options;const{centerPointLabels,display}=opts.pointLabels;const itemOpts={extra:getTickBackdropHeight(opts)/2,additionalAngle:centerPointLabels?PI/valueCount:0};let area;for(let i=0;i270||angle<90){y-=h;} return y;} function drawPointLabelBox(ctx,opts,item){const{left,top,right,bottom}=item;const{backdropColor}=opts;if(!isNullOrUndef(backdropColor)){const borderRadius=toTRBLCorners(opts.borderRadius);const padding=toPadding(opts.backdropPadding);ctx.fillStyle=backdropColor;const backdropLeft=left-padding.left;const backdropTop=top-padding.top;const backdropWidth=right-left+padding.width;const backdropHeight=bottom-top+padding.height;if(Object.values(borderRadius).some((v)=>v!==0)){ctx.beginPath();addRoundedRectPath(ctx,{x:backdropLeft,y:backdropTop,w:backdropWidth,h:backdropHeight,radius:borderRadius});ctx.fill();}else{ctx.fillRect(backdropLeft,backdropTop,backdropWidth,backdropHeight);}}} function drawPointLabels(scale,labelCount){const{ctx,options:{pointLabels}}=scale;for(let i=labelCount-1;i>=0;i--){const item=scale._pointLabelItems[i];if(!item.visible){continue;} const optsAtIndex=pointLabels.setContext(scale.getPointLabelContext(i));drawPointLabelBox(ctx,optsAtIndex,item);const plFont=toFont(optsAtIndex.font);const{x,y,textAlign}=item;renderText(ctx,scale._pointLabels[i],x,y+plFont.lineHeight/2,plFont,{color:optsAtIndex.color,textAlign:textAlign,textBaseline:'middle'});}} function pathRadiusLine(scale,radius,circular,labelCount){const{ctx}=scale;if(circular){ctx.arc(scale.xCenter,scale.yCenter,radius,0,TAU);}else{let pointPosition=scale.getPointPosition(0,radius);ctx.moveTo(pointPosition.x,pointPosition.y);for(let i=1;i{const label=callback(this.options.pointLabels.callback,[value,index],this);return label||label===0?label:'';}).filter((v,i)=>this.chart.getDataVisibility(i));} fit(){const opts=this.options;if(opts.display&&opts.pointLabels.display){fitWithPointLabels(this);}else{this.setCenterPoint(0,0,0,0);}} setCenterPoint(leftMovement,rightMovement,topMovement,bottomMovement){this.xCenter+=Math.floor((leftMovement-rightMovement)/2);this.yCenter+=Math.floor((topMovement-bottomMovement)/2);this.drawingArea-=Math.min(this.drawingArea/2,Math.max(leftMovement,rightMovement,topMovement,bottomMovement));} getIndexAngle(index){const angleMultiplier=TAU/(this._pointLabels.length||1);const startAngle=this.options.startAngle||0;return _normalizeAngle(index*angleMultiplier+toRadians(startAngle));} getDistanceFromCenterForValue(value){if(isNullOrUndef(value)){return NaN;} const scalingFactor=this.drawingArea/(this.max-this.min);if(this.options.reverse){return(this.max-value)*scalingFactor;} return(value-this.min)*scalingFactor;} getValueForDistanceFromCenter(distance){if(isNullOrUndef(distance)){return NaN;} const scaledDistance=distance/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-scaledDistance:this.min+scaledDistance;} getPointLabelContext(index){const pointLabels=this._pointLabels||[];if(index>=0&&index{if(index!==0||index===0&&this.min<0){offset=this.getDistanceFromCenterForValue(tick.value);const context=this.getContext(index);const optsAtIndex=grid.setContext(context);const optsAtIndexBorder=border.setContext(context);drawRadiusLine(this,optsAtIndex,offset,labelCount,optsAtIndexBorder);}});} if(angleLines.display){ctx.save();for(i=labelCount-1;i>=0;i--){const optsAtIndex=angleLines.setContext(this.getPointLabelContext(i));const{color,lineWidth}=optsAtIndex;if(!lineWidth||!color){continue;} ctx.lineWidth=lineWidth;ctx.strokeStyle=color;ctx.setLineDash(optsAtIndex.borderDash);ctx.lineDashOffset=optsAtIndex.borderDashOffset;offset=this.getDistanceFromCenterForValue(opts.reverse?this.min:this.max);position=this.getPointPosition(i,offset);ctx.beginPath();ctx.moveTo(this.xCenter,this.yCenter);ctx.lineTo(position.x,position.y);ctx.stroke();} ctx.restore();}} drawBorder(){} drawLabels(){const ctx=this.ctx;const opts=this.options;const tickOpts=opts.ticks;if(!tickOpts.display){return;} const startAngle=this.getIndexAngle(0);let offset,width;ctx.save();ctx.translate(this.xCenter,this.yCenter);ctx.rotate(startAngle);ctx.textAlign='center';ctx.textBaseline='middle';this.ticks.forEach((tick,index)=>{if(index===0&&this.min>=0&&!opts.reverse){return;} const optsAtIndex=tickOpts.setContext(this.getContext(index));const tickFont=toFont(optsAtIndex.font);offset=this.getDistanceFromCenterForValue(this.ticks[index].value);if(optsAtIndex.showLabelBackdrop){ctx.font=tickFont.string;width=ctx.measureText(tick.label).width;ctx.fillStyle=optsAtIndex.backdropColor;const padding=toPadding(optsAtIndex.backdropPadding);ctx.fillRect(-width/2-padding.left,-offset-tickFont.size/2-padding.top,width+padding.width,tickFont.size+padding.height);} renderText(ctx,tick.label,0,-offset,tickFont,{color:optsAtIndex.color,strokeColor:optsAtIndex.textStrokeColor,strokeWidth:optsAtIndex.textStrokeWidth});});ctx.restore();} drawTitle(){}} const INTERVALS={millisecond:{common:true,size:1,steps:1000},second:{common:true,size:1000,steps:60},minute:{common:true,size:60000,steps:60},hour:{common:true,size:3600000,steps:24},day:{common:true,size:86400000,steps:30},week:{common:false,size:604800000,steps:4},month:{common:true,size:2.628e9,steps:12},quarter:{common:false,size:7.884e9,steps:4},year:{common:true,size:3.154e10}};const UNITS=Object.keys(INTERVALS);function sorter(a,b){return a-b;} function parse(scale,input){if(isNullOrUndef(input)){return null;} const adapter=scale._adapter;const{parser,round,isoWeekday}=scale._parseOpts;let value=input;if(typeof parser==='function'){value=parser(value);} if(!isNumberFinite(value)){value=typeof parser==='string'?adapter.parse(value,parser):adapter.parse(value);} if(value===null){return null;} if(round){value=round==='week'&&(isNumber(isoWeekday)||isoWeekday===true)?adapter.startOf(value,'isoWeek',isoWeekday):adapter.startOf(value,round);} return+value;} function determineUnitForAutoTicks(minUnit,min,max,capacity){const ilen=UNITS.length;for(let i=UNITS.indexOf(minUnit);i=UNITS.indexOf(minUnit);i--){const unit=UNITS[i];if(INTERVALS[unit].common&&scale._adapter.diff(max,min,unit)>=numTicks-1){return unit;}} return UNITS[minUnit?UNITS.indexOf(minUnit):0];} function determineMajorUnit(unit){for(let i=UNITS.indexOf(unit)+1,ilen=UNITS.length;i=time?timestamps[lo]:timestamps[hi];ticks[timestamp]=true;}} function setMajorTicks(scale,ticks,map,majorUnit){const adapter=scale._adapter;const first=+adapter.startOf(ticks[0].value,majorUnit);const last=ticks[ticks.length-1].value;let major,index;for(major=first;major<=last;major=+adapter.add(major,1,majorUnit)){index=map[major];if(index>=0){ticks[index].major=true;}} return ticks;} function ticksFromTimestamps(scale,values,majorUnit){const ticks=[];const map={};const ilen=values.length;let i,value;for(i=0;i+tick.value));}} initOffsets(timestamps=[]){let start=0;let end=0;let first,last;if(this.options.offset&×tamps.length){first=this.getDecimalForValue(timestamps[0]);if(timestamps.length===1){start=1-first;}else{start=(this.getDecimalForValue(timestamps[1])-first)/2;} last=this.getDecimalForValue(timestamps[timestamps.length-1]);if(timestamps.length===1){end=last;}else{end=(last-this.getDecimalForValue(timestamps[timestamps.length-2]))/2;}} const limit=timestamps.length<3?0.5:0.25;start=_limitValue(start,0,limit);end=_limitValue(end,0,limit);this._offsets={start,end,factor:1/(start+1+end)};} _generate(){const adapter=this._adapter;const min=this.min;const max=this.max;const options=this.options;const timeOpts=options.time;const minor=timeOpts.unit||determineUnitForAutoTicks(timeOpts.minUnit,min,max,this._getLabelCapacity(min));const stepSize=valueOrDefault(options.ticks.stepSize,1);const weekday=minor==='week'?timeOpts.isoWeekday:false;const hasWeekday=isNumber(weekday)||weekday===true;const ticks={};let first=min;let time,count;if(hasWeekday){first=+adapter.startOf(first,'isoWeek',weekday);} first=+adapter.startOf(first,hasWeekday?'day':minor);if(adapter.diff(max,min,minor)>100000*stepSize){throw new Error(min+' and '+max+' are too far apart with stepSize of '+stepSize+' '+minor);} const timestamps=options.ticks.source==='data'&&this.getDataTimestamps();for(time=first,count=0;time+x);} getLabelForValue(value){const adapter=this._adapter;const timeOpts=this.options.time;if(timeOpts.tooltipFormat){return adapter.format(value,timeOpts.tooltipFormat);} return adapter.format(value,timeOpts.displayFormats.datetime);} format(value,format){const options=this.options;const formats=options.time.displayFormats;const unit=this._unit;const fmt=format||formats[unit];return this._adapter.format(value,fmt);} _tickFormatFunction(time,index,ticks,format){const options=this.options;const formatter=options.ticks.callback;if(formatter){return callback(formatter,[time,index,ticks],this);} const formats=options.time.displayFormats;const unit=this._unit;const majorUnit=this._majorUnit;const minorFormat=unit&&formats[unit];const majorFormat=majorUnit&&formats[majorUnit];const tick=ticks[index];const major=majorUnit&&majorFormat&&tick&&tick.major;return this._adapter.format(time,format||(major?majorFormat:minorFormat));} generateTickLabels(ticks){let i,ilen,tick;for(i=0,ilen=ticks.length;i0?capacity:1;} getDataTimestamps(){let timestamps=this._cache.data||[];let i,ilen;if(timestamps.length){return timestamps;} const metas=this.getMatchingVisibleMetas();if(this._normalized&&metas.length){return this._cache.data=metas[0].controller.getAllParsedValues(this);} for(i=0,ilen=metas.length;i=table[lo].pos&&val<=table[hi].pos){({lo,hi}=_lookupByKey(table,'pos',val));} ({pos:prevSource,time:prevTarget}=table[lo]);({pos:nextSource,time:nextTarget}=table[hi]);}else{if(val>=table[lo].time&&val<=table[hi].time){({lo,hi}=_lookupByKey(table,'time',val));} ({time:prevSource,pos:prevTarget}=table[lo]);({time:nextSource,pos:nextTarget}=table[hi]);} const span=nextSource-prevSource;return span?prevTarget+(nextTarget-prevTarget)*(val-prevSource)/span:prevTarget;} class TimeSeriesScale extends TimeScale{static id='timeseries';static defaults=TimeScale.defaults;constructor(props){super(props);this._table=[];this._minPos=undefined;this._tableRange=undefined;} initOffsets(){const timestamps=this._getTimestampsForTable();const table=this._table=this.buildLookupTable(timestamps);this._minPos=interpolate(table,this.min);this._tableRange=interpolate(table,this.max)-this._minPos;super.initOffsets(timestamps);} buildLookupTable(timestamps){const{min,max}=this;const items=[];const table=[];let i,ilen,prev,curr,next;for(i=0,ilen=timestamps.length;i=min&&curr<=max){items.push(curr);}} if(items.length<2){return[{time:min,pos:0},{time:max,pos:1}];} for(i=0,ilen=items.length;ia-b);} _getTimestampsForTable(){let timestamps=this._cache.all||[];if(timestamps.length){return timestamps;} const data=this.getDataTimestamps();const label=this.getLabelTimestamps();if(data.length&&label.length){timestamps=this.normalize(data.concat(label));}else{timestamps=data.length?data:label;} timestamps=this._cache.all=timestamps;return timestamps;} getDecimalForValue(value){return(interpolate(this._table,value)-this._minPos)/this._tableRange;} getValueForPixel(pixel){const offsets=this._offsets;const decimal=this.getDecimalForPixel(pixel)/offsets.factor-offsets.end;return interpolate(this._table,decimal*this._tableRange+this._minPos,true);}} var scales=Object.freeze({__proto__:null,CategoryScale:CategoryScale,LinearScale:LinearScale,LogarithmicScale:LogarithmicScale,RadialLinearScale:RadialLinearScale,TimeScale:TimeScale,TimeSeriesScale:TimeSeriesScale});const BORDER_COLORS=['rgb(54, 162, 235)','rgb(255, 99, 132)','rgb(255, 159, 64)','rgb(255, 205, 86)','rgb(75, 192, 192)','rgb(153, 102, 255)','rgb(201, 203, 207)'];const BACKGROUND_COLORS=BORDER_COLORS.map((color)=>color.replace('rgb(','rgba(').replace(')',', 0.5)'));function getBorderColor(i){return BORDER_COLORS[i%BORDER_COLORS.length];} function getBackgroundColor(i){return BACKGROUND_COLORS[i%BACKGROUND_COLORS.length];} function colorizeDefaultDataset(dataset,i){dataset.borderColor=getBorderColor(i);dataset.backgroundColor=getBackgroundColor(i);return++i;} function colorizeDoughnutDataset(dataset,i){dataset.backgroundColor=dataset.data.map(()=>getBorderColor(i++));return i;} function colorizePolarAreaDataset(dataset,i){dataset.backgroundColor=dataset.data.map(()=>getBackgroundColor(i++));return i;} function getColorizer(chart){let i=0;return(dataset,datasetIndex)=>{const controller=chart.getDatasetMeta(datasetIndex).controller;if(controller instanceof DoughnutController){i=colorizeDoughnutDataset(dataset,i);}else if(controller instanceof PolarAreaController){i=colorizePolarAreaDataset(dataset,i);}else if(controller){i=colorizeDefaultDataset(dataset,i);}};} function containsColorsDefinitions(descriptors){let k;for(k in descriptors){if(descriptors[k].borderColor||descriptors[k].backgroundColor){return true;}} return false;} function containsColorsDefinition(descriptor){return descriptor&&(descriptor.borderColor||descriptor.backgroundColor);} function containsDefaultColorsDefenitions(){return defaults.borderColor!=='rgba(0,0,0,0.1)'||defaults.backgroundColor!=='rgba(0,0,0,0.1)';} var plugin_colors={id:'colors',defaults:{enabled:true,forceOverride:false},beforeLayout(chart,_args,options){if(!options.enabled){return;} const{data:{datasets},options:chartOptions}=chart.config;const{elements}=chartOptions;const containsColorDefenition=containsColorsDefinitions(datasets)||containsColorsDefinition(chartOptions)||elements&&containsColorsDefinitions(elements)||containsDefaultColorsDefenitions();if(!options.forceOverride&&containsColorDefenition){return;} const colorizer=getColorizer(chart);datasets.forEach(colorizer);}};function lttbDecimation(data,start,count,availableWidth,options){const samples=options.samples||availableWidth;if(samples>=count){return data.slice(start,start+count);} const decimated=[];const bucketWidth=(count-2)/(samples-2);let sampledIndex=0;const endIndex=start+count-1;let a=start;let i,maxAreaPoint,maxArea,area,nextA;decimated[sampledIndex++]=data[a];for(i=0;imaxArea){maxArea=area;maxAreaPoint=data[j];nextA=j;}} decimated[sampledIndex++]=maxAreaPoint;a=nextA;} decimated[sampledIndex++]=data[endIndex];return decimated;} function minMaxDecimation(data,start,count,availableWidth){let avgX=0;let countX=0;let i,point,x,y,prevX,minIndex,maxIndex,startIndex,minY,maxY;const decimated=[];const endIndex=start+count-1;const xMin=data[start].x;const xMax=data[endIndex].x;const dx=xMax-xMin;for(i=start;imaxY){maxY=y;maxIndex=i;} avgX=(countX*avgX+point.x)/++countX;}else{const lastIndex=i-1;if(!isNullOrUndef(minIndex)&&!isNullOrUndef(maxIndex)){const intermediateIndex1=Math.min(minIndex,maxIndex);const intermediateIndex2=Math.max(minIndex,maxIndex);if(intermediateIndex1!==startIndex&&intermediateIndex1!==lastIndex){decimated.push({...data[intermediateIndex1],x:avgX});} if(intermediateIndex2!==startIndex&&intermediateIndex2!==lastIndex){decimated.push({...data[intermediateIndex2],x:avgX});}} if(i>0&&lastIndex!==startIndex){decimated.push(data[lastIndex]);} decimated.push(point);prevX=truncX;countX=0;minY=maxY=y;minIndex=maxIndex=startIndex=i;}} return decimated;} function cleanDecimatedDataset(dataset){if(dataset._decimated){const data=dataset._data;delete dataset._decimated;delete dataset._data;Object.defineProperty(dataset,'data',{configurable:true,enumerable:true,writable:true,value:data});}} function cleanDecimatedData(chart){chart.data.datasets.forEach((dataset)=>{cleanDecimatedDataset(dataset);});} function getStartAndCountOfVisiblePointsSimplified(meta,points){const pointCount=points.length;let start=0;let count;const{iScale}=meta;const{min,max,minDefined,maxDefined}=iScale.getUserBounds();if(minDefined){start=_limitValue(_lookupByKey(points,iScale.axis,min).lo,0,pointCount-1);} if(maxDefined){count=_limitValue(_lookupByKey(points,iScale.axis,max).hi+1,start,pointCount)-start;}else{count=pointCount-start;} return{start,count};} var plugin_decimation={id:'decimation',defaults:{algorithm:'min-max',enabled:false},beforeElementsUpdate:(chart,args,options)=>{if(!options.enabled){cleanDecimatedData(chart);return;} const availableWidth=chart.width;chart.data.datasets.forEach((dataset,datasetIndex)=>{const{_data,indexAxis}=dataset;const meta=chart.getDatasetMeta(datasetIndex);const data=_data||dataset.data;if(resolve([indexAxis,chart.options.indexAxis])==='y'){return;} if(!meta.controller.supportsDecimation){return;} const xAxis=chart.scales[meta.xAxisID];if(xAxis.type!=='linear'&&xAxis.type!=='time'){return;} if(chart.options.parsing){return;} let{start,count}=getStartAndCountOfVisiblePointsSimplified(meta,data);const threshold=options.threshold||4*availableWidth;if(count<=threshold){cleanDecimatedDataset(dataset);return;} if(isNullOrUndef(_data)){dataset._data=data;delete dataset.data;Object.defineProperty(dataset,'data',{configurable:true,enumerable:true,get:function(){return this._decimated;},set:function(d){this._data=d;}});} let decimated;switch(options.algorithm){case'lttb':decimated=lttbDecimation(data,start,count,availableWidth,options);break;case'min-max':decimated=minMaxDecimation(data,start,count,availableWidth);break;default:throw new Error(`Unsupported decimation algorithm '${options.algorithm}'`);} dataset._decimated=decimated;});},destroy(chart){cleanDecimatedData(chart);}};function _segments(line,target,property){const segments=line.segments;const points=line.points;const tpoints=target.points;const parts=[];for(const segment of segments){let{start,end}=segment;end=_findSegmentEnd(start,end,points);const bounds=_getBounds(property,points[start],points[end],segment.loop);if(!target.segments){parts.push({source:segment,target:bounds,start:points[start],end:points[end]});continue;} const targetSegments=_boundSegments(target,bounds);for(const tgt of targetSegments){const subBounds=_getBounds(property,tpoints[tgt.start],tpoints[tgt.end],tgt.loop);const fillSources=_boundSegment(segment,points,subBounds);for(const fillSource of fillSources){parts.push({source:fillSource,target:tgt,start:{[property]:_getEdge(bounds,subBounds,'start',Math.max)},end:{[property]:_getEdge(bounds,subBounds,'end',Math.min)}});}}} return parts;} function _getBounds(property,first,last,loop){if(loop){return;} let start=first[property];let end=last[property];if(property==='angle'){start=_normalizeAngle(start);end=_normalizeAngle(end);} return{property,start,end};} function _pointsFromSegments(boundary,line){const{x=null,y=null}=boundary||{};const linePoints=line.points;const points=[];line.segments.forEach(({start,end})=>{end=_findSegmentEnd(start,end,linePoints);const first=linePoints[start];const last=linePoints[end];if(y!==null){points.push({x:first.x,y});points.push({x:last.x,y});}else if(x!==null){points.push({x,y:first.y});points.push({x,y:last.y});}});return points;} function _findSegmentEnd(start,end,points){for(;end>start;end--){const point=points[end];if(!isNaN(point.x)&&!isNaN(point.y)){break;}} return end;} function _getEdge(a,b,prop,fn){if(a&&b){return fn(a[prop],b[prop]);} return a?a[prop]:b?b[prop]:0;} function _createBoundaryLine(boundary,line){let points=[];let _loop=false;if(isArray(boundary)){_loop=true;points=boundary;}else{points=_pointsFromSegments(boundary,line);} return points.length?new LineElement({points,options:{tension:0},_loop,_fullLoop:_loop}):null;} function _shouldApplyFill(source){return source&&source.fill!==false;} function _resolveTarget(sources,index,propagate){const source=sources[index];let fill=source.fill;const visited=[index];let target;if(!propagate){return fill;} while(fill!==false&&visited.indexOf(fill)===-1){if(!isNumberFinite(fill)){return fill;} target=sources[fill];if(!target){return false;} if(target.visible){return fill;} visited.push(fill);fill=target.fill;} return false;} function _decodeFill(line,index,count){const fill=parseFillOption(line);if(isObject(fill)){return isNaN(fill.value)?false:fill;} let target=parseFloat(fill);if(isNumberFinite(target)&&Math.floor(target)===target){return decodeTargetIndex(fill[0],index,target,count);} return['origin','start','end','stack','shape'].indexOf(fill)>=0&&fill;} function decodeTargetIndex(firstCh,index,target,count){if(firstCh==='-'||firstCh==='+'){target=index+target;} if(target===index||target<0||target>=count){return false;} return target;} function _getTargetPixel(fill,scale){let pixel=null;if(fill==='start'){pixel=scale.bottom;}else if(fill==='end'){pixel=scale.top;}else if(isObject(fill)){pixel=scale.getPixelForValue(fill.value);}else if(scale.getBasePixel){pixel=scale.getBasePixel();} return pixel;} function _getTargetValue(fill,scale,startValue){let value;if(fill==='start'){value=startValue;}else if(fill==='end'){value=scale.options.reverse?scale.min:scale.max;}else if(isObject(fill)){value=fill.value;}else{value=scale.getBaseValue();} return value;} function parseFillOption(line){const options=line.options;const fillOption=options.fill;let fill=valueOrDefault(fillOption&&fillOption.target,fillOption);if(fill===undefined){fill=!!options.backgroundColor;} if(fill===false||fill===null){return false;} if(fill===true){return'origin';} return fill;} function _buildStackLine(source){const{scale,index,line}=source;const points=[];const segments=line.segments;const sourcePoints=line.points;const linesBelow=getLinesBelow(scale,index);linesBelow.push(_createBoundaryLine({x:null,y:scale.bottom},line));for(let i=0;i=0;--i){const source=metasets[i].$filler;if(!source){continue;} source.line.updateControlPoints(area,source.axis);if(draw&&source.fill){_drawfill(chart.ctx,source,area);}}},beforeDatasetsDraw(chart,_args,options){if(options.drawTime!=='beforeDatasetsDraw'){return;} const metasets=chart.getSortedVisibleDatasetMetas();for(let i=metasets.length-1;i>=0;--i){const source=metasets[i].$filler;if(_shouldApplyFill(source)){_drawfill(chart.ctx,source,chart.chartArea);}}},beforeDatasetDraw(chart,args,options){const source=args.meta.$filler;if(!_shouldApplyFill(source)||options.drawTime!=='beforeDatasetDraw'){return;} _drawfill(chart.ctx,source,chart.chartArea);},defaults:{propagate:true,drawTime:'beforeDatasetDraw'}};const getBoxSize=(labelOpts,fontSize)=>{let{boxHeight=fontSize,boxWidth=fontSize}=labelOpts;if(labelOpts.usePointStyle){boxHeight=Math.min(boxHeight,fontSize);boxWidth=labelOpts.pointStyleWidth||Math.min(boxWidth,fontSize);} return{boxWidth,boxHeight,itemHeight:Math.max(fontSize,boxHeight)};};const itemsEqual=(a,b)=>a!==null&&b!==null&&a.datasetIndex===b.datasetIndex&&a.index===b.index;class Legend extends Element{constructor(config){super();this._added=false;this.legendHitBoxes=[];this._hoveredItem=null;this.doughnutMode=false;this.chart=config.chart;this.options=config.options;this.ctx=config.ctx;this.legendItems=undefined;this.columnSizes=undefined;this.lineWidths=undefined;this.maxHeight=undefined;this.maxWidth=undefined;this.top=undefined;this.bottom=undefined;this.left=undefined;this.right=undefined;this.height=undefined;this.width=undefined;this._margins=undefined;this.position=undefined;this.weight=undefined;this.fullSize=undefined;} update(maxWidth,maxHeight,margins){this.maxWidth=maxWidth;this.maxHeight=maxHeight;this._margins=margins;this.setDimensions();this.buildLabels();this.fit();} setDimensions(){if(this.isHorizontal()){this.width=this.maxWidth;this.left=this._margins.left;this.right=this.width;}else{this.height=this.maxHeight;this.top=this._margins.top;this.bottom=this.height;}} buildLabels(){const labelOpts=this.options.labels||{};let legendItems=callback(labelOpts.generateLabels,[this.chart],this)||[];if(labelOpts.filter){legendItems=legendItems.filter((item)=>labelOpts.filter(item,this.chart.data));} if(labelOpts.sort){legendItems=legendItems.sort((a,b)=>labelOpts.sort(a,b,this.chart.data));} if(this.options.reverse){legendItems.reverse();} this.legendItems=legendItems;} fit(){const{options,ctx}=this;if(!options.display){this.width=this.height=0;return;} const labelOpts=options.labels;const labelFont=toFont(labelOpts.font);const fontSize=labelFont.size;const titleHeight=this._computeTitleHeight();const{boxWidth,itemHeight}=getBoxSize(labelOpts,fontSize);let width,height;ctx.font=labelFont.string;if(this.isHorizontal()){width=this.maxWidth;height=this._fitRows(titleHeight,fontSize,boxWidth,itemHeight)+10;}else{height=this.maxHeight;width=this._fitCols(titleHeight,labelFont,boxWidth,itemHeight)+10;} this.width=Math.min(width,options.maxWidth||this.maxWidth);this.height=Math.min(height,options.maxHeight||this.maxHeight);} _fitRows(titleHeight,fontSize,boxWidth,itemHeight){const{ctx,maxWidth,options:{labels:{padding}}}=this;const hitboxes=this.legendHitBoxes=[];const lineWidths=this.lineWidths=[0];const lineHeight=itemHeight+padding;let totalHeight=titleHeight;ctx.textAlign='left';ctx.textBaseline='middle';let row=-1;let top=-lineHeight;this.legendItems.forEach((legendItem,i)=>{const itemWidth=boxWidth+fontSize/2+ctx.measureText(legendItem.text).width;if(i===0||lineWidths[lineWidths.length-1]+itemWidth+2*padding>maxWidth){totalHeight+=lineHeight;lineWidths[lineWidths.length-(i>0?0:1)]=0;top+=lineHeight;row++;} hitboxes[i]={left:0,top,row,width:itemWidth,height:itemHeight};lineWidths[lineWidths.length-1]+=itemWidth+padding;});return totalHeight;} _fitCols(titleHeight,labelFont,boxWidth,_itemHeight){const{ctx,maxHeight,options:{labels:{padding}}}=this;const hitboxes=this.legendHitBoxes=[];const columnSizes=this.columnSizes=[];const heightLimit=maxHeight-titleHeight;let totalWidth=padding;let currentColWidth=0;let currentColHeight=0;let left=0;let col=0;this.legendItems.forEach((legendItem,i)=>{const{itemWidth,itemHeight}=calculateItemSize(boxWidth,labelFont,ctx,legendItem,_itemHeight);if(i>0&¤tColHeight+itemHeight+2*padding>heightLimit){totalWidth+=currentColWidth+padding;columnSizes.push({width:currentColWidth,height:currentColHeight});left+=currentColWidth+padding;col++;currentColWidth=currentColHeight=0;} hitboxes[i]={left,top:currentColHeight,col,width:itemWidth,height:itemHeight};currentColWidth=Math.max(currentColWidth,itemWidth);currentColHeight+=itemHeight+padding;});totalWidth+=currentColWidth;columnSizes.push({width:currentColWidth,height:currentColHeight});return totalWidth;} adjustHitBoxes(){if(!this.options.display){return;} const titleHeight=this._computeTitleHeight();const{legendHitBoxes:hitboxes,options:{align,labels:{padding},rtl}}=this;const rtlHelper=getRtlAdapter(rtl,this.left,this.width);if(this.isHorizontal()){let row=0;let left=_alignStartEnd(align,this.left+padding,this.right-this.lineWidths[row]);for(const hitbox of hitboxes){if(row!==hitbox.row){row=hitbox.row;left=_alignStartEnd(align,this.left+padding,this.right-this.lineWidths[row]);} hitbox.top+=this.top+titleHeight+padding;hitbox.left=rtlHelper.leftForLtr(rtlHelper.x(left),hitbox.width);left+=hitbox.width+padding;}}else{let col=0;let top=_alignStartEnd(align,this.top+titleHeight+padding,this.bottom-this.columnSizes[col].height);for(const hitbox of hitboxes){if(hitbox.col!==col){col=hitbox.col;top=_alignStartEnd(align,this.top+titleHeight+padding,this.bottom-this.columnSizes[col].height);} hitbox.top=top;hitbox.left+=this.left+padding;hitbox.left=rtlHelper.leftForLtr(rtlHelper.x(hitbox.left),hitbox.width);top+=hitbox.height+padding;}}} isHorizontal(){return this.options.position==='top'||this.options.position==='bottom';} draw(){if(this.options.display){const ctx=this.ctx;clipArea(ctx,this);this._draw();unclipArea(ctx);}} _draw(){const{options:opts,columnSizes,lineWidths,ctx}=this;const{align,labels:labelOpts}=opts;const defaultColor=defaults.color;const rtlHelper=getRtlAdapter(opts.rtl,this.left,this.width);const labelFont=toFont(labelOpts.font);const{padding}=labelOpts;const fontSize=labelFont.size;const halfFontSize=fontSize/2;let cursor;this.drawTitle();ctx.textAlign=rtlHelper.textAlign('left');ctx.textBaseline='middle';ctx.lineWidth=0.5;ctx.font=labelFont.string;const{boxWidth,boxHeight,itemHeight}=getBoxSize(labelOpts,fontSize);const drawLegendBox=function(x,y,legendItem){if(isNaN(boxWidth)||boxWidth<=0||isNaN(boxHeight)||boxHeight<0){return;} ctx.save();const lineWidth=valueOrDefault(legendItem.lineWidth,1);ctx.fillStyle=valueOrDefault(legendItem.fillStyle,defaultColor);ctx.lineCap=valueOrDefault(legendItem.lineCap,'butt');ctx.lineDashOffset=valueOrDefault(legendItem.lineDashOffset,0);ctx.lineJoin=valueOrDefault(legendItem.lineJoin,'miter');ctx.lineWidth=lineWidth;ctx.strokeStyle=valueOrDefault(legendItem.strokeStyle,defaultColor);ctx.setLineDash(valueOrDefault(legendItem.lineDash,[]));if(labelOpts.usePointStyle){const drawOptions={radius:boxHeight*Math.SQRT2/2,pointStyle:legendItem.pointStyle,rotation:legendItem.rotation,borderWidth:lineWidth};const centerX=rtlHelper.xPlus(x,boxWidth/2);const centerY=y+halfFontSize;drawPointLegend(ctx,drawOptions,centerX,centerY,labelOpts.pointStyleWidth&&boxWidth);}else{const yBoxTop=y+Math.max((fontSize-boxHeight)/2,0);const xBoxLeft=rtlHelper.leftForLtr(x,boxWidth);const borderRadius=toTRBLCorners(legendItem.borderRadius);ctx.beginPath();if(Object.values(borderRadius).some((v)=>v!==0)){addRoundedRectPath(ctx,{x:xBoxLeft,y:yBoxTop,w:boxWidth,h:boxHeight,radius:borderRadius});}else{ctx.rect(xBoxLeft,yBoxTop,boxWidth,boxHeight);} ctx.fill();if(lineWidth!==0){ctx.stroke();}} ctx.restore();};const fillText=function(x,y,legendItem){renderText(ctx,legendItem.text,x,y+itemHeight/2,labelFont,{strikethrough:legendItem.hidden,textAlign:rtlHelper.textAlign(legendItem.textAlign)});};const isHorizontal=this.isHorizontal();const titleHeight=this._computeTitleHeight();if(isHorizontal){cursor={x:_alignStartEnd(align,this.left+padding,this.right-lineWidths[0]),y:this.top+padding+titleHeight,line:0};}else{cursor={x:this.left+padding,y:_alignStartEnd(align,this.top+titleHeight+padding,this.bottom-columnSizes[0].height),line:0};} overrideTextDirection(this.ctx,opts.textDirection);const lineHeight=itemHeight+padding;this.legendItems.forEach((legendItem,i)=>{ctx.strokeStyle=legendItem.fontColor;ctx.fillStyle=legendItem.fontColor;const textWidth=ctx.measureText(legendItem.text).width;const textAlign=rtlHelper.textAlign(legendItem.textAlign||(legendItem.textAlign=labelOpts.textAlign));const width=boxWidth+halfFontSize+textWidth;let x=cursor.x;let y=cursor.y;rtlHelper.setWidth(this.width);if(isHorizontal){if(i>0&&x+width+padding>this.right){y=cursor.y+=lineHeight;cursor.line++;x=cursor.x=_alignStartEnd(align,this.left+padding,this.right-lineWidths[cursor.line]);}}else if(i>0&&y+lineHeight>this.bottom){x=cursor.x=x+columnSizes[cursor.line].width+padding;cursor.line++;y=cursor.y=_alignStartEnd(align,this.top+titleHeight+padding,this.bottom-columnSizes[cursor.line].height);} const realX=rtlHelper.x(x);drawLegendBox(realX,y,legendItem);x=_textX(textAlign,x+boxWidth+halfFontSize,isHorizontal?x+width:this.right,opts.rtl);fillText(rtlHelper.x(x),y,legendItem);if(isHorizontal){cursor.x+=width+padding;}else if(typeof legendItem.text!=='string'){const fontLineHeight=labelFont.lineHeight;cursor.y+=calculateLegendItemHeight(legendItem,fontLineHeight)+padding;}else{cursor.y+=lineHeight;}});restoreTextDirection(this.ctx,opts.textDirection);} drawTitle(){const opts=this.options;const titleOpts=opts.title;const titleFont=toFont(titleOpts.font);const titlePadding=toPadding(titleOpts.padding);if(!titleOpts.display){return;} const rtlHelper=getRtlAdapter(opts.rtl,this.left,this.width);const ctx=this.ctx;const position=titleOpts.position;const halfFontSize=titleFont.size/2;const topPaddingPlusHalfFontSize=titlePadding.top+halfFontSize;let y;let left=this.left;let maxWidth=this.width;if(this.isHorizontal()){maxWidth=Math.max(...this.lineWidths);y=this.top+topPaddingPlusHalfFontSize;left=_alignStartEnd(opts.align,left,this.right-maxWidth);}else{const maxHeight=this.columnSizes.reduce((acc,size)=>Math.max(acc,size.height),0);y=topPaddingPlusHalfFontSize+_alignStartEnd(opts.align,this.top,this.bottom-maxHeight-opts.labels.padding-this._computeTitleHeight());} const x=_alignStartEnd(position,left,left+maxWidth);ctx.textAlign=rtlHelper.textAlign(_toLeftRightCenter(position));ctx.textBaseline='middle';ctx.strokeStyle=titleOpts.color;ctx.fillStyle=titleOpts.color;ctx.font=titleFont.string;renderText(ctx,titleOpts.text,x,y,titleFont);} _computeTitleHeight(){const titleOpts=this.options.title;const titleFont=toFont(titleOpts.font);const titlePadding=toPadding(titleOpts.padding);return titleOpts.display?titleFont.lineHeight+titlePadding.height:0;} _getLegendItemAt(x,y){let i,hitBox,lh;if(_isBetween(x,this.left,this.right)&&_isBetween(y,this.top,this.bottom)){lh=this.legendHitBoxes;for(i=0;ia.length>b.length?a:b);} return boxWidth+labelFont.size/2+ctx.measureText(legendItemText).width;} function calculateItemHeight(_itemHeight,legendItem,fontLineHeight){let itemHeight=_itemHeight;if(typeof legendItem.text!=='string'){itemHeight=calculateLegendItemHeight(legendItem,fontLineHeight);} return itemHeight;} function calculateLegendItemHeight(legendItem,fontLineHeight){const labelHeight=legendItem.text?legendItem.text.length:0;return fontLineHeight*labelHeight;} function isListened(type,opts){if((type==='mousemove'||type==='mouseout')&&(opts.onHover||opts.onLeave)){return true;} if(opts.onClick&&(type==='click'||type==='mouseup')){return true;} return false;} var plugin_legend={id:'legend',_element:Legend,start(chart,_args,options){const legend=chart.legend=new Legend({ctx:chart.ctx,options,chart});layouts.configure(chart,legend,options);layouts.addBox(chart,legend);},stop(chart){layouts.removeBox(chart,chart.legend);delete chart.legend;},beforeUpdate(chart,_args,options){const legend=chart.legend;layouts.configure(chart,legend,options);legend.options=options;},afterUpdate(chart){const legend=chart.legend;legend.buildLabels();legend.adjustHitBoxes();},afterEvent(chart,args){if(!args.replay){chart.legend.handleEvent(args.event);}},defaults:{display:true,position:'top',align:'center',fullSize:true,reverse:false,weight:1000,onClick(e,legendItem,legend){const index=legendItem.datasetIndex;const ci=legend.chart;if(ci.isDatasetVisible(index)){ci.hide(index);legendItem.hidden=true;}else{ci.show(index);legendItem.hidden=false;}},onHover:null,onLeave:null,labels:{color:(ctx)=>ctx.chart.options.color,boxWidth:40,padding:10,generateLabels(chart){const datasets=chart.data.datasets;const{labels:{usePointStyle,pointStyle,textAlign,color,useBorderRadius,borderRadius}}=chart.legend.options;return chart._getSortedDatasetMetas().map((meta)=>{const style=meta.controller.getStyle(usePointStyle?0:undefined);const borderWidth=toPadding(style.borderWidth);return{text:datasets[meta.index].label,fillStyle:style.backgroundColor,fontColor:color,hidden:!meta.visible,lineCap:style.borderCapStyle,lineDash:style.borderDash,lineDashOffset:style.borderDashOffset,lineJoin:style.borderJoinStyle,lineWidth:(borderWidth.width+borderWidth.height)/4,strokeStyle:style.borderColor,pointStyle:pointStyle||style.pointStyle,rotation:style.rotation,textAlign:textAlign||style.textAlign,borderRadius:useBorderRadius&&(borderRadius||style.borderRadius),datasetIndex:meta.index};},this);}},title:{color:(ctx)=>ctx.chart.options.color,display:false,position:'center',text:''}},descriptors:{_scriptable:(name)=>!name.startsWith('on'),labels:{_scriptable:(name)=>!['generateLabels','filter','sort'].includes(name)}}};class Title extends Element{constructor(config){super();this.chart=config.chart;this.options=config.options;this.ctx=config.ctx;this._padding=undefined;this.top=undefined;this.bottom=undefined;this.left=undefined;this.right=undefined;this.width=undefined;this.height=undefined;this.position=undefined;this.weight=undefined;this.fullSize=undefined;} update(maxWidth,maxHeight){const opts=this.options;this.left=0;this.top=0;if(!opts.display){this.width=this.height=this.right=this.bottom=0;return;} this.width=this.right=maxWidth;this.height=this.bottom=maxHeight;const lineCount=isArray(opts.text)?opts.text.length:1;this._padding=toPadding(opts.padding);const textSize=lineCount*toFont(opts.font).lineHeight+this._padding.height;if(this.isHorizontal()){this.height=textSize;}else{this.width=textSize;}} isHorizontal(){const pos=this.options.position;return pos==='top'||pos==='bottom';} _drawArgs(offset){const{top,left,bottom,right,options}=this;const align=options.align;let rotation=0;let maxWidth,titleX,titleY;if(this.isHorizontal()){titleX=_alignStartEnd(align,left,right);titleY=top+offset;maxWidth=right-left;}else{if(options.position==='left'){titleX=left+offset;titleY=_alignStartEnd(align,bottom,top);rotation=PI*-0.5;}else{titleX=right-offset;titleY=_alignStartEnd(align,top,bottom);rotation=PI*0.5;} maxWidth=bottom-top;} return{titleX,titleY,maxWidth,rotation};} draw(){const ctx=this.ctx;const opts=this.options;if(!opts.display){return;} const fontOpts=toFont(opts.font);const lineHeight=fontOpts.lineHeight;const offset=lineHeight/2+this._padding.top;const{titleX,titleY,maxWidth,rotation}=this._drawArgs(offset);renderText(ctx,opts.text,0,0,fontOpts,{color:opts.color,maxWidth,rotation,textAlign:_toLeftRightCenter(opts.align),textBaseline:'middle',translation:[titleX,titleY]});}} function createTitle(chart,titleOpts){const title=new Title({ctx:chart.ctx,options:titleOpts,chart});layouts.configure(chart,title,titleOpts);layouts.addBox(chart,title);chart.titleBlock=title;} var plugin_title={id:'title',_element:Title,start(chart,_args,options){createTitle(chart,options);},stop(chart){const titleBlock=chart.titleBlock;layouts.removeBox(chart,titleBlock);delete chart.titleBlock;},beforeUpdate(chart,_args,options){const title=chart.titleBlock;layouts.configure(chart,title,options);title.options=options;},defaults:{align:'center',display:false,font:{weight:'bold'},fullSize:true,padding:10,position:'top',text:'',weight:2000},defaultRoutes:{color:'color'},descriptors:{_scriptable:true,_indexable:false}};const map=new WeakMap();var plugin_subtitle={id:'subtitle',start(chart,_args,options){const title=new Title({ctx:chart.ctx,options,chart});layouts.configure(chart,title,options);layouts.addBox(chart,title);map.set(chart,title);},stop(chart){layouts.removeBox(chart,map.get(chart));map.delete(chart);},beforeUpdate(chart,_args,options){const title=map.get(chart);layouts.configure(chart,title,options);title.options=options;},defaults:{align:'center',display:false,font:{weight:'normal'},fullSize:true,padding:0,position:'top',text:'',weight:1500},defaultRoutes:{color:'color'},descriptors:{_scriptable:true,_indexable:false}};const positioners={average(items){if(!items.length){return false;} let i,len;let xSet=new Set();let y=0;let count=0;for(i=0,len=items.length;ia+b)/xSet.size;return{x:xAverage,y:y/count};},nearest(items,eventPosition){if(!items.length){return false;} let x=eventPosition.x;let y=eventPosition.y;let minDistance=Number.POSITIVE_INFINITY;let i,len,nearestElement;for(i=0,len=items.length;i-1){return str.split('\n');} return str;} function createTooltipItem(chart,item){const{element,datasetIndex,index}=item;const controller=chart.getDatasetMeta(datasetIndex).controller;const{label,value}=controller.getLabelAndValue(index);return{chart,label,parsed:controller.getParsed(index),raw:chart.data.datasets[datasetIndex].data[index],formattedValue:value,dataset:controller.getDataset(),dataIndex:index,datasetIndex,element};} function getTooltipSize(tooltip,options){const ctx=tooltip.chart.ctx;const{body,footer,title}=tooltip;const{boxWidth,boxHeight}=options;const bodyFont=toFont(options.bodyFont);const titleFont=toFont(options.titleFont);const footerFont=toFont(options.footerFont);const titleLineCount=title.length;const footerLineCount=footer.length;const bodyLineItemCount=body.length;const padding=toPadding(options.padding);let height=padding.height;let width=0;let combinedBodyLength=body.reduce((count,bodyItem)=>count+bodyItem.before.length+bodyItem.lines.length+bodyItem.after.length,0);combinedBodyLength+=tooltip.beforeBody.length+tooltip.afterBody.length;if(titleLineCount){height+=titleLineCount*titleFont.lineHeight+(titleLineCount-1)*options.titleSpacing+options.titleMarginBottom;} if(combinedBodyLength){const bodyLineHeight=options.displayColors?Math.max(boxHeight,bodyFont.lineHeight):bodyFont.lineHeight;height+=bodyLineItemCount*bodyLineHeight+(combinedBodyLength-bodyLineItemCount)*bodyFont.lineHeight+(combinedBodyLength-1)*options.bodySpacing;} if(footerLineCount){height+=options.footerMarginTop+footerLineCount*footerFont.lineHeight+(footerLineCount-1)*options.footerSpacing;} let widthPadding=0;const maxLineWidth=function(line){width=Math.max(width,ctx.measureText(line).width+widthPadding);};ctx.save();ctx.font=titleFont.string;each(tooltip.title,maxLineWidth);ctx.font=bodyFont.string;each(tooltip.beforeBody.concat(tooltip.afterBody),maxLineWidth);widthPadding=options.displayColors?boxWidth+2+options.boxPadding:0;each(body,(bodyItem)=>{each(bodyItem.before,maxLineWidth);each(bodyItem.lines,maxLineWidth);each(bodyItem.after,maxLineWidth);});widthPadding=0;ctx.font=footerFont.string;each(tooltip.footer,maxLineWidth);ctx.restore();width+=padding.width;return{width,height};} function determineYAlign(chart,size){const{y,height}=size;if(ychart.height-height/2){return'bottom';} return'center';} function doesNotFitWithAlign(xAlign,chart,options,size){const{x,width}=size;const caret=options.caretSize+options.caretPadding;if(xAlign==='left'&&x+width+caret>chart.width){return true;} if(xAlign==='right'&&x-width-caret<0){return true;}} function determineXAlign(chart,options,size,yAlign){const{x,width}=size;const{width:chartWidth,chartArea:{left,right}}=chart;let xAlign='center';if(yAlign==='center'){xAlign=x<=(left+right)/2?'left':'right';}else if(x<=width/2){xAlign='left';}else if(x>=chartWidth-width/2){xAlign='right';} if(doesNotFitWithAlign(xAlign,chart,options,size)){xAlign='center';} return xAlign;} function determineAlignment(chart,options,size){const yAlign=size.yAlign||options.yAlign||determineYAlign(chart,size);return{xAlign:size.xAlign||options.xAlign||determineXAlign(chart,options,size,yAlign),yAlign};} function alignX(size,xAlign){let{x,width}=size;if(xAlign==='right'){x-=width;}else if(xAlign==='center'){x-=width/2;} return x;} function alignY(size,yAlign,paddingAndSize){let{y,height}=size;if(yAlign==='top'){y+=paddingAndSize;}else if(yAlign==='bottom'){y-=height+paddingAndSize;}else{y-=height/2;} return y;} function getBackgroundPoint(options,size,alignment,chart){const{caretSize,caretPadding,cornerRadius}=options;const{xAlign,yAlign}=alignment;const paddingAndSize=caretSize+caretPadding;const{topLeft,topRight,bottomLeft,bottomRight}=toTRBLCorners(cornerRadius);let x=alignX(size,xAlign);const y=alignY(size,yAlign,paddingAndSize);if(yAlign==='center'){if(xAlign==='left'){x+=paddingAndSize;}else if(xAlign==='right'){x-=paddingAndSize;}}else if(xAlign==='left'){x-=Math.max(topLeft,bottomLeft)+caretSize;}else if(xAlign==='right'){x+=Math.max(topRight,bottomRight)+caretSize;} return{x:_limitValue(x,0,chart.width-size.width),y:_limitValue(y,0,chart.height-size.height)};} function getAlignedX(tooltip,align,options){const padding=toPadding(options.padding);return align==='center'?tooltip.x+tooltip.width/2:align==='right'?tooltip.x+tooltip.width-padding.right:tooltip.x+padding.left;} function getBeforeAfterBodyLines(callback){return pushOrConcat([],splitNewlines(callback));} function createTooltipContext(parent,tooltip,tooltipItems){return createContext(parent,{tooltip,tooltipItems,type:'tooltip'});} function overrideCallbacks(callbacks,context){const override=context&&context.dataset&&context.dataset.tooltip&&context.dataset.tooltip.callbacks;return override?callbacks.override(override):callbacks;} const defaultCallbacks={beforeTitle:noop,title(tooltipItems){if(tooltipItems.length>0){const item=tooltipItems[0];const labels=item.chart.data.labels;const labelCount=labels?labels.length:0;if(this&&this.options&&this.options.mode==='dataset'){return item.dataset.label||'';}else if(item.label){return item.label;}else if(labelCount>0&&item.dataIndex{const bodyItem={before:[],lines:[],after:[]};const scoped=overrideCallbacks(callbacks,context);pushOrConcat(bodyItem.before,splitNewlines(invokeCallbackWithFallback(scoped,'beforeLabel',this,context)));pushOrConcat(bodyItem.lines,invokeCallbackWithFallback(scoped,'label',this,context));pushOrConcat(bodyItem.after,splitNewlines(invokeCallbackWithFallback(scoped,'afterLabel',this,context)));bodyItems.push(bodyItem);});return bodyItems;} getAfterBody(tooltipItems,options){return getBeforeAfterBodyLines(invokeCallbackWithFallback(options.callbacks,'afterBody',this,tooltipItems));} getFooter(tooltipItems,options){const{callbacks}=options;const beforeFooter=invokeCallbackWithFallback(callbacks,'beforeFooter',this,tooltipItems);const footer=invokeCallbackWithFallback(callbacks,'footer',this,tooltipItems);const afterFooter=invokeCallbackWithFallback(callbacks,'afterFooter',this,tooltipItems);let lines=[];lines=pushOrConcat(lines,splitNewlines(beforeFooter));lines=pushOrConcat(lines,splitNewlines(footer));lines=pushOrConcat(lines,splitNewlines(afterFooter));return lines;} _createItems(options){const active=this._active;const data=this.chart.data;const labelColors=[];const labelPointStyles=[];const labelTextColors=[];let tooltipItems=[];let i,len;for(i=0,len=active.length;ioptions.filter(element,index,array,data));} if(options.itemSort){tooltipItems=tooltipItems.sort((a,b)=>options.itemSort(a,b,data));} each(tooltipItems,(context)=>{const scoped=overrideCallbacks(options.callbacks,context);labelColors.push(invokeCallbackWithFallback(scoped,'labelColor',this,context));labelPointStyles.push(invokeCallbackWithFallback(scoped,'labelPointStyle',this,context));labelTextColors.push(invokeCallbackWithFallback(scoped,'labelTextColor',this,context));});this.labelColors=labelColors;this.labelPointStyles=labelPointStyles;this.labelTextColors=labelTextColors;this.dataPoints=tooltipItems;return tooltipItems;} update(changed,replay){const options=this.options.setContext(this.getContext());const active=this._active;let properties;let tooltipItems=[];if(!active.length){if(this.opacity!==0){properties={opacity:0};}}else{const position=positioners[options.position].call(this,active,this._eventPosition);tooltipItems=this._createItems(options);this.title=this.getTitle(tooltipItems,options);this.beforeBody=this.getBeforeBody(tooltipItems,options);this.body=this.getBody(tooltipItems,options);this.afterBody=this.getAfterBody(tooltipItems,options);this.footer=this.getFooter(tooltipItems,options);const size=this._size=getTooltipSize(this,options);const positionAndSize=Object.assign({},position,size);const alignment=determineAlignment(this.chart,options,positionAndSize);const backgroundPoint=getBackgroundPoint(options,positionAndSize,alignment,this.chart);this.xAlign=alignment.xAlign;this.yAlign=alignment.yAlign;properties={opacity:1,x:backgroundPoint.x,y:backgroundPoint.y,width:size.width,height:size.height,caretX:position.x,caretY:position.y};} this._tooltipItems=tooltipItems;this.$context=undefined;if(properties){this._resolveAnimations().update(this,properties);} if(changed&&options.external){options.external.call(this,{chart:this.chart,tooltip:this,replay});}} drawCaret(tooltipPoint,ctx,size,options){const caretPosition=this.getCaretPosition(tooltipPoint,size,options);ctx.lineTo(caretPosition.x1,caretPosition.y1);ctx.lineTo(caretPosition.x2,caretPosition.y2);ctx.lineTo(caretPosition.x3,caretPosition.y3);} getCaretPosition(tooltipPoint,size,options){const{xAlign,yAlign}=this;const{caretSize,cornerRadius}=options;const{topLeft,topRight,bottomLeft,bottomRight}=toTRBLCorners(cornerRadius);const{x:ptX,y:ptY}=tooltipPoint;const{width,height}=size;let x1,x2,x3,y1,y2,y3;if(yAlign==='center'){y2=ptY+height/2;if(xAlign==='left'){x1=ptX;x2=x1-caretSize;y1=y2+caretSize;y3=y2-caretSize;}else{x1=ptX+width;x2=x1+caretSize;y1=y2-caretSize;y3=y2+caretSize;} x3=x1;}else{if(xAlign==='left'){x2=ptX+Math.max(topLeft,bottomLeft)+caretSize;}else if(xAlign==='right'){x2=ptX+width-Math.max(topRight,bottomRight)-caretSize;}else{x2=this.caretX;} if(yAlign==='top'){y1=ptY;y2=y1-caretSize;x1=x2-caretSize;x3=x2+caretSize;}else{y1=ptY+height;y2=y1+caretSize;x1=x2+caretSize;x3=x2-caretSize;} y3=y1;} return{x1,x2,x3,y1,y2,y3};} drawTitle(pt,ctx,options){const title=this.title;const length=title.length;let titleFont,titleSpacing,i;if(length){const rtlHelper=getRtlAdapter(options.rtl,this.x,this.width);pt.x=getAlignedX(this,options.titleAlign,options);ctx.textAlign=rtlHelper.textAlign(options.titleAlign);ctx.textBaseline='middle';titleFont=toFont(options.titleFont);titleSpacing=options.titleSpacing;ctx.fillStyle=options.titleColor;ctx.font=titleFont.string;for(i=0;iv!==0)){ctx.beginPath();ctx.fillStyle=options.multiKeyBackground;addRoundedRectPath(ctx,{x:outerX,y:colorY,w:boxWidth,h:boxHeight,radius:borderRadius});ctx.fill();ctx.stroke();ctx.fillStyle=labelColor.backgroundColor;ctx.beginPath();addRoundedRectPath(ctx,{x:innerX,y:colorY+1,w:boxWidth-2,h:boxHeight-2,radius:borderRadius});ctx.fill();}else{ctx.fillStyle=options.multiKeyBackground;ctx.fillRect(outerX,colorY,boxWidth,boxHeight);ctx.strokeRect(outerX,colorY,boxWidth,boxHeight);ctx.fillStyle=labelColor.backgroundColor;ctx.fillRect(innerX,colorY+1,boxWidth-2,boxHeight-2);}} ctx.fillStyle=this.labelTextColors[i];} drawBody(pt,ctx,options){const{body}=this;const{bodySpacing,bodyAlign,displayColors,boxHeight,boxWidth,boxPadding}=options;const bodyFont=toFont(options.bodyFont);let bodyLineHeight=bodyFont.lineHeight;let xLinePadding=0;const rtlHelper=getRtlAdapter(options.rtl,this.x,this.width);const fillLineOfText=function(line){ctx.fillText(line,rtlHelper.x(pt.x+xLinePadding),pt.y+bodyLineHeight/2);pt.y+=bodyLineHeight+bodySpacing;};const bodyAlignForCalculation=rtlHelper.textAlign(bodyAlign);let bodyItem,textColor,lines,i,j,ilen,jlen;ctx.textAlign=bodyAlign;ctx.textBaseline='middle';ctx.font=bodyFont.string;pt.x=getAlignedX(this,bodyAlignForCalculation,options);ctx.fillStyle=options.bodyColor;each(this.beforeBody,fillLineOfText);xLinePadding=displayColors&&bodyAlignForCalculation!=='right'?bodyAlign==='center'?boxWidth/2+boxPadding:boxWidth+2+boxPadding:0;for(i=0,ilen=body.length;i0){ctx.stroke();}} _updateAnimationTarget(options){const chart=this.chart;const anims=this.$animations;const animX=anims&&anims.x;const animY=anims&&anims.y;if(animX||animY){const position=positioners[options.position].call(this,this._active,this._eventPosition);if(!position){return;} const size=this._size=getTooltipSize(this,options);const positionAndSize=Object.assign({},position,this._size);const alignment=determineAlignment(chart,options,positionAndSize);const point=getBackgroundPoint(options,positionAndSize,alignment,chart);if(animX._to!==point.x||animY._to!==point.y){this.xAlign=alignment.xAlign;this.yAlign=alignment.yAlign;this.width=size.width;this.height=size.height;this.caretX=position.x;this.caretY=position.y;this._resolveAnimations().update(this,point);}}} _willRender(){return!!this.opacity;} draw(ctx){const options=this.options.setContext(this.getContext());let opacity=this.opacity;if(!opacity){return;} this._updateAnimationTarget(options);const tooltipSize={width:this.width,height:this.height};const pt={x:this.x,y:this.y};opacity=Math.abs(opacity)<1e-3?0:opacity;const padding=toPadding(options.padding);const hasTooltipContent=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;if(options.enabled&&hasTooltipContent){ctx.save();ctx.globalAlpha=opacity;this.drawBackground(pt,ctx,tooltipSize,options);overrideTextDirection(ctx,options.textDirection);pt.y+=padding.top;this.drawTitle(pt,ctx,options);this.drawBody(pt,ctx,options);this.drawFooter(pt,ctx,options);restoreTextDirection(ctx,options.textDirection);ctx.restore();}} getActiveElements(){return this._active||[];} setActiveElements(activeElements,eventPosition){const lastActive=this._active;const active=activeElements.map(({datasetIndex,index})=>{const meta=this.chart.getDatasetMeta(datasetIndex);if(!meta){throw new Error('Cannot find a dataset at index '+datasetIndex);} return{datasetIndex,element:meta.data[index],index};});const changed=!_elementsEqual(lastActive,active);const positionChanged=this._positionChanged(active,eventPosition);if(changed||positionChanged){this._active=active;this._eventPosition=eventPosition;this._ignoreReplayEvents=true;this.update(true);}} handleEvent(e,replay,inChartArea=true){if(replay&&this._ignoreReplayEvents){return false;} this._ignoreReplayEvents=false;const options=this.options;const lastActive=this._active||[];const active=this._getActiveElements(e,lastActive,replay,inChartArea);const positionChanged=this._positionChanged(active,e);const changed=replay||!_elementsEqual(active,lastActive)||positionChanged;if(changed){this._active=active;if(options.enabled||options.external){this._eventPosition={x:e.x,y:e.y};this.update(true,replay);}} return changed;} _getActiveElements(e,lastActive,replay,inChartArea){const options=this.options;if(e.type==='mouseout'){return[];} if(!inChartArea){return lastActive.filter((i)=>this.chart.data.datasets[i.datasetIndex]&&this.chart.getDatasetMeta(i.datasetIndex).controller.getParsed(i.index)!==undefined);} const active=this.chart.getElementsAtEventForMode(e,options.mode,options,replay);if(options.reverse){active.reverse();} return active;} _positionChanged(active,e){const{caretX,caretY,options}=this;const position=positioners[options.position].call(this,active,e);return position!==false&&(caretX!==position.x||caretY!==position.y);}} var plugin_tooltip={id:'tooltip',_element:Tooltip,positioners,afterInit(chart,_args,options){if(options){chart.tooltip=new Tooltip({chart,options});}},beforeUpdate(chart,_args,options){if(chart.tooltip){chart.tooltip.initialize(options);}},reset(chart,_args,options){if(chart.tooltip){chart.tooltip.initialize(options);}},afterDraw(chart){const tooltip=chart.tooltip;if(tooltip&&tooltip._willRender()){const args={tooltip};if(chart.notifyPlugins('beforeTooltipDraw',{...args,cancelable:true})===false){return;} tooltip.draw(chart.ctx);chart.notifyPlugins('afterTooltipDraw',args);}},afterEvent(chart,args){if(chart.tooltip){const useFinalPosition=args.replay;if(chart.tooltip.handleEvent(args.event,useFinalPosition,args.inChartArea)){args.changed=true;}}},defaults:{enabled:true,external:null,position:'average',backgroundColor:'rgba(0,0,0,0.8)',titleColor:'#fff',titleFont:{weight:'bold'},titleSpacing:2,titleMarginBottom:6,titleAlign:'left',bodyColor:'#fff',bodySpacing:2,bodyFont:{},bodyAlign:'left',footerColor:'#fff',footerSpacing:2,footerMarginTop:6,footerFont:{weight:'bold'},footerAlign:'left',padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(ctx,opts)=>opts.bodyFont.size,boxWidth:(ctx,opts)=>opts.bodyFont.size,multiKeyBackground:'#fff',displayColors:true,boxPadding:0,borderColor:'rgba(0,0,0,0)',borderWidth:0,animation:{duration:400,easing:'easeOutQuart'},animations:{numbers:{type:'number',properties:['x','y','width','height','caretX','caretY']},opacity:{easing:'linear',duration:200}},callbacks:defaultCallbacks},defaultRoutes:{bodyFont:'font',footerFont:'font',titleFont:'font'},descriptors:{_scriptable:(name)=>name!=='filter'&&name!=='itemSort'&&name!=='external',_indexable:false,callbacks:{_scriptable:false,_indexable:false},animation:{_fallback:false},animations:{_fallback:'animation'}},additionalOptionScopes:['interaction']};Chart.register(controllers,scales,elements,plugins);Chart.helpers={...helpers};Chart._adapters=_adapters;Chart.Animation=Animation;Chart.Animations=Animations;Chart.animator=animator;Chart.controllers=registry.controllers.items;Chart.DatasetController=DatasetController;Chart.Element=Element;Chart.elements=elements;Chart.Interaction=Interaction;Chart.layouts=layouts;Chart.platforms=platforms;Chart.Scale=Scale;Chart.Ticks=Ticks;Object.assign(Chart,controllers,scales,elements,plugins,platforms);Chart.Chart=Chart;if(typeof window!=='undefined'){window.Chart=Chart;} return Chart;}));; /* /web/static/lib/chartjs-adapter-luxon/chartjs-adapter-luxon.js */ (function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?factory(require("chart.js"),require("luxon")):typeof define==="function"&&define.amd?define(["chart.js","luxon"],factory):((global=typeof globalThis!=="undefined"?globalThis:global||self),factory(global.Chart,global.luxon));})(this,function(chart_js,luxon){"use strict";const FORMATS={datetime:luxon.DateTime.DATETIME_MED_WITH_SECONDS,millisecond:"h:mm:ss.SSS a",second:luxon.DateTime.TIME_WITH_SECONDS,minute:luxon.DateTime.TIME_SIMPLE,hour:{hour:"numeric"},day:{day:"numeric",month:"short"},week:"DD",month:{month:"short",year:"numeric"},quarter:"'Q'q - yyyy",year:{year:"numeric"},};chart_js._adapters._date.override({_id:"luxon",_create:function(time){return luxon.DateTime.fromMillis(time,this.options);},init(chartOptions){if(!this.options.locale){this.options.locale=chartOptions.locale;}},formats:function(){return FORMATS;},parse:function(value,format){const options=this.options;const type=typeof value;if(value===null||type==="undefined"){return null;} if(type==="number"){value=this._create(value);}else if(type==="string"){if(typeof format==="string"){value=luxon.DateTime.fromFormat(value,format,options);}else{value=luxon.DateTime.fromISO(value,options);}}else if(value instanceof Date){value=luxon.DateTime.fromJSDate(value,options);}else if(type==="object"&&!(value instanceof luxon.DateTime)){value=luxon.DateTime.fromObject(value,options);} return value.isValid?value.valueOf():null;},format:function(time,format){const datetime=this._create(time);return typeof format==="string"?datetime.toFormat(format):datetime.toLocaleString(format);},add:function(time,amount,unit){const args={};args[unit]=amount;return this._create(time).plus(args).valueOf();},diff:function(max,min,unit){return this._create(max).diff(this._create(min)).as(unit).valueOf();},startOf:function(time,unit,weekday){if(unit==="isoWeek"){weekday=Math.trunc(Math.min(Math.max(0,weekday),6));const dateTime=this._create(time);return dateTime.minus({days:(dateTime.weekday-weekday+7)%7}).startOf("day").valueOf();} return unit?this._create(time).startOf(unit).valueOf():time;},endOf:function(time,unit){return this._create(time).endOf(unit).valueOf();},});});