-
Notifications
You must be signed in to change notification settings - Fork 2
/
hermes.esm.js
1 lines (1 loc) · 50 KB
/
hermes.esm.js
1
const ActionType={FilterCreate:"filter-create",FilterMove:"filter-move",FilterResizeAfter:"filter-resize-after",FilterResizeBefore:"filter-resize-before",LabelMove:"label-move",None:"none"},DimensionLayout={AxisEvenlySpaced:"axis-evenly-spaced",Equidistant:"equidistant"},DimensionType={Categorical:"categorical",Linear:"linear",Logarithmic:"logarithmic"},Direction={Horizontal:"horizontal",Vertical:"vertical"},FocusType={DimensionAxis:"dimension-axis",DimensionLabel:"dimension-label",Filter:"filter",FilterResize:"filter-resize"},LabelPlacement={After:"after",Before:"before"},PathType={Bezier:"bezier",Straight:"straight"},INVALID_VALUE=Number.NaN,INVALID_POINT={x:Number.NaN,y:Number.NaN},INVALID_RECT={h:Number.NaN,w:Number.NaN,x:Number.NaN,y:Number.NaN},INVALID_ACTION={dimIndex:-1,p0:INVALID_POINT,p1:INVALID_POINT,type:ActionType.None},BEZIER_FACTOR=.3,DIRECTION="inherit",FONT="normal 12px san-serif",LINE_CAP="butt",LINE_DASH_OFFSET=0,LINE_JOIN="round",LINE_WIDTH=1,MITER_LIMIT=10,STROKE_STYLE="black",TEXT_BASELINE="middle",TRUNCATE_SIZE=24,TRUNCATE_SUFFIX="...",HERMES_CONFIG={debug:!1,direction:Direction.Horizontal,filters:{},hooks:{},interactions:{throttleDelayMouseMove:50,throttleDelayResize:50},style:{axes:{axis:{boundaryPadding:15,infLineDash:[2,4],infOffset:24,lineWidth:1,nanGap:24,strokeStyle:"rgba(147, 147, 147, 1.0)"},axisActive:{lineWidth:3,strokeStyle:"rgba(99, 200, 255, 1.0)"},axisHover:{lineWidth:3,strokeStyle:"rgba(79, 180, 246, 1.0)"},filter:{cornerRadius:2,fillStyle:"rgba(235, 100, 200, 1.0)",strokeStyle:"rgba(255, 255, 255, 1.0)",width:4},filterActive:{cornerRadius:3,fillStyle:"rgba(255, 120, 220, 1.0)",width:8},filterAxisHover:{cornerRadius:2,fillStyle:"rgba(235, 100, 200, 1.0)",width:6},filterHover:{cornerRadius:2,fillStyle:"rgba(235, 100, 200, 1.0)",width:8},label:{fillStyle:"rgba(0, 0, 0, 1.0)",font:"normal 11px sans-serif",lineWidth:3,offset:4,placement:LabelPlacement.After,strokeStyle:"rgba(255, 255, 255, 1.0)"},labelActive:{fillStyle:"rgba(0, 0, 0, 1.0)"},labelHover:{fillStyle:"rgba(0, 0, 0, 1.0)"},tick:{length:4,lineWidth:1,strokeStyle:"rgba(147, 147, 147, 1.0)"},tickActive:{strokeStyle:"rgba(99, 200, 255, 1.0)"},tickHover:{strokeStyle:"rgba(79, 180, 246, 1.0)"}},data:{default:{lineWidth:1,strokeStyle:"rgba(82, 144, 244, 1.0)"},filtered:{lineWidth:1,strokeStyle:"rgba(0, 0, 0, 0.05)"},overrideNaN:{lineWidth:1,strokeStyle:"rgba(255, 0, 0, 0.2)"},overrideNegativeInfinity:{lineWidth:1,strokeStyle:"rgba(255, 0, 0, 0.2)"},overridePositiveInfinity:{lineWidth:1,strokeStyle:"rgba(255, 0, 0, 0.2)"},path:{options:{},type:PathType.Straight},series:[],targetColorScale:[],targetDimensionKey:void 0},dimension:{label:{angle:void 0,boundaryPadding:5,fillStyle:"rgba(0, 0, 0, 1.0)",font:"normal 11px sans-serif",lineWidth:3,offset:16,placement:LabelPlacement.Before,strokeStyle:"rgba(255, 255, 255, 1.0)"},labelActive:{fillStyle:"rgba(99, 200, 255, 1.0)"},labelHover:{fillStyle:"rgba(79, 180, 246, 1.0)"},layout:DimensionLayout.AxisEvenlySpaced},padding:[32,64]}},FILTER={hasNaN:!1,hasNegativeInfinity:!1,hasPositiveInfinity:!1,p0:Number.NaN,p1:Number.NaN,percent0:Number.NaN,percent1:Number.NaN,value0:Number.NaN,value1:Number.NaN},FILTER_EPSILON=.01,IX={dimension:{axis:0,bound:void 0,boundOffset:void 0,offset:0},filters:{active:FILTER,key:void 0},shared:{action:INVALID_ACTION,focus:void 0}},isError=e=>e instanceof Error,isNumber=e=>"number"==typeof e,isMap=e=>e instanceof Map,isObject=e=>"object"==typeof e&&null!=e&&Object.getPrototypeOf(e)===Object.prototype&&!Array.isArray(e)&&!isMap(e)&&!isSet(e),isSet=e=>e instanceof Set,isString=e=>"string"==typeof e,clone=e=>JSON.parse(JSON.stringify(e)),capDataRange=(e,t)=>Math.min(t[1],Math.max(t[0],e)),deepMerge=(...e)=>e.reduce(((e,t)=>(Object.keys(t).forEach((i=>{isObject(e[i])&&isObject(t[i])?e[i]=deepMerge(e[i],t[i]):(Array.isArray(e[i])&&Array.isArray(t[i]),e[i]=t[i])})),e)),{}),EPSILON=1e-6,getDataRange=(e,t)=>{const i=e=>t===DimensionType.Logarithmic?isFinite(Math.log(e)):isFinite(e),s=e.reduce(((e,t)=>(isNumber(t)&&!isNaN(t)&&(i(t)&&(t<e.finite[0]&&(e.finite[0]=t),t>e.finite[1]&&(e.finite[1]=t)),t<e.actual[0]&&(e.actual[0]=t),t>e.actual[1]&&(e.actual[1]=t)),e)),{actual:[1/0,-1/0],finite:[Number.MAX_VALUE,-Number.MAX_VALUE]});if(s.actual[0]===s.actual[1]&&s.finite[0]===s.finite[1]&&s.actual[0]===s.finite[0]){const e=t===DimensionType.Logarithmic?1:Math.pow(10,Math.log10(s.actual[0])-1);s.actual[0]-=e,s.actual[1]+=e,s.finite[0]=i(s.actual[0])?s.actual[0]:s.actual[0]+EPSILON,s.finite[1]=i(s.actual[1])?s.actual[1]:s.actual[1]-EPSILON}return s},idempotentItem=(e,t)=>e[t%e.length],idempotentLogNumber=(e,t,i,s,a,n={})=>{const r=10===e?Math.log10:2===e?Math.log2:Math.log,o=r===Math.log?Math.log(e):1,l=r(t)/o,c=r(i)/o;return e**idempotentNumber(l,c,s,a,n)},idempotentNumber=(e,t,i,s,a={})=>{var n,r,o;const l=i>1?i-1:1,c=(e-t)/l;if(0!==Object.keys(a).length){const e=null!==(n=a.includeNaN)&&void 0!==n?n:0,t=(null!==(r=a.includeNegativeInfinity)&&void 0!==r?r:0)+e,l=(null!==(o=a.includePositiveInfinity)&&void 0!==o?o:0)+t,c=s/i;if(c<=e)return Number.NaN;if(c<=t)return Number.NEGATIVE_INFINITY;if(c<=l)return Number.POSITIVE_INFINITY}return s%(l+1)*c+t},processData=e=>{const t=Object.keys(e),i={hasInfinity:!1,hasNaN:!1,seriesCount:0};for(const s of t){i.seriesCount=i.seriesCount||e[s].length;for(const t of e[s])isNumber(t)&&isNaN(t)&&(i.hasNaN=!0),!isNumber(t)||isNaN(t)||isFinite(t)||(i.hasInfinity=!0)}return i},randomInt=(e,t=0)=>Math.floor(Math.random()*(e-t))+t,randomItem=e=>e[randomInt(e.length)],randomLogNumber=(e,t,i,s={})=>{const a=10===e?Math.log10:2===e?Math.log2:Math.log,n=a===Math.log?Math.log(e):1,r=a(t)/n,o=a(i)/n,l=randomNumber(r,o,s);return isNaN(l)||!isFinite(l)?l:e**l},randomNumber=(e,t,i={})=>{if(null!=i.includeNaN){const e=capDataRange(i.includeNaN,[0,1]);if(Math.random()<e)return Number.NaN}if(null!=i.includeNegativeInfinity){const e=capDataRange(i.includeNegativeInfinity,[0,1]);if(Math.random()<e)return-1/0}if(null!=i.includePositiveInfinity){const e=capDataRange(i.includePositiveInfinity,[0,1]);if(Math.random()<e)return 1/0}return Math.random()*(e-t)+t},obj2str=(e,t=!0)=>{const i=JSON.stringify(e,(function(e,t){if(isNumber(t)){if(isNaN(t))return"Number.NaN";if(!isFinite(t)){if(t===1/0)return"Number.Infinity";if(t===-1/0)return"-Number.Infinity"}}else if("function"==typeof t)return`${t}`;return t}),2);return t?i.replace(/"(-?(Number\.)?(NaN|Infinity))"/g,"$1"):i},str2obj=(str,infNaN=!0)=>{function reviver(key,value){if(isString(value)){if(/^-(Number\.)?Infinity$/.test(value))return-1/0;if(/^(Number\.)?Infinity$/.test(value))return 1/0;if(/^(Number\.)?NaN$/.test(value))return NaN;if(/^\s*function/gm.test(value)||/^\s*\(?\s*{?\s*[\w$]*\s*(,\s*[\w$]*\s*)*}?\s*\)?\s*=>/gm.test(value))return eval("("+value+")")}return value}const string=infNaN?str.replace(/(-?(Number\.)?(NaN|Infinity))/g,'"$1"'):str;return JSON.parse(string,reviver)},readableNumber=(e,t=6)=>{let i=e.toString();const s=Math.abs(e);return isNaN(e)?i="NaN":Number.isFinite(e)?0!==s&&(s<.01||s>999?i=e.toExponential(t):Number.isInteger(e)||(i=e.toFixed(t))):i=(e<0?"-":"")+"Infinity",i},readableTick=e=>{let t=readableNumber(e);return t=t.replace(/(e)\+(\d+)/,"$1$2"),t=t.replace(/0+(e-?\d+)$/,"$1"),t=t.replace(/(\.[0-9]+?)0+$/,"$1"),t=t.replace(/\.(e)/,"$1"),t},truncate=(e,t={})=>{var i,s;const a=null!==(i=t.size)&&void 0!==i?i:TRUNCATE_SIZE,n=null!==(s=t.suffix)&&void 0!==s?s:TRUNCATE_SUFFIX;return e.length<=a?e:`${e.substring(0,a)}${n}`},value2str=e=>isString(e)?e:e.toString(),DEFAULT_DATA_ON_EDGE=!0,DEFAULT_REVERSE=!1,MIN_TICK_DISTANCE=50;class NiceScale{constructor(e,t,i,s={}){this.direction=e,this.minValue=t,this.maxValue=i,this.axisLength=1,this.maxTicks=1,this.dataOnEdge=DEFAULT_DATA_ON_EDGE,this.range=0,this.reverse=DEFAULT_REVERSE,this.tickLabels=[],this.tickPos=[],this.ticks=[],this.tickPadding=0,this.tickSpacing=0,this.max=i,this.min=t,null!=s.dataOnEdge&&(this.dataOnEdge=s.dataOnEdge),e===Direction.Horizontal?this.reverse=null!=s.reverse&&s.reverse:this.reverse=null==s.reverse||!s.reverse,this.setMinMaxValues(t,i,!1)}setAxisLength(e){this.axisLength=e,this.maxTicks=e/MIN_TICK_DISTANCE,this.calculate()}setMinMaxValues(e,t,i=!0){if(e===t){const i=e;if(0===i)e=-1,t=1;else if(i<0){e=i-((t=-(2**(Math.log2(Math.abs(i))-1)))-i)}else{t=i+(i-(e=2**(Math.log2(i)-1)))}}this.minValue=e,this.maxValue=t,this.max=t,this.min=e,this.range=t-e,i&&this.calculate()}niceNum(e,t){const i=Math.abs(e),s=Math.floor(Math.log10(i)),a=i/10**s;let n;return n=t?a<1.5?1:a<3?2:a<7?5:10:a<=1?1:a<=2?2:a<=5?5:10,n*10**s}}class CategoricalScale extends NiceScale{constructor(e,t=[],i={}){super(e,0,0,i),this.direction=e,this.categories=t,this.reverse&&this.categories.reverse(),this.tickLabels=this.categories.map((e=>value2str(e)))}percentToValue(e){return this.posToValue(e*this.axisLength)}posToValue(e){let t=1/0,i=Number.NaN;for(let s=0;s<this.tickPos.length;s++){const a=this.tickPos[s],n=Math.abs(e-a);n<t&&(t=n,i=this.categories[s])}return i}valueToPercent(e){const t=value2str(e),i=this.tickLabels.findIndex((e=>e===t));return-1!==i?this.tickPos[i]/this.axisLength:0}valueToPos(e){return this.valueToPercent(e)*this.axisLength}calculate(){const e=this.tickLabels.length;let t=0;this.tickSpacing=this.axisLength/(this.dataOnEdge?e-1:e),this.tickPos=[];for(let i=0;i<e;i++)[0,e].includes(i)?t+=this.dataOnEdge?0:this.tickSpacing/2:t+=this.tickSpacing,this.tickPos.push(t)}}const MESSAGE_PREFIX="[Hermes]",DEFAULT_MESSAGE="Critical error encountered!";class HermesError extends Error{constructor(e){const t=isError(e)?e.message:isString(e)?e:DEFAULT_MESSAGE;super(`${MESSAGE_PREFIX} ${t}`)}}class LinearScale extends NiceScale{constructor(e,t,i,s,a,n={}){super(e,t,i,n),this.direction=e,this.finiteMin=t,this.finiteMax=i,this.actualMin=s,this.actualMax=a,this.config=n,this.actualMax=a,this.actualMin=s}percentToValue(e){if(0===e)return this.reverse?this.actualMax:this.actualMin;if(1===e)return this.reverse?this.actualMin:this.actualMax;const t=this.dataOnEdge?this.minValue:this.min,i=this.dataOnEdge?this.maxValue:this.max;return(this.reverse?1-e:e)*(i-t)+t}posToValue(e){return this.percentToValue(e/this.axisLength)}valueToPercent(e){if(!isNumber(e))return Number.NaN;if(e===this.actualMax)return this.reverse?0:1;if(e===this.actualMin)return this.reverse?1:0;const t=this.dataOnEdge?this.minValue:this.min,i=(e-t)/((this.dataOnEdge?this.maxValue:this.max)-t);return this.reverse?1-i:i}valueToPos(e){return this.valueToPercent(e)*this.axisLength}calculate(){this.range=this.niceNum(this.maxValue-this.minValue,!1),this.tickSpacing=this.niceNum(this.range/this.maxTicks,!0),this.min=Math.floor(this.minValue/this.tickSpacing)*this.tickSpacing,this.max=Math.ceil(this.maxValue/this.tickSpacing)*this.tickSpacing;const e=Math.round((this.max-this.min)/this.tickSpacing);this.ticks=[],this.tickLabels=[];for(let t=0;t<=e;t++){let i=t*this.tickSpacing+this.min;this.dataOnEdge&&0===t&&(i=this.minValue),this.dataOnEdge&&t===e&&(i=this.maxValue),this.ticks.push(i);let s=readableTick(i);this.dataOnEdge&&[0,e].includes(t)&&(s=`*${s}`),this.tickLabels.push(s)}this.tickPos=this.ticks.map((e=>this.valueToPos(e)))}}const DEFAULT_LOG_BASE=10,basedLog=e=>t=>Math.log(t)/Math.log(e);class LogScale extends NiceScale{constructor(e,t,i,s,a,n=DEFAULT_LOG_BASE,r={}){super(e,t,i,r),this.direction=e,this.finiteMin=t,this.finiteMax=i,this.actualMin=s,this.actualMax=a,this.logBase=n,this.maxExp=Number.NaN,this.maxExpExact=Number.NaN,this.minExp=Number.NaN,this.minExpExact=Number.NaN,this.log=basedLog(n),this.logBase=n,this.actualMax=a,this.actualMin=s}setLogBase(e=DEFAULT_LOG_BASE){this.logBase=e,this.calculate()}percentToValue(e){if(0===e)return this.reverse?this.actualMax:this.actualMin;if(1===e)return this.reverse?this.actualMin:this.actualMax;const t=this.dataOnEdge?this.minExpExact:this.minExp,i=(this.reverse?1-e:e)*this.rangeExp()+t;return this.logBase**i}posToValue(e){return this.percentToValue(e/this.axisLength)}valueToPercent(e){if(!isNumber(e))return 0;const t=this.log(e),i=this.dataOnEdge?this.minExpExact:this.minExp,s=(t-i)/((this.dataOnEdge?this.maxExpExact:this.maxExp)-i);return this.reverse?1-s:s}valueToPos(e){return this.valueToPercent(e)*this.axisLength}rangeExp(){return this.dataOnEdge?this.maxExpExact-this.minExpExact:this.maxExp-this.minExp}calculate(){this.log=basedLog(this.logBase),this.minExpExact=this.log(this.minValue),this.maxExpExact=this.log(this.maxValue),this.minExp=Math.floor(this.minExpExact),this.maxExp=Math.ceil(this.maxExpExact),this.range=this.logBase**this.maxExp-this.logBase**this.minExp,this.tickSpacing=1;const e=Math.round((this.maxExp-this.minExp)/this.tickSpacing);this.ticks=[],this.tickLabels=[];for(let t=0;t<=e;t++){const i=t*this.tickSpacing+this.minExp;let s=this.logBase**i;this.dataOnEdge&&0===t&&(s=this.logBase**this.minExpExact),this.dataOnEdge&&t===e&&(s=this.logBase**this.maxExpExact),this.ticks.push(s);let a=readableTick(s);this.dataOnEdge&&[0,e].includes(t)&&(a=`*${a}`),this.tickLabels.push(a)}this.tickPos=this.ticks.map((e=>this.valueToPos(e)))}}const distance=(e,t)=>Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2),rotatePoint=(e,t,i,s=0,a=0)=>{const n=e-s,r=t-a,o=Math.cos(i),l=Math.sin(i);return{x:o*n-l*r+s,y:l*n+o*r+a}},dotProduct=(e,t)=>e.x*t.x+e.y*t.y,isPointInTriangle=(e,t,i,s)=>{const a={x:s.x-t.x,y:s.y-t.y},n={x:i.x-t.x,y:i.y-t.y},r={x:e.x-t.x,y:e.y-t.y},o=dotProduct(a,a),l=dotProduct(a,n),c=dotProduct(a,r),h=dotProduct(n,n),d=dotProduct(n,r),u=1/(o*h-l*l),p=(h*c-l*d)*u,y=(o*d-l*c)*u;return p>=0&&y>=0&&p+y<1},shiftRect=(e,t)=>({h:e.h,w:e.w,x:e.x+t.x,y:e.y+t.y}),drawBoundary=(e,t,i={})=>{if(e.save(),i.fillStyle){e.fillStyle=i.fillStyle,e.beginPath(),e.moveTo(t[0].x,t[0].y);for(let i=1;i<t.length;i++)e.lineTo(t[i].x,t[i].y);e.closePath(),e.fill()}if(i.strokeStyle){e.lineCap=i.lineCap||LINE_CAP,e.lineDashOffset=i.lineDashOffset||LINE_DASH_OFFSET,e.lineJoin=i.lineJoin||LINE_JOIN,e.lineWidth=i.lineWidth||LINE_WIDTH,e.miterLimit=i.miterLimit||MITER_LIMIT,e.strokeStyle=i.strokeStyle,e.beginPath(),e.moveTo(t[0].x,t[0].y);for(let i=1;i<t.length;i++)e.lineTo(t[i].x,t[i].y);e.closePath(),e.stroke()}e.restore()},drawCircle=(e,t,i,s,a={})=>{e.save(),a.fillStyle&&(e.fillStyle=null==a?void 0:a.fillStyle,e.moveTo(t+s,i),e.beginPath(),e.arc(t,i,s,0,2*Math.PI),e.fill()),a.strokeStyle&&(e.lineCap=a.lineCap||LINE_CAP,e.lineDashOffset=a.lineDashOffset||LINE_DASH_OFFSET,e.lineJoin=a.lineJoin||LINE_JOIN,e.lineWidth=a.lineWidth||LINE_WIDTH,e.miterLimit=a.miterLimit||MITER_LIMIT,e.strokeStyle=a.strokeStyle,e.moveTo(t+s,i),e.beginPath(),e.arc(t,i,s,0,2*Math.PI),e.stroke()),e.restore()},drawData=(e,t,i,s,a={})=>{var n;if(t.length<2)return;e.save(),e.lineCap=a.lineCap||LINE_CAP,e.lineDashOffset=a.lineDashOffset||LINE_DASH_OFFSET,e.lineJoin=a.lineJoin||LINE_JOIN,e.lineWidth=a.lineWidth||LINE_WIDTH,e.miterLimit=a.miterLimit||MITER_LIMIT,e.strokeStyle=a.strokeStyle||STROKE_STYLE,e.beginPath(),e.moveTo(t[0].x,t[0].y);const r=null!==(n=s.options.bezierFactor)&&void 0!==n?n:BEZIER_FACTOR;for(let a=1;a<t.length;a++){const[n,o]=[t[a].x,t[a].y];if(s.type===PathType.Straight)e.lineTo(n,o);else if(s.type===PathType.Bezier){const[s,l]=[t[a-1].x,t[a-1].y],[c,h]=[s+(i?(n-s)*r:0),l+(i?0:(o-l)*r)],[d,u]=[n-(i?(n-s)*r:0),o-(i?0:(o-l)*r)];e.bezierCurveTo(c,h,d,u,n,o)}}e.stroke(),e.restore()},drawLine=(e,t,i,s,a,n={})=>{e.save(),e.lineCap=n.lineCap||LINE_CAP,e.lineDashOffset=n.lineDashOffset||LINE_DASH_OFFSET,e.lineJoin=n.lineJoin||LINE_JOIN,e.lineWidth=n.lineWidth||LINE_WIDTH,e.miterLimit=n.miterLimit||MITER_LIMIT,e.strokeStyle=n.strokeStyle||STROKE_STYLE,e.beginPath(),e.setLineDash(n.lineDash||[]),e.moveTo(roundPixel(t),roundPixel(i)),e.lineTo(roundPixel(s),roundPixel(a)),e.stroke(),e.restore()},drawRect=(e,t,i,s,a,n={})=>{e.save();const r=roundPixel(t),o=roundPixel(i),l=n.cornerRadius||0;n.fillStyle&&(e.fillStyle=n.fillStyle,0===l?e.fillRect(r,o,s,a):(drawRoundedRect(e,r,o,s,a,l),e.fill())),n.strokeStyle&&(e.lineCap=n.lineCap||LINE_CAP,e.lineDashOffset=n.lineDashOffset||LINE_DASH_OFFSET,e.lineJoin=n.lineJoin||LINE_JOIN,e.lineWidth=n.lineWidth||LINE_WIDTH,e.miterLimit=n.miterLimit||MITER_LIMIT,e.strokeStyle=n.strokeStyle,0===l?e.strokeRect(r,o,s,a):(drawRoundedRect(e,r,o,s,a,l),e.stroke())),e.restore()},drawRoundedRect=(e,t,i,s,a,n)=>{e.beginPath(),e.moveTo(t+n,i),e.lineTo(t+s-n,i),e.quadraticCurveTo(t+s,i,t+s,i+n),e.lineTo(t+s,i+a-n),e.quadraticCurveTo(t+s,i+a,t+s-n,i+a),e.lineTo(t+n,i+a),e.quadraticCurveTo(t,i+a,t,i+a-n),e.lineTo(t,i+n),e.quadraticCurveTo(t,i,t+n,i),e.closePath()},drawText=(e,t,i,s,a,n={})=>{const r=normalizeRad(a),o=r>Math.PI/2&&r<=3*Math.PI/2,l=-a-(o?Math.PI:0);e.save(),setFont(e,n.font),e.direction=n.direction||DIRECTION,e.textAlign=n.textAlign||(o?"right":"left"),e.textBaseline=n.textBaseline||TEXT_BASELINE,l%2*Math.PI!=0&&(e.translate(i,s),e.rotate(l),e.translate(-i,-s)),n.strokeStyle&&(e.lineCap=n.lineCap||LINE_CAP,e.lineDashOffset=n.lineDashOffset||LINE_DASH_OFFSET,e.lineJoin=n.lineJoin||LINE_JOIN,e.lineWidth=n.lineWidth||LINE_WIDTH,e.miterLimit=n.miterLimit||MITER_LIMIT,e.strokeStyle=n.strokeStyle,e.strokeText(t,i,s)),n.fillStyle&&(e.fillStyle=n.fillStyle,e.fillText(t,i,s)),e.restore()},getTextBoundary=(e,t,i,s,a,n=0,r=0,o=0)=>{const l=e+n-o,c=t+r-o,h=e+i+n+o,d=t+s+r+o,u=[{x:l,y:c},{x:h,y:c},{x:h,y:d},{x:l,y:d}];if(null!=a){const i=normalizeRad(a);return u.map((s=>rotatePoint(s.x,s.y,-i,e,t)))}return u},getTextSize=(e,t,i=FONT)=>{setFont(e,i);const s=e.measureText(t),a=s.actualBoundingBoxLeft+s.actualBoundingBoxRight;return{h:s.actualBoundingBoxAscent+s.actualBoundingBoxDescent,w:a}},normalizePadding=e=>{const t=devicePixelRatio<=1?1:2-.5**(devicePixelRatio-1);return Array.isArray(e)?2===e.length?[e[0]*t,e[1]*t,e[0]*t,e[1]*t]:e.map((e=>e*t)):new Array(4).fill(e*t)},normalizeRad=e=>(e+2*Math.PI)%(2*Math.PI),roundPixel=e=>Math.round(e-.5)+.5,setFont=(e,t=FONT)=>{const i=new RegExp(/(-?\d*\.?\d+)px/),s=t.match(i);if(2===(null==s?void 0:s.length)){const a=Math.round(parseFloat(s[1])*devicePixelRatio);e.font=t.replace(i,`${a}px`)}else e.font=t},hex2rgb=e=>{const t={b:0,g:0,r:0},i=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return i&&i.length>3&&(t.r=parseInt(i[1],16),t.g=parseInt(i[2],16),t.b=parseInt(i[3],16)),t},rgba2str=e=>null!=e.a?`rgba(${e.r}, ${e.g}, ${e.b}, ${e.a})`:`rgb(${e.r}, ${e.g}, ${e.b})`,rgbaFromGradient=(e,t,i)=>{const s=Math.round((t.r-e.r)*i+e.r),a=Math.round((t.g-e.g)*i+e.g),n=Math.round((t.b-e.b)*i+e.b);if(null!=e.a&&null!=t.a){return{a:(t.a-e.a)*i+e.a,b:n,g:a,r:s}}return{b:n,g:a,r:s}},scale2rgba=(e,t)=>{const i=e.length;if(i<1)return"#000000";if(1===i)return e[0];const s=t*(i-1),a=Math.floor(s),n=Math.ceil(s),r=str2rgba(e[a]),o=str2rgba(e[n]),l=rgbaFromGradient(r,o,s-a);return rgba2str(l)},str2rgba=e=>{if(/^#/.test(e))return hex2rgb(e);const t=/^rgba?\(\s*?(\d+)\s*?,\s*?(\d+)\s*?,\s*?(\d+)\s*?(,\s*?([\d.]+)\s*?)?\)$/i.exec(e);if(t&&t.length>3){const e={a:1,b:0,g:0,r:0};return e.r=parseInt(t[1]),e.g=parseInt(t[2]),e.b=parseInt(t[3]),t.length>5&&void 0!==t[5]&&(e.a=parseFloat(t[5])),e}return{a:1,b:0,g:0,r:0}},getElement=e=>isString(e)?document.querySelector(e):e,getMousePoint=(e,t)=>{const i=t.getBoundingClientRect();return{x:(e.clientX-i.x)*devicePixelRatio,y:(e.clientY-i.y)*devicePixelRatio}},throttle=(e,t)=>{let i;return(...s)=>{null==i&&(i=setTimeout((()=>{e(...s),i=void 0}),t))}},DIMENSION_SWAP_THRESHOLD=30,FILTER_REMOVE_THRESHOLD=1,FILTER_RESIZE_THRESHOLD=3,getDragBound=(e,t,i)=>{const s=t.shared.action,a=s.type===ActionType.LabelMove&&s.dimIndex===e,n=t.dimension.bound||INVALID_RECT,r=t.dimension.boundOffset||{x:0,y:0};return a?shiftRect(n,r):i},isFilterEmpty=e=>isNaN(e.p0)&&isNaN(e.p1),isFilterInvalid=e=>e.p0>=e.p1,isIntersectingFilters=(e,t)=>e.p0<=t.p1&&t.p0<=e.p1,mergeFilters=(e,t)=>{const i=clone(FILTER);return e.p0<t.p0?(i.p0=e.p0,i.percent0=e.percent0,i.value0=e.value0):(i.p0=t.p0,i.percent0=t.percent0,i.value0=t.value0),e.p1>t.p1?(i.p1=e.p1,i.percent1=e.percent1,i.value1=e.value1):(i.p1=t.p1,i.percent1=t.percent1,i.value1=t.value1),i.hasNaN=e.hasNaN||t.hasNaN,i.hasNegativeInfinity=e.hasNegativeInfinity||t.hasNegativeInfinity,i.hasPositiveInfinity=e.hasPositiveInfinity||t.hasPositiveInfinity,i},DEFAULT_DIMENSION_COUNT=10,dimensionRanges={accuracy:[.55,.99],dropout:[.2,.8],"global-batch-size":[5,30],"layer-free-decay":[.001,.1],"layer-split-factor":[1,16],"learning-rate":[1e-4,.1],"learning-rate-decay":[1e-6,.001],loss:[1.7,2.4],"metrics-base":[.5,.9],"n-filters":[8,64]},dimensionSamples=[{dataOnEdge:!1,key:"dropout",label:"Dropout",type:DimensionType.Linear},{dataOnEdge:!1,key:"global-batch-size",label:"Global Batch Size",type:DimensionType.Linear},{categories:[4,8,16,32,64],dataOnEdge:!1,key:"layer-dense-size",label:"Layer Dense Size",type:DimensionType.Categorical},{dataOnEdge:!1,key:"layer-free-decay",label:"Layer Free Decay",logBase:10,type:DimensionType.Logarithmic},{categories:[!0,!1],dataOnEdge:!1,key:"layer-inverse",label:"Layer Inverse",type:DimensionType.Categorical},{dataOnEdge:!1,key:"learning-rate",label:"Learning Rate",logBase:10,type:DimensionType.Logarithmic},{dataOnEdge:!1,key:"learning-rate-decay",label:"Learning Rate Decay",logBase:10,type:DimensionType.Logarithmic},{dataOnEdge:!1,key:"layer-split-factor",label:"Layer Split Factor",logBase:2,type:DimensionType.Logarithmic},{dataOnEdge:!1,key:"metrics-base",label:"Metrics Base",type:DimensionType.Linear},{dataOnEdge:!1,key:"n-filters",label:"N Filters",type:DimensionType.Linear}],metricDimensionSamples=[{dataOnEdge:!0,disableDrag:!0,key:"accuracy",label:"Accuracy",type:DimensionType.Linear},{dataOnEdge:!0,disableDrag:!0,key:"loss",label:"Loss",type:DimensionType.Logarithmic}],generateData=(e,t,i=!0,s={})=>e.reduce(((e,a)=>(e[a.key]=new Array(t).fill(null).map(((e,n)=>{if(a.type===DimensionType.Categorical){if(a.categories)return i?randomItem(a.categories):idempotentItem(a.categories,n)}else if(a.type===DimensionType.Linear){const e=dimensionRanges[a.key];if(e)return i?randomNumber(e[1],e[0],s):idempotentNumber(e[1],e[0],t,n,s)}else if(a.type===DimensionType.Logarithmic){const e=dimensionRanges[a.key];if(e&&a.logBase)return i?randomLogNumber(a.logBase,e[1],e[0],s):idempotentLogNumber(a.logBase,e[1],e[0],t,n)}return INVALID_VALUE})),e)),{}),generateDimensions=(e=DEFAULT_DIMENSION_COUNT,t=!0)=>{const i=new Array(e-1).fill(null).map(((e,i)=>t?randomItem(dimensionSamples):idempotentItem(dimensionSamples,i))),s=t?randomItem(metricDimensionSamples):idempotentItem(metricDimensionSamples,0);return i.push(s),i};var tester=Object.freeze({__proto__:null,DEFAULT_DIMENSION_COUNT:DEFAULT_DIMENSION_COUNT,dimensionRanges:dimensionRanges,dimensionSamples:dimensionSamples,metricDimensionSamples:metricDimensionSamples,generateData:generateData,generateDimensions:generateDimensions});class Hermes{constructor(e,t,i,s){this.config=HERMES_CONFIG,this.data={},this.dataInfo={hasInfinity:!1,hasNaN:!1,seriesCount:0},this.dimensions=[],this.dimensionsOriginal=[],this.filters={},this.size={h:0,w:0},this.ix=clone(IX),this._=void 0;const a=getElement(e);if(!a)throw new HermesError("Target element selector did not match anything.");this.element=a;const n=this.element.getBoundingClientRect();0!==n.width&&0!==n.height||console.warn("Target element width and height must both be greater than 0px.");const r=this.element.querySelectorAll("canvas");0===r.length?(this.canvas=document.createElement("canvas"),this.element.appendChild(this.canvas)):this.canvas=r[0];const o=this.canvas.getContext("2d");if(!o)throw new HermesError("Unable to get context from target element.");this.ctx=o,t&&this.setDimensions(t,!1),i&&this.setConfig(i,!1),s&&this.setData(s,!1),(t||i||s)&&this.redraw(),this.listeners={dblclick:this.handleDoubleClick.bind(this),mousedown:this.handleMouseDown.bind(this),mousemove:0===this.config.interactions.throttleDelayMouseMove?this.handleMouseMove.bind(this):throttle((e=>this.handleMouseMove.bind(this)(e)),this.config.interactions.throttleDelayMouseMove),mouseup:this.handleMouseUp.bind(this)},this.enable()}static deepMerge(...e){return deepMerge(...e)}static obj2str(e,t){return obj2str(e,t)}static str2obj(e,t){return str2obj(e,t)}static getTester(){return tester}static validateData(e,t){const i={count:0,message:"",valid:!0},s=Object.keys(e),a=Object.values(e);for(let e=0;e<a.length;e++){const t=a[e];if(0===e)i.count=t.length;else if(t.length!==i.count)return i.message=`Data length for "${s[e]}" is not uniform with other dimension data length.`,i.valid=!1,i;if(-1!==t.findIndex((e=>null==e))){const a=null===t;return i.message=`Data for "${s[e]}" has ${a?"null":"undefined"}`,i.valid=!1,i}}const n=Object.keys(e);for(let e=0;e<t.length;e++){const s=t[e].key;if(!n.includes(s))return i.message=`Data for "${s} is missing.`,i.valid=!1,i}return i}static validateDimension(e){if(e.type===DimensionType.Categorical){if(!e.categories||0===e.categories.length)return{message:`Categorical dimension "${e.key}" is missing "categories".`,valid:!1}}else if(e.type===DimensionType.Logarithmic&&(null==e.logBase||0===e.logBase))return{message:`Logarithmic dimension "${e.key}" is missing "logBase".`,valid:!1};return{message:"",valid:!0}}static validateDimensions(e){if(0===e.length)return{message:"Need at least one dimension defined.",valid:!1};for(let t=0;t<e.length;t++){const{message:i,valid:s}=Hermes.validateDimension(e[t]);if(!s)return{message:i,valid:s}}return{message:"",valid:!0}}setConfig(e={},t=!0){this.config=deepMerge(HERMES_CONFIG,e),this.addObservers(),t&&this.redraw()}setData(e,t=!0){const i=Hermes.validateData(e,this.dimensionsOriginal);if(!i.valid)throw new HermesError(i.message);this.data=e,this.dataInfo=processData(this.data),this.setDimensions(this.dimensionsOriginal,!1),t&&this.redraw()}setDimensions(e,t=!0){const i=Hermes.validateDimensions(e);if(!i.valid)throw new HermesError(i.message);const s=this.config.direction===Direction.Horizontal?Direction.Vertical:Direction.Horizontal;this.dimensionsOriginal=e,this.dimensions=clone(e).map((e=>{const t=e.key,i=this.data[t]||[],a={...e,labelTruncated:truncate(e.label,{size:this.config.style.dimension.label.truncate}),rangeActual:void 0,rangeFinite:void 0,scale:new LinearScale(s,0,100,0,100)};if(e.type===DimensionType.Linear||e.type===DimensionType.Logarithmic){const t=getDataRange(i,e.type);e.type===DimensionType.Linear?a.scale=new LinearScale(s,t.finite[0],t.finite[1],t.actual[0],t.actual[1],e):e.type===DimensionType.Logarithmic&&(a.scale=new LogScale(s,t.finite[0],t.finite[1],t.actual[0],t.actual[1],e.logBase,e))}else e.type===DimensionType.Categorical&&(a.scale=new CategoricalScale(s,e.categories,e));return a})),t&&this.redraw()}setSize(e,t,i=!0){var s,a;const n={h:this.size.h,w:this.size.w},r=Math.round(e*devicePixelRatio),o=Math.round(t*devicePixelRatio);this.canvas.width=r,this.canvas.height=o,this.canvas.style.width=`${e}px`,this.canvas.style.height=`${t}px`,this.size={h:o,w:r},null===(a=(s=this.config.hooks).onResize)||void 0===a||a.call(s,clone(this.size),n),i&&this.redraw()}disable(){this.removeListeners(),this.removeObservers(),this.ix=clone(IX),this.updateCursor(),this.redraw()}enable(){this.addListeners(),this.addObservers()}redraw(){0===this.size.w&&0===this.size.h||(this.calculate(),this.clear(),this.config.debug&&this.drawDebugOutline(),this.draw())}destroy(){this.removeListeners(),this.removeObservers(),this.canvas&&this.element.contains(this.canvas)&&this.element.removeChild(this.canvas)}addListeners(){this.element.addEventListener("dblclick",this.listeners.dblclick),this.element.addEventListener("mousedown",this.listeners.mousedown),window.addEventListener("mousemove",this.listeners.mousemove),window.addEventListener("mouseup",this.listeners.mouseup)}addObservers(){this.resizeObserver&&(this.resizeObserver.unobserve(this.element),this.resizeObserver=void 0),this.resizeObserver=new ResizeObserver(0===this.config.interactions.throttleDelayResize?this.handleResize.bind(this):throttle((e=>this.handleResize.bind(this)(e)),this.config.interactions.throttleDelayResize)),this.resizeObserver.observe(this.element)}removeListeners(){this.element.removeEventListener("dblclick",this.listeners.dblclick),this.element.removeEventListener("mousedown",this.listeners.mousedown),window.removeEventListener("mousemove",this.listeners.mousemove),window.removeEventListener("mouseup",this.listeners.mouseup)}removeObservers(){var e;null===(e=this.resizeObserver)||void 0===e||e.unobserve(this.element),this.resizeObserver=void 0}calculate(){this.calculateLayout(),this.calculateStyles()}calculateLayout(){var e,t;const i={dims:{list:new Array(this.dimensions.length).fill(void 0).map((()=>({axes:{},label:{},layout:{}}))),map:this.dimensions.reduce(((e,t,i)=>(e[t.key]=i,e)),{}),shared:{axes:{},label:{},layout:{}}},layout:{drawRect:{},padding:normalizePadding(this.config.style.padding)}},{h:s,w:a}=this.size,n=i.layout,r=i.dims.shared.axes,o=i.dims.shared.label,l=i.dims.shared.layout,c=this.dimensions.length,h=this.config.direction===Direction.Horizontal,d=this.config.style.dimension.label,u=this.config.style.dimension.label.boundaryPadding,p=this.config.style.dimension.layout,y=this.config.style.axes.label,f=this.config.style.axes.axis,g=this.config.style.axes.axis.boundaryPadding,m=d.placement===LabelPlacement.Before,x=null!=d.angle,v=y.placement===LabelPlacement.Before;if(n.drawRect={h:s-n.padding[0]-n.padding[2],w:a-n.padding[1]-n.padding[3],x:n.padding[3],y:n.padding[0]},o.cos=x?Math.cos(null!==(e=d.angle)&&void 0!==e?e:0):void 0,o.sin=x?Math.sin(null!==(t=d.angle)&&void 0!==t?t:0):void 0,o.rad=d.angle||(h?void 0:m?-Math.PI:0),o.maxLengthCos=0,o.maxLengthSin=0,this.dimensions.forEach(((e,t)=>{const s=getTextSize(this.ctx,e.labelTruncated,d.font),a=i.dims.list[t].label;a.w=s.w,a.h=s.h,a.lengthCos=x?s.w*o.cos:s.w,a.lengthSin=x?s.w*o.sin:s.h,Math.abs(a.lengthCos)>Math.abs(o.maxLengthCos)&&(o.maxLengthCos=a.lengthCos),Math.abs(a.lengthSin)>Math.abs(o.maxLengthSin)&&(o.maxLengthSin=a.lengthSin)})),r.start=r.stop=0,r.startInfinity=r.stopInfinity=r.startNaN=r.stopNaN=void 0,h){if(m){const e=Math.max(0,o.maxLengthSin);r.start=n.padding[0]+e+d.offset,r.stop=s-n.padding[2]}else{const e=x?Math.max(0,-o.maxLengthSin):o.maxLengthSin;r.start=n.padding[0],r.stop=s-n.padding[2]-e-d.offset}r.stopNaN=this.dataInfo.hasNaN?r.stop:void 0,r.startInfinity=r.start,r.stopInfinity=r.stop-(this.dataInfo.hasNaN?f.nanGap:0),r.startData=r.startInfinity+(this.dataInfo.hasInfinity?f.infOffset:0),r.stopData=r.stopInfinity-(this.dataInfo.hasInfinity?f.infOffset:0)}else{if(m){const e=x?Math.max(0,-o.maxLengthCos):o.maxLengthCos;r.start=n.padding[3]+e+d.offset,r.stop=a-n.padding[1]}else{const e=Math.max(0,o.maxLengthCos);r.start=n.padding[3],r.stop=a-n.padding[1]-e-d.offset}r.startNaN=this.dataInfo.hasNaN?r.start:void 0,r.startInfinity=r.start+(this.dataInfo.hasNaN?f.nanGap:0),r.stopInfinity=r.stop,r.startData=r.startInfinity+(this.dataInfo.hasInfinity?f.infOffset:0),r.stopData=r.stopInfinity-(this.dataInfo.hasInfinity?f.infOffset:0)}if(r.length=r.stop-r.start,r.labelFactor=v?-1:1,l.totalBoundSpace=0,this.dimensions.forEach(((e,t)=>{const o=i.dims.list[t].axes,c=i.dims.list[t].label,d=i.dims.list[t].layout,u=e.scale;o.tickLabels=[],o.tickPos=[],o.maxLength=0,u&&(u.setAxisLength(r.stopData-r.startData),o.tickLabels=u.tickLabels.slice(),o.tickPos=u.tickPos.slice(),u.tickLabels.forEach((e=>{const t=getTextSize(this.ctx,e,y.font);o.maxLength=Math.max(t.w,o.maxLength)}))),x?(d.spaceBefore=h?c.lengthCos<0?-c.lengthCos:0:c.lengthSin>0?c.lengthSin:0,d.spaceAfter=h?c.lengthCos>0?c.lengthCos:0:c.lengthSin<0?-c.lengthSin:0):(d.spaceBefore=(h?c.lengthCos:c.lengthSin)/2,d.spaceAfter=(h?c.lengthCos:c.lengthSin)/2),v?d.spaceBefore=Math.max(d.spaceBefore,o.maxLength):d.spaceAfter=Math.max(d.spaceAfter,o.maxLength),h?(d.bound={h:s-n.padding[0]-n.padding[2],w:d.spaceBefore+d.spaceAfter,x:0,y:n.padding[0]},l.totalBoundSpace+=d.bound.w):(d.bound={h:d.spaceBefore+d.spaceAfter,w:a-n.padding[1]-n.padding[3],x:n.padding[3],y:0},l.totalBoundSpace+=d.bound.h)})),h){const e=n.drawRect.w-l.totalBoundSpace;l.gap=c>1?Math.max(e,0)/(c-1):0,l.offset=n.padding[3],l.space=c>1?n.drawRect.w/(c-1):0}else{const e=n.drawRect.h-l.totalBoundSpace;l.gap=c>1?Math.max(e,0)/(c-1):0,l.offset=n.padding[0],l.space=c>1?n.drawRect.h/(c-1):0}let b=l.offset;for(let e=0;e<i.dims.list.length;e++){const t=i.dims.list[e].label,s=i.dims.list[e].layout;h?(p===DimensionLayout.AxisEvenlySpaced?(s.bound.x=b-s.spaceBefore,b+=l.space):p===DimensionLayout.Equidistant&&(s.bound.x=b,b+=l.gap+s.bound.w),s.axisBoundaryStart={x:s.spaceBefore,y:r.start-n.padding[0]},s.axisBoundaryStop={x:s.spaceBefore,y:r.stop-n.padding[0]},s.axisInfinityStart={x:s.spaceBefore,y:r.startInfinity-n.padding[0]},s.axisInfinityStop={x:s.spaceBefore,y:r.stopInfinity-n.padding[0]},s.axisDataStart={x:s.spaceBefore,y:r.startData-n.padding[0]},s.axisDataStop={x:s.spaceBefore,y:r.stopData-n.padding[0]},s.labelPoint={x:s.spaceBefore,y:m?r.start-d.offset-n.padding[0]:r.stop+d.offset-n.padding[0]}):(p===DimensionLayout.AxisEvenlySpaced?(s.bound.y=b-s.spaceBefore,b+=l.space):p===DimensionLayout.Equidistant&&(s.bound.y=b,b+=l.gap+s.bound.h),s.axisBoundaryStart={x:r.start-n.padding[3],y:s.spaceBefore},s.axisBoundaryStop={x:r.stop-n.padding[3],y:s.spaceBefore},s.axisInfinityStart={x:r.startInfinity-n.padding[3],y:s.spaceBefore},s.axisInfinityStop={x:r.stopInfinity-n.padding[3],y:s.spaceBefore},s.axisDataStart={x:r.startData-n.padding[3],y:s.spaceBefore},s.axisDataStop={x:r.stopData-n.padding[3],y:s.spaceBefore},s.labelPoint={x:m?r.start-d.offset-n.padding[1]:r.stop+d.offset-n.padding[1],y:s.spaceBefore});const a=h?-t.w/2:0,c=h?m?-t.h:0:-t.h/2;s.labelBoundary=getTextBoundary(s.bound.x+s.labelPoint.x,s.bound.y+s.labelPoint.y,t.w,t.h,o.rad,x?0:a,x?-t.h/2:c,u),s.axisBoundary=[{x:s.bound.x+s.axisBoundaryStart.x-(h?g:0),y:s.bound.y+s.axisBoundaryStart.y-(h?0:g)},{x:s.bound.x+s.axisBoundaryStart.x+(h?g:0),y:s.bound.y+s.axisBoundaryStart.y+(h?0:g)},{x:s.bound.x+s.axisBoundaryStop.x+(h?g:0),y:s.bound.y+s.axisBoundaryStop.y+(h?0:g)},{x:s.bound.x+s.axisBoundaryStop.x-(h?g:0),y:s.bound.y+s.axisBoundaryStop.y-(h?0:g)}]}this._=i}calculateStyles(){if(!this._)return;this._.styles=this._.styles||[];const e=this.config.style,t=e.axes,i=e.dimension,s=this._.dims.list,a=this._.styles,n=this.ix.shared.action,r=this.ix.shared.focus,o=n.type!==ActionType.None;for(let e=0;e<s.length;e++){const s=this.dimensions[e].key,l=this.filters[s]||[],c=n.type===ActionType.LabelMove&&n.dimIndex===e,h=(null==r?void 0:r.type)===FocusType.DimensionLabel&&(null==r?void 0:r.dimIndex)===e,d=(n.type===ActionType.FilterCreate||n.type===ActionType.FilterMove||n.type===ActionType.FilterResizeAfter||n.type===ActionType.FilterResizeBefore)&&n.dimIndex===e,u=((null==r?void 0:r.type)===FocusType.DimensionAxis||(null==r?void 0:r.type)===FocusType.Filter||(null==r?void 0:r.type)===FocusType.FilterResize)&&(null==r?void 0:r.dimIndex)===e;a[e]=a[e]||{},a[e].label={...i.label,...c||!h||o?{}:i.labelHover,...c?i.labelActive:{}},a[e].axis={...t.axis,...d||!u||o?{}:t.axisHover,...d?t.axisActive:{}},a[e].tick={...t.tick,...d||!u||o?{}:t.tickHover,...d?t.tickActive:{}},a[e].tickLabel={...t.label,...d||!u||o?{}:t.labelHover,...d?t.labelActive:{}},a[e].filters=l.map(((i,s)=>{const a=((null==r?void 0:r.type)===FocusType.Filter||(null==r?void 0:r.type)===FocusType.FilterResize)&&(null==r?void 0:r.dimIndex)===e&&(null==r?void 0:r.filterIndex)===s,o=d||u&&!a,l=a&&void 0===n.filterIndex,c=n.dimIndex===e&&n.filterIndex===s;return{...t.filter,...o?t.filterAxisHover:{},...l?t.filterHover:{},...c?t.filterActive:{}}}))}}getFocusByPoint(e){if(!this._)return;const t=this._.dims.shared.axes,i=this.config.direction===Direction.Horizontal?"y":"x",s=this._.dims.shared.axes.length;for(let a=0;a<this._.dims.list.length;a++){const n=this.dimensions[a].key,r=this._.dims.list[a].layout,o=r.labelBoundary;if((isPointInTriangle(e,o[0],o[1],o[2])||isPointInTriangle(e,o[2],o[3],o[0]))&&!this.dimensions[a].disableDrag)return{dimIndex:a,type:FocusType.DimensionLabel};const l=r.axisBoundary;if(isPointInTriangle(e,l[0],l[1],l[2])||isPointInTriangle(e,l[2],l[3],l[0])){const o=this.filters[n]||[],l=r.bound[i]+r.axisBoundaryStart[i],c=(e[i]-l)/s,h=o.findIndex((e=>c>=e.p0&&c<=e.p1));let d=FocusType.DimensionAxis;if(-1!==h){const e=FILTER_RESIZE_THRESHOLD/t.length,i=o[h];d=c<=i.p0+e||c>=i.p1-e?FocusType.FilterResize:FocusType.Filter}return{dimIndex:a,filterIndex:h,type:d}}}}updateActiveLabel(){var e,t;if(!this._||this.ix.shared.action.type!==ActionType.LabelMove)return;const i=this._.dims.list,s=this.ix,a=s.dimension,n=s.shared.action,r=this.config.direction===Direction.Horizontal,o=r?"x":"y";a.boundOffset={x:r?n.p1.x-n.p0.x:0,y:r?0:n.p1.y-n.p0.y};let l=-1;const c=a.axis+a.boundOffset[o];for(let e=0;e<i.length;e++){if(n.dimIndex===e||this.dimensions[e].disableDrag)continue;const t=i[e].layout,s=t.bound[o]+t.axisBoundaryStart[o],a=Math.abs(c-s)<DIMENSION_SWAP_THRESHOLD;if(n.dimIndex<e){if(c<s&&!a)break;l=e}if(n.dimIndex>e&&(c<s||a)){l=e;break}}if(-1!==l){const i=n.dimIndex,s=this.dimensions.splice(n.dimIndex,1);if(0===s.length)return;this.dimensions.splice(l,0,s[0]),n.dimIndex=l,null===(t=(e=this.config.hooks).onDimensionMove)||void 0===t||t.call(e,clone(s[0]),l,i)}}setConfigFilters(e={}){if(this.calculate(),!this._)return;const t=this._.dims.map;Object.keys(e).forEach((e=>{this.filters[e]=this.config.filters[e].map((i=>this.processConfigFilter(i,t[e]))).filter((e=>null!=e))})),this.redraw()}setActiveFilter(e,t){if(!this._)return;const i=this.filters,s=this.ix,a=s.shared.action,n=s.filters,r=this._.dims.shared.axes,o=(i[e]||[]).findIndex((e=>t>=e.p0&&t<=e.p1));-1!==o?(n.active=i[e][o],n.active.startP0=n.active.p0,n.active.startP1=n.active.p1,a.filterIndex=o,t>=n.active.p0&&t<=n.active.p0+FILTER_RESIZE_THRESHOLD/r.length?a.type=ActionType.FilterResizeBefore:t>=n.active.p1-FILTER_RESIZE_THRESHOLD/r.length&&t<=n.active.p1?a.type=ActionType.FilterResizeAfter:a.type=ActionType.FilterMove):(a.type=ActionType.FilterCreate,n.active={...FILTER,p0:t,p1:t},i[e]=i[e]||[],i[e].push(n.active),a.filterIndex=i[e].length-1)}updateActiveFilter(e){var t,i,s,a,n,r,o,l,c,h,d,u;if(!this._)return;const p=this._.dims.list,y=this._.dims.shared.axes,f=this.ix,g=f.filters,m=f.shared.action,x=this.filters,v=m.dimIndex,b=this.config.direction===Direction.Horizontal?"y":"x";if(!(m.type===ActionType.FilterCreate||m.type===ActionType.FilterMove||m.type===ActionType.FilterResizeAfter||m.type===ActionType.FilterResizeBefore)||!g.key)return;const I=this.dimensions[m.dimIndex].key,N=p[m.dimIndex].layout.bound,S=p[m.dimIndex].layout.axisBoundaryStart[b];if(m.type===ActionType.FilterMove){const e=null!==(t=g.active.startP0)&&void 0!==t?t:0,s=null!==(i=g.active.startP1)&&void 0!==i?i:0,a=s-e,n=(m.p1[b]-m.p0[b])/y.length;g.active.p0=e+n,g.active.p1=s+n,g.active.p0<=0?(g.active.p0=0,g.active.p1=a):g.active.p1>=1&&(g.active.p0=1-a,g.active.p1=1)}else m.type===ActionType.FilterResizeBefore?(g.active.p0=(m.p1[b]-N[b]-S)/y.length,g.active.p0=capDataRange(g.active.p0,[0,1])):(g.active.p1=(m.p1[b]-N[b]-S)/y.length,g.active.p1=capDataRange(g.active.p1,[0,1]));if(this.processFilter(g.active,v),"mouseup"===e.type){if(distance(m.p0,m.p1)<FILTER_REMOVE_THRESHOLD){const e=x[g.key]||[],t=(g.active.p1-g.active.p0)/2+g.active.p0,i=e.findIndex((e=>t>=e.p0&&t<=e.p1));if(-1!==i){const t=clone(e[i]);null===(a=(s=this.config.hooks).onFilterRemove)||void 0===a||a.call(s,{[I]:[t]}),e.splice(i,1)}}else{if(g.active.p1<g.active.p0){const e=g.active.p1;g.active.p1=g.active.p0,g.active.p0=e,this.processFilter(g.active,v)}const e={[I]:[clone(g.active)]};switch(m.type){case ActionType.FilterCreate:null===(r=(n=this.config.hooks).onFilterCreate)||void 0===r||r.call(n,e);break;case ActionType.FilterMove:null===(l=(o=this.config.hooks).onFilterMove)||void 0===l||l.call(o,e);break;case ActionType.FilterResizeAfter:case ActionType.FilterResizeBefore:null===(h=(c=this.config.hooks).onFilterResize)||void 0===h||h.call(c,e)}}g.active={...FILTER},g.key=void 0,this.cleanUpFilters(),null===(u=null===(d=this.config.hooks)||void 0===d?void 0:d.onFilterChange)||void 0===u||u.call(d,clone(this.filters))}}getDimensionLayoutInfo(e){if(!this._||!this.dataInfo)return;const t=this._.dims.list[e].layout,i=this.config.direction===Direction.Horizontal,s=t.axisBoundaryStop.x-t.axisBoundaryStart.x,a=t.axisBoundaryStop.y-t.axisBoundaryStart.y,n=i?(t.axisDataStart.y-t.axisBoundaryStart.y)/a:(t.axisDataStart.x-t.axisBoundaryStart.x)/s,r=i?(t.axisDataStop.y-t.axisBoundaryStart.y)/a:(t.axisDataStop.x-t.axisBoundaryStart.x)/s,o=r-n;return{hasInfinity:this.dataInfo.hasInfinity,hasNaN:this.dataInfo.hasNaN,isHorizontal:i,layout:t,pLength:o,pStart:n,pStop:r,xLength:s,yLength:a}}processFilter(e,t){const i=this.getDimensionLayoutInfo(t);if(!i)return;const s=Math.min(e.p0,e.p1),a=Math.max(e.p0,e.p1);if(i.hasInfinity)if(i.isHorizontal){const t=(i.layout.axisInfinityStop.y-i.layout.axisBoundaryStart.y)/i.yLength;e.hasPositiveInfinity=0===s,e.hasNegativeInfinity=s<=t&&a>=t}else{const t=(i.layout.axisInfinityStart.x-i.layout.axisBoundaryStart.x)/i.xLength;e.hasNegativeInfinity=s<=t&&a>=t,e.hasPositiveInfinity=1===a}i.hasNaN&&(e.hasNaN=i.isHorizontal&&1===a||!i.isHorizontal&&0===s),s<=i.pStart?e.percent0=0:s>i.pStart&&s<=i.pStop&&(e.percent0=(s-i.pStart)/i.pLength),a>=i.pStop?e.percent1=1:a>=i.pStart&&a<i.pStop&&(e.percent1=(a-i.pStart)/i.pLength),isNaN(e.percent0)||(e.value0=this.dimensions[t].scale.percentToValue(e.percent0)),isNaN(e.percent1)||(e.value1=this.dimensions[t].scale.percentToValue(e.percent1))}processConfigFilter(e,t){const i=this.getDimensionLayoutInfo(t);if(!i)return;const s={...FILTER,...e};if(null!=e.p0&&null!=e.p1)this.processFilter(s,t);else{const a=[],n=[];if(null!=e.value0&&null!=e.value1&&(s.percent0=this.dimensions[t].scale.valueToPercent(e.value0),s.percent1=this.dimensions[t].scale.valueToPercent(e.value1),a.push(s.percent0*i.pLength+i.pStart),n.push(s.percent1*i.pLength+i.pStart)),i.hasInfinity)if(i.isHorizontal){if(e.hasPositiveInfinity)a.push(0),n.push(0+FILTER_EPSILON);else if(e.hasNegativeInfinity){const e=(i.layout.axisInfinityStop.y-i.layout.axisBoundaryStart.y)/i.yLength;a.push(e-FILTER_EPSILON),n.push(e+FILTER_EPSILON)}}else if(e.hasPositiveInfinity)a.push(1-FILTER_EPSILON),n.push(1);else if(e.hasNegativeInfinity){const e=(i.layout.axisInfinityStart.x-i.layout.axisBoundaryStart.x)/i.xLength;a.push(e-FILTER_EPSILON),n.push(e+FILTER_EPSILON)}i.hasNaN&&e.hasNaN&&(i.isHorizontal?(a.push(1-FILTER_EPSILON),n.push(1)):(a.push(0),n.push(0+FILTER_EPSILON))),s.p0=Math.min(...a),s.p1=Math.max(...n)}return s}cleanUpFilters(){Object.keys(this.filters).forEach((e=>{const t=this.filters[e]||[];for(let e=0;e<t.length;e++)if(isFilterInvalid(t[e]))t[e]={...FILTER};else for(let i=e+1;i<t.length;i++)isFilterEmpty(t[e])||isFilterEmpty(t[i])||isIntersectingFilters(t[e],t[i])&&(t[i]=mergeFilters(t[e],t[i]),t[e]={...FILTER});this.filters[e]=t.filter((e=>!isFilterEmpty(e)))}))}updateCursor(){const e=this.ix,t=e.shared.action,i=e.shared.focus,s=this.config.direction===Direction.Horizontal;let a="default";t.type!==ActionType.None?t.type===ActionType.FilterMove||t.type===ActionType.LabelMove?a="grabbing":t.type===ActionType.FilterResizeAfter||t.type===ActionType.FilterResizeBefore?a=s?"ns-resize":"ew-resize":t.type===ActionType.FilterCreate&&(a="crosshair"):void 0!==i&&(i.type===FocusType.DimensionLabel?a="grab":i.type===FocusType.DimensionAxis?a="crosshair":i.type===FocusType.Filter?a="grab":i.type===FocusType.FilterResize&&(a=s?"ns-resize":"ew-resize")),this.canvas.style.cursor=a}clear(){const{h:e,w:t}=this.size;this.ctx.clearRect(0,0,t,e)}draw(){var e,t;if(!this._)return;const i=this._.dims.list,s=this._.dims.shared.axes,a=this._.dims.shared.label,n=this._.styles,r=this.ix,o=this.ix.shared.focus,l=this.filters,c=this.config.direction===Direction.Horizontal,h=this.config.style.axes,d=this.config.style.data,u=this.config.style.dimension,p=u.label.placement===LabelPlacement.Before,y=h.label.placement===LabelPlacement.Before;for(let s=0;s<this.dataInfo.seriesCount;s++){let a=d.default,n=!1,o=!1,h=!1,u=!1,p=!1;const y=this.dimensions.map(((e,t)=>{var y,f,g,m,x,v;const b=e.key,I=i[t].layout,N=getDragBound(t,r,I.bound),S=this.data[b][s],E=isNumber(S),L=E&&isNaN(S),T=E&&!L&&!isFinite(S),D=T&&S===-1/0,F=T&&S===1/0,M=L||T?0:null!==(f=null===(y=e.scale)||void 0===y?void 0:y.valueToPercent(S))&&void 0!==f?f:0;let k=N.x,A=N.y;if(L)k+=c?I.axisDataStart.x:I.axisBoundaryStart.x,A+=c?I.axisBoundaryStop.y:I.axisDataStart.y;else if(T){const e=D?c?I.axisInfinityStop.x:I.axisInfinityStart.x:c?I.axisInfinityStart.x:I.axisInfinityStop.x,t=F?c?I.axisInfinityStart.y:I.axisInfinityStop.y:c?I.axisInfinityStop.y:I.axisInfinityStart.y;k+=c?I.axisDataStart.x:e,A+=c?t:I.axisDataStart.y}else{const t=null!==(m=null===(g=e.scale)||void 0===g?void 0:g.valueToPos(S))&&void 0!==m?m:0;k+=I.axisDataStart.x+(c?0:t),A+=I.axisDataStart.y+(c?t:0)}if(b===d.targetDimensionKey){const t=null!==(v=null===(x=e.scale)||void 0===x?void 0:x.reverse)&&void 0!==v&&v,i=d.targetColorScale||[],s=scale2rgba(t?i.slice().reverse():i,M);a.strokeStyle=s}if(l[b]&&0!==l[b].length){n=!0;let e=!1;for(let t=0;t<l[b].length;t++){const i=l[b][t];L&&i.hasNaN?(e=!0,o=!0):D&&i.hasNegativeInfinity?(e=!0,h=!0):F&&i.hasPositiveInfinity&&(e=!0,u=!0),!L&&!T&&!isNaN(i.percent0)&&!isNaN(i.percent1)&&M>=i.percent0&&M<=i.percent1&&(e=!0)}e||(p=!0)}else L?o=!0:D?h=!0:F&&(u=!0);return{x:k,y:A}}));(null===(e=d.series)||void 0===e?void 0:e[s])&&(a=null===(t=d.series)||void 0===t?void 0:t[s]),n&&p?a=d.filtered:o&&d.overrideNaN?a=d.overrideNaN:h&&d.overrideNegativeInfinity?a=d.overrideNegativeInfinity:u&&d.overridePositiveInfinity&&(a=d.overridePositiveInfinity),drawData(this.ctx,y,c,d.path,a)}const f=null==u.label.angle&&c,g={textAlign:f?"center":void 0,textBaseline:f?p?"bottom":"top":void 0};this.dimensions.forEach(((e,t)=>{var s;const o=getDragBound(t,r,i[t].layout.bound),l=i[t].layout.labelPoint,c=o.x+l.x,h=o.y+l.y,d={...n[t].label,...g};drawText(this.ctx,e.labelTruncated,c,h,null!==(s=a.rad)&&void 0!==s?s:0,d)}));const m=null==h.label.angle&&c,x={textAlign:m?void 0:"center",textBaseline:m?void 0:y?"bottom":"top"};i.forEach(((e,t)=>{var i;const a=this.dimensions[t].key,d=getDragBound(t,r,e.layout.bound),u=e.layout.axisBoundaryStart,p=e.layout.axisBoundaryStop,f=e.layout.axisInfinityStart,g=e.layout.axisInfinityStop,m=e.layout.axisDataStart,v=e.layout.axisDataStop,b=e.axes.tickLabels,I=e.axes.tickPos,N=y?-1:1,S={...n[t].tickLabel,...x},E=c?N*h.tick.length:0,L=c?0:N*h.tick.length,T=l[a]||[];if(drawLine(this.ctx,d.x+m.x,d.y+m.y,d.x+v.x,d.y+v.y,n[t].axis),this.dataInfo.hasInfinity){drawLine(this.ctx,d.x+f.x,d.y+f.y,d.x+m.x,d.y+m.y,{...n[t].axis,lineDash:h.axis.infLineDash}),drawLine(this.ctx,d.x+v.x,d.y+v.y,d.x+g.x,d.y+g.y,{...n[t].axis,lineDash:h.axis.infLineDash,lineDashOffset:null!==(i=h.axis.infLineDash[0])&&void 0!==i?i:0});const e=d.x+f.x,s=d.y+f.y,a=e+E,r=s+L;drawLine(this.ctx,e,s,a,r,n[t].tick);const o=d.x+g.x,l=d.y+g.y,u=o+E,p=l+L;drawLine(this.ctx,o,l,u,p,n[t].tick);const x=c?a+N*h.label.offset:e,b=c?s:r+N*h.label.offset,I=null!=h.label.angle?h.label.angle:c&&y?Math.PI:0,T=c?"+Ꝏ":"-Ꝏ";drawText(this.ctx,T,x,b,I,S);const D=c?u+N*h.label.offset:o,F=c?l:p+N*h.label.offset,M=null!=h.label.angle?h.label.angle:c&&y?Math.PI:0,k=c?"-Ꝏ":"+Ꝏ";drawText(this.ctx,k,D,F,M,S)}if(this.dataInfo.hasNaN){const e=d.x+(c?p.x:u.x),i=d.y+(c?p.y:u.y),s=e+E,a=i+L;drawLine(this.ctx,e,i,s,a,n[t].tick);const r=c?s+N*h.label.offset:e,o=c?i:a+N*h.label.offset,l=null!=h.label.angle?h.label.angle:c&&y?Math.PI:0;drawText(this.ctx,"NaN",r,o,l,S)}for(let e=0;e<b.length;e++){let i=b[e];if("*"===i[0]){if((null==o?void 0:o.dimIndex)!==t||(null==o?void 0:o.type)!==FocusType.DimensionAxis&&(null==o?void 0:o.type)!==FocusType.Filter&&(null==o?void 0:o.type)!==FocusType.FilterResize)continue;i=i.substring(1)}const s=c?0:I[e],a=c?I[e]:0,r=c?N*h.tick.length:0,l=c?0:N*h.tick.length,u=d.x+m.x+s,p=d.y+m.y+a,f=d.x+m.x+s+r,g=d.y+m.y+a+l;drawLine(this.ctx,u,p,f,g,n[t].tick);const v=c?f+N*h.label.offset:u,S=c?p:g+N*h.label.offset,E=null!=h.label.angle?h.label.angle:c&&y?Math.PI:0,L={...n[t].tickLabel,...x};drawText(this.ctx,i,v,S,E,L)}T.forEach(((e,i)=>{const a=e.p0*s.length,r=e.p1*s.length,o=n[t].filters[i].width,l=o/2,h=d.x+u.x+(c?-l:a),p=d.y+u.y+(c?a:-l),y=c?o:r-a,f=c?r-a:o;drawRect(this.ctx,h,p,y,f,n[t].filters[i])}))}))}drawDebugOutline(){if(!this._)return;const{h:e,w:t}=this.size,i=this._.layout,s=this._.dims.list,a=this._.dims.shared.layout,n=this.config.direction===Direction.Horizontal,r={strokeStyle:"#dddddd"};drawLine(this.ctx,0,i.padding[0],t,i.padding[0],r),drawLine(this.ctx,0,e-i.padding[2],t,e-i.padding[2],r),drawLine(this.ctx,i.padding[3],0,i.padding[3],e,r),drawLine(this.ctx,t-i.padding[1],0,t-i.padding[1],e,r);const o={strokeStyle:"#999999"},l={strokeStyle:"#ff0000"},c={strokeStyle:"#eeeeee"},h={strokeStyle:"#0099cc"},d={strokeStyle:"#ffcc00"};s.forEach(((e,t)=>{const s=e.layout.bound,r=e.layout.axisBoundary,u=e.layout.labelPoint,p=e.layout.labelBoundary;drawRect(this.ctx,n?i.padding[3]+t*a.space:s.x,n?s.y:i.padding[0]+t*a.space,n?a.space:s.w,n?s.h:a.space,o),drawRect(this.ctx,s.x,s.y,s.w,s.h,l),drawCircle(this.ctx,s.x+u.x,s.y+u.y,3,h),drawBoundary(this.ctx,p,d),drawBoundary(this.ctx,r,c)}))}handleResize(e){const t=e.find((e=>e.target===this.element));if(!t)return;const{width:i,height:s}=t.contentRect;0===this.size.w&&0===this.size.h&&0!==i&&0!==s?(this.setSize(i,s),this.setConfigFilters(this.config.filters)):this.setSize(i,s)}handleDoubleClick(){var e,t;this.setDimensions(this.dimensionsOriginal,!1),this.filters={},this.ix=clone(IX),this.redraw(),null===(t=(e=this.config.hooks).onReset)||void 0===t||t.call(e)}handleMouseDown(e){var t,i;if(!this._)return;const s=this.ix.shared,a=this.ix.shared.action,n=this.ix.dimension,r=this.ix.filters,o=this._.dims.shared.axes,l=this.config.direction===Direction.Horizontal,c=l?"x":"y",h=l?"y":"x",d=getMousePoint(e,this.element);if(a.p0=d,a.p1=d,a.filterIndex=-1,s.focus=this.getFocusByPoint(d),s.focus){const e=s.focus.dimIndex,l=this._.dims.list[e].layout,d=l.bound,u=l.axisBoundaryStart;if((null===(t=s.focus)||void 0===t?void 0:t.type)===FocusType.DimensionLabel)a.type=ActionType.LabelMove,a.dimIndex=e,n.axis=d[c]+u[c],n.bound=d;else if([FocusType.DimensionAxis,FocusType.Filter,FocusType.FilterResize].includes(null===(i=s.focus)||void 0===i?void 0:i.type)){a.type=ActionType.FilterCreate,a.dimIndex=e,r.key=this.dimensions[e].key;const t=(a.p0[h]-d[h]-u[h])/o.length;this.setActiveFilter(r.key,t),this.processFilter(r.active,e)}}this.updateCursor(),this.redraw()}handleMouseMove(e){if(!this._)return;const t=getMousePoint(e,this.element);this.ix.shared.action.p1=t,this.ix.shared.focus=this.getFocusByPoint(t),this.updateActiveLabel(),this.updateActiveFilter(e),this.updateCursor(),this.redraw()}handleMouseUp(e){if(!this._)return;const t=getMousePoint(e,this.element);this.ix.shared.action.p1=t,this.updateActiveLabel(),this.updateActiveFilter(e),this.ix=clone(IX),this.ix.shared.focus=this.getFocusByPoint(t),this.updateCursor(),this.redraw()}}export{ActionType,DimensionLayout,DimensionType,Direction,FocusType,LabelPlacement,PathType,Hermes as default};