matebot 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- matebot/__init__.py +3 -0
- matebot/bags.py +77 -0
- matebot/cli.py +293 -0
- matebot/commands.py +272 -0
- matebot/config.py +91 -0
- matebot/conversation.py +263 -0
- matebot/digest.py +80 -0
- matebot/hints.py +53 -0
- matebot/machine.py +195 -0
- matebot/messengers/__init__.py +28 -0
- matebot/messengers/base.py +58 -0
- matebot/messengers/discord.py +88 -0
- matebot/messengers/telegram.py +118 -0
- matebot/plot.py +100 -0
- matebot/sitegen.py +119 -0
- matebot/slog.py +225 -0
- matebot/state.py +42 -0
- matebot/sync.py +163 -0
- matebot/watcher.py +137 -0
- matebot/web/app.js +395 -0
- matebot/web/index.html +43 -0
- matebot/web/style.css +166 -0
- matebot/web/vendor/chart.umd.js +20 -0
- matebot/web/vendor/chartjs-plugin-annotation.min.js +7 -0
- matebot-0.2.0.dist-info/METADATA +232 -0
- matebot-0.2.0.dist-info/RECORD +29 -0
- matebot-0.2.0.dist-info/WHEEL +4 -0
- matebot-0.2.0.dist-info/entry_points.txt +2 -0
- matebot-0.2.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* chartjs-plugin-annotation v3.1.0
|
|
3
|
+
* https://www.chartjs.org/chartjs-plugin-annotation/index
|
|
4
|
+
* (c) 2024 chartjs-plugin-annotation Contributors
|
|
5
|
+
* Released under the MIT License
|
|
6
|
+
*/
|
|
7
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("chart.js"),require("chart.js/helpers")):"function"==typeof define&&define.amd?define(["chart.js","chart.js/helpers"],e):(t="undefined"!=typeof globalThis?globalThis:t||self)["chartjs-plugin-annotation"]=e(t.Chart,t.Chart.helpers)}(this,(function(t,e){"use strict";const o={modes:{point:(t,e)=>i(t,e,{intersect:!0}),nearest:(t,o,n)=>function(t,o,n){let r=Number.POSITIVE_INFINITY;return i(t,o,n).reduce(((t,i)=>{const s=i.getCenterPoint(),a=function(t,e,o){if("x"===o)return{x:t.x,y:e.y};if("y"===o)return{x:e.x,y:t.y};return e}(o,s,n.axis),d=e.distanceBetweenPoints(o,a);return d<r?(t=[i],r=d):d===r&&t.push(i),t}),[]).sort(((t,e)=>t._index-e._index)).slice(0,1)}(t,o,n),x:(t,e,o)=>i(t,e,{intersect:o.intersect,axis:"x"}),y:(t,e,o)=>i(t,e,{intersect:o.intersect,axis:"y"})}};function n(t,e,n){return(o.modes[n.mode]||o.modes.nearest)(t,e,n)}function i(t,e,o){return t.filter((t=>o.intersect?t.inRange(e.x,e.y):function(t,e,o){return"x"!==o&&"y"!==o?t.inRange(e.x,e.y,"x",!0)||t.inRange(e.x,e.y,"y",!0):t.inRange(e.x,e.y,o,!0)}(t,e,o.axis)))}function r(t,e,o){const n=Math.cos(o),i=Math.sin(o),r=e.x,s=e.y;return{x:r+n*(t.x-r)-i*(t.y-s),y:s+i*(t.x-r)+n*(t.y-s)}}const s=(t,e)=>e>t||t.length>e.length&&t.slice(0,e.length)===e,a=.001,d=(t,e,o)=>Math.min(o,Math.max(e,t)),l=(t,e)=>t.value>=t.start-e&&t.value<=t.end+e;function c(t,e,o){for(const n of Object.keys(t))t[n]=d(t[n],e,o);return t}function h(t,{x:e,y:o,x2:n,y2:i},r,{borderWidth:s,hitTolerance:d}){const l=(s+d)/2,c=t.x>=e-l-a&&t.x<=n+l+a,h=t.y>=o-l-a&&t.y<=i+l+a;return"x"===r?c:("y"===r||c)&&h}function u(t,{rect:o,center:n},i,{rotation:s,borderWidth:a,hitTolerance:d}){return h(r(t,n,e.toRadians(-s)),o,i,{borderWidth:a,hitTolerance:d})}function f(t,e){const{centerX:o,centerY:n}=t.getProps(["centerX","centerY"],e);return{x:o,y:n}}const x=t=>"string"==typeof t&&t.endsWith("%"),y=t=>parseFloat(t)/100,p=t=>d(y(t),0,1),b=(t,e)=>({x:t,y:e,x2:t,y2:e,width:0,height:0}),g={box:t=>b(t.centerX,t.centerY),doughnutLabel:t=>b(t.centerX,t.centerY),ellipse:t=>({centerX:t.centerX,centerY:t.centerX,radius:0,width:0,height:0}),label:t=>b(t.centerX,t.centerY),line:t=>b(t.x,t.y),point:t=>({centerX:t.centerX,centerY:t.centerY,radius:0,width:0,height:0}),polygon:t=>b(t.centerX,t.centerY)};function m(t,e){return"start"===e?0:"end"===e?t:x(e)?p(e)*t:t/2}function v(t,e,o=!0){return"number"==typeof e?e:x(e)?(o?p(e):y(e))*t:t}function w(t,o,{borderWidth:n,position:i,xAdjust:r,yAdjust:s},a){const d=e.isObject(a),l=o.width+(d?a.width:0)+n,c=o.height+(d?a.height:0)+n,h=M(i),u=k(t.x,l,r,h.x),f=k(t.y,c,s,h.y);return{x:u,y:f,x2:u+l,y2:f+c,width:l,height:c,centerX:u+l/2,centerY:f+c/2}}function M(t,o="center"){return e.isObject(t)?{x:e.valueOrDefault(t.x,o),y:e.valueOrDefault(t.y,o)}:{x:t=e.valueOrDefault(t,o),y:t}}const P=(t,e)=>t&&t.autoFit&&e<1;function S(t,o){const n=t.font,i=e.isArray(n)?n:[n];return P(t,o)?i.map((function(t){const n=e.toFont(t);return n.size=Math.floor(t.size*o),n.lineHeight=t.lineHeight,e.toFont(n)})):i.map((t=>e.toFont(t)))}function C(t){return t&&(e.defined(t.xValue)||e.defined(t.yValue))}function k(t,e,o=0,n){return t-m(e,n)+o}function A(t,o,n){const i=n.init;if(i)return!0===i?D(o,n):function(t,o,n){const i=e.callback(n.init,[{chart:t,properties:o,options:n}]);if(!0===i)return D(o,n);if(e.isObject(i))return i}(t,o,n)}function T(t,o,n){let i=!1;return o.forEach((o=>{e.isFunction(t[o])?(i=!0,n[o]=t[o]):e.defined(n[o])&&delete n[o]})),i}function D(t,e){const o=e.type||"line";return g[o](t)}const j=new Map,O=t=>isNaN(t)||t<=0,R=t=>t.reduce((function(t,e){return t+=e.string}),"");function I(t){if(t&&"object"==typeof t){const e=t.toString();return"[object HTMLImageElement]"===e||"[object HTMLCanvasElement]"===e}}function Y(t,{x:o,y:n},i){i&&(t.translate(o,n),t.rotate(e.toRadians(i)),t.translate(-o,-n))}function X(t,e){if(e&&e.borderWidth)return t.lineCap=e.borderCapStyle||"butt",t.setLineDash(e.borderDash),t.lineDashOffset=e.borderDashOffset,t.lineJoin=e.borderJoinStyle||"miter",t.lineWidth=e.borderWidth,t.strokeStyle=e.borderColor,!0}function _(t,e){t.shadowColor=e.backgroundShadowColor,t.shadowBlur=e.shadowBlur,t.shadowOffsetX=e.shadowOffsetX,t.shadowOffsetY=e.shadowOffsetY}function E(t,o){const n=o.content;if(I(n)){return{width:v(n.width,o.width),height:v(n.height,o.height)}}const i=S(o),r=o.textStrokeWidth,s=e.isArray(n)?n:[n],a=s.join()+R(i)+r+(t._measureText?"-spriting":"");return j.has(a)||j.set(a,function(t,e,o,n){t.save();const i=e.length;let r=0,s=n;for(let a=0;a<i;a++){const i=o[Math.min(a,o.length-1)];t.font=i.string;const d=e[a];r=Math.max(r,t.measureText(d).width+n),s+=i.lineHeight}return t.restore(),{width:r,height:s}}(t,s,i,r)),j.get(a)}function W(t,o,n){const{x:i,y:r,width:s,height:a}=o;t.save(),_(t,n);const d=X(t,n);t.fillStyle=n.backgroundColor,t.beginPath(),e.addRoundedRectPath(t,{x:i,y:r,w:s,h:a,radius:c(e.toTRBLCorners(n.borderRadius),0,Math.min(s,a)/2)}),t.closePath(),t.fill(),d&&(t.shadowColor=n.borderShadowColor,t.stroke()),t.restore()}function z(t,o,n,i){const r=n.content;if(I(r))return t.save(),t.globalAlpha=function(t,o){const n=e.isNumber(t)?t:o;return e.isNumber(n)?d(n,0,1):1}(n.opacity,r.style.opacity),t.drawImage(r,o.x,o.y,o.width,o.height),void t.restore();const s=e.isArray(r)?r:[r],a=S(n,i),l=n.color,c=e.isArray(l)?l:[l],h=function(t,e){const{x:o,width:n}=t,i=e.textAlign;return"center"===i?o+n/2:"end"===i||"right"===i?o+n:o}(o,n),u=o.y+n.textStrokeWidth/2;t.save(),t.textBaseline="middle",t.textAlign=n.textAlign,function(t,e){if(e.textStrokeWidth>0)return t.lineJoin="round",t.miterLimit=2,t.lineWidth=e.textStrokeWidth,t.strokeStyle=e.textStrokeColor,!0}(t,n)&&function(t,{x:e,y:o},n,i){t.beginPath();let r=0;n.forEach((function(n,s){const a=i[Math.min(s,i.length-1)],d=a.lineHeight;t.font=a.string,t.strokeText(n,e,o+d/2+r),r+=d})),t.stroke()}(t,{x:h,y:u},s,a),function(t,{x:e,y:o},n,{fonts:i,colors:r}){let s=0;n.forEach((function(n,a){const d=r[Math.min(a,r.length-1)],l=i[Math.min(a,i.length-1)],c=l.lineHeight;t.beginPath(),t.font=l.string,t.fillStyle=d,t.fillText(n,e,o+c/2+s),s+=c,t.fill()}))}(t,{x:h,y:u},s,{fonts:a,colors:c}),t.restore()}function F(t,o,n,i){const{radius:r,options:s}=o,a=s.pointStyle,d=s.rotation;let l=(d||0)*e.RAD_PER_DEG;if(I(a))return t.save(),t.translate(n,i),t.rotate(l),t.drawImage(a,-a.width/2,-a.height/2,a.width,a.height),void t.restore();O(r)||function(t,{x:o,y:n,radius:i,rotation:r,style:s,rad:a}){let d,l,c,h;switch(t.beginPath(),s){default:t.arc(o,n,i,0,e.TAU),t.closePath();break;case"triangle":t.moveTo(o+Math.sin(a)*i,n-Math.cos(a)*i),a+=e.TWO_THIRDS_PI,t.lineTo(o+Math.sin(a)*i,n-Math.cos(a)*i),a+=e.TWO_THIRDS_PI,t.lineTo(o+Math.sin(a)*i,n-Math.cos(a)*i),t.closePath();break;case"rectRounded":h=.516*i,c=i-h,d=Math.cos(a+e.QUARTER_PI)*c,l=Math.sin(a+e.QUARTER_PI)*c,t.arc(o-d,n-l,h,a-e.PI,a-e.HALF_PI),t.arc(o+l,n-d,h,a-e.HALF_PI,a),t.arc(o+d,n+l,h,a,a+e.HALF_PI),t.arc(o-l,n+d,h,a+e.HALF_PI,a+e.PI),t.closePath();break;case"rect":if(!r){c=Math.SQRT1_2*i,t.rect(o-c,n-c,2*c,2*c);break}a+=e.QUARTER_PI;case"rectRot":d=Math.cos(a)*i,l=Math.sin(a)*i,t.moveTo(o-d,n-l),t.lineTo(o+l,n-d),t.lineTo(o+d,n+l),t.lineTo(o-l,n+d),t.closePath();break;case"crossRot":a+=e.QUARTER_PI;case"cross":d=Math.cos(a)*i,l=Math.sin(a)*i,t.moveTo(o-d,n-l),t.lineTo(o+d,n+l),t.moveTo(o+l,n-d),t.lineTo(o-l,n+d);break;case"star":d=Math.cos(a)*i,l=Math.sin(a)*i,t.moveTo(o-d,n-l),t.lineTo(o+d,n+l),t.moveTo(o+l,n-d),t.lineTo(o-l,n+d),a+=e.QUARTER_PI,d=Math.cos(a)*i,l=Math.sin(a)*i,t.moveTo(o-d,n-l),t.lineTo(o+d,n+l),t.moveTo(o+l,n-d),t.lineTo(o-l,n+d);break;case"line":d=Math.cos(a)*i,l=Math.sin(a)*i,t.moveTo(o-d,n-l),t.lineTo(o+d,n+l);break;case"dash":t.moveTo(o,n),t.lineTo(o+Math.cos(a)*i,n+Math.sin(a)*i)}t.fill()}(t,{x:n,y:i,radius:r,rotation:d,style:a,rad:l})}const H=["left","bottom","top","right"];function N(t,o){const{pointX:n,pointY:i,options:s}=o,a=s.callout,d=a&&a.display&&function(t,o){const n=o.position;if(H.includes(n))return n;return function(t,o){const{x:n,y:i,x2:s,y2:a,width:d,height:l,pointX:c,pointY:h,centerX:u,centerY:f,rotation:x}=t,y={x:u,y:f},p=o.start,b=v(d,p),g=v(l,p),m=[n,n+b,n+b,s],w=[i+g,a,i,a],M=[];for(let t=0;t<4;t++){const o=r({x:m[t],y:w[t]},y,e.toRadians(x));M.push({position:H[t],distance:e.distanceBetweenPoints(o,{x:c,y:h})})}return M.sort(((t,e)=>t.distance-e.distance))[0].position}(t,o)}(o,a);if(!d||function(t,e,o){const{pointX:n,pointY:i}=t,r=e.margin;let s=n,a=i;"left"===o?s+=r:"right"===o?s-=r:"top"===o?a+=r:"bottom"===o&&(a-=r);return t.inRange(s,a)}(o,a,d))return;t.save(),t.beginPath();if(!X(t,a))return t.restore();const{separatorStart:l,separatorEnd:c}=function(t,e){const{x:o,y:n,x2:i,y2:r}=t,s=function(t,e){const{width:o,height:n,options:i}=t,r=i.callout.margin+i.borderWidth/2;if("right"===e)return o+r;if("bottom"===e)return n+r;return-r}(t,e);let a,d;"left"===e||"right"===e?(a={x:o+s,y:n},d={x:a.x,y:r}):(a={x:o,y:n+s},d={x:i,y:a.y});return{separatorStart:a,separatorEnd:d}}(o,d),{sideStart:h,sideEnd:u}=function(t,e,o){const{y:n,width:i,height:r,options:s}=t,a=s.callout.start,d=function(t,e){const o=e.side;if("left"===t||"top"===t)return-o;return o}(e,s.callout);let l,c;"left"===e||"right"===e?(l={x:o.x,y:n+v(r,a)},c={x:l.x+d,y:l.y}):(l={x:o.x+v(i,a),y:o.y},c={x:l.x,y:l.y+d});return{sideStart:l,sideEnd:c}}(o,d,l);(a.margin>0||0===s.borderWidth)&&(t.moveTo(l.x,l.y),t.lineTo(c.x,c.y)),t.moveTo(h.x,h.y),t.lineTo(u.x,u.y);const f=r({x:n,y:i},o.getCenterPoint(),e.toRadians(-o.rotation));t.lineTo(f.x,f.y),t.stroke(),t.restore()}const L={xScaleID:{min:"xMin",max:"xMax",start:"left",end:"right",startProp:"x",endProp:"x2"},yScaleID:{min:"yMin",max:"yMax",start:"bottom",end:"top",startProp:"y",endProp:"y2"}};function V(t,o,n){return o="number"==typeof o?o:t.parse(o),e.isFinite(o)?t.getPixelForValue(o):n}function B(t,e,o){const n=e[o];if(n||"scaleID"===o)return n;const i=o.charAt(0),r=Object.values(t).filter((t=>t.axis&&t.axis===i));return r.length?r[0].id:i}function $(t,e){if(t){const o=t.options.reverse;return{start:V(t,e.min,o?e.end:e.start),end:V(t,e.max,o?e.start:e.end)}}}function U(t,e){const{chartArea:o,scales:n}=t,i=n[B(n,e,"xScaleID")],r=n[B(n,e,"yScaleID")];let s=o.width/2,a=o.height/2;return i&&(s=V(i,e.xValue,i.left+i.width/2)),r&&(a=V(r,e.yValue,r.top+r.height/2)),{x:s,y:a}}function J(t,e){const o=t.scales,n=o[B(o,e,"xScaleID")],i=o[B(o,e,"yScaleID")];if(!n&&!i)return{};let{left:r,right:s}=n||t.chartArea,{top:a,bottom:d}=i||t.chartArea;const l=K(n,{min:e.xMin,max:e.xMax,start:r,end:s});r=l.start,s=l.end;const c=K(i,{min:e.yMin,max:e.yMax,start:d,end:a});return a=c.start,d=c.end,{x:r,y:a,x2:s,y2:d,width:s-r,height:d-a,centerX:r+(s-r)/2,centerY:a+(d-a)/2}}function q(t,e){if(!C(e)){const o=J(t,e);let n=e.radius;n&&!isNaN(n)||(n=Math.min(o.width,o.height)/2,e.radius=n);const i=2*n,r=o.centerX+e.xAdjust,s=o.centerY+e.yAdjust;return{x:r-n,y:s-n,x2:r+n,y2:s+n,centerX:r,centerY:s,width:i,height:i,radius:n}}return function(t,e){const o=U(t,e),n=2*e.radius;return{x:o.x-e.radius+e.xAdjust,y:o.y-e.radius+e.yAdjust,x2:o.x+e.radius+e.xAdjust,y2:o.y+e.radius+e.yAdjust,centerX:o.x+e.xAdjust,centerY:o.y+e.yAdjust,radius:e.radius,width:n,height:n}}(t,e)}function Q(t,e){const{scales:o,chartArea:n}=t,i=o[e.scaleID],r={x:n.left,y:n.top,x2:n.right,y2:n.bottom};return i?function(t,e,o){const n=V(t,o.value,NaN),i=V(t,o.endValue,n);t.isHorizontal()?(e.x=n,e.x2=i):(e.y=n,e.y2=i)}(i,r,e):function(t,e,o){for(const n of Object.keys(L)){const i=t[B(t,o,n)];if(i){const{min:t,max:r,start:s,end:a,startProp:d,endProp:l}=L[n],c=$(i,{min:o[t],max:o[r],start:i[s],end:i[a]});e[d]=c.start,e[l]=c.end}}}(o,r,e),r}function G(t,e){const o=J(t,e);return o.initProperties=A(t,o,e),o.elements=[{type:"label",optionScope:"label",properties:tt(t,o,e),initProperties:o.initProperties}],o}function K(t,e){const o=$(t,e)||e;return{start:Math.min(o.start,o.end),end:Math.max(o.start,o.end)}}function Z(t,e){const{start:o,end:n,borderWidth:i}=t,{position:r,padding:{start:s,end:a},adjust:d}=e;return o+i/2+d+m(n-i-o-s-a-e.size,r)}function tt(t,o,n){const i=n.label;i.backgroundColor="transparent",i.callout.display=!1;const r=M(i.position),s=e.toPadding(i.padding),a=E(t.ctx,i),d=function({properties:t,options:e},o,n,i){const{x:r,x2:s,width:a}=t;return Z({start:r,end:s,size:a,borderWidth:e.borderWidth},{position:n.x,padding:{start:i.left,end:i.right},adjust:e.label.xAdjust,size:o.width})}({properties:o,options:n},a,r,s),l=function({properties:t,options:e},o,n,i){const{y:r,y2:s,height:a}=t;return Z({start:r,end:s,size:a,borderWidth:e.borderWidth},{position:n.y,padding:{start:i.top,end:i.bottom},adjust:e.label.yAdjust,size:o.height})}({properties:o,options:n},a,r,s),c=a.width+s.width,h=a.height+s.height;return{x:d,y:l,x2:d+c,y2:l+h,width:c,height:h,centerX:d+c/2,centerY:l+h/2,rotation:i.rotation}}const et=["enter","leave"],ot=et.concat("click");function nt(t,e,o){if(t.listened)switch(e.type){case"mousemove":case"mouseout":return function(t,e,o){if(!t.moveListened)return;let i;i="mousemove"===e.type?n(t.visibleElements,e,o.interaction):[];const r=t.hovered;t.hovered=i;const s={state:t,event:e};let a=it(s,"leave",r,i);return it(s,"enter",i,r)||a}(t,e,o);case"click":return function(t,e,o){const i=t.listeners,r=n(t.visibleElements,e,o.interaction);let s;for(const t of r)s=rt(t.options.click||i.click,t,e)||s;return s}(t,e,o)}}function it({state:t,event:e},o,n,i){let r;for(const s of n)i.indexOf(s)<0&&(r=rt(s.options[o]||t.listeners[o],s,e)||r);return r}function rt(t,o,n){return!0===e.callback(t,[o.$context,n])}const st=["afterDraw","beforeDraw"];function at(t,o,n){if(t.hooked){const i=o.options[n]||t.hooks[n];return e.callback(i,[o.$context])}}function dt(t,o,n){const i=function(t,o,n){const i=o.axis,r=o.id,s=i+"ScaleID",a={min:e.valueOrDefault(o.min,Number.NEGATIVE_INFINITY),max:e.valueOrDefault(o.max,Number.POSITIVE_INFINITY)};for(const e of n)e.scaleID===r?ut(e,o,["value","endValue"],a):B(t,e,s)===r&&ut(e,o,[i+"Min",i+"Max",i+"Value"],a);return a}(t.scales,o,n);let r=lt(o,i,"min","suggestedMin");r=lt(o,i,"max","suggestedMax")||r,r&&e.isFunction(o.handleTickRangeOptions)&&o.handleTickRangeOptions()}function lt(t,o,n,i){if(e.isFinite(o[n])&&!function(t,o,n){return e.defined(t[o])||e.defined(t[n])}(t.options,n,i)){const e=t[n]!==o[n];return t[n]=o[n],e}}function ct(t,e){for(const o of["scaleID","xScaleID","yScaleID"]){const n=B(e,t,o);n&&!e[n]&&ht(t,o)&&console.warn(`No scale found with id '${n}' for annotation '${t.id}'`)}}function ht(t,o){if("scaleID"===o)return!0;const n=o.charAt(0);for(const o of["Min","Max","Value"])if(e.defined(t[n+o]))return!0;return!1}function ut(t,o,n,i){for(const r of n){const n=t[r];if(e.defined(n)){const t=o.parse(n);i.min=Math.min(i.min,t),i.max=Math.max(i.max,t)}}}class ft extends t.Element{inRange(t,o,n,i){const{x:s,y:a}=r({x:t,y:o},this.getCenterPoint(i),e.toRadians(-this.options.rotation));return h({x:s,y:a},this.getProps(["x","y","x2","y2"],i),n,this.options)}getCenterPoint(t){return f(this,t)}draw(t){t.save(),Y(t,this.getCenterPoint(),this.options.rotation),W(t,this,this.options),t.restore()}get label(){return this.elements&&this.elements[0]}resolveElementProperties(t,e){return G(t,e)}}ft.id="boxAnnotation",ft.defaults={adjustScaleRange:!0,backgroundShadowColor:"transparent",borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderRadius:0,borderShadowColor:"transparent",borderWidth:1,display:!0,init:void 0,hitTolerance:0,label:{backgroundColor:"transparent",borderWidth:0,callout:{display:!1},color:"black",content:null,display:!1,drawTime:void 0,font:{family:void 0,lineHeight:void 0,size:void 0,style:void 0,weight:"bold"},height:void 0,hitTolerance:void 0,opacity:void 0,padding:6,position:"center",rotation:void 0,textAlign:"start",textStrokeColor:void 0,textStrokeWidth:0,width:void 0,xAdjust:0,yAdjust:0,z:void 0},rotation:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,xMax:void 0,xMin:void 0,xScaleID:void 0,yMax:void 0,yMin:void 0,yScaleID:void 0,z:0},ft.defaultRoutes={borderColor:"color",backgroundColor:"color"},ft.descriptors={label:{_fallback:!0}};class xt extends t.Element{inRange(t,e,o,n){return u({x:t,y:e},{rect:this.getProps(["x","y","x2","y2"],n),center:this.getCenterPoint(n)},o,{rotation:this.rotation,borderWidth:0,hitTolerance:this.options.hitTolerance})}getCenterPoint(t){return f(this,t)}draw(t){const e=this.options;e.display&&e.content&&(!function(t,e){const{_centerX:o,_centerY:n,_radius:i,_startAngle:r,_endAngle:s,_counterclockwise:a,options:d}=e;t.save();const l=X(t,d);t.fillStyle=d.backgroundColor,t.beginPath(),t.arc(o,n,i,r,s,a),t.closePath(),t.fill(),l&&t.stroke();t.restore()}(t,this),t.save(),Y(t,this.getCenterPoint(),this.rotation),z(t,this,e,this._fitRatio),t.restore())}resolveElementProperties(o,n){const i=function(e,o){return e.getSortedVisibleDatasetMetas().reduce((function(n,i){const r=i.controller;return r instanceof t.DoughnutController&&function(t,e,o){if(!e.autoHide)return!0;for(let e=0;e<o.length;e++)if(!o[e].hidden&&t.getDataVisibility(e))return!0}(e,o,i.data)&&(!n||r.innerRadius<n.controller.innerRadius)&&r.options.circumference>=90?i:n}),void 0)}(o,n);if(!i)return{};const{controllerMeta:r,point:s,radius:a}=function({chartArea:t},o,n){const{left:i,top:r,right:s,bottom:a}=t,{innerRadius:d,offsetX:l,offsetY:c}=n.controller,h=(i+s)/2+l,u=(r+a)/2+c,f={left:Math.max(h-d,i),right:Math.min(h+d,s),top:Math.max(u-d,r),bottom:Math.min(u+d,a)},x={x:(f.left+f.right)/2,y:(f.top+f.bottom)/2},y=o.spacing+o.borderWidth/2,p=d-y,b=x.y>u,g=function(t,o,n,i){const r=Math.pow(n-t,2),s=Math.pow(i,2),a=-2*o,d=Math.pow(o,2)+r-s,l=Math.pow(a,2)-4*d;if(l<=0)return{_startAngle:0,_endAngle:e.TAU};const c=(-a-Math.sqrt(l))/2,h=(-a+Math.sqrt(l))/2;return{_startAngle:e.getAngleFromPoint({x:o,y:n},{x:c,y:t}).angle,_endAngle:e.getAngleFromPoint({x:o,y:n},{x:h,y:t}).angle}}(b?r+y:a-y,h,u,p),m={_centerX:h,_centerY:u,_radius:p,_counterclockwise:b,...g};return{controllerMeta:m,point:x,radius:Math.min(d,Math.min(f.right-f.left,f.bottom-f.top)/2)}}(o,n,i);let d=E(o.ctx,n);const l=function({width:t,height:e},o){const n=Math.sqrt(Math.pow(t,2)+Math.pow(e,2));return 2*o/n}(d,a);P(n,l)&&(d={width:d.width*l,height:d.height*l});const{position:c,xAdjust:h,yAdjust:u}=n,f=w(s,d,{borderWidth:0,position:c,xAdjust:h,yAdjust:u});return{initProperties:A(o,f,n),...f,...r,rotation:n.rotation,_fitRatio:l}}}xt.id="doughnutLabelAnnotation",xt.defaults={autoFit:!0,autoHide:!0,backgroundColor:"transparent",backgroundShadowColor:"transparent",borderColor:"transparent",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderShadowColor:"transparent",borderWidth:0,color:"black",content:null,display:!0,font:{family:void 0,lineHeight:void 0,size:void 0,style:void 0,weight:void 0},height:void 0,hitTolerance:0,init:void 0,opacity:void 0,position:"center",rotation:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,spacing:1,textAlign:"center",textStrokeColor:void 0,textStrokeWidth:0,width:void 0,xAdjust:0,yAdjust:0},xt.defaultRoutes={};class yt extends t.Element{inRange(t,e,o,n){return u({x:t,y:e},{rect:this.getProps(["x","y","x2","y2"],n),center:this.getCenterPoint(n)},o,{rotation:this.rotation,borderWidth:this.options.borderWidth,hitTolerance:this.options.hitTolerance})}getCenterPoint(t){return f(this,t)}draw(t){const o=this.options,n=!e.defined(this._visible)||this._visible;o.display&&o.content&&n&&(t.save(),Y(t,this.getCenterPoint(),this.rotation),N(t,this),W(t,this,o),z(t,function({x:t,y:o,width:n,height:i,options:r}){const s=r.borderWidth/2,a=e.toPadding(r.padding);return{x:t+a.left+s,y:o+a.top+s,width:n-a.left-a.right-r.borderWidth,height:i-a.top-a.bottom-r.borderWidth}}(this),o),t.restore())}resolveElementProperties(t,o){let n;if(C(o))n=U(t,o);else{const{centerX:e,centerY:i}=J(t,o);n={x:e,y:i}}const i=e.toPadding(o.padding),r=w(n,E(t.ctx,o),o,i);return{initProperties:A(t,r,o),pointX:n.x,pointY:n.y,...r,rotation:o.rotation}}}yt.id="labelAnnotation",yt.defaults={adjustScaleRange:!0,backgroundColor:"transparent",backgroundShadowColor:"transparent",borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderRadius:0,borderShadowColor:"transparent",borderWidth:0,callout:{borderCapStyle:"butt",borderColor:void 0,borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderWidth:1,display:!1,margin:5,position:"auto",side:5,start:"50%"},color:"black",content:null,display:!0,font:{family:void 0,lineHeight:void 0,size:void 0,style:void 0,weight:void 0},height:void 0,hitTolerance:0,init:void 0,opacity:void 0,padding:6,position:"center",rotation:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,textAlign:"center",textStrokeColor:void 0,textStrokeWidth:0,width:void 0,xAdjust:0,xMax:void 0,xMin:void 0,xScaleID:void 0,xValue:void 0,yAdjust:0,yMax:void 0,yMin:void 0,yScaleID:void 0,yValue:void 0,z:0},yt.defaultRoutes={borderColor:"color"};const pt=(t,e,o)=>({x:t.x+o*(e.x-t.x),y:t.y+o*(e.y-t.y)}),bt=(t,e,o)=>pt(e,o,Math.abs((t-e.y)/(o.y-e.y))).x,gt=(t,e,o)=>pt(e,o,Math.abs((t-e.x)/(o.x-e.x))).y,mt=t=>t*t,vt=(t,e,{x:o,y:n,x2:i,y2:r},s)=>"y"===s?{start:Math.min(n,r),end:Math.max(n,r),value:e}:{start:Math.min(o,i),end:Math.max(o,i),value:t},wt=(t,e,o,n)=>(1-n)*(1-n)*t+2*(1-n)*n*e+n*n*o,Mt=(t,e,o,n)=>({x:wt(t.x,e.x,o.x,n),y:wt(t.y,e.y,o.y,n)}),Pt=(t,e,o,n)=>2*(1-n)*(e-t)+2*n*(o-e),St=(t,o,n,i)=>-Math.atan2(Pt(t.x,o.x,n.x,i),Pt(t.y,o.y,n.y,i))+.5*e.PI;class Ct extends t.Element{inRange(t,e,o,n){const i=(this.options.borderWidth+this.options.hitTolerance)/2;if("x"!==o&&"y"!==o){const o={mouseX:t,mouseY:e},{path:r,ctx:s}=this;if(r){X(s,this.options),s.lineWidth+=this.options.hitTolerance;const{chart:i}=this.$context,a=t*i.currentDevicePixelRatio,d=e*i.currentDevicePixelRatio,l=s.isPointInStroke(r,a,d)||Tt(this,o,n);return s.restore(),l}return function(t,{mouseX:e,mouseY:o},n=a,i){const{x:r,y:s,x2:d,y2:l}=t.getProps(["x","y","x2","y2"],i),c=d-r,h=l-s,u=mt(c)+mt(h),f=0===u?-1:((e-r)*c+(o-s)*h)/u;let x,y;f<0?(x=r,y=s):f>1?(x=d,y=l):(x=r+f*c,y=s+f*h);return mt(e-x)+mt(o-y)<=n}(this,o,mt(i),n)||Tt(this,o,n)}return function(t,{mouseX:e,mouseY:o},n,{hitSize:i,useFinalPosition:r}){const s=vt(e,o,t.getProps(["x","y","x2","y2"],r),n);return l(s,i)||Tt(t,{mouseX:e,mouseY:o},r,n)}(this,{mouseX:t,mouseY:e},o,{hitSize:i,useFinalPosition:n})}getCenterPoint(t){return f(this,t)}draw(t){const{x:o,y:n,x2:i,y2:r,cp:s,options:a}=this;if(t.save(),!X(t,a))return t.restore();_(t,a);const d=Math.sqrt(Math.pow(i-o,2)+Math.pow(r-n,2));if(a.curve&&s)return function(t,o,n,i){const{x:r,y:s,x2:a,y2:d,options:l}=o,{startOpts:c,endOpts:h,startAdjust:u,endAdjust:f}=Ot(o),x={x:r,y:s},y={x:a,y:d},p=St(x,n,y,0),b=St(x,n,y,1)-e.PI,g=Mt(x,n,y,u/i),m=Mt(x,n,y,1-f/i),v=new Path2D;t.beginPath(),v.moveTo(g.x,g.y),v.quadraticCurveTo(n.x,n.y,m.x,m.y),t.shadowColor=l.borderShadowColor,t.stroke(v),o.path=v,o.ctx=t,Yt(t,g,{angle:p,adjust:u},c),Yt(t,m,{angle:b,adjust:f},h)}(t,this,s,d),t.restore();const{startOpts:l,endOpts:c,startAdjust:h,endAdjust:u}=Ot(this),f=Math.atan2(r-n,i-o);t.translate(o,n),t.rotate(f),t.beginPath(),t.moveTo(0+h,0),t.lineTo(d-u,0),t.shadowColor=a.borderShadowColor,t.stroke(),It(t,0,h,l),It(t,d,-u,c),t.restore()}get label(){return this.elements&&this.elements[0]}resolveElementProperties(t,o){const n=Q(t,o),{x:i,y:s,x2:a,y2:d}=n,l=function({x:t,y:e,x2:o,y2:n},{top:i,right:r,bottom:s,left:a}){return!(t<a&&o<a||t>r&&o>r||e<i&&n<i||e>s&&n>s)}(n,t.chartArea),c=l?function(t,e,o){const{x:n,y:i}=At(t,e,o),{x:r,y:s}=At(e,t,o);return{x:n,y:i,x2:r,y2:s,width:Math.abs(r-n),height:Math.abs(s-i)}}({x:i,y:s},{x:a,y:d},t.chartArea):{x:i,y:s,x2:a,y2:d,width:Math.abs(a-i),height:Math.abs(d-s)};if(c.centerX=(a+i)/2,c.centerY=(d+s)/2,c.initProperties=A(t,c,o),o.curve){const t={x:c.x,y:c.y},n={x:c.x2,y:c.y2};c.cp=function(t,e,o){const{x:n,y:i,x2:s,y2:a,centerX:d,centerY:l}=t,c=Math.atan2(a-i,s-n),h=M(e.controlPoint,0);return r({x:d+v(o,h.x,!1),y:l+v(o,h.y,!1)},{x:d,y:l},c)}(c,o,e.distanceBetweenPoints(t,n))}const h=function(t,o,n){const i=n.borderWidth,r=e.toPadding(n.padding),s=E(t.ctx,n),a=s.width+r.width+i,d=s.height+r.height+i;return function(t,o,n,i){const{width:r,height:s,padding:a}=n,{xAdjust:d,yAdjust:l}=o,c={x:t.x,y:t.y},h={x:t.x2,y:t.y2},u="auto"===o.rotation?function(t){const{x:o,y:n,x2:i,y2:r}=t,s=Math.atan2(r-n,i-o);return s>e.PI/2?s-e.PI:s<e.PI/-2?s+e.PI:s}(t):e.toRadians(o.rotation),f=function(t,e,o){const n=Math.cos(o),i=Math.sin(o);return{w:Math.abs(t*n)+Math.abs(e*i),h:Math.abs(t*i)+Math.abs(e*n)}}(r,s,u),x=function(t,e,o,n){let i;const r=function(t,e){const{x:o,x2:n,y:i,y2:r}=t,s=Math.min(i,r)-e.top,a=Math.min(o,n)-e.left,d=e.bottom-Math.max(i,r),l=e.right-Math.max(o,n);return{x:Math.min(a,l),y:Math.min(s,d),dx:a<=l?1:-1,dy:s<=d?1:-1}}(t,n);i="start"===e.position?Dt({w:t.x2-t.x,h:t.y2-t.y},o,e,r):"end"===e.position?1-Dt({w:t.x-t.x2,h:t.y-t.y2},o,e,r):m(1,e.position);return i}(t,o,{labelSize:f,padding:a},i),y=t.cp?Mt(c,t.cp,h,x):pt(c,h,x),p={size:f.w,min:i.left,max:i.right,padding:a.left},b={size:f.h,min:i.top,max:i.bottom,padding:a.top},g=jt(y.x,p)+d,v=jt(y.y,b)+l;return{x:g-r/2,y:v-s/2,x2:g+r/2,y2:v+s/2,centerX:g,centerY:v,pointX:y.x,pointY:y.y,width:r,height:s,rotation:e.toDegrees(u)}}(o,n,{width:a,height:d,padding:r},t.chartArea)}(t,c,o.label);return h._visible=l,c.elements=[{type:"label",optionScope:"label",properties:h,initProperties:c.initProperties}],c}}Ct.id="lineAnnotation";const kt={backgroundColor:void 0,backgroundShadowColor:void 0,borderColor:void 0,borderDash:void 0,borderDashOffset:void 0,borderShadowColor:void 0,borderWidth:void 0,display:void 0,fill:void 0,length:void 0,shadowBlur:void 0,shadowOffsetX:void 0,shadowOffsetY:void 0,width:void 0};function At({x:t,y:e},o,{top:n,right:i,bottom:r,left:s}){return t<s&&(e=gt(s,{x:t,y:e},o),t=s),t>i&&(e=gt(i,{x:t,y:e},o),t=i),e<n&&(t=bt(n,{x:t,y:e},o),e=n),e>r&&(t=bt(r,{x:t,y:e},o),e=r),{x:t,y:e}}function Tt(t,{mouseX:e,mouseY:o},n,i){const r=t.label;return r.options.display&&r.inRange(e,o,i,n)}function Dt(t,e,o,n){const{labelSize:i,padding:r}=e,s=t.w*n.dx,a=t.h*n.dy,l=s>0&&(i.w/2+r.left-n.x)/s,c=a>0&&(i.h/2+r.top-n.y)/a;return d(Math.max(l,c),0,.25)}function jt(t,e){const{size:o,min:n,max:i,padding:r}=e,s=o/2;return o>i-n?(i+n)/2:(n>=t-r-s&&(t=n+r+s),i<=t+r+s&&(t=i-r-s),t)}function Ot(t){const e=t.options,o=e.arrowHeads&&e.arrowHeads.start,n=e.arrowHeads&&e.arrowHeads.end;return{startOpts:o,endOpts:n,startAdjust:Rt(t,o),endAdjust:Rt(t,n)}}function Rt(t,e){if(!e||!e.display)return 0;const{length:o,width:n}=e,i=t.options.borderWidth/2,r={x:o,y:n+i},s={x:0,y:i};return Math.abs(bt(0,r,s))}function It(t,e,o,n){if(!n||!n.display)return;const{length:i,width:r,fill:s,backgroundColor:a,borderColor:d}=n,l=Math.abs(e-i)+o;t.beginPath(),_(t,n),X(t,n),t.moveTo(l,-r),t.lineTo(e+o,0),t.lineTo(l,r),!0===s?(t.fillStyle=a||d,t.closePath(),t.fill(),t.shadowColor="transparent"):t.shadowColor=n.borderShadowColor,t.stroke()}function Yt(t,{x:e,y:o},{angle:n,adjust:i},r){r&&r.display&&(t.save(),t.translate(e,o),t.rotate(n),It(t,0,-i,r),t.restore())}Ct.defaults={adjustScaleRange:!0,arrowHeads:{display:!1,end:Object.assign({},kt),fill:!1,length:12,start:Object.assign({},kt),width:6},borderDash:[],borderDashOffset:0,borderShadowColor:"transparent",borderWidth:2,curve:!1,controlPoint:{y:"-50%"},display:!0,endValue:void 0,init:void 0,hitTolerance:0,label:{backgroundColor:"rgba(0,0,0,0.8)",backgroundShadowColor:"transparent",borderCapStyle:"butt",borderColor:"black",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderRadius:6,borderShadowColor:"transparent",borderWidth:0,callout:Object.assign({},yt.defaults.callout),color:"#fff",content:null,display:!1,drawTime:void 0,font:{family:void 0,lineHeight:void 0,size:void 0,style:void 0,weight:"bold"},height:void 0,hitTolerance:void 0,opacity:void 0,padding:6,position:"center",rotation:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,textAlign:"center",textStrokeColor:void 0,textStrokeWidth:0,width:void 0,xAdjust:0,yAdjust:0,z:void 0},scaleID:void 0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,value:void 0,xMax:void 0,xMin:void 0,xScaleID:void 0,yMax:void 0,yMin:void 0,yScaleID:void 0,z:0},Ct.descriptors={arrowHeads:{start:{_fallback:!0},end:{_fallback:!0},_fallback:!0}},Ct.defaultRoutes={borderColor:"color"};class Xt extends t.Element{inRange(t,o,n,i){const s=this.options.rotation,d=(this.options.borderWidth+this.options.hitTolerance)/2;if("x"!==n&&"y"!==n)return function(t,o,n,i){const{width:r,height:s,centerX:a,centerY:d}=o,l=r/2,c=s/2;if(l<=0||c<=0)return!1;const h=e.toRadians(n||0),u=Math.cos(h),f=Math.sin(h),x=Math.pow(u*(t.x-a)+f*(t.y-d),2),y=Math.pow(f*(t.x-a)-u*(t.y-d),2);return x/Math.pow(l+i,2)+y/Math.pow(c+i,2)<=1.0001}({x:t,y:o},this.getProps(["width","height","centerX","centerY"],i),s,d);const{x:l,y:c,x2:h,y2:u}=this.getProps(["x","y","x2","y2"],i),f="y"===n?{start:c,end:u}:{start:l,end:h},x=r({x:t,y:o},this.getCenterPoint(i),e.toRadians(-s));return x[n]>=f.start-d-a&&x[n]<=f.end+d+a}getCenterPoint(t){return f(this,t)}draw(t){const{width:o,height:n,centerX:i,centerY:r,options:s}=this;t.save(),Y(t,this.getCenterPoint(),s.rotation),_(t,this.options),t.beginPath(),t.fillStyle=s.backgroundColor;const a=X(t,s);t.ellipse(i,r,n/2,o/2,e.PI/2,0,2*e.PI),t.fill(),a&&(t.shadowColor=s.borderShadowColor,t.stroke()),t.restore()}get label(){return this.elements&&this.elements[0]}resolveElementProperties(t,e){return G(t,e)}}Xt.id="ellipseAnnotation",Xt.defaults={adjustScaleRange:!0,backgroundShadowColor:"transparent",borderDash:[],borderDashOffset:0,borderShadowColor:"transparent",borderWidth:1,display:!0,hitTolerance:0,init:void 0,label:Object.assign({},ft.defaults.label),rotation:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,xMax:void 0,xMin:void 0,xScaleID:void 0,yMax:void 0,yMin:void 0,yScaleID:void 0,z:0},Xt.defaultRoutes={borderColor:"color",backgroundColor:"color"},Xt.descriptors={label:{_fallback:!0}};class _t extends t.Element{inRange(t,e,o,n){const{x:i,y:r,x2:s,y2:a,width:d}=this.getProps(["x","y","x2","y2","width"],n),c=(this.options.borderWidth+this.options.hitTolerance)/2;if("x"!==o&&"y"!==o)return function(t,e,o,n){return!(!t||!e||o<=0)&&Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2)<=Math.pow(o+n,2)}({x:t,y:e},this.getCenterPoint(n),d/2,c);return l("y"===o?{start:r,end:a,value:e}:{start:i,end:s,value:t},c)}getCenterPoint(t){return f(this,t)}draw(t){const e=this.options,o=e.borderWidth;if(e.radius<.1)return;t.save(),t.fillStyle=e.backgroundColor,_(t,e);const n=X(t,e);F(t,this,this.centerX,this.centerY),n&&!I(e.pointStyle)&&(t.shadowColor=e.borderShadowColor,t.stroke()),t.restore(),e.borderWidth=o}resolveElementProperties(t,e){const o=q(t,e);return o.initProperties=A(t,o,e),o}}_t.id="pointAnnotation",_t.defaults={adjustScaleRange:!0,backgroundShadowColor:"transparent",borderDash:[],borderDashOffset:0,borderShadowColor:"transparent",borderWidth:1,display:!0,hitTolerance:0,init:void 0,pointStyle:"circle",radius:10,rotation:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,xAdjust:0,xMax:void 0,xMin:void 0,xScaleID:void 0,xValue:void 0,yAdjust:0,yMax:void 0,yMin:void 0,yScaleID:void 0,yValue:void 0,z:0},_t.defaultRoutes={borderColor:"color",backgroundColor:"color"};class Et extends t.Element{inRange(t,o,n,i){if("x"!==n&&"y"!==n)return this.options.radius>=.1&&this.elements.length>1&&function(t,e,o,n){let i=!1,r=t[t.length-1].getProps(["bX","bY"],n);for(const s of t){const t=s.getProps(["bX","bY"],n);t.bY>o!=r.bY>o&&e<(r.bX-t.bX)*(o-t.bY)/(r.bY-t.bY)+t.bX&&(i=!i),r=t}return i}(this.elements,t,o,i);const s=r({x:t,y:o},this.getCenterPoint(i),e.toRadians(-this.options.rotation)),a=this.elements.map((t=>"y"===n?t.bY:t.bX)),d=Math.min(...a),l=Math.max(...a);return s[n]>=d&&s[n]<=l}getCenterPoint(t){return f(this,t)}draw(t){const{elements:e,options:o}=this;t.save(),t.beginPath(),t.fillStyle=o.backgroundColor,_(t,o);const n=X(t,o);let i=!0;for(const o of e)i?(t.moveTo(o.x,o.y),i=!1):t.lineTo(o.x,o.y);t.closePath(),t.fill(),n&&(t.shadowColor=o.borderShadowColor,t.stroke()),t.restore()}resolveElementProperties(t,o){const n=q(t,o),{sides:i,rotation:r}=o,s=[],a=2*e.PI/i;let d=r*e.RAD_PER_DEG;for(let e=0;e<i;e++,d+=a){const e=Wt(n,o,d);e.initProperties=A(t,n,o),s.push(e)}return n.elements=s,n}}function Wt({centerX:t,centerY:e},{radius:o,borderWidth:n,hitTolerance:i},r){const s=(n+i)/2,a=Math.sin(r),d=Math.cos(r),l={x:t+a*o,y:e-d*o};return{type:"point",optionScope:"point",properties:{x:l.x,y:l.y,centerX:l.x,centerY:l.y,bX:t+a*(o+s),bY:e-d*(o+s)}}}Et.id="polygonAnnotation",Et.defaults={adjustScaleRange:!0,backgroundShadowColor:"transparent",borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderShadowColor:"transparent",borderWidth:1,display:!0,hitTolerance:0,init:void 0,point:{radius:0},radius:10,rotation:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,sides:3,xAdjust:0,xMax:void 0,xMin:void 0,xScaleID:void 0,xValue:void 0,yAdjust:0,yMax:void 0,yMin:void 0,yScaleID:void 0,yValue:void 0,z:0},Et.defaultRoutes={borderColor:"color",backgroundColor:"color"};const zt={box:ft,doughnutLabel:xt,ellipse:Xt,label:yt,line:Ct,point:_t,polygon:Et};Object.keys(zt).forEach((e=>{t.defaults.describe(`elements.${zt[e].id}`,{_fallback:"plugins.annotation.common"})}));const Ft={update:Object.assign},Ht=ot.concat(st),Nt=(t,o)=>e.isObject(o)?Qt(t,o):t,Lt=t=>"color"===t||"font"===t;function Vt(t="line"){return zt[t]?t:(console.warn(`Unknown annotation type: '${t}', defaulting to 'line'`),"line")}function Bt(o,n,i,r){const s=function(e,o,n){if("reset"===n||"none"===n||"resize"===n)return Ft;return new t.Animations(e,o)}(o,i.animations,r),a=n.annotations,d=function(t,e){const o=e.length,n=t.length;if(n<o){const e=o-n;t.splice(n,0,...new Array(e))}else n>o&&t.splice(o,n-o);return t}(n.elements,a);for(let t=0;t<a.length;t++){const n=a[t],i=Jt(d,t,n.type),r=n.setContext(Gt(o,i,d,n)),l=i.resolveElementProperties(o,r);l.skip=$t(l),"elements"in l&&(Ut(i,l.elements,r,s),delete l.elements),e.defined(i.x)||Object.assign(i,l),Object.assign(i,l.initProperties),l.options=qt(r),s.update(i,l)}}function $t(t){return isNaN(t.x)||isNaN(t.y)}function Ut(t,e,o,n){const i=t.elements||(t.elements=[]);i.length=e.length;for(let t=0;t<e.length;t++){const r=e[t],s=r.properties,a=Jt(i,t,r.type,r.initProperties),d=o[r.optionScope].override(r);s.options=qt(d),n.update(a,s)}}function Jt(t,e,o,n){const i=zt[Vt(o)];let r=t[e];return r&&r instanceof i||(r=t[e]=new i,Object.assign(r,n)),r}function qt(t){const e=zt[Vt(t.type)],o={};o.id=t.id,o.type=t.type,o.drawTime=t.drawTime,Object.assign(o,Qt(t,e.defaults),Qt(t,e.defaultRoutes));for(const e of Ht)o[e]=t[e];return o}function Qt(t,o){const n={};for(const i of Object.keys(o)){const r=o[i],s=t[i];Lt(i)&&e.isArray(s)?n[i]=s.map((t=>Nt(t,r))):n[i]=Nt(s,r)}return n}function Gt(t,e,o,n){return e.$context||(e.$context=Object.assign(Object.create(t.getContext()),{element:e,get elements(){return o.filter((t=>t&&t.options))},id:n.id,type:"annotation"}))}const Kt=new Map,Zt=t=>"doughnutLabel"!==t.type,te=ot.concat(st);var ee={id:"annotation",version:"3.1.0",beforeRegister(){!function(t,e,o,n=!0){const i=o.split(".");let r=0;for(const a of e.split(".")){const d=i[r++];if(parseInt(a,10)<parseInt(d,10))break;if(s(d,a)){if(n)throw new Error(`${t} v${o} is not supported. v${e} or newer is required.`);return!1}}}("chart.js","4.0",t.Chart.version)},afterRegister(){t.Chart.register(zt)},afterUnregister(){t.Chart.unregister(zt)},beforeInit(t){Kt.set(t,{annotations:[],elements:[],visibleElements:[],listeners:{},listened:!1,moveListened:!1,hooks:{},hooked:!1,hovered:[]})},beforeUpdate(t,o,n){const i=Kt.get(t).annotations=[];let r=n.annotations;e.isObject(r)?Object.keys(r).forEach((t=>{const o=r[t];e.isObject(o)&&(o.id=t,i.push(o))})):e.isArray(r)&&i.push(...r),function(t,e){for(const o of t)ct(o,e)}(i.filter(Zt),t.scales)},afterDataLimits(t,e){const o=Kt.get(t);dt(t,e.scale,o.annotations.filter(Zt).filter((t=>t.display&&t.adjustScaleRange)))},afterUpdate(t,o,n){const i=Kt.get(t);!function(t,o,n){o.listened=T(n,ot,o.listeners),o.moveListened=!1,et.forEach((t=>{e.isFunction(n[t])&&(o.moveListened=!0)})),o.listened&&o.moveListened||o.annotations.forEach((t=>{!o.listened&&e.isFunction(t.click)&&(o.listened=!0),o.moveListened||et.forEach((n=>{e.isFunction(t[n])&&(o.listened=!0,o.moveListened=!0)}))}))}(0,i,n),Bt(t,i,n,o.mode),i.visibleElements=i.elements.filter((t=>!t.skip&&t.options.display)),function(t,o,n){const i=o.visibleElements;o.hooked=T(n,st,o.hooks),o.hooked||i.forEach((t=>{o.hooked||st.forEach((n=>{e.isFunction(t.options[n])&&(o.hooked=!0)}))}))}(0,i,n)},beforeDatasetsDraw(t,e,o){oe(t,"beforeDatasetsDraw",o.clip)},afterDatasetsDraw(t,e,o){oe(t,"afterDatasetsDraw",o.clip)},beforeDatasetDraw(t,e,o){oe(t,e.index,o.clip)},beforeDraw(t,e,o){oe(t,"beforeDraw",o.clip)},afterDraw(t,e,o){oe(t,"afterDraw",o.clip)},beforeEvent(t,e,o){nt(Kt.get(t),e.event,o)&&(e.changed=!0)},afterDestroy(t){Kt.delete(t)},getAnnotations(t){const e=Kt.get(t);return e?e.elements:[]},_getAnnotationElementsAtEventForMode:(t,e,o)=>n(t,e,o),defaults:{animations:{numbers:{properties:["x","y","x2","y2","width","height","centerX","centerY","pointX","pointY","radius"],type:"number"},colors:{properties:["backgroundColor","borderColor"],type:"color"}},clip:!0,interaction:{mode:void 0,axis:void 0,intersect:void 0},common:{drawTime:"afterDatasetsDraw",init:!1,label:{}}},descriptors:{_indexable:!1,_scriptable:t=>!te.includes(t)&&"init"!==t,annotations:{_allKeys:!1,_fallback:(t,e)=>`elements.${zt[Vt(e.type)].id}`},interaction:{_fallback:!0},common:{label:{_indexable:Lt,_fallback:!0},_indexable:Lt}},additionalOptionScopes:[""]};function oe(t,o,n){const{ctx:i,chartArea:r}=t,s=Kt.get(t);n&&e.clipArea(i,r);const a=function(t,e){const o=[];for(const n of t)if(n.options.drawTime===e&&o.push({element:n,main:!0}),n.elements&&n.elements.length)for(const t of n.elements)t.options.display&&t.options.drawTime===e&&o.push({element:t});return o}(s.visibleElements,o).sort(((t,e)=>t.element.options.z-e.element.options.z));for(const t of a)ne(i,r,s,t);n&&e.unclipArea(i)}function ne(t,e,o,n){const i=n.element;n.main?(at(o,i,"beforeDraw"),i.draw(t,e),at(o,i,"afterDraw")):i.draw(t,e)}return t.Chart.register(ee),ee}));
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: matebot
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: The proactive companion for GaggiMate espresso machines: post-shot logging bot, .slog decoder, shot-journal site generator
|
|
5
|
+
Project-URL: Homepage, https://github.com/AlexNly/matebot
|
|
6
|
+
Project-URL: Issues, https://github.com/AlexNly/matebot/issues
|
|
7
|
+
Author: Alexander Nicolay
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: coffee,discord,espresso,gaggimate,homelab,telegram
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Home Automation
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Requires-Dist: aiohttp>=3.9
|
|
16
|
+
Provides-Extra: all
|
|
17
|
+
Requires-Dist: discord-py>=2.3; extra == 'all'
|
|
18
|
+
Requires-Dist: matplotlib>=3.8; extra == 'all'
|
|
19
|
+
Requires-Dist: matrix-nio>=0.24; extra == 'all'
|
|
20
|
+
Requires-Dist: python-telegram-bot<23,>=21; extra == 'all'
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
24
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
25
|
+
Provides-Extra: discord
|
|
26
|
+
Requires-Dist: discord-py>=2.3; extra == 'discord'
|
|
27
|
+
Provides-Extra: matrix
|
|
28
|
+
Requires-Dist: matrix-nio>=0.24; extra == 'matrix'
|
|
29
|
+
Provides-Extra: plots
|
|
30
|
+
Requires-Dist: matplotlib>=3.8; extra == 'plots'
|
|
31
|
+
Provides-Extra: telegram
|
|
32
|
+
Requires-Dist: python-telegram-bot<23,>=21; extra == 'telegram'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# matebot
|
|
36
|
+
|
|
37
|
+
A post-shot companion for [GaggiMate](https://gaggimate.eu) espresso machines.
|
|
38
|
+
|
|
39
|
+
I kept forgetting to log my shots. Not for lack of caring — but after every
|
|
40
|
+
shot the ritual was: pull out the phone, open the web UI, find Shot History,
|
|
41
|
+
tap edit, type everything in. Most days that didn't happen, and by 23:47,
|
|
42
|
+
lying in bed, the grind setting of today's best shot was gone for good.
|
|
43
|
+
|
|
44
|
+
matebot turns the workflow around: when a shot finishes, the machine messages
|
|
45
|
+
*you* and asks the few things you'd otherwise forget — rating, taste, beans,
|
|
46
|
+
grind, doses. Thirty seconds of tapping while you sip. The answers are written
|
|
47
|
+
straight back into GaggiMate's own Shot Notes, exactly as if you'd typed them
|
|
48
|
+
into the web UI.
|
|
49
|
+
|
|
50
|
+
<p align="center">
|
|
51
|
+
<img src="docs/screenshots/telegram-chat.png" width="420" alt="matebot asking for a shot rating on Telegram right after the shot finished">
|
|
52
|
+
</p>
|
|
53
|
+
|
|
54
|
+
## What it does
|
|
55
|
+
|
|
56
|
+
- Watches the machine over its WebSocket API and detects finished brew shots
|
|
57
|
+
(backflush/descale/flush runs and anything under 10 s are ignored).
|
|
58
|
+
- Runs a short questionnaire via **Telegram** or **Discord** (Matrix planned),
|
|
59
|
+
with one-tap "same as last shot" defaults for beans, grind and dose.
|
|
60
|
+
- Saves the answers into the machine's shot history — GaggiMate stays the
|
|
61
|
+
source of truth, with or without matebot.
|
|
62
|
+
- Optionally archives every shot (`.slog` + notes), your brew profiles and
|
|
63
|
+
machine settings (credentials redacted) to a git repository after each shot.
|
|
64
|
+
- Generates a static **shot journal** from that archive, ready for GitHub
|
|
65
|
+
Pages. Because the journal lives outside the machine, it survives firmware
|
|
66
|
+
updates and downgrades, a dying SD card, or a water-damaged machine.
|
|
67
|
+
- Ships a standalone `.slog` decoder (`matebot decode shot.slog --csv`).
|
|
68
|
+
- After a sour, bitter or low-rated shot it suggests the next dial-in step
|
|
69
|
+
(grind → ratio → temperature, one variable at a time), following
|
|
70
|
+
[modsmthng's Automatic Pro cheat sheet](https://modsmthng.github.io/Automatic-Pro/)
|
|
71
|
+
— disable with `MATEBOT_HINTS=0`.
|
|
72
|
+
|
|
73
|
+
## The shot journal
|
|
74
|
+
|
|
75
|
+
[Live example](https://alexnly.github.io/GAGGIMATE-0614/) — every shot with
|
|
76
|
+
the familiar combined pressure/flow/temperature chart, phase markers, ratings
|
|
77
|
+
and notes.
|
|
78
|
+
|
|
79
|
+
<p align="center">
|
|
80
|
+
<img src="docs/screenshots/journal-list.png" width="49%" alt="Shot journal list with ratings, ratios and peak pressure">
|
|
81
|
+
<img src="docs/screenshots/journal-detail.png" width="49%" alt="Per-shot detail with combined pressure/flow/temperature chart">
|
|
82
|
+
</p>
|
|
83
|
+
|
|
84
|
+
## Install
|
|
85
|
+
|
|
86
|
+
### Docker
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
mkdir matebot && cd matebot
|
|
90
|
+
curl -O https://raw.githubusercontent.com/AlexNly/matebot/main/docker-compose.example.yml
|
|
91
|
+
cp docker-compose.example.yml docker-compose.yml
|
|
92
|
+
# edit: machine host, bot token, chat id
|
|
93
|
+
docker compose up -d
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Images are multi-arch (`amd64` + `arm64`, so a Raspberry Pi works):
|
|
97
|
+
`ghcr.io/alexnly/matebot:latest`. There is no cloud service behind this —
|
|
98
|
+
the bot needs to run on something in your home network that is always on.
|
|
99
|
+
A Pi Zero 2 W and a USB charger is the whole data center.
|
|
100
|
+
|
|
101
|
+
### pip
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
pip install "matebot[telegram] @ git+https://github.com/AlexNly/matebot"
|
|
105
|
+
matebot run
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### NixOS (flake)
|
|
109
|
+
|
|
110
|
+
```nix
|
|
111
|
+
inputs.matebot.url = "github:AlexNly/matebot";
|
|
112
|
+
|
|
113
|
+
services.matebot = {
|
|
114
|
+
enable = true;
|
|
115
|
+
machineHost = "192.168.1.50";
|
|
116
|
+
environmentFile = "/etc/secrets/matebot"; # TELEGRAM_BOT_TOKEN=... / TELEGRAM_CHAT_ID=...
|
|
117
|
+
dataRepo = "/var/lib/gaggimate-journal"; # optional
|
|
118
|
+
};
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Setup
|
|
122
|
+
|
|
123
|
+
1. Telegram: create a bot with [@BotFather](https://t.me/BotFather)
|
|
124
|
+
(`/newbot`), copy the token. Message your bot once, then read your chat id
|
|
125
|
+
from `https://api.telegram.org/bot<TOKEN>/getUpdates`.
|
|
126
|
+
Discord: create an application + bot, invite it to a server, enable the
|
|
127
|
+
*message content* intent, copy the channel id.
|
|
128
|
+
2. Point `MATEBOT_MACHINE_HOST` at your GaggiMate. A DHCP reservation is more
|
|
129
|
+
reliable than `gaggimate.local`.
|
|
130
|
+
3. Pull a shot.
|
|
131
|
+
|
|
132
|
+
## Chat commands
|
|
133
|
+
|
|
134
|
+
Besides the post-shot questionnaire, the bot answers commands (any messenger):
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
/wake turn the machine on — pings you when it's at temperature
|
|
138
|
+
/sleep back to standby
|
|
139
|
+
/status mode, boiler temperature, water level
|
|
140
|
+
/last the last logged shot (with journal link if configured)
|
|
141
|
+
/fix redo the questionnaire for the last shot
|
|
142
|
+
/help list commands
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Smart plug cold start (optional)
|
|
146
|
+
|
|
147
|
+
GaggiMate in standby still draws power, so many people cut it at a smart
|
|
148
|
+
plug — which normally kills `/wake`. Give MATEbot the plug's on/off commands
|
|
149
|
+
and `/wake` becomes a true cold start (plug on → wait for the machine to
|
|
150
|
+
boot → brew mode → ready ping), while `/sleep` powers everything down:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Tasmota (Nous A1T, Eightree, ...)
|
|
154
|
+
MATEBOT_WAKE_HOOK='curl -sf "http://192.168.1.60/cm?cmnd=Power%20On"'
|
|
155
|
+
MATEBOT_SLEEP_HOOK='curl -sf "http://192.168.1.60/cm?cmnd=Power%20Off"'
|
|
156
|
+
|
|
157
|
+
# Shelly
|
|
158
|
+
MATEBOT_WAKE_HOOK='curl -sf "http://192.168.1.60/relay/0?turn=on"'
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Any shell command works (Home Assistant webhook, `tinytuya`, zigbee2mqtt…).
|
|
162
|
+
|
|
163
|
+
## Configuration
|
|
164
|
+
|
|
165
|
+
Environment variables, or the same keys in `~/.config/matebot/config.toml`:
|
|
166
|
+
|
|
167
|
+
| Variable | Default | Meaning |
|
|
168
|
+
|---|---|---|
|
|
169
|
+
| `MATEBOT_MACHINE_HOST` | `gaggimate.local` | GaggiMate hostname/IP |
|
|
170
|
+
| `MATEBOT_MESSENGER` | `telegram` | `telegram` or `discord` |
|
|
171
|
+
| `TELEGRAM_BOT_TOKEN` / `TELEGRAM_CHAT_ID` | — | Telegram credentials |
|
|
172
|
+
| `DISCORD_BOT_TOKEN` / `DISCORD_CHANNEL_ID` | — | Discord credentials |
|
|
173
|
+
| `MATEBOT_DATA_REPO` | — | Path to a git clone; enables archive + journal |
|
|
174
|
+
| `MATEBOT_SITE_TITLE` | `Shot Journal` | Title of the generated journal |
|
|
175
|
+
| `MATEBOT_JOURNAL_URL` | — | Public journal URL, used for `/last` deep links |
|
|
176
|
+
| `MATEBOT_HINTS` | `1` | Dial-in hints after sour/bitter/low-rated shots |
|
|
177
|
+
| `MATEBOT_STATE_DIR` | `~/.local/state/matebot` | Bot state (defaults, resume) |
|
|
178
|
+
| `MATEBOT_MIN_SHOT_S` | `10` | Ignore shots shorter than this |
|
|
179
|
+
| `MATEBOT_IGNORE_PROFILES` | `(?i)backflush\|descale\|flush\|clean` | Profile regex to skip |
|
|
180
|
+
|
|
181
|
+
## CLI
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
matebot run # the bot (--replay frames.jsonl --dry-run to test)
|
|
185
|
+
matebot decode SHOT.slog # .slog -> JSON (--csv for CSV)
|
|
186
|
+
matebot sitegen shots/ -o docs/ --title "My Shot Journal"
|
|
187
|
+
matebot sync # one-off journal sync (shots, profiles, settings, site)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Publishing your journal on GitHub Pages
|
|
191
|
+
|
|
192
|
+
1. Create a repo for your data, clone it where matebot runs, set
|
|
193
|
+
`MATEBOT_DATA_REPO` to the clone.
|
|
194
|
+
2. On GitHub: Settings → Pages → Deploy from branch → `main` / `/docs`.
|
|
195
|
+
3. Every shot now updates `https://<you>.github.io/<repo>/`.
|
|
196
|
+
|
|
197
|
+
## How it talks to the machine
|
|
198
|
+
|
|
199
|
+
Local network only — nothing leaves your LAN except the messenger API and
|
|
200
|
+
your own git remote. Requires GaggiMate firmware ≥ v1.7 (binary shot logs).
|
|
201
|
+
|
|
202
|
+
- `ws://<machine>/ws` — `evt:status` for shot detection,
|
|
203
|
+
`req:history:notes:save` for notes, `req:profiles:list` for backup
|
|
204
|
+
- `GET /api/history/index.bin`, `<id>.slog`, `<id>.json` — shot downloads
|
|
205
|
+
- `GET /api/settings` — settings backup; WiFi/AP/Home-Assistant credentials
|
|
206
|
+
are redacted before anything is written to disk
|
|
207
|
+
|
|
208
|
+
The `.slog` v5 binary format (512-byte header, 26-byte samples at 250 ms) is
|
|
209
|
+
documented in [`src/matebot/slog.py`](src/matebot/slog.py).
|
|
210
|
+
|
|
211
|
+
### WhatsApp?
|
|
212
|
+
|
|
213
|
+
There is no reasonable self-hosted WhatsApp bot API. Two workable paths:
|
|
214
|
+
bridge your Telegram/Matrix chat via [mautrix](https://docs.mau.fi/bridges/),
|
|
215
|
+
or Meta's WhatsApp Business Cloud API (requires a business account). Native
|
|
216
|
+
support: contributions welcome.
|
|
217
|
+
|
|
218
|
+
## Credits
|
|
219
|
+
|
|
220
|
+
- [GaggiMate](https://gaggimate.eu) by jniebuhr — the machine controller this
|
|
221
|
+
companion talks to.
|
|
222
|
+
- The journal's shot chart recreates the look of GaggiMate's own web UI
|
|
223
|
+
(independent reimplementation — GaggiMate's UI code is CC BY-NC-SA and none
|
|
224
|
+
of it is copied). Rendered with [Chart.js](https://www.chartjs.org/) and
|
|
225
|
+
chartjs-plugin-annotation (MIT, vendored).
|
|
226
|
+
- The dial-in hints follow the guide from
|
|
227
|
+
[Automatic Pro cheat sheet](https://modsmthng.github.io/Automatic-Pro/) by
|
|
228
|
+
**modsmthng**.
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
MIT. Not affiliated with the GaggiMate project.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
matebot/__init__.py,sha256=ccvXr0bRKJB6aMEkYlbEBx15PNkHycRxmbNQGBoJIPU,98
|
|
2
|
+
matebot/bags.py,sha256=gwjIAF-oXQPSnEH7YCUhQbzZux0cHJpc73iKXsviU50,2542
|
|
3
|
+
matebot/cli.py,sha256=vK8Jh13tzEP4t31v6pqHqwDtFgwLzaGYTSIQFUnDLNA,12403
|
|
4
|
+
matebot/commands.py,sha256=8ENrRWXqp7Os4U5TcfrZ7iBzJZIfWLu3wyPIH8ytHyg,10751
|
|
5
|
+
matebot/config.py,sha256=f_Bf659FnKzeQ0l0Xyb4EfNtkX-yzUUS9h8WeQY0iso,3522
|
|
6
|
+
matebot/conversation.py,sha256=uOChXTMOmpw8W-pct6-OsgIDGVQwnfQTFni67F0uXTs,9218
|
|
7
|
+
matebot/digest.py,sha256=Gylf82eRNRXaP3VPfbReSpLgnuaYUhgdu2e0EJKaqBw,2629
|
|
8
|
+
matebot/hints.py,sha256=9w5WO_cRMv4_ET1aG33jdajgMKx4Z-A5lc7ipxP_T8w,2151
|
|
9
|
+
matebot/machine.py,sha256=DJ47yAlyUglFnsTR1ImYirB-iuYCIzMWG5JWz4oTdZI,8027
|
|
10
|
+
matebot/plot.py,sha256=XvS75begF3q6RuR0ubkc6hUCOJHiaeBetxhePNoVEmg,3675
|
|
11
|
+
matebot/sitegen.py,sha256=5QJxg7lH_N77_XsM3MhUF16fQ0xAac-GoOQPZ4uLLBw,4076
|
|
12
|
+
matebot/slog.py,sha256=NhR_w3pM9x2ofO5z-TH5Ulhc0ZUAUMwN52DAhCBMtZo,7284
|
|
13
|
+
matebot/state.py,sha256=bxwUC0Wq8YY8JhCIOui3sAHImbXe34P1WgQ8YDNc5zM,1224
|
|
14
|
+
matebot/sync.py,sha256=7gbZtLoJDHmdHljF4PScbzLf7LgGA8OK74hIEablzeg,6330
|
|
15
|
+
matebot/watcher.py,sha256=CW4ab-3PFDbaf967brRthFA9S5T7X8aCPmWQ82fHPr4,5126
|
|
16
|
+
matebot/messengers/__init__.py,sha256=Wg6Bqz4QV_B36vIrv_Ff5q9K9Hwy3mDZnGe9iXGHN70,824
|
|
17
|
+
matebot/messengers/base.py,sha256=4ex6nOLtbqdRqEWZOI2Y65KitSYhq7yz_j8dfEJj3v0,1629
|
|
18
|
+
matebot/messengers/discord.py,sha256=6wA8wW4FCNmBDoKsW80Ohpa15W54cvcZToTxTXCHy8k,3099
|
|
19
|
+
matebot/messengers/telegram.py,sha256=DGqCoAEqTyTShuX5BlyQoJJ0uX8vOBDBCA8jnlN--zU,4722
|
|
20
|
+
matebot/web/app.js,sha256=DYo_jue8Y3u7vbVX2nRn5Bx4xBjwbWgwspIS_9yDums,15386
|
|
21
|
+
matebot/web/index.html,sha256=ED55pu3uDxEIYYNcxrXanYPuRoXyeaFwejW2qr2MOWM,1646
|
|
22
|
+
matebot/web/style.css,sha256=ha7poLdO6uWR42JcbuAHU85HzB7x7HMKcnu-faNyj7U,6453
|
|
23
|
+
matebot/web/vendor/chart.umd.js,sha256=xAh36I3k33IBUyAU4U-3B_DwehlqTsY-BwVEuAGE-wA,206553
|
|
24
|
+
matebot/web/vendor/chartjs-plugin-annotation.min.js,sha256=_wN4amD2yTzKz-D7tsLjxnHXkwhWo2ifLzkxE9jWVew,38359
|
|
25
|
+
matebot-0.2.0.dist-info/METADATA,sha256=Kte5MSspNqY5FTAtNkDNEglEcQZYmcEFYfgRU__3EJE,9445
|
|
26
|
+
matebot-0.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
27
|
+
matebot-0.2.0.dist-info/entry_points.txt,sha256=sVKADTQQONPckxoXT7pcJ1CeCnXjxWxKRjL8rc1UH0s,45
|
|
28
|
+
matebot-0.2.0.dist-info/licenses/LICENSE,sha256=m_Ja0TMn9UXYj15ODsQ-Z9Hhdmm_IOsirRUb13IzTm4,1074
|
|
29
|
+
matebot-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexander Nicolay
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|