Socket
Socket
Sign inDemoInstall

vega-scenegraph

Package Overview
Dependencies
Maintainers
2
Versions
110
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vega-scenegraph - npm Package Compare versions

Comparing version 4.8.3 to 4.9.0

src/util/markup.js

2

build/vega-scenegraph.min.js

@@ -1,1 +0,1 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("vega-util"),require("d3-shape"),require("d3-path"),require("vega-canvas"),require("vega-loader"),require("vega-scale")):"function"==typeof define&&define.amd?define(["exports","vega-util","d3-shape","d3-path","vega-canvas","vega-loader","vega-scale"],e):e((t=t||self).vega={},t.vega,t.d3,t.d3,t.vega,t.vega,t.vega)}(this,(function(t,e,n,i,r,o,s){"use strict";var a=0;function l(t){return t&&t.gradient}function u(t,e,n){let i=t.id,r=t.gradient,o="radial"===r?"p_":"";return i||(i=t.id="gradient_"+a++,"radial"===r?(t.x1=c(t.x1,.5),t.y1=c(t.y1,.5),t.r1=c(t.r1,0),t.x2=c(t.x2,.5),t.y2=c(t.y2,.5),t.r2=c(t.r2,.5),o="p_"):(t.x1=c(t.x1,0),t.y1=c(t.y1,0),t.x2=c(t.x2,1),t.y2=c(t.y2,0))),e[i]=t,"url("+(n||"")+"#"+o+i+")"}function c(t,e){return null!=t?t:e}var h={basis:{curve:n.curveBasis},"basis-closed":{curve:n.curveBasisClosed},"basis-open":{curve:n.curveBasisOpen},bundle:{curve:n.curveBundle,tension:"beta",value:.85},cardinal:{curve:n.curveCardinal,tension:"tension",value:0},"cardinal-open":{curve:n.curveCardinalOpen,tension:"tension",value:0},"cardinal-closed":{curve:n.curveCardinalClosed,tension:"tension",value:0},"catmull-rom":{curve:n.curveCatmullRom,tension:"alpha",value:.5},"catmull-rom-closed":{curve:n.curveCatmullRomClosed,tension:"alpha",value:.5},"catmull-rom-open":{curve:n.curveCatmullRomOpen,tension:"alpha",value:.5},linear:{curve:n.curveLinear},"linear-closed":{curve:n.curveLinearClosed},monotone:{horizontal:n.curveMonotoneY,vertical:n.curveMonotoneX},natural:{curve:n.curveNatural},step:{curve:n.curveStep},"step-after":{curve:n.curveStepAfter},"step-before":{curve:n.curveStepBefore}};function f(t,n,i){var r=e.hasOwnProperty(h,t)&&h[t],o=null;return r&&(o=r.curve||r[n||"vertical"],r.tension&&null!=i&&(o=o[r.tension](i))),o}var d={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},g=[/([MLHVCSQTAZmlhvcsqtaz])/g,/###/,/(\d)([-+])/g,/\s|,|###/];function p(t){var e,n,i,r,o,s,a,l,u,c,h,f=[];for(l=0,c=(e=t.slice().replace(g[0],"###$1").split(g[1]).slice(1)).length;l<c;++l){for(i=(n=e[l]).slice(1).trim().replace(g[2],"$1###$2").split(g[3]),r=[s=n.charAt(0)],u=0,h=i.length;u<h;++u)(o=+i[u])===o&&r.push(o);if(a=d[s.toLowerCase()],r.length-1>a)for(u=1,h=r.length;u<h;u+=a)f.push([s].concat(r.slice(u,u+a)));else f.push(r)}return f}const v=Math.PI/180,y=Math.PI/2,_=2*Math.PI,m=Math.sqrt(3)/2;var x={},b={},k=[].join;function w(t){var e=k.call(t);if(b[e])return b[e];var n=t[0],i=t[1],r=t[2],o=t[3],s=t[4],a=t[5],l=t[6],u=t[7],c=u*s,h=-l*a,f=l*s,d=u*a,g=Math.cos(r),p=Math.sin(r),v=Math.cos(o),y=Math.sin(o),_=.5*(o-r),m=Math.sin(.5*_),x=8/3*m*m/Math.sin(_),w=n+g-x*p,T=i+p+x*g,A=n+v,M=i+y,C=A+x*y,R=M-x*v;return b[e]=[c*w+h*T,f*w+d*T,c*C+h*R,f*C+d*R,c*A+h*M,f*A+d*M]}var T=["l",0,0,0,0,0,0,0];function A(t,e,n){var i=T[0]=t[0];if("a"===i||"A"===i)T[1]=e*t[1],T[2]=n*t[2],T[3]=t[3],T[4]=t[4],T[5]=t[5],T[6]=e*t[6],T[7]=n*t[7];else if("h"===i||"H"===i)T[1]=e*t[1];else if("v"===i||"V"===i)T[1]=n*t[1];else for(var r=1,o=t.length;r<o;++r)T[r]=(r%2==1?e:n)*t[r];return T}function M(t,e,n,i,r,o){var s,a,l,u,c,h=null,f=0,d=0,g=0,p=0;null==n&&(n=0),null==i&&(i=0),null==r&&(r=1),null==o&&(o=r),t.beginPath&&t.beginPath();for(var v=0,y=e.length;v<y;++v){switch(s=e[v],1===r&&1===o||(s=A(s,r,o)),s[0]){case"l":f+=s[1],d+=s[2],t.lineTo(f+n,d+i);break;case"L":f=s[1],d=s[2],t.lineTo(f+n,d+i);break;case"h":f+=s[1],t.lineTo(f+n,d+i);break;case"H":f=s[1],t.lineTo(f+n,d+i);break;case"v":d+=s[1],t.lineTo(f+n,d+i);break;case"V":d=s[1],t.lineTo(f+n,d+i);break;case"m":f+=s[1],d+=s[2],t.moveTo(f+n,d+i);break;case"M":f=s[1],d=s[2],t.moveTo(f+n,d+i);break;case"c":a=f+s[5],l=d+s[6],g=f+s[3],p=d+s[4],t.bezierCurveTo(f+s[1]+n,d+s[2]+i,g+n,p+i,a+n,l+i),f=a,d=l;break;case"C":f=s[5],d=s[6],g=s[3],p=s[4],t.bezierCurveTo(s[1]+n,s[2]+i,g+n,p+i,f+n,d+i);break;case"s":a=f+s[3],l=d+s[4],g=2*f-g,p=2*d-p,t.bezierCurveTo(g+n,p+i,f+s[1]+n,d+s[2]+i,a+n,l+i),g=f+s[1],p=d+s[2],f=a,d=l;break;case"S":a=s[3],l=s[4],g=2*f-g,p=2*d-p,t.bezierCurveTo(g+n,p+i,s[1]+n,s[2]+i,a+n,l+i),f=a,d=l,g=s[1],p=s[2];break;case"q":a=f+s[3],l=d+s[4],g=f+s[1],p=d+s[2],t.quadraticCurveTo(g+n,p+i,a+n,l+i),f=a,d=l;break;case"Q":a=s[3],l=s[4],t.quadraticCurveTo(s[1]+n,s[2]+i,a+n,l+i),f=a,d=l,g=s[1],p=s[2];break;case"t":a=f+s[1],l=d+s[2],null===h[0].match(/[QqTt]/)?(g=f,p=d):"t"===h[0]?(g=2*f-u,p=2*d-c):"q"===h[0]&&(g=2*f-g,p=2*d-p),u=g,c=p,t.quadraticCurveTo(g+n,p+i,a+n,l+i),d=l,g=(f=a)+s[1],p=d+s[2];break;case"T":a=s[1],l=s[2],g=2*f-g,p=2*d-p,t.quadraticCurveTo(g+n,p+i,a+n,l+i),f=a,d=l;break;case"a":C(t,f+n,d+i,[s[1],s[2],s[3],s[4],s[5],s[6]+f+n,s[7]+d+i]),f+=s[6],d+=s[7];break;case"A":C(t,f+n,d+i,[s[1],s[2],s[3],s[4],s[5],s[6]+n,s[7]+i]),f=s[6],d=s[7];break;case"z":case"Z":t.closePath()}h=s}}function C(t,e,n,i){for(var r=function(t,e,n,i,r,o,s,a,l){var u=k.call(arguments);if(x[u])return x[u];var c=s*v,h=Math.sin(c),f=Math.cos(c),d=f*(a-t)*.5+h*(l-e)*.5,g=f*(l-e)*.5-h*(a-t)*.5,p=d*d/((n=Math.abs(n))*n)+g*g/((i=Math.abs(i))*i);p>1&&(n*=p=Math.sqrt(p),i*=p);var m=f/n,b=h/n,w=-h/i,T=f/i,A=m*a+b*l,M=w*a+T*l,C=m*t+b*e,R=w*t+T*e,z=(C-A)*(C-A)+(R-M)*(R-M),P=1/z-.25;P<0&&(P=0);var S=Math.sqrt(P);o==r&&(S=-S);var L=.5*(A+C)-S*(R-M),O=.5*(M+R)+S*(C-A),N=Math.atan2(M-O,A-L),q=Math.atan2(R-O,C-L),D=q-N;D<0&&1===o?D+=_:D>0&&0===o&&(D-=_);for(var E=Math.ceil(Math.abs(D/(y+.001))),I=[],B=0;B<E;++B){var V=N+B*D/E,H=N+(B+1)*D/E;I[B]=[L,O,V,H,n,i,h,f]}return x[u]=I}(i[5],i[6],i[0],i[1],i[3],i[4],i[2],e,n),o=0;o<r.length;++o){var s=w(r[o]);t.bezierCurveTo(s[0],s[1],s[2],s[3],s[4],s[5])}}var R=.5773502691896257,z={circle:{draw:function(t,e){var n=Math.sqrt(e)/2;t.moveTo(n,0),t.arc(0,0,n,0,_)}},cross:{draw:function(t,e){var n=Math.sqrt(e)/2,i=n/2.5;t.moveTo(-n,-i),t.lineTo(-n,i),t.lineTo(-i,i),t.lineTo(-i,n),t.lineTo(i,n),t.lineTo(i,i),t.lineTo(n,i),t.lineTo(n,-i),t.lineTo(i,-i),t.lineTo(i,-n),t.lineTo(-i,-n),t.lineTo(-i,-i),t.closePath()}},diamond:{draw:function(t,e){var n=Math.sqrt(e)/2;t.moveTo(-n,0),t.lineTo(0,-n),t.lineTo(n,0),t.lineTo(0,n),t.closePath()}},square:{draw:function(t,e){var n=Math.sqrt(e),i=-n/2;t.rect(i,i,n,n)}},arrow:{draw:function(t,e){var n=Math.sqrt(e)/2,i=n/7,r=n/2.5,o=n/8;t.moveTo(-i,n),t.lineTo(i,n),t.lineTo(i,-o),t.lineTo(r,-o),t.lineTo(0,-n),t.lineTo(-r,-o),t.lineTo(-i,-o),t.closePath()}},wedge:{draw:function(t,e){var n=Math.sqrt(e)/2,i=m*n,r=i-n*R,o=n/4;t.moveTo(0,-i-r),t.lineTo(-o,i-r),t.lineTo(o,i-r),t.closePath()}},triangle:{draw:function(t,e){var n=Math.sqrt(e)/2,i=m*n,r=i-n*R;t.moveTo(0,-i-r),t.lineTo(-n,i-r),t.lineTo(n,i-r),t.closePath()}},"triangle-up":{draw:function(t,e){var n=Math.sqrt(e)/2,i=m*n;t.moveTo(0,-i),t.lineTo(-n,i),t.lineTo(n,i),t.closePath()}},"triangle-down":{draw:function(t,e){var n=Math.sqrt(e)/2,i=m*n;t.moveTo(0,i),t.lineTo(-n,-i),t.lineTo(n,-i),t.closePath()}},"triangle-right":{draw:function(t,e){var n=Math.sqrt(e)/2,i=m*n;t.moveTo(i,0),t.lineTo(-i,-n),t.lineTo(-i,n),t.closePath()}},"triangle-left":{draw:function(t,e){var n=Math.sqrt(e)/2,i=m*n;t.moveTo(-i,0),t.lineTo(i,-n),t.lineTo(i,n),t.closePath()}},stroke:{draw:function(t,e){var n=Math.sqrt(e)/2;t.moveTo(-n,0),t.lineTo(n,0)}}};function P(t){return e.hasOwnProperty(z,t)?z[t]:function(t){if(!e.hasOwnProperty(S,t)){var n=p(t);S[t]={draw:function(t,e){M(t,n,0,0,Math.sqrt(e)/2)}}}return S[t]}(t)}var S={};const L=.448084975506;function O(t){return t.x}function N(t){return t.y}function q(t){return t.width}function D(t){return t.height}function E(t){return"function"==typeof t?t:()=>+t}function I(t,e,n){return Math.max(e,Math.min(t,n))}function B(){var t=O,e=N,n=q,r=D,o=E(0),s=o,a=o,l=o,u=null;function c(c,h,f){var d,g=null!=h?h:+t.call(this,c),p=null!=f?f:+e.call(this,c),v=+n.call(this,c),y=+r.call(this,c),_=Math.min(v,y)/2,m=I(+o.call(this,c),0,_),x=I(+s.call(this,c),0,_),b=I(+a.call(this,c),0,_),k=I(+l.call(this,c),0,_);if(u||(u=d=i.path()),m<=0&&x<=0&&b<=0&&k<=0)u.rect(g,p,v,y);else{var w=g+v,T=p+y;u.moveTo(g+m,p),u.lineTo(w-x,p),u.bezierCurveTo(w-L*x,p,w,p+L*x,w,p+x),u.lineTo(w,T-k),u.bezierCurveTo(w,T-L*k,w-L*k,T,w-k,T),u.lineTo(g+b,T),u.bezierCurveTo(g+L*b,T,g,T-L*b,g,T-b),u.lineTo(g,p+m),u.bezierCurveTo(g,p+L*m,g+L*m,p,g+m,p),u.closePath()}if(d)return u=null,d+""||null}return c.x=function(e){return arguments.length?(t=E(e),c):t},c.y=function(t){return arguments.length?(e=E(t),c):e},c.width=function(t){return arguments.length?(n=E(t),c):n},c.height=function(t){return arguments.length?(r=E(t),c):r},c.cornerRadius=function(t,e,n,i){return arguments.length?(o=E(t),s=null!=e?E(e):o,l=null!=n?E(n):o,a=null!=i?E(i):s,c):o},c.context=function(t){return arguments.length?(u=null==t?null:t,c):u},c}function V(){var t,e,n,r,o,s,a,l,u=null;function c(t,e,n){var i=n/2;if(o){var r=a-e,c=t-s;if(r||c){var h=Math.sqrt(r*r+c*c),f=(r/=h)*l,d=(c/=h)*l,g=Math.atan2(c,r);u.moveTo(s-f,a-d),u.lineTo(t-r*i,e-c*i),u.arc(t,e,i,g-Math.PI,g),u.lineTo(s+f,a+d),u.arc(s,a,l,g,g+Math.PI)}else u.arc(t,e,i,0,_);u.closePath()}else o=1;s=t,a=e,l=i}function h(s){var a,l,h,f=s.length,d=!1;for(null==u&&(u=h=i.path()),a=0;a<=f;++a)!(a<f&&r(l=s[a],a,s))===d&&(d=!d)&&(o=0),d&&c(+t(l,a,s),+e(l,a,s),+n(l,a,s));if(h)return u=null,h+""||null}return h.x=function(e){return arguments.length?(t=e,h):t},h.y=function(t){return arguments.length?(e=t,h):e},h.size=function(t){return arguments.length?(n=t,h):n},h.defined=function(t){return arguments.length?(r=t,h):r},h.context=function(t){return arguments.length?(u=null==t?null:t,h):u},h}function H(t,e){return null!=t?t:e}const G=t=>t.x||0,j=t=>t.y||0,W=t=>!(!1===t.defined),U=n.arc().startAngle(t=>t.startAngle||0).endAngle(t=>t.endAngle||0).padAngle(t=>t.padAngle||0).innerRadius(t=>t.innerRadius||0).outerRadius(t=>t.outerRadius||0).cornerRadius(t=>t.cornerRadius||0),X=n.area().x(G).y1(j).y0(t=>(t.y||0)+(t.height||0)).defined(W),F=n.area().y(j).x1(G).x0(t=>(t.x||0)+(t.width||0)).defined(W),Y=n.line().x(G).y(j).defined(W),J=B().x(G).y(j).width(t=>t.width||0).height(t=>t.height||0).cornerRadius(t=>H(t.cornerRadiusTopLeft,t.cornerRadius)||0,t=>H(t.cornerRadiusTopRight,t.cornerRadius)||0,t=>H(t.cornerRadiusBottomRight,t.cornerRadius)||0,t=>H(t.cornerRadiusBottomLeft,t.cornerRadius)||0),$=n.symbol().type(t=>P(t.shape||"circle")).size(t=>H(t.size,64)),Q=V().x(G).y(j).defined(W).size(t=>t.size||1);function Z(t){return t.cornerRadius||t.cornerRadiusTopLeft||t.cornerRadiusTopRight||t.cornerRadiusBottomRight||t.cornerRadiusBottomLeft}function K(t,e,n,i){return J.context(t)(e,n,i)}var tt=1;function et(){tt=1}function nt(t,n,i){var r=n.clip,o=t._defs,s=n.clip_id||(n.clip_id="clip"+tt++),a=o.clipping[s]||(o.clipping[s]={id:s});return e.isFunction(r)?a.path=r(null):Z(i)?a.path=K(null,i,0,0):(a.width=i.width||0,a.height=i.height||0),"url(#"+s+")"}function it(t){this.clear(),t&&this.union(t)}var rt=it.prototype;function ot(t){this.mark=t,this.bounds=this.bounds||new it}function st(t){ot.call(this,t),this.items=this.items||[]}function at(t){this._pending=0,this._loader=t||o.loader()}rt.clone=function(){return new it(this)},rt.clear=function(){return this.x1=+Number.MAX_VALUE,this.y1=+Number.MAX_VALUE,this.x2=-Number.MAX_VALUE,this.y2=-Number.MAX_VALUE,this},rt.empty=function(){return this.x1===+Number.MAX_VALUE&&this.y1===+Number.MAX_VALUE&&this.x2===-Number.MAX_VALUE&&this.y2===-Number.MAX_VALUE},rt.equals=function(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2},rt.set=function(t,e,n,i){return n<t?(this.x2=t,this.x1=n):(this.x1=t,this.x2=n),i<e?(this.y2=e,this.y1=i):(this.y1=e,this.y2=i),this},rt.add=function(t,e){return t<this.x1&&(this.x1=t),e<this.y1&&(this.y1=e),t>this.x2&&(this.x2=t),e>this.y2&&(this.y2=e),this},rt.expand=function(t){return this.x1-=t,this.y1-=t,this.x2+=t,this.y2+=t,this},rt.round=function(){return this.x1=Math.floor(this.x1),this.y1=Math.floor(this.y1),this.x2=Math.ceil(this.x2),this.y2=Math.ceil(this.y2),this},rt.scale=function(t){return this.x1*=t,this.y1*=t,this.x2*=t,this.y2*=t,this},rt.translate=function(t,e){return this.x1+=t,this.x2+=t,this.y1+=e,this.y2+=e,this},rt.rotate=function(t,e,n){const i=this.rotatedPoints(t,e,n);return this.clear().add(i[0],i[1]).add(i[2],i[3]).add(i[4],i[5]).add(i[6],i[7])},rt.rotatedPoints=function(t,e,n){var{x1:i,y1:r,x2:o,y2:s}=this,a=Math.cos(t),l=Math.sin(t),u=e-e*a+n*l,c=n-e*l-n*a;return[a*i-l*r+u,l*i+a*r+c,a*i-l*s+u,l*i+a*s+c,a*o-l*r+u,l*o+a*r+c,a*o-l*s+u,l*o+a*s+c]},rt.union=function(t){return t.x1<this.x1&&(this.x1=t.x1),t.y1<this.y1&&(this.y1=t.y1),t.x2>this.x2&&(this.x2=t.x2),t.y2>this.y2&&(this.y2=t.y2),this},rt.intersect=function(t){return t.x1>this.x1&&(this.x1=t.x1),t.y1>this.y1&&(this.y1=t.y1),t.x2<this.x2&&(this.x2=t.x2),t.y2<this.y2&&(this.y2=t.y2),this},rt.encloses=function(t){return t&&this.x1<=t.x1&&this.x2>=t.x2&&this.y1<=t.y1&&this.y2>=t.y2},rt.alignsWith=function(t){return t&&(this.x1==t.x1||this.x2==t.x2||this.y1==t.y1||this.y2==t.y2)},rt.intersects=function(t){return t&&!(this.x2<t.x1||this.x1>t.x2||this.y2<t.y1||this.y1>t.y2)},rt.contains=function(t,e){return!(t<this.x1||t>this.x2||e<this.y1||e>this.y2)},rt.width=function(){return this.x2-this.x1},rt.height=function(){return this.y2-this.y1},e.inherits(st,ot);var lt=at.prototype;function ut(t){t._pending+=1}function ct(t){t._pending-=1}function ht(t,e,n){if(e.stroke&&0!==e.opacity&&0!==e.strokeOpacity){const i=null!=e.strokeWidth?+e.strokeWidth:1;t.expand(i+(n?function(t,e){return t.strokeJoin&&"miter"!==t.strokeJoin?0:e}(e,i):0))}return t}lt.pending=function(){return this._pending},lt.sanitizeURL=function(t){var e=this;return ut(e),e._loader.sanitize(t,{context:"href"}).then((function(t){return ct(e),t})).catch((function(){return ct(e),null}))},lt.loadImage=function(t){const n=this,i=r.image();return ut(n),n._loader.sanitize(t,{context:"image"}).then((function(t){const r=t.href;if(!r||!i)throw{url:r};const o=new i,s=e.hasOwnProperty(t,"crossOrigin")?t.crossOrigin:"anonymous";return null!=s&&(o.crossOrigin=s),o.onload=()=>ct(n),o.onerror=()=>ct(n),o.src=r,o})).catch((function(t){return ct(n),{complete:!1,width:0,height:0,src:t&&t.url||""}}))},lt.ready=function(){var t=this;return new Promise((function(e){!function n(i){t.pending()?setTimeout((function(){n(!0)}),10):e(i)}(!1)}))};var ft,dt,gt,pt=_-1e-8;function vt(t){return ft=t,vt}function yt(){}function _t(t,e){ft.add(t,e)}function mt(t,e){_t(dt=t,gt=e)}function xt(t){_t(t,ft.y1)}function bt(t){_t(ft.x1,t)}function kt(t,e,n,i){const r=(t-e)/(t+n-2*e);0<r&&r<1&&i(t+(e-t)*r)}function wt(t,e,n,i,r){const o=i-t+3*e-3*n,s=t+n-2*e,a=t-e;let l,u=0,c=0;Math.abs(o)>1e-14?(l=s*s+a*o,l>=0&&(l=Math.sqrt(l),u=(-s+l)/o,c=(-s-l)/o)):u=.5*a/s,0<u&&u<1&&r(Tt(u,t,e,n,i)),0<c&&c<1&&r(Tt(c,t,e,n,i))}function Tt(t,e,n,i,r){const o=1-t,s=o*o,a=t*t;return s*o*e+3*s*t*n+3*o*a*i+a*t*r}vt.beginPath=yt,vt.closePath=yt,vt.moveTo=mt,vt.lineTo=mt,vt.rect=function(t,e,n,i){_t(t+n,e+i),mt(t,e)},vt.quadraticCurveTo=function(t,e,n,i){kt(dt,t,n,xt),kt(gt,e,i,bt),mt(n,i)},vt.bezierCurveTo=function(t,e,n,i,r,o){wt(dt,t,n,r,xt),wt(gt,e,i,o,bt),mt(r,o)},vt.arc=function(t,e,n,i,r,o){if(dt=n*Math.cos(r)+t,gt=n*Math.sin(r)+e,Math.abs(r-i)>pt)_t(t-n,e-n),_t(t+n,e+n);else{const s=i=>_t(n*Math.cos(i)+t,n*Math.sin(i)+e);let a,l;if(s(i),s(r),r!==i)if((i%=_)<0&&(i+=_),(r%=_)<0&&(r+=_),r<i&&(o=!o,a=i,i=r,r=a),o)for(r-=_,a=i-i%y,l=0;l<4&&a>r;++l,a-=y)s(a);else for(a=i-i%y+y,l=0;l<4&&a<r;++l,a+=y)s(a)}};var At=(At=r.canvas(1,1))?At.getContext("2d"):null;const Mt=new it;function Ct(t){return function(e,n){if(!At)return!0;t(At,e),Mt.clear().union(e.bounds).intersect(n).round();const{x1:i,y1:r,x2:o,y2:s}=Mt;for(let t=r;t<=s;++t)for(let e=i;e<=o;++e)if(At.isPointInPath(e,t))return!0;return!1}}function Rt(t,e){return e.contains(t.x||0,t.y||0)}function zt(t,e){const n=t.x||0,i=t.y||0,r=t.width||0,o=t.height||0;return e.intersects(Mt.set(n,i,n+r,i+o))}function Pt(t,e){const n=t.x||0,i=t.y||0;return St(e,n,i,null!=t.x2?t.x2:n,null!=t.y2?t.y2:i)}function St(t,e,n,i,r){const{x1:o,y1:s,x2:a,y2:l}=t,u=i-e,c=r-n;let h,f,d,g,p=0,v=1;for(g=0;g<4;++g){if(0===g&&(h=-u,f=-(o-e)),1===g&&(h=u,f=a-e),2===g&&(h=-c,f=-(s-n)),3===g&&(h=c,f=l-n),Math.abs(h)<1e-10&&f<0)return!1;if(d=f/h,h<0){if(d>v)return!1;d>p&&(p=d)}else if(h>0){if(d<p)return!1;d<v&&(v=d)}}return!0}function Lt(t,e){t.globalCompositeOperation=e.blend||"source-over"}function Ot(t,e){return null==t?e:t}function Nt(t,e){const n=e.length;for(let i=0;i<n;++i)t.addColorStop(e[i].offset,e[i].color);return t}function qt(t,e,n){return l(n)?function(t,e,n){const i=n.width(),o=n.height();let s;if("radial"===e.gradient)s=t.createRadialGradient(n.x1+Ot(e.x1,.5)*i,n.y1+Ot(e.y1,.5)*o,Math.max(i,o)*Ot(e.r1,0),n.x1+Ot(e.x2,.5)*i,n.y1+Ot(e.y2,.5)*o,Math.max(i,o)*Ot(e.r2,.5));else{const a=Ot(e.x1,0),l=Ot(e.y1,0),u=Ot(e.x2,1),c=Ot(e.y2,0);if(a!==u&&l!==c&&i!==o){const n=r.canvas(Math.ceil(i),Math.ceil(o)),s=n.getContext("2d");return s.scale(i,o),s.fillStyle=Nt(s.createLinearGradient(a,l,u,c),e.stops),s.fillRect(0,0,i,o),t.createPattern(n,"no-repeat")}s=t.createLinearGradient(n.x1+a*i,n.y1+l*o,n.x1+u*i,n.y1+c*o)}return Nt(s,e.stops)}(t,n,e.bounds):n}function Dt(t,e,n){return(n*=null==e.fillOpacity?1:e.fillOpacity)>0&&(t.globalAlpha=n,t.fillStyle=qt(t,e,e.fill),!0)}var Et=[];function It(t,e,n){var i=null!=(i=e.strokeWidth)?i:1;return!(i<=0)&&((n*=null==e.strokeOpacity?1:e.strokeOpacity)>0&&(t.globalAlpha=n,t.strokeStyle=qt(t,e,e.stroke),t.lineWidth=i,t.lineCap=e.strokeCap||"butt",t.lineJoin=e.strokeJoin||"miter",t.miterLimit=e.strokeMiterLimit||10,t.setLineDash&&(t.setLineDash(e.strokeDash||Et),t.lineDashOffset=e.strokeDashOffset||0),!0))}function Bt(t,e){return t.zindex-e.zindex||t.index-e.index}function Vt(t){if(!t.zdirty)return t.zitems;var e,n,i,r=t.items,o=[];for(n=0,i=r.length;n<i;++n)(e=r[n]).index=n,e.zindex&&o.push(e);return t.zdirty=!1,t.zitems=o.sort(Bt)}function Ht(t,e){var n,i,r=t.items;if(r&&r.length){var o=Vt(t);if(o&&o.length){for(n=0,i=r.length;n<i;++n)r[n].zindex||e(r[n]);r=o}for(n=0,i=r.length;n<i;++n)e(r[n])}}function Gt(t,e){var n,i,r=t.items;if(!r||!r.length)return null;var o=Vt(t);for(o&&o.length&&(r=o),i=r.length;--i>=0;)if(n=e(r[i]))return n;if(r===o)for(i=(r=t.items).length;--i>=0;)if(!r[i].zindex&&(n=e(r[i])))return n;return null}function jt(t){return function(e,n,i){Ht(n,(function(n){i&&!i.intersects(n.bounds)||Ut(t,e,n,n)}))}}function Wt(t){return function(e,n,i){!n.items.length||i&&!i.intersects(n.bounds)||Ut(t,e,n.items[0],n.items)}}function Ut(t,e,n,i){var r=null==n.opacity?1:n.opacity;0!==r&&(t(e,i)||(Lt(e,n),n.fill&&Dt(e,n,r)&&e.fill(),n.stroke&&It(e,n,r)&&e.stroke()))}function Xt(t){return t=t||e.truthy,function(e,n,i,r,o,s){return i*=e.pixelRatio,r*=e.pixelRatio,Gt(n,(function(n){var a=n.bounds;if((!a||a.contains(o,s))&&a)return t(e,n,i,r,o,s)?n:void 0}))}}function Ft(t,e){return function(n,i,r,o){var s,a,l=Array.isArray(i)?i[0]:i,u=null==e?l.fill:e,c=l.stroke&&n.isPointInStroke;return c&&(s=l.strokeWidth,a=l.strokeCap,n.lineWidth=null!=s?s:1,n.lineCap=null!=a?a:"butt"),!t(n,i)&&(u&&n.isPointInPath(r,o)||c&&n.isPointInStroke(r,o))}}function Yt(t){return Xt(Ft(t))}function Jt(t,e){return"translate("+t+","+e+")"}function $t(t){return"rotate("+t+")"}function Qt(t){return Jt(t.x||0,t.y||0)}function Zt(t){return Jt(t.x||0,t.y||0)+(t.angle?" "+$t(t.angle):"")+(t.scaleX||t.scaleY?" "+(e=t.scaleX||1,n=t.scaleY||1,"scale("+e+","+n+")"):"");var e,n}function Kt(t,e,n){function i(t,n){var i=n.x||0,r=n.y||0,o=n.angle||0;t.translate(i,r),o&&t.rotate(o*=v),t.beginPath(),e(t,n),o&&t.rotate(-o),t.translate(-i,-r)}return{type:t,tag:"path",nested:!1,attr:function(t,n){t("transform",Zt(n)),t("d",e(null,n))},bound:function(t,n){var i=n.x||0,r=n.y||0;return e(vt(t),n),ht(t,n).translate(i,r),n.angle&&t.rotate(n.angle*v,i,r),t},draw:jt(i),pick:Yt(i),isect:n||Ct(i)}}var te=Kt("arc",(function(t,e){return U.context(t)(e)}));function ee(t,e,n){function i(t,n){t.beginPath(),e(t,n)}var r=Ft(i);return{type:t,tag:"path",nested:!0,attr:function(t,n){var i=n.mark.items;i.length&&t("d",e(null,i))},bound:function(t,n){var i=n.items;return 0===i.length?t:(e(vt(t),i),ht(t,i[0]))},draw:Wt(i),pick:function(t,e,n,i,o,s){var a=e.items,l=e.bounds;return!a||!a.length||l&&!l.contains(o,s)?null:(n*=t.pixelRatio,i*=t.pixelRatio,r(t,a,n,i)?a[0]:null)},isect:Rt,tip:n}}var ne=ee("area",(function(t,e){var n=e[0],i=n.interpolate||"linear";return("horizontal"===n.orient?F:X).curve(f(i,n.orient,n.tension)).context(t)(e)}),(function(t,e){for(var n,i,r="horizontal"===t[0].orient?e[1]:e[0],o="horizontal"===t[0].orient?"y":"x",s=t.length,a=1/0;--s>=0;)!1!==t[s].defined&&(i=Math.abs(t[s][o]-r))<a&&(a=i,n=t[s]);return n}));function ie(t,e){t.beginPath(),Z(e)?K(t,e,0,0):t.rect(0,0,e.width||0,e.height||0),t.clip()}function re(t){const e=Ot(t.strokeWidth,1);return null!=t.strokeOffset?t.strokeOffset:t.stroke&&e>.5&&e<1.5?.5-Math.abs(e-1):0}function oe(t,e){const n=re(e);t("d",K(null,e,n,n))}function se(t,e,n,i){const r=re(e);t.beginPath(),K(t,e,(n||0)+r,(i||0)+r)}const ae=Ft(se),le=Ft(se,!1);var ue={type:"group",tag:"g",nested:!1,attr:function(t,e){t("transform",Qt(e))},bound:function(t,e){if(!e.clip&&e.items){const n=e.items,i=n.length;for(let e=0;e<i;++e)t.union(n[e].bounds)}return(e.clip||e.width||e.height)&&!e.noBound&&t.add(0,0).add(e.width||0,e.height||0),ht(t,e),t.translate(e.x||0,e.y||0)},draw:function(t,e,n){Ht(e,e=>{const i=e.x||0,r=e.y||0,o=e.strokeForeground,s=null==e.opacity?1:e.opacity;(e.stroke||e.fill)&&s&&(se(t,e,i,r),Lt(t,e),e.fill&&Dt(t,e,s)&&t.fill(),e.stroke&&!o&&It(t,e,s)&&t.stroke()),t.save(),t.translate(i,r),e.clip&&ie(t,e),n&&n.translate(-i,-r),Ht(e,e=>{this.draw(t,e,n)}),n&&n.translate(i,r),t.restore(),o&&e.stroke&&s&&(se(t,e,i,r),Lt(t,e),It(t,e,s)&&t.stroke())})},pick:function(t,e,n,i,r,o){if(e.bounds&&!e.bounds.contains(r,o)||!e.items)return null;const s=n*t.pixelRatio,a=i*t.pixelRatio;return Gt(e,l=>{let u,c,h,f,d,g,p,v,y;if(v=l.bounds,(!v||v.contains(r,o))&&(f=l.x||0,d=l.y||0,g=f+(l.width||0),p=d+(l.height||0),y=l.clip,!y||!(r<f||r>g||o<d||o>p)))return t.save(),t.translate(f,d),f=r-f,d=o-d,y&&Z(l)&&!ae(t,l,s,a)?(t.restore(),null):(c=l.strokeForeground,h=!1!==e.interactive,h&&c&&l.stroke&&le(t,l,s,a)?(t.restore(),l):(u=Gt(l,t=>function(t,e,n){return(!1!==t.interactive||"group"===t.marktype)&&t.bounds&&t.bounds.contains(e,n)}(t,f,d)?this.pick(t,n,i,f,d):null),!u&&h&&(l.fill||!c&&l.stroke)&&ae(t,l,s,a)&&(u=l),t.restore(),u||null))})},isect:zt,content:function(t,e,n){t("clip-path",e.clip?nt(n,e,e):null)},background:function(t,e){t("class","background"),t("aria-hidden",!0),oe(t,e)},foreground:function(t,e){t("class","foreground"),t("aria-hidden",!0),e.strokeForeground?oe(t,e):t("d","")}},ce={version:"1.1",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"};function he(t,e){var n=t.image;return(!n||t.url&&t.url!==n.url)&&(n={complete:!1,width:0,height:0},e.loadImage(t.url).then(e=>{t.image=e,t.image.url=t.url})),n}function fe(t,e){return null!=t.width?t.width:e&&e.width?!1!==t.aspect&&t.height?t.height*e.width/e.height:e.width:0}function de(t,e){return null!=t.height?t.height:e&&e.height?!1!==t.aspect&&t.width?t.width*e.height/e.width:e.height:0}function ge(t,e){return"center"===t?e/2:"right"===t?e:0}function pe(t,e){return"middle"===t?e/2:"bottom"===t?e:0}var ve={type:"image",tag:"image",nested:!1,attr:function(t,e,n){const i=he(e,n),r=fe(e,i),o=de(e,i),s=(e.x||0)-ge(e.align,r),a=(e.y||0)-pe(e.baseline,o);t("href",!i.src&&i.toDataURL?i.toDataURL():i.src||"",ce["xmlns:xlink"],"xlink:href"),t("transform",Jt(s,a)),t("width",r),t("height",o),t("preserveAspectRatio",!1===e.aspect?"none":"xMidYMid")},bound:function(t,e){const n=e.image,i=fe(e,n),r=de(e,n),o=(e.x||0)-ge(e.align,i),s=(e.y||0)-pe(e.baseline,r);return t.set(o,s,o+i,s+r)},draw:function(t,e,n){Ht(e,e=>{if(n&&!n.intersects(e.bounds))return;let i,r,o,s,a=he(e,this),l=fe(e,a),u=de(e,a),c=(e.x||0)-ge(e.align,l),h=(e.y||0)-pe(e.baseline,u);!1!==e.aspect&&(r=a.width/a.height,o=e.width/e.height,r==r&&o==o&&r!==o&&(o<r?(s=l/r,h+=(u-s)/2,u=s):(s=u*r,c+=(l-s)/2,l=s))),(a.complete||a.toDataURL)&&(Lt(t,e),t.globalAlpha=null!=(i=e.opacity)?i:1,t.imageSmoothingEnabled=!1!==e.smooth,t.drawImage(a,c,h,l,u))})},pick:Xt(),isect:e.truthy,get:he,xOffset:ge,yOffset:pe},ye=ee("line",(function(t,e){var n=e[0],i=n.interpolate||"linear";return Y.curve(f(i,n.orient,n.tension)).context(t)(e)}),(function(t,e){for(var n,i,r=Math.pow(t[0].strokeWidth||1,2),o=t.length;--o>=0;)if(!1!==t[o].defined&&(n=t[o].x-e[0])*n+(i=t[o].y-e[1])*i<r)return t[o];return null}));function _e(t,e){var n=e.path;if(null==n)return!0;var i=e.x||0,r=e.y||0,o=e.scaleX||1,s=e.scaleY||1,a=(e.angle||0)*v,l=e.pathCache;l&&l.path===n||((e.pathCache=l=p(n)).path=n),a&&t.rotate&&t.translate?(t.translate(i,r),t.rotate(a),M(t,l,0,0,o,s),t.rotate(-a),t.translate(-i,-r)):M(t,l,i,r,o,s)}var me={type:"path",tag:"path",nested:!1,attr:function(t,e){var n=e.scaleX||1,i=e.scaleY||1;1===n&&1===i||t("vector-effect","non-scaling-stroke"),t("transform",Zt(e)),t("d",e.path)},bound:function(t,e){return _e(vt(t),e)?t.set(0,0,0,0):ht(t,e,!0),e.angle&&t.rotate(e.angle*v,e.x||0,e.y||0),t},draw:jt(_e),pick:Yt(_e),isect:Ct(_e)};function xe(t,e){t.beginPath(),K(t,e)}var be={type:"rect",tag:"path",nested:!1,attr:function(t,e){t("d",K(null,e))},bound:function(t,e){var n,i;return ht(t.set(n=e.x||0,i=e.y||0,n+e.width||0,i+e.height||0),e)},draw:jt(xe),pick:Yt(xe),isect:zt};function ke(t,e,n){var i,r,o,s;return!(!e.stroke||!It(t,e,n))&&(i=e.x||0,r=e.y||0,o=null!=e.x2?e.x2:i,s=null!=e.y2?e.y2:r,t.beginPath(),t.moveTo(i,r),t.lineTo(o,s),!0)}var we={type:"rule",tag:"line",nested:!1,attr:function(t,e){t("transform",Qt(e)),t("x2",null!=e.x2?e.x2-(e.x||0):0),t("y2",null!=e.y2?e.y2-(e.y||0):0)},bound:function(t,e){var n,i;return ht(t.set(n=e.x||0,i=e.y||0,null!=e.x2?e.x2:n,null!=e.y2?e.y2:i),e)},draw:function(t,e,n){Ht(e,(function(e){if(!n||n.intersects(e.bounds)){var i=null==e.opacity?1:e.opacity;i&&ke(t,e,i)&&(Lt(t,e),t.stroke())}}))},pick:Xt((function(t,e,n,i){return!!t.isPointInStroke&&(ke(t,e,1)&&t.isPointInStroke(n,i))})),isect:Pt},Te=Kt("shape",(function(t,e){return(e.mark.shape||e.shape).context(t)(e)})),Ae=Kt("symbol",(function(t,e){return $.context(t)(e)}),Rt);const Me=e.lruCache();var Ce={height:Oe,measureWidth:Se,estimateWidth:ze,width:ze,canvas:Re};function Re(t){Ce.width=t&&At?Se:ze}function ze(t,e){return Pe(De(t,e),Oe(t))}function Pe(t,e){return~~(.8*t.length*e)}function Se(t,e){return Oe(t)<=0||!(e=De(t,e))?0:Le(e,Ie(t))}function Le(t,e){const n=`(${e}) ${t}`;let i=Me.get(n);return void 0===i&&(At.font=e,i=At.measureText(t).width,Me.set(n,i)),i}function Oe(t){return null!=t.fontSize?+t.fontSize||0:11}function Ne(t){return null!=t.lineHeight?t.lineHeight:Oe(t)+2}function qe(t){return n=t.lineBreak&&t.text&&!e.isArray(t.text)?t.text.split(t.lineBreak):t.text,e.isArray(n)?n.length>1?n:n[0]:n;var n}function De(t,e){const n=null==e?"":(e+"").trim();return t.limit>0&&n.length?function(t,e){var n=+t.limit,i=function(t){if(Ce.width===Se){const e=Ie(t);return t=>Le(t,e)}{const e=Oe(t);return t=>Pe(t,e)}}(t);if(i(e)<n)return e;var r,o=t.ellipsis||"…",s="rtl"===t.dir,a=0,l=e.length;if(n-=i(o),s){for(;a<l;)r=a+l>>>1,i(e.slice(r))>n?a=r+1:l=r;return o+e.slice(a)}for(;a<l;)r=1+(a+l>>>1),i(e.slice(0,r))<n?a=r:l=r-1;return e.slice(0,a)+o}(t,n):n}function Ee(t,e){var n=t.font;return(e&&n?String(n).replace(/"/g,"'"):n)||"sans-serif"}function Ie(t,e){return(t.fontStyle?t.fontStyle+" ":"")+(t.fontVariant?t.fontVariant+" ":"")+(t.fontWeight?t.fontWeight+" ":"")+Oe(t)+"px "+Ee(t,e)}function Be(t){var e=t.baseline,n=Oe(t);return Math.round("top"===e?.79*n:"middle"===e?.3*n:"bottom"===e?-.21*n:"line-top"===e?.29*n+.5*Ne(t):"line-bottom"===e?.29*n-.5*Ne(t):0)}Re(!0);var Ve={left:"start",center:"middle",right:"end"},He=new it;function Ge(t){var e,n=t.x||0,i=t.y||0,r=t.radius||0;return r&&(e=(t.theta||0)-y,n+=r*Math.cos(e),i+=r*Math.sin(e)),He.x1=n,He.y1=i,He}function je(t,n,i){var r,o=Ce.height(n),s=n.align,a=Ge(n),l=a.x1,u=a.y1,c=n.dx||0,h=(n.dy||0)+Be(n)-Math.round(.8*o),f=qe(n);if(e.isArray(f)?(o+=Ne(n)*(f.length-1),r=f.reduce((t,e)=>Math.max(t,Ce.width(n,e)),0)):r=Ce.width(n,f),"center"===s?c-=r/2:"right"===s&&(c-=r),t.set(c+=l,h+=u,c+r,h+o),n.angle&&!i)t.rotate(n.angle*v,l,u);else if(2===i)return t.rotatedPoints(n.angle*v,l,u);return t}var We={arc:te,area:ne,group:ue,image:ve,line:ye,path:me,rect:be,rule:we,shape:Te,symbol:Ae,text:{type:"text",tag:"text",nested:!1,attr:function(t,e){var n,i=e.dx||0,r=(e.dy||0)+Be(e),o=Ge(e),s=o.x1,a=o.y1,l=e.angle||0;t("text-anchor",Ve[e.align]||"start"),l?(n=Jt(s,a)+" "+$t(l),(i||r)&&(n+=" "+Jt(i,r))):n=Jt(s+i,a+r),t("transform",n)},bound:je,draw:function(t,n,i){Ht(n,(function(n){var r,o,s,a,l,u,c,h=null==n.opacity?1:n.opacity;if(!(i&&!i.intersects(n.bounds)||0===h||n.fontSize<=0||null==n.text||0===n.text.length)){if(t.font=Ie(n),t.textAlign=n.align||"left",o=(r=Ge(n)).x1,s=r.y1,n.angle&&(t.save(),t.translate(o,s),t.rotate(n.angle*v),o=s=0),o+=n.dx||0,s+=(n.dy||0)+Be(n),u=qe(n),Lt(t,n),e.isArray(u))for(l=Ne(n),a=0;a<u.length;++a)c=De(n,u[a]),n.fill&&Dt(t,n,h)&&t.fillText(c,o,s),n.stroke&&It(t,n,h)&&t.strokeText(c,o,s),s+=l;else c=De(n,u),n.fill&&Dt(t,n,h)&&t.fillText(c,o,s),n.stroke&&It(t,n,h)&&t.strokeText(c,o,s);n.angle&&t.restore()}}))},pick:Xt((function(t,e,n,i,r,o){if(e.fontSize<=0)return!1;if(!e.angle)return!0;var s=Ge(e),a=s.x1,l=s.y1,u=je(He,e,1),c=-e.angle*v,h=Math.cos(c),f=Math.sin(c),d=h*r-f*o+(a-h*a+f*l),g=f*r+h*o+(l-f*a-h*l);return u.contains(d,g)})),isect:function(t,e){var n=je(He,t,2);return St(e,n[0],n[1],n[2],n[3])||St(e,n[0],n[1],n[4],n[5])||St(e,n[4],n[5],n[6],n[7])||St(e,n[2],n[3],n[6],n[7])}},trail:ee("trail",(function(t,e){return Q.context(t)(e)}),(function(t,e){for(var n,i,r=t.length;--r>=0;)if(!1!==t[r].defined&&(n=t[r].x-e[0])*n+(i=t[r].y-e[1])*i<(n=t[r].size||1)*n)return t[r];return null}))};function Ue(t,e,n){var i=We[t.mark.marktype],r=e||i.bound;return i.nested&&(t=t.mark),r(t.bounds||(t.bounds=new it),t,n)}var Xe={mark:null};function Fe(t,e,n){var i,r,o,s,a=We[t.marktype],l=a.bound,u=t.items,c=u&&u.length;if(a.nested)return c?o=u[0]:(Xe.mark=t,o=Xe),s=Ue(o,l,n),e=e&&e.union(s)||s;if(e=e||t.bounds&&t.bounds.clear()||new it,c)for(i=0,r=u.length;i<r;++i)e.union(Ue(u[i],l,n));return t.bounds=e}var Ye=["marktype","name","role","interactive","clip","items","zindex","x","y","width","height","align","baseline","fill","fillOpacity","opacity","blend","stroke","strokeOpacity","strokeWidth","strokeCap","strokeDash","strokeDashOffset","strokeForeground","strokeOffset","startAngle","endAngle","innerRadius","outerRadius","cornerRadius","padAngle","cornerRadiusTopLeft","cornerRadiusTopRight","cornerRadiusBottomLeft","cornerRadiusBottomRight","interpolate","tension","orient","defined","url","aspect","smooth","path","scaleX","scaleY","x2","y2","size","shape","text","angle","theta","radius","dir","dx","dy","ellipsis","limit","lineBreak","lineHeight","font","fontSize","fontWeight","fontStyle","fontVariant","description","aria","ariaRole","ariaRoleDescription"];function Je(t,e){return JSON.stringify(t,Ye,e)}function $e(t){return function t(e){var n,i,r,o=e.marktype,s=e.items;if(s)for(i=0,r=s.length;i<r;++i)n=o?"mark":"group",s[i][n]=e,s[i].zindex&&(s[i][n].zdirty=!0),"group"===(o||n)&&t(s[i]);o&&Fe(e);return e}("string"==typeof t?JSON.parse(t):t)}function Qe(t){arguments.length?this.root=$e(t):(this.root=Ke({marktype:"group",name:"root",role:"frame"}),this.root.items=[new st(this.root)])}var Ze=Qe.prototype;function Ke(t,e){const n={bounds:new it,clip:!!t.clip,group:e,interactive:!1!==t.interactive,items:[],marktype:t.marktype,name:t.name||void 0,role:t.role||void 0,zindex:t.zindex||0};return null!=t.aria&&(n.aria=t.aria),t.description&&(n.description=t.description),n}function tn(t,e,n){return!t&&"undefined"!=typeof document&&document.createElement&&(t=document),t?n?t.createElementNS(n,e):t.createElement(e):null}function en(t,e){e=e.toLowerCase();for(var n=t.childNodes,i=0,r=n.length;i<r;++i)if(n[i].tagName.toLowerCase()===e)return n[i]}function nn(t,e,n,i){var r,o=t.childNodes[e];return o&&o.tagName.toLowerCase()===n.toLowerCase()||(r=o||null,o=tn(t.ownerDocument,n,i),t.insertBefore(o,r)),o}function rn(t,e){for(var n=t.childNodes,i=n.length;i>e;)t.removeChild(n[--i]);return t}function on(t){return"mark-"+t.marktype+(t.role?" role-"+t.role:"")+(t.name?" "+t.name:"")}function sn(t,e){var n=e.getBoundingClientRect();return[t.clientX-n.left-(e.clientLeft||0),t.clientY-n.top-(e.clientTop||0)]}function an(t,e){this._active=null,this._handlers={},this._loader=t||o.loader(),this._tooltip=e||ln}function ln(t,e,n,i){t.element().setAttribute("title",i||"")}Ze.toJSON=function(t){return Je(this.root,t||0)},Ze.mark=function(t,e,n){var i=Ke(t,e=e||this.root.items[0]);return e.items[n]=i,i.zindex&&(i.group.zdirty=!0),i};const un=an.prototype;function cn(t){this._el=null,this._bgcolor=null,this._loader=new at(t)}un.initialize=function(t,e,n){return this._el=t,this._obj=n||null,this.origin(e)},un.element=function(){return this._el},un.canvas=function(){return this._el&&this._el.firstChild},un.origin=function(t){return arguments.length?(this._origin=t||[0,0],this):this._origin.slice()},un.scene=function(t){return arguments.length?(this._scene=t,this):this._scene},un.on=function(){},un.off=function(){},un._handlerIndex=function(t,e,n){for(let i=t?t.length:0;--i>=0;)if(t[i].type===e&&(!n||t[i].handler===n))return i;return-1},un.handlers=function(t){const e=this._handlers,n=[];if(t)n.push.apply(n,e[this.eventName(t)]);else for(const t in e)n.push.apply(n,e[t]);return n},un.eventName=function(t){const e=t.indexOf(".");return e<0?t:t.slice(0,e)},un.handleHref=function(t,e,n){this._loader.sanitize(n,{context:"href"}).then(e=>{const n=new MouseEvent(t.type,t),i=tn(null,"a");for(const t in e)i.setAttribute(t,e[t]);i.dispatchEvent(n)}).catch((function(){}))},un.handleTooltip=function(t,e,n){if(e&&null!=e.tooltip){e=function(t,e,n,i){var r,o,s=t&&t.mark;if(s&&(r=We[s.marktype]).tip){for((o=sn(e,n))[0]-=i[0],o[1]-=i[1];t=t.mark.group;)o[0]-=t.x||0,o[1]-=t.y||0;t=r.tip(s.items,o)}return t}(e,t,this.canvas(),this._origin);const i=n&&e&&e.tooltip||null;this._tooltip.call(this._obj,this,t,e,i)}},un.getItemBoundingClientRect=function(t){const e=this.canvas();if(!e)return;const n=e.getBoundingClientRect(),i=this._origin,r=t.bounds,o=r.width(),s=r.height();let a=r.x1+i[0]+n.left,l=r.y1+i[1]+n.top;for(;t.mark&&(t=t.mark.group);)a+=t.x||0,l+=t.y||0;return{x:a,y:l,width:o,height:s,left:a,top:l,right:a+o,bottom:l+s}};var hn=cn.prototype;hn.initialize=function(t,e,n,i,r){return this._el=t,this.resize(e,n,i,r)},hn.element=function(){return this._el},hn.canvas=function(){return this._el&&this._el.firstChild},hn.background=function(t){return 0===arguments.length?this._bgcolor:(this._bgcolor=t,this)},hn.resize=function(t,e,n,i){return this._width=t,this._height=e,this._origin=n||[0,0],this._scale=i||1,this},hn.dirty=function(){},hn.render=function(t){var e=this;return e._call=function(){e._render(t)},e._call(),e._call=null,e},hn._render=function(){},hn.renderAsync=function(t){var e=this.render(t);return this._ready?this._ready.then((function(){return e})):Promise.resolve(e)},hn._load=function(t,e){var n=this,i=n._loader[t](e);if(!n._ready){var r=n._call;n._ready=n._loader.ready().then((function(t){t&&r(),n._ready=null}))}return i},hn.sanitizeURL=function(t){return this._load("sanitizeURL",t)},hn.loadImage=function(t){return this._load("loadImage",t)};const fn="dragleave",dn="mousedown",gn="mousemove",pn="mouseout",vn="click",yn=["keydown","keypress","keyup","dragenter",fn,"dragover",dn,"mouseup",gn,pn,"mouseover",vn,"dblclick","wheel","mousewheel","touchstart","touchmove","touchend"],_n=gn,mn=pn,xn=vn;function bn(t,e){an.call(this,t,e),this._down=null,this._touch=null,this._first=!0,this._events={}}const kn=e.inherits(bn,an);kn.initialize=function(t,e,n){return this._canvas=t&&en(t,"canvas"),[vn,dn,gn,pn,fn].forEach(t=>wn(this,t)),an.prototype.initialize.call(this,t,e,n)};function wn(t,e){(t=>"touchstart"===t||"touchmove"===t||"touchend"===t?["touchstart","touchmove","touchend"]:[t])(e).forEach(e=>function(t,e){const n=t.canvas();n&&!t._events[e]&&(t._events[e]=1,n.addEventListener(e,t[e]?n=>t[e](n):n=>t.fire(e,n)))}(t,e))}function Tn(t,e,n){return function(i){const r=this._active,o=this.pickEvent(i);o===r||(r&&r.exit||this.fire(n,i),this._active=o,this.fire(e,i)),this.fire(t,i)}}function An(t){return function(e){this.fire(t,e),this._active=null}}kn.canvas=function(){return this._canvas},kn.context=function(){return this._canvas.getContext("2d")},kn.events=yn,kn.DOMMouseScroll=function(t){this.fire("mousewheel",t)},kn.mousemove=Tn(gn,"mouseover",pn),kn.dragover=Tn("dragover","dragenter",fn),kn.mouseout=An(pn),kn.dragleave=An(fn),kn.mousedown=function(t){this._down=this._active,this.fire(dn,t)},kn.click=function(t){this._down===this._active&&(this.fire(vn,t),this._down=null)},kn.touchstart=function(t){this._touch=this.pickEvent(t.changedTouches[0]),this._first&&(this._active=this._touch,this._first=!1),this.fire("touchstart",t,!0)},kn.touchmove=function(t){this.fire("touchmove",t,!0)},kn.touchend=function(t){this.fire("touchend",t,!0),this._touch=null},kn.fire=function(t,e,n){const i=n?this._touch:this._active,r=this._handlers[t];if(e.vegaType=t,t===xn&&i&&i.href?this.handleHref(e,i,i.href):t!==_n&&t!==mn||this.handleTooltip(e,i,t!==mn),r)for(let t=0,n=r.length;t<n;++t)r[t].handler.call(this._obj,e,i)},kn.on=function(t,e){const n=this.eventName(t),i=this._handlers;return this._handlerIndex(i[n],t,e)<0&&(wn(this,t),(i[n]||(i[n]=[])).push({type:t,handler:e})),this},kn.off=function(t,e){const n=this.eventName(t),i=this._handlers[n],r=this._handlerIndex(i,t,e);return r>=0&&i.splice(r,1),this},kn.pickEvent=function(t){const e=sn(t,this._canvas),n=this._origin;return this.pick(this._scene,e[0],e[1],e[0]-n[0],e[1]-n[1])},kn.pick=function(t,e,n,i,r){const o=this.context();return We[t.marktype].pick.call(this,o,t,e,n,i,r)};var Mn="undefined"!=typeof window&&window.devicePixelRatio||1;function Cn(t){cn.call(this,t),this._options={},this._redraw=!1,this._dirty=new it,this._tempb=new it}const Rn=e.inherits(Cn,cn),zn=cn.prototype;Rn.initialize=function(t,e,n,i,o,s){return this._options=s||{},this._canvas=this._options.externalContext?null:r.canvas(1,1,this._options.type),t&&this._canvas&&(rn(t,0).appendChild(this._canvas),this._canvas.setAttribute("class","marks")),zn.initialize.call(this,t,e,n,i,o)},Rn.resize=function(t,n,i,r){if(zn.resize.call(this,t,n,i,r),this._canvas)!function(t,e,n,i,r,o){const s="undefined"!=typeof HTMLElement&&t instanceof HTMLElement&&null!=t.parentNode,a=t.getContext("2d"),l=s?Mn:r;t.width=e*l,t.height=n*l;for(const t in o)a[t]=o[t];s&&1!==l&&(t.style.width=e+"px",t.style.height=n+"px"),a.pixelRatio=l,a.setTransform(l,0,0,l,l*i[0],l*i[1])}(this._canvas,this._width,this._height,this._origin,this._scale,this._options.context);else{const t=this._options.externalContext;t||e.error("CanvasRenderer is missing a valid canvas or context"),t.scale(this._scale,this._scale),t.translate(this._origin[0],this._origin[1])}return this._redraw=!0,this},Rn.canvas=function(){return this._canvas},Rn.context=function(){return this._options.externalContext||(this._canvas?this._canvas.getContext("2d"):null)},Rn.dirty=function(t){let e=this._tempb.clear().union(t.bounds),n=t.mark.group;for(;n;)e.translate(n.x||0,n.y||0),n=n.mark.group;this._dirty.union(e)};function Pn(t,e){an.call(this,t,e);const n=this;n._hrefHandler=Ln(n,(t,e)=>{e&&e.href&&n.handleHref(t,e,e.href)}),n._tooltipHandler=Ln(n,(t,e)=>{n.handleTooltip(t,e,t.type!==mn)})}Rn._render=function(t){const e=this.context(),n=this._origin,i=this._width,r=this._height,o=this._dirty,s=(a=n,l=i,u=r,(new it).set(0,0,l,u).translate(-a[0],-a[1]));var a,l,u;e.save();const c=this._redraw||o.empty()?(this._redraw=!1,s.expand(1)):function(t,e,n){return e.expand(1).round(),t.pixelRatio%1&&e.scale(t.pixelRatio).round().scale(1/t.pixelRatio),e.translate(-n[0]%1,-n[1]%1),t.beginPath(),t.rect(e.x1,e.y1,e.width(),e.height()),t.clip(),e}(e,s.intersect(o),n);return this.clear(-n[0],-n[1],i,r),this.draw(e,t,c),e.restore(),o.clear(),this},Rn.draw=function(t,n,i){const r=We[n.marktype];n.clip&&function(t,n){var i=n.clip;t.save(),e.isFunction(i)?(t.beginPath(),i(t),t.clip()):ie(t,n.group)}(t,n),r.draw.call(this,t,n,i),n.clip&&t.restore()},Rn.clear=function(t,e,n,i){const r=this._options,o=this.context();"pdf"===r.type||r.externalContext||o.clearRect(t,e,n,i),null!=this._bgcolor&&(o.fillStyle=this._bgcolor,o.fillRect(t,e,n,i))};const Sn=e.inherits(Pn,an);Sn.initialize=function(t,e,n){let i=this._svg;return i&&(i.removeEventListener(xn,this._hrefHandler),i.removeEventListener(_n,this._tooltipHandler),i.removeEventListener(mn,this._tooltipHandler)),this._svg=i=t&&en(t,"svg"),i&&(i.addEventListener(xn,this._hrefHandler),i.addEventListener(_n,this._tooltipHandler),i.addEventListener(mn,this._tooltipHandler)),an.prototype.initialize.call(this,t,e,n)},Sn.canvas=function(){return this._svg};const Ln=(t,e)=>n=>{let i=n.target.__data__;i=Array.isArray(i)?i[0]:i,n.vegaType=n.type,e.call(t._obj,n,i)};Sn.on=function(t,e){const n=this.eventName(t),i=this._handlers;if(this._handlerIndex(i[n],t,e)<0){const r={type:t,handler:e,listener:Ln(this,e)};(i[n]||(i[n]=[])).push(r),this._svg&&this._svg.addEventListener(n,r.listener)}return this},Sn.off=function(t,e){const n=this.eventName(t),i=this._handlers[n],r=this._handlerIndex(i,t,e);return r>=0&&(this._svg&&this._svg.removeEventListener(n,i[r].listener),i.splice(r,1)),this};const On=(t,e,n)=>({role:t,"aria-roledescription":e,"aria-label":n||void 0}),Nn=e.toSet(["axis-domain","axis-grid","axis-label","axis-tick","axis-title","legend-band","legend-entry","legend-gradient","legend-label","legend-title","legend-symbol","title"]),qn={axis:{desc:"axis",caption:function(t){const e=t.datum,n=t.orient,i=e.title?Vn(t):null,r=t.context,o=r.scales[e.scale].value,a=r.dataflow.locale(),l=o.type;return("left"===n||"right"===n?"Y":"X")+"-axis"+(i?` titled '${i}'`:"")+` for a ${s.isDiscrete(l)?"discrete":l} scale with `+s.domainCaption(a,o,t)}},legend:{desc:"legend",caption:function(t){const n=t.datum,i=n.title?Vn(t):null,r=((n.type||"")+" legend").trim(),o=n.scales,a=Object.keys(o),l=t.context,u=l.scales[o[a[0]]].value,c=l.dataflow.locale();return h=r,(h.length?h[0].toUpperCase()+h.slice(1):h)+(i?` titled '${i}'`:"")+" for "+function(t){return(t=t.map(t=>t+("fill"===t||"stroke"===t?" color":""))).length<2?t[0]:t.slice(0,-1).join(", ")+" and "+e.peek(t)}(a)+" with "+s.domainCaption(c,u,t);var h}},"title-text":{desc:"title",caption:t=>`Title text '${Bn(t)}'`},"title-subtitle":{desc:"subtitle",caption:t=>`Subtitle text '${Bn(t)}'`}},Dn={ariaRole:"role",ariaRoleDescription:"aria-roledescription",description:"aria-label"};function En(t,e){const n=!1===e.aria;if(t("aria-hidden",n||void 0),n||null==e.description)for(const e in Dn)t(Dn[e],void 0);else{const n=e.mark.marktype;t("aria-label",e.description),t("role",e.ariaRole||("group"===n?"graphics-object":"graphics-symbol")),t("aria-roledescription",e.ariaRoleDescription||n+" mark")}}function In(t){return!1===t.aria?{"aria-hidden":!0}:Nn[t.role]?null:qn[t.role]?function(t,e){try{const n=t.items[0],i=e.caption||(()=>"");return On(e.role||"graphics-symbol",e.desc,n.description||i(n))}catch(t){return null}}(t,qn[t.role]):function(t){const e=t.marktype,n="group"===e||"text"===e||t.items.some(t=>null!=t.description&&!1!==t.aria);return On(n?"graphics-object":"graphics-symbol",e+" mark container",t.description)}(t)}function Bn(t){return e.array(t.text).join(" ")}function Vn(t){try{return e.array(e.peek(t.items).items[0].text).join(" ")}catch(t){return null}}const Hn=t=>(t+"").replace(/&/g,"&amp;").replace(/"/g,"&quot;");function Gn(t,e,n){var i,r,o="<"+t;if(e)for(i in e)null!=(r=e[i])&&(o+=" "+i+'="'+Hn(r)+'"');return n&&(o+=" "+n),o+">"}function jn(t){return"</"+t+">"}const Wn={fill:"fill",fillOpacity:"fill-opacity",stroke:"stroke",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",strokeCap:"stroke-linecap",strokeJoin:"stroke-linejoin",strokeDash:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeMiterLimit:"stroke-miterlimit",opacity:"opacity",blend:"mix-blend-mode"},Un={fill:"none","stroke-miterlimit":10},Xn=ce.xmlns;function Fn(t){cn.call(this,t),this._dirtyID=0,this._dirty=[],this._svg=null,this._root=null,this._defs=null}var Yn=e.inherits(Fn,cn),Jn=cn.prototype;function $n(t,e,n){var i,r,o;if("radial"===e.gradient){var s=nn(t,n++,"pattern",Xn);s.setAttribute("id","p_"+e.id),s.setAttribute("viewBox","0,0,1,1"),s.setAttribute("width","100%"),s.setAttribute("height","100%"),s.setAttribute("preserveAspectRatio","xMidYMid slice"),(s=nn(s,0,"rect",Xn)).setAttribute("width","1"),s.setAttribute("height","1"),s.setAttribute("fill","url("+si()+"#"+e.id+")"),(t=nn(t,n++,"radialGradient",Xn)).setAttribute("id",e.id),t.setAttribute("fx",e.x1),t.setAttribute("fy",e.y1),t.setAttribute("fr",e.r1),t.setAttribute("cx",e.x2),t.setAttribute("cy",e.y2),t.setAttribute("r",e.r2)}else(t=nn(t,n++,"linearGradient",Xn)).setAttribute("id",e.id),t.setAttribute("x1",e.x1),t.setAttribute("x2",e.x2),t.setAttribute("y1",e.y1),t.setAttribute("y2",e.y2);for(i=0,r=e.stops.length;i<r;++i)(o=nn(t,i,"stop",Xn)).setAttribute("offset",e.stops[i].offset),o.setAttribute("stop-color",e.stops[i].color);return rn(t,i),n}function Qn(t,e,n){var i;return(t=nn(t,n,"clipPath",Xn)).setAttribute("id",e.id),e.path?(i=nn(t,0,"path",Xn)).setAttribute("d",e.path):((i=nn(t,0,"rect",Xn)).setAttribute("x",0),i.setAttribute("y",0),i.setAttribute("width",e.width),i.setAttribute("height",e.height)),rn(t,1),n+1}function Zn(t,e){for(;t&&t.dirty!==e;t=t.mark.group){if(t.dirty=e,!t.mark||t.mark.dirty===e)return;t.mark.dirty=e}}function Kn(t,e,n,i,r){let o,s=t._svg;if(!s&&(o=e.ownerDocument,s=tn(o,i,Xn),t._svg=s,t.mark&&(s.__data__=t,s.__values__={fill:"default"},"g"===i))){const e=tn(o,"path",Xn);s.appendChild(e),e.__data__=t;const n=tn(o,"g",Xn);s.appendChild(n),n.__data__=t;const i=tn(o,"path",Xn);s.appendChild(i),i.__data__=t,i.__values__={fill:"default"}}return(s.ownerSVGElement!==r||function(t,e){return t.parentNode&&t.parentNode.childNodes.length>1&&t.previousSibling!=e}(s,n))&&e.insertBefore(s,n?n.nextSibling:e.firstChild),s}Yn.initialize=function(t,e,n,i){if(this._defs={gradient:{},clipping:{}},t){this._svg=nn(t,0,"svg",Xn),this._svg.setAttribute("class","marks"),rn(t,1),this._root=nn(this._svg,0,"g",Xn);for(const t in Un)this._root.setAttribute(t,Un[t]);rn(this._svg,1)}return this.background(this._bgcolor),Jn.initialize.call(this,t,e,n,i)},Yn.background=function(t){return arguments.length&&this._svg&&this._svg.style.setProperty("background-color",t),Jn.background.apply(this,arguments)},Yn.resize=function(t,e,n,i){return Jn.resize.call(this,t,e,n,i),this._svg&&(this._svg.setAttribute("width",this._width*this._scale),this._svg.setAttribute("height",this._height*this._scale),this._svg.setAttribute("viewBox","0 0 "+this._width+" "+this._height),this._root.setAttribute("transform","translate("+this._origin+")")),this._dirty=[],this},Yn.canvas=function(){return this._svg},Yn.svg=function(){if(!this._svg)return null;var t={class:"marks",width:this._width*this._scale,height:this._height*this._scale,viewBox:"0 0 "+this._width+" "+this._height};for(var e in ce)t[e]=ce[e];var n=this._bgcolor?Gn("rect",{width:this._width,height:this._height,fill:this._bgcolor})+jn("rect"):"";return Gn("svg",t)+(this._defs.el?this._defs.el.outerHTML:"")+n+this._root.outerHTML+jn("svg")},Yn._render=function(t){return this._dirtyCheck()&&(this._dirtyAll&&this._resetDefs(),this.draw(this._root,t),rn(this._root,1)),this.updateDefs(),this._dirty=[],++this._dirtyID,this},Yn.updateDefs=function(){const t=this._svg,e=this._defs;let n=e.el,i=0;for(const r in e.gradient)n||(e.el=n=nn(t,0,"defs",Xn)),i=$n(n,e.gradient[r],i);for(const r in e.clipping)n||(e.el=n=nn(t,0,"defs",Xn)),i=Qn(n,e.clipping[r],i);n&&(0===i?(t.removeChild(n),e.el=null):rn(n,i))},Yn._resetDefs=function(){var t=this._defs;t.gradient={},t.clipping={}},Yn.dirty=function(t){t.dirty!==this._dirtyID&&(t.dirty=this._dirtyID,this._dirty.push(t))},Yn.isDirty=function(t){return this._dirtyAll||!t._svg||t.dirty===this._dirtyID},Yn._dirtyCheck=function(){this._dirtyAll=!0;var t=this._dirty;if(!t.length||!this._dirtyID)return!0;var e,n,i,r,o,s,a,l=++this._dirtyID;for(o=0,s=t.length;o<s;++o)(n=(e=t[o]).mark).marktype!==i&&(i=n.marktype,r=We[i]),n.zdirty&&n.dirty!==l&&(this._dirtyAll=!1,Zn(e,l),n.items.forEach((function(t){t.dirty=l}))),n.zdirty||(e.exit?(r.nested&&n.items.length?(a=n.items[0])._svg&&this._update(r,a._svg,a):e._svg&&(a=e._svg.parentNode)&&a.removeChild(e._svg),e._svg=null):(e=r.nested?n.items[0]:e)._update!==l&&(e._svg&&e._svg.ownerSVGElement?this._update(r,e._svg,e):(this._dirtyAll=!1,Zn(e,l)),e._update=l));return!this._dirtyAll},Yn.draw=function(t,e,n){if(!this.isDirty(e))return e._svg;var i,r=this._svg,o=We[e.marktype],s=!1===e.interactive?"none":null,a="g"===o.tag,l=null,u=0;(i=Kn(e,t,n,"g",r)).setAttribute("class",on(e));const c=In(e);for(const t in c)oi(i,t,c[t]);a||oi(i,"pointer-events",s),oi(i,"clip-path",e.clip?nt(this,e,e.group):null);const h=t=>{const e=this.isDirty(t),n=Kn(t,i,l,o.tag,r);e&&(this._update(o,n,t),a&&function(t,e,n){e=e.lastChild.previousSibling;let i,r=0;Ht(n,n=>{i=t.draw(e,n,i),++r}),rn(e,1+r)}(this,n,t)),l=n,++u};return o.nested?e.items.length&&h(e.items[0]):Ht(e,h),rn(i,u),i};var ti=null,ei=null,ni={group:function(t,e,n){const i=ti=e.childNodes[2];ei=i.__values__,t.foreground(ri,n,this),ei=e.__values__,ti=e.childNodes[1],t.content(ri,n,this);const r=ti=e.childNodes[0];t.background(ri,n,this);const o=!1===n.mark.interactive?"none":null;if(o!==ei.events&&(oi(i,"pointer-events",o),oi(r,"pointer-events",o),ei.events=o),n.strokeForeground&&n.stroke){const t=n.fill;oi(i,"display",null),this.style(r,n),oi(r,"stroke",null),t&&(n.fill=null),ei=i.__values__,this.style(i,n),t&&(n.fill=t),ti=null}else oi(i,"display","none")},image:function(t,e,n){!1===n.smooth?(ii(e,"image-rendering","optimizeSpeed"),ii(e,"image-rendering","pixelated")):ii(e,"image-rendering",null)},text:function(t,n,i){let r,o,s,a,l=qe(i);e.isArray(l)?(o=l.map(t=>De(i,t)),r=o.join("\n"),r!==ei.text&&(rn(n,0),s=n.ownerDocument,a=Ne(i),o.forEach((t,e)=>{const r=tn(s,"tspan",Xn);r.__data__=i,r.textContent=t,e&&(r.setAttribute("x",0),r.setAttribute("dy",a)),n.appendChild(r)}),ei.text=r)):(o=De(i,l),o!==ei.text&&(n.textContent=o,ei.text=o)),oi(n,"font-family",Ee(i)),oi(n,"font-size",Oe(i)+"px"),oi(n,"font-style",i.fontStyle),oi(n,"font-variant",i.fontVariant),oi(n,"font-weight",i.fontWeight)}};function ii(t,e,n){n!==ei[e]&&(null==n?t.style.removeProperty(e):t.style.setProperty(e,n+""),ei[e]=n)}function ri(t,e,n){e!==ei[t]&&(n?function(t,e,n,i){null!=n?t.setAttributeNS(i,e,n):t.removeAttributeNS(i,e)}(ti,t,e,n):oi(ti,t,e),ei[t]=e)}function oi(t,e,n){null!=n?t.setAttribute(e,n):t.removeAttribute(e)}function si(){let t;return"undefined"==typeof window?"":(t=window.location).hash?t.href.slice(0,-t.hash.length):t.href}function ai(t){cn.call(this,t),this._text={head:"",bg:"",root:"",foot:"",defs:"",body:""},this._defs={gradient:{},clipping:{}}}Yn._update=function(t,e,n){ti=e,ei=e.__values__,En(ri,n),t.attr(ri,n,this);const i=ni[t.type];i&&i.call(this,t,e,n),ti&&this.style(ti,n)},Yn.style=function(t,e){if(null!=e)for(const n in Wn){let i="font"===n?Ee(e):e[n];if(i===ei[n])continue;const r=Wn[n];null==i?t.removeAttribute(r):(l(i)&&(i=u(i,this._defs.gradient,si())),t.setAttribute(r,i+"")),ei[n]=i}};var li=e.inherits(ai,cn),ui=cn.prototype;function ci(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}li.resize=function(t,n,i,r){ui.resize.call(this,t,n,i,r);var o=this._origin,s=this._text,a={class:"marks",width:this._width*this._scale,height:this._height*this._scale,viewBox:"0 0 "+this._width+" "+this._height};for(var l in ce)a[l]=ce[l];s.head=Gn("svg",a);var u=this._bgcolor;return"transparent"!==u&&"none"!==u||(u=null),s.bg=u?Gn("rect",{width:this._width,height:this._height,fill:u})+jn("rect"):"",s.root=Gn("g",e.extend({},Un,{transform:"translate("+o+")"})),s.foot=jn("g")+jn("svg"),this},li.background=function(){var t=ui.background.apply(this,arguments);return arguments.length&&this._text.head&&this.resize(this._width,this._height,this._origin,this._scale),t},li.svg=function(){var t=this._text;return t.head+t.defs+t.bg+t.root+t.body+t.foot},li._render=function(t){return this._text.body=this.mark(t),this._text.defs=this.buildDefs(),this},li.buildDefs=function(){let t,e="";for(const n in this._defs.gradient){const i=this._defs.gradient[n],r=i.stops;"radial"===i.gradient?(e+=Gn(t="pattern",{id:"p_"+n,viewBox:"0,0,1,1",width:"100%",height:"100%",preserveAspectRatio:"xMidYMid slice"}),e+=Gn("rect",{width:"1",height:"1",fill:"url(#"+n+")"})+jn("rect"),e+=jn(t),e+=Gn(t="radialGradient",{id:n,fx:i.x1,fy:i.y1,fr:i.r1,cx:i.x2,cy:i.y2,r:i.r2})):e+=Gn(t="linearGradient",{id:n,x1:i.x1,x2:i.x2,y1:i.y1,y2:i.y2});for(let t=0;t<r.length;++t)e+=Gn("stop",{offset:r[t].offset,"stop-color":r[t].color})+jn("stop");e+=jn(t)}for(const t in this._defs.clipping){const n=this._defs.clipping[t];e+=Gn("clipPath",{id:t}),n.path?e+=Gn("path",{d:n.path})+jn("path"):e+=Gn("rect",{x:0,y:0,width:n.width,height:n.height})+jn("rect"),e+=jn("clipPath")}return e?Gn("defs")+e+jn("defs"):""},li.attr=function(t,e,n,i){const r={},o=(t,e,n,i)=>{r[i||t]=e};return Array.isArray(n)?n.forEach(t=>t(o,e,this)):n(o,e,this),i&&function(t,e,n,i,r){if(null==e)return t;"bgrect"===i&&!1===n.interactive&&(t["pointer-events"]="none");if("bgfore"===i&&(!1===n.interactive&&(t["pointer-events"]="none"),t.display="none",null!==e.fill))return t;"image"===i&&!1===e.smooth&&(t.style="image-rendering: optimizeSpeed; image-rendering: pixelated;");"text"===i&&(t["font-family"]=Ee(e),t["font-size"]=Oe(e)+"px",e.fontStyle&&(t["font-style"]=e.fontStyle),e.fontVariant&&(t["font-variant"]=e.fontVariant),e.fontWeight&&(t["font-weight"]=e.fontWeight));for(const n in Wn){let i=e[n];const o=Wn[n];("transparent"!==i||"fill"!==o&&"stroke"!==o)&&null!=i&&(l(i)&&(i=u(i,r.gradient,"")),t[o]=i)}}(r,e,t,i,this._defs),r},li.href=function(t){var e,n=this,i=t.href;if(i){if(e=n._hrefs&&n._hrefs[i])return e;n.sanitizeURL(i).then(t=>{t["xlink:href"]=t.href,t.href=null,(n._hrefs||(n._hrefs={}))[i]=t})}return null},li.mark=function(t){const n=We[t.marktype],i=n.tag,r=[En,n.attr];let o="";o+=Gn("g",e.extend({class:on(t),"clip-path":t.clip?nt(this,t,t.group):null},In(t),{"pointer-events":"g"!==i&&!1===t.interactive?"none":null}));const s=s=>{const a=this.href(s);if(a&&(o+=Gn("a",a)),o+=Gn(i,this.attr(t,s,r,"g"!==i?i:null)),"text"===i){const t=qe(s);if(e.isArray(t)){const e={x:0,dy:Ne(s)};for(let n=0;n<t.length;++n)o+=Gn("tspan",n?e:null)+ci(De(s,t[n]))+jn("tspan")}else o+=ci(De(s,t))}else if("g"===i){const e=s.strokeForeground,i=s.fill,r=s.stroke;e&&r&&(s.stroke=null),o+=Gn("path",this.attr(t,s,n.background,"bgrect"))+jn("path"),o+=Gn("g",this.attr(t,s,n.content))+this.markGroup(s)+jn("g"),e&&r?(i&&(s.fill=null),s.stroke=r,o+=Gn("path",this.attr(t,s,n.foreground,"bgrect"))+jn("path"),i&&(s.fill=i)):o+=Gn("path",this.attr(t,s,n.foreground,"bgfore"))+jn("path")}o+=jn(i),a&&(o+=jn("a"))};return n.nested?t.items&&t.items.length&&s(t.items[0]):Ht(t,s),o+jn("g")},li.markGroup=function(t){let e="";return Ht(t,t=>{e+=this.mark(t)}),e};var hi={Canvas:"canvas",PNG:"png",SVG:"svg",None:"none"},fi={};function di(t,e,n,i){if(function(t,e,n){return t.bounds&&e.intersects(t.bounds)&&("group"===t.marktype||!1!==t.interactive&&(!n||n(t)))}(t,e,n)){const r=t.items,o=t.marktype,s=r.length;let a=0;if("group"===o)for(;a<s;++a)gi(r[a],e,n,i);else for(const t=We[o].isect;a<s;++a){let n=r[a];pi(n,e,t)&&i.push(n)}}return i}function gi(t,e,n,i){n&&n(t.mark)&&pi(t,e,We.group.isect)&&i.push(t);const r=t.items,o=r&&r.length;if(o){const s=t.x||0,a=t.y||0;e.translate(-s,-a);for(let t=0;t<o;++t)di(r[t],e,n,i);e.translate(s,a)}return i}function pi(t,e,n){const i=t.bounds;return e.encloses(i)||e.intersects(i)&&n(t,e)}fi.canvas=fi.png={renderer:Cn,headless:Cn,handler:bn},fi.svg={renderer:Fn,headless:ai,handler:Pn},fi.none={};var vi=new it;function yi(t,n,i){return t===n||("path"===i?_i(t,n):t instanceof Date&&n instanceof Date?+t==+n:e.isNumber(t)&&e.isNumber(n)?Math.abs(t-n)<=1e-9:t&&n&&(e.isObject(t)||e.isObject(n))?null!=t&&null!=n&&function(t,e){var n,i,r=Object.keys(t),o=Object.keys(e);if(r.length!==o.length)return!1;for(r.sort(),o.sort(),i=r.length-1;i>=0;i--)if(r[i]!=o[i])return!1;for(i=r.length-1;i>=0;i--)if(n=r[i],!yi(t[n],e[n],n))return!1;return typeof t==typeof e}(t,n):t==n)}function _i(t,e){return yi(p(t),p(e))}t.Bounds=it,t.CanvasHandler=bn,t.CanvasRenderer=Cn,t.Gradient=function(t,e){var n,i=[];return n={gradient:"linear",x1:t?t[0]:0,y1:t?t[1]:0,x2:e?e[0]:1,y2:e?e[1]:0,stops:i,stop:function(t,e){return i.push({offset:t,color:e}),n}}},t.GroupItem=st,t.Handler=an,t.Item=ot,t.Marks=We,t.RenderType=hi,t.Renderer=cn,t.ResourceLoader=at,t.SVGHandler=Pn,t.SVGRenderer=Fn,t.SVGStringRenderer=ai,t.Scenegraph=Qe,t.boundClip=function(t){var n=t.clip;if(e.isFunction(n))n(vt(vi.clear()));else{if(!n)return;vi.set(0,0,t.group.width,t.group.height)}t.bounds.intersect(vi)},t.boundContext=vt,t.boundItem=Ue,t.boundMark=Fe,t.boundStroke=ht,t.closeTag=jn,t.domChild=nn,t.domClear=rn,t.domCreate=tn,t.domFind=en,t.font=Ie,t.fontFamily=Ee,t.fontSize=Oe,t.intersect=function(t,n,i){const r=[],o=(new it).union(n),s=t.marktype;return s?di(t,o,i,r):"group"===s?gi(t,o,i,r):e.error("Intersect scene must be mark node or group item.")},t.intersectBoxLine=St,t.intersectPath=Ct,t.intersectPoint=Rt,t.intersectRule=Pt,t.lineHeight=Ne,t.multiLineOffset=function(t){const n=qe(t);return(e.isArray(n)?n.length-1:0)*Ne(t)},t.openTag=Gn,t.pathCurves=f,t.pathEqual=_i,t.pathParse=p,t.pathRectangle=B,t.pathRender=M,t.pathSymbols=P,t.pathTrail=V,t.point=sn,t.renderModule=function(t,e){return t=String(t||"").toLowerCase(),arguments.length>1?(fi[t]=e,this):fi[t]},t.resetSVGClipId=et,t.resetSVGDefIds=function(){et(),a=0},t.sceneEqual=yi,t.sceneFromJSON=$e,t.scenePickVisit=Gt,t.sceneToJSON=Je,t.sceneVisit=Ht,t.sceneZOrder=Vt,t.textMetrics=Ce,Object.defineProperty(t,"__esModule",{value:!0})}));
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("vega-util"),require("d3-shape"),require("d3-path"),require("vega-canvas"),require("vega-loader"),require("vega-scale")):"function"==typeof define&&define.amd?define(["exports","vega-util","d3-shape","d3-path","vega-canvas","vega-loader","vega-scale"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).vega={},t.vega,t.d3,t.d3,t.vega,t.vega,t.vega)}(this,(function(t,e,n,i,r,s,o){"use strict";var a=0;function l(t){return t&&t.gradient}function c(t,e,n){let i=t.id,r=t.gradient,s="radial"===r?"p_":"";return i||(i=t.id="gradient_"+a++,"radial"===r?(t.x1=h(t.x1,.5),t.y1=h(t.y1,.5),t.r1=h(t.r1,0),t.x2=h(t.x2,.5),t.y2=h(t.y2,.5),t.r2=h(t.r2,.5),s="p_"):(t.x1=h(t.x1,0),t.y1=h(t.y1,0),t.x2=h(t.x2,1),t.y2=h(t.y2,0))),e[i]=t,"url("+(n||"")+"#"+s+i+")"}function h(t,e){return null!=t?t:e}const u={basis:{curve:n.curveBasis},"basis-closed":{curve:n.curveBasisClosed},"basis-open":{curve:n.curveBasisOpen},bundle:{curve:n.curveBundle,tension:"beta",value:.85},cardinal:{curve:n.curveCardinal,tension:"tension",value:0},"cardinal-open":{curve:n.curveCardinalOpen,tension:"tension",value:0},"cardinal-closed":{curve:n.curveCardinalClosed,tension:"tension",value:0},"catmull-rom":{curve:n.curveCatmullRom,tension:"alpha",value:.5},"catmull-rom-closed":{curve:n.curveCatmullRomClosed,tension:"alpha",value:.5},"catmull-rom-open":{curve:n.curveCatmullRomOpen,tension:"alpha",value:.5},linear:{curve:n.curveLinear},"linear-closed":{curve:n.curveLinearClosed},monotone:{horizontal:n.curveMonotoneY,vertical:n.curveMonotoneX},natural:{curve:n.curveNatural},step:{curve:n.curveStep},"step-after":{curve:n.curveStepAfter},"step-before":{curve:n.curveStepBefore}};function d(t,n,i){var r=e.hasOwnProperty(u,t)&&u[t],s=null;return r&&(s=r.curve||r[n||"vertical"],r.tension&&null!=i&&(s=s[r.tension](i))),s}const f={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},p=[/([MLHVCSQTAZmlhvcsqtaz])/g,/###/,/(\.\d+)(\.\d)/g,/(\d)([-+])/g,/\s|,|###/];function g(t){let e,n,i,r,s,o,a,l,c,h,u,d=[];for(e=t.slice().replace(p[0],"###$1").split(p[1]).slice(1),l=0,h=e.length;l<h;++l){for(n=e[l],i=n.slice(1).trim().replace(p[2],"$1###$2").replace(p[3],"$1###$2").split(p[4]),o=n.charAt(0),r=[o],c=0,u=i.length;c<u;++c)(s=+i[c])===s&&r.push(s);if(a=f[o.toLowerCase()],r.length-1>a){let t=1,e=r.length;for(d.push([o].concat(r.slice(t,t+=a))),o="M"===o?"L":"m"===o?"l":o;t<e;t+=a)d.push([o].concat(r.slice(t,t+a)))}else d.push(r)}return d}const v=Math.PI/180,y=Math.PI/2,m=2*Math.PI,x=Math.sqrt(3)/2;var _={},b={},k=[].join;function w(t){var e=k.call(t);if(b[e])return b[e];var n=t[0],i=t[1],r=t[2],s=t[3],o=t[4],a=t[5],l=t[6],c=t[7],h=c*o,u=-l*a,d=l*o,f=c*a,p=Math.cos(r),g=Math.sin(r),v=Math.cos(s),y=Math.sin(s),m=.5*(s-r),x=Math.sin(.5*m),_=8/3*x*x/Math.sin(m),w=n+p-_*g,T=i+g+_*p,M=n+v,C=i+y,R=M+_*y,A=C-_*v;return b[e]=[h*w+u*T,d*w+f*T,h*R+u*A,d*R+f*A,h*M+u*C,d*M+f*C]}var T=["l",0,0,0,0,0,0,0];function M(t,e,n){var i=T[0]=t[0];if("a"===i||"A"===i)T[1]=e*t[1],T[2]=n*t[2],T[3]=t[3],T[4]=t[4],T[5]=t[5],T[6]=e*t[6],T[7]=n*t[7];else if("h"===i||"H"===i)T[1]=e*t[1];else if("v"===i||"V"===i)T[1]=n*t[1];else for(var r=1,s=t.length;r<s;++r)T[r]=(r%2==1?e:n)*t[r];return T}function C(t,e,n,i,r,s){var o,a,l,c,h,u=null,d=0,f=0,p=0,g=0;null==n&&(n=0),null==i&&(i=0),null==r&&(r=1),null==s&&(s=r),t.beginPath&&t.beginPath();for(var v=0,y=e.length;v<y;++v){switch(o=e[v],1===r&&1===s||(o=M(o,r,s)),o[0]){case"l":d+=o[1],f+=o[2],t.lineTo(d+n,f+i);break;case"L":d=o[1],f=o[2],t.lineTo(d+n,f+i);break;case"h":d+=o[1],t.lineTo(d+n,f+i);break;case"H":d=o[1],t.lineTo(d+n,f+i);break;case"v":f+=o[1],t.lineTo(d+n,f+i);break;case"V":f=o[1],t.lineTo(d+n,f+i);break;case"m":d+=o[1],f+=o[2],t.moveTo(d+n,f+i);break;case"M":d=o[1],f=o[2],t.moveTo(d+n,f+i);break;case"c":a=d+o[5],l=f+o[6],p=d+o[3],g=f+o[4],t.bezierCurveTo(d+o[1]+n,f+o[2]+i,p+n,g+i,a+n,l+i),d=a,f=l;break;case"C":d=o[5],f=o[6],p=o[3],g=o[4],t.bezierCurveTo(o[1]+n,o[2]+i,p+n,g+i,d+n,f+i);break;case"s":a=d+o[3],l=f+o[4],p=2*d-p,g=2*f-g,t.bezierCurveTo(p+n,g+i,d+o[1]+n,f+o[2]+i,a+n,l+i),p=d+o[1],g=f+o[2],d=a,f=l;break;case"S":a=o[3],l=o[4],p=2*d-p,g=2*f-g,t.bezierCurveTo(p+n,g+i,o[1]+n,o[2]+i,a+n,l+i),d=a,f=l,p=o[1],g=o[2];break;case"q":a=d+o[3],l=f+o[4],p=d+o[1],g=f+o[2],t.quadraticCurveTo(p+n,g+i,a+n,l+i),d=a,f=l;break;case"Q":a=o[3],l=o[4],t.quadraticCurveTo(o[1]+n,o[2]+i,a+n,l+i),d=a,f=l,p=o[1],g=o[2];break;case"t":a=d+o[1],l=f+o[2],null===u[0].match(/[QqTt]/)?(p=d,g=f):"t"===u[0]?(p=2*d-c,g=2*f-h):"q"===u[0]&&(p=2*d-p,g=2*f-g),c=p,h=g,t.quadraticCurveTo(p+n,g+i,a+n,l+i),f=l,p=(d=a)+o[1],g=f+o[2];break;case"T":a=o[1],l=o[2],p=2*d-p,g=2*f-g,t.quadraticCurveTo(p+n,g+i,a+n,l+i),d=a,f=l;break;case"a":R(t,d+n,f+i,[o[1],o[2],o[3],o[4],o[5],o[6]+d+n,o[7]+f+i]),d+=o[6],f+=o[7];break;case"A":R(t,d+n,f+i,[o[1],o[2],o[3],o[4],o[5],o[6]+n,o[7]+i]),d=o[6],f=o[7];break;case"z":case"Z":t.closePath()}u=o}}function R(t,e,n,i){for(var r=function(t,e,n,i,r,s,o,a,l){var c=k.call(arguments);if(_[c])return _[c];var h=o*v,u=Math.sin(h),d=Math.cos(h),f=d*(a-t)*.5+u*(l-e)*.5,p=d*(l-e)*.5-u*(a-t)*.5,g=f*f/((n=Math.abs(n))*n)+p*p/((i=Math.abs(i))*i);g>1&&(n*=g=Math.sqrt(g),i*=g);var x=d/n,b=u/n,w=-u/i,T=d/i,M=x*a+b*l,C=w*a+T*l,R=x*t+b*e,A=w*t+T*e,z=1/((R-M)*(R-M)+(A-C)*(A-C))-.25;z<0&&(z=0);var P=Math.sqrt(z);s==r&&(P=-P);var S=.5*(M+R)-P*(A-C),L=.5*(C+A)+P*(R-M),O=Math.atan2(C-L,M-S),N=Math.atan2(A-L,R-S)-O;N<0&&1===s?N+=m:N>0&&0===s&&(N-=m);for(var q=Math.ceil(Math.abs(N/(y+.001))),D=[],E=0;E<q;++E){var I=O+E*N/q,V=O+(E+1)*N/q;D[E]=[S,L,I,V,n,i,u,d]}return _[c]=D}(i[5],i[6],i[0],i[1],i[3],i[4],i[2],e,n),s=0;s<r.length;++s){var o=w(r[s]);t.bezierCurveTo(o[0],o[1],o[2],o[3],o[4],o[5])}}var A=.5773502691896257,z={circle:{draw:function(t,e){var n=Math.sqrt(e)/2;t.moveTo(n,0),t.arc(0,0,n,0,m)}},cross:{draw:function(t,e){var n=Math.sqrt(e)/2,i=n/2.5;t.moveTo(-n,-i),t.lineTo(-n,i),t.lineTo(-i,i),t.lineTo(-i,n),t.lineTo(i,n),t.lineTo(i,i),t.lineTo(n,i),t.lineTo(n,-i),t.lineTo(i,-i),t.lineTo(i,-n),t.lineTo(-i,-n),t.lineTo(-i,-i),t.closePath()}},diamond:{draw:function(t,e){var n=Math.sqrt(e)/2;t.moveTo(-n,0),t.lineTo(0,-n),t.lineTo(n,0),t.lineTo(0,n),t.closePath()}},square:{draw:function(t,e){var n=Math.sqrt(e),i=-n/2;t.rect(i,i,n,n)}},arrow:{draw:function(t,e){var n=Math.sqrt(e)/2,i=n/7,r=n/2.5,s=n/8;t.moveTo(-i,n),t.lineTo(i,n),t.lineTo(i,-s),t.lineTo(r,-s),t.lineTo(0,-n),t.lineTo(-r,-s),t.lineTo(-i,-s),t.closePath()}},wedge:{draw:function(t,e){var n=Math.sqrt(e)/2,i=x*n,r=i-n*A,s=n/4;t.moveTo(0,-i-r),t.lineTo(-s,i-r),t.lineTo(s,i-r),t.closePath()}},triangle:{draw:function(t,e){var n=Math.sqrt(e)/2,i=x*n,r=i-n*A;t.moveTo(0,-i-r),t.lineTo(-n,i-r),t.lineTo(n,i-r),t.closePath()}},"triangle-up":{draw:function(t,e){var n=Math.sqrt(e)/2,i=x*n;t.moveTo(0,-i),t.lineTo(-n,i),t.lineTo(n,i),t.closePath()}},"triangle-down":{draw:function(t,e){var n=Math.sqrt(e)/2,i=x*n;t.moveTo(0,i),t.lineTo(-n,-i),t.lineTo(n,-i),t.closePath()}},"triangle-right":{draw:function(t,e){var n=Math.sqrt(e)/2,i=x*n;t.moveTo(i,0),t.lineTo(-i,-n),t.lineTo(-i,n),t.closePath()}},"triangle-left":{draw:function(t,e){var n=Math.sqrt(e)/2,i=x*n;t.moveTo(-i,0),t.lineTo(i,-n),t.lineTo(i,n),t.closePath()}},stroke:{draw:function(t,e){var n=Math.sqrt(e)/2;t.moveTo(-n,0),t.lineTo(n,0)}}};function P(t){return e.hasOwnProperty(z,t)?z[t]:function(t){if(!e.hasOwnProperty(S,t)){var n=g(t);S[t]={draw:function(t,e){C(t,n,0,0,Math.sqrt(e)/2)}}}return S[t]}(t)}var S={};const L=.448084975506;function O(t){return t.x}function N(t){return t.y}function q(t){return t.width}function D(t){return t.height}function E(t){return"function"==typeof t?t:()=>+t}function I(t,e,n){return Math.max(e,Math.min(t,n))}function V(){var t=O,e=N,n=q,r=D,s=E(0),o=s,a=s,l=s,c=null;function h(h,u,d){var f,p=null!=u?u:+t.call(this,h),g=null!=d?d:+e.call(this,h),v=+n.call(this,h),y=+r.call(this,h),m=Math.min(v,y)/2,x=I(+s.call(this,h),0,m),_=I(+o.call(this,h),0,m),b=I(+a.call(this,h),0,m),k=I(+l.call(this,h),0,m);if(c||(c=f=i.path()),x<=0&&_<=0&&b<=0&&k<=0)c.rect(p,g,v,y);else{var w=p+v,T=g+y;c.moveTo(p+x,g),c.lineTo(w-_,g),c.bezierCurveTo(w-L*_,g,w,g+L*_,w,g+_),c.lineTo(w,T-k),c.bezierCurveTo(w,T-L*k,w-L*k,T,w-k,T),c.lineTo(p+b,T),c.bezierCurveTo(p+L*b,T,p,T-L*b,p,T-b),c.lineTo(p,g+x),c.bezierCurveTo(p,g+L*x,p+L*x,g,p+x,g),c.closePath()}if(f)return c=null,f+""||null}return h.x=function(e){return arguments.length?(t=E(e),h):t},h.y=function(t){return arguments.length?(e=E(t),h):e},h.width=function(t){return arguments.length?(n=E(t),h):n},h.height=function(t){return arguments.length?(r=E(t),h):r},h.cornerRadius=function(t,e,n,i){return arguments.length?(s=E(t),o=null!=e?E(e):s,l=null!=n?E(n):s,a=null!=i?E(i):o,h):s},h.context=function(t){return arguments.length?(c=null==t?null:t,h):c},h}function B(){var t,e,n,r,s,o,a,l,c=null;function h(t,e,n){var i=n/2;if(s){var r=a-e,h=t-o;if(r||h){var u=Math.sqrt(r*r+h*h),d=(r/=u)*l,f=(h/=u)*l,p=Math.atan2(h,r);c.moveTo(o-d,a-f),c.lineTo(t-r*i,e-h*i),c.arc(t,e,i,p-Math.PI,p),c.lineTo(o+d,a+f),c.arc(o,a,l,p,p+Math.PI)}else c.arc(t,e,i,0,m);c.closePath()}else s=1;o=t,a=e,l=i}function u(o){var a,l,u,d=o.length,f=!1;for(null==c&&(c=u=i.path()),a=0;a<=d;++a)!(a<d&&r(l=o[a],a,o))===f&&(f=!f)&&(s=0),f&&h(+t(l,a,o),+e(l,a,o),+n(l,a,o));if(u)return c=null,u+""||null}return u.x=function(e){return arguments.length?(t=e,u):t},u.y=function(t){return arguments.length?(e=t,u):e},u.size=function(t){return arguments.length?(n=t,u):n},u.defined=function(t){return arguments.length?(r=t,u):r},u.context=function(t){return arguments.length?(c=null==t?null:t,u):c},u}function $(t,e){return null!=t?t:e}const H=t=>t.x||0,j=t=>t.y||0,G=t=>!(!1===t.defined),W=n.arc().startAngle(t=>t.startAngle||0).endAngle(t=>t.endAngle||0).padAngle(t=>t.padAngle||0).innerRadius(t=>t.innerRadius||0).outerRadius(t=>t.outerRadius||0).cornerRadius(t=>t.cornerRadius||0),X=n.area().x(H).y1(j).y0(t=>(t.y||0)+(t.height||0)).defined(G),U=n.area().y(j).x1(H).x0(t=>(t.x||0)+(t.width||0)).defined(G),F=n.line().x(H).y(j).defined(G),Y=V().x(H).y(j).width(t=>t.width||0).height(t=>t.height||0).cornerRadius(t=>$(t.cornerRadiusTopLeft,t.cornerRadius)||0,t=>$(t.cornerRadiusTopRight,t.cornerRadius)||0,t=>$(t.cornerRadiusBottomRight,t.cornerRadius)||0,t=>$(t.cornerRadiusBottomLeft,t.cornerRadius)||0),J=n.symbol().type(t=>P(t.shape||"circle")).size(t=>$(t.size,64)),Q=B().x(H).y(j).defined(G).size(t=>t.size||1);function Z(t){return t.cornerRadius||t.cornerRadiusTopLeft||t.cornerRadiusTopRight||t.cornerRadiusBottomRight||t.cornerRadiusBottomLeft}function K(t,e,n,i){return Y.context(t)(e,n,i)}var tt=1;function et(){tt=1}function nt(t,n,i){var r=n.clip,s=t._defs,o=n.clip_id||(n.clip_id="clip"+tt++),a=s.clipping[o]||(s.clipping[o]={id:o});return e.isFunction(r)?a.path=r(null):Z(i)?a.path=K(null,i,0,0):(a.width=i.width||0,a.height=i.height||0),"url(#"+o+")"}function it(t){this.clear(),t&&this.union(t)}function rt(t){this.mark=t,this.bounds=this.bounds||new it}function st(t){rt.call(this,t),this.items=this.items||[]}function ot(t){this._pending=0,this._loader=t||s.loader()}function at(t){t._pending+=1}function lt(t){t._pending-=1}function ct(t,e,n){if(e.stroke&&0!==e.opacity&&0!==e.strokeOpacity){const i=null!=e.strokeWidth?+e.strokeWidth:1;t.expand(i+(n?function(t,e){return t.strokeJoin&&"miter"!==t.strokeJoin?0:e}(e,i):0))}return t}it.prototype={clone(){return new it(this)},clear(){return this.x1=+Number.MAX_VALUE,this.y1=+Number.MAX_VALUE,this.x2=-Number.MAX_VALUE,this.y2=-Number.MAX_VALUE,this},empty(){return this.x1===+Number.MAX_VALUE&&this.y1===+Number.MAX_VALUE&&this.x2===-Number.MAX_VALUE&&this.y2===-Number.MAX_VALUE},equals(t){return this.x1===t.x1&&this.y1===t.y1&&this.x2===t.x2&&this.y2===t.y2},set(t,e,n,i){return n<t?(this.x2=t,this.x1=n):(this.x1=t,this.x2=n),i<e?(this.y2=e,this.y1=i):(this.y1=e,this.y2=i),this},add(t,e){return t<this.x1&&(this.x1=t),e<this.y1&&(this.y1=e),t>this.x2&&(this.x2=t),e>this.y2&&(this.y2=e),this},expand(t){return this.x1-=t,this.y1-=t,this.x2+=t,this.y2+=t,this},round(){return this.x1=Math.floor(this.x1),this.y1=Math.floor(this.y1),this.x2=Math.ceil(this.x2),this.y2=Math.ceil(this.y2),this},scale(t){return this.x1*=t,this.y1*=t,this.x2*=t,this.y2*=t,this},translate(t,e){return this.x1+=t,this.x2+=t,this.y1+=e,this.y2+=e,this},rotate(t,e,n){const i=this.rotatedPoints(t,e,n);return this.clear().add(i[0],i[1]).add(i[2],i[3]).add(i[4],i[5]).add(i[6],i[7])},rotatedPoints(t,e,n){var{x1:i,y1:r,x2:s,y2:o}=this,a=Math.cos(t),l=Math.sin(t),c=e-e*a+n*l,h=n-e*l-n*a;return[a*i-l*r+c,l*i+a*r+h,a*i-l*o+c,l*i+a*o+h,a*s-l*r+c,l*s+a*r+h,a*s-l*o+c,l*s+a*o+h]},union(t){return t.x1<this.x1&&(this.x1=t.x1),t.y1<this.y1&&(this.y1=t.y1),t.x2>this.x2&&(this.x2=t.x2),t.y2>this.y2&&(this.y2=t.y2),this},intersect(t){return t.x1>this.x1&&(this.x1=t.x1),t.y1>this.y1&&(this.y1=t.y1),t.x2<this.x2&&(this.x2=t.x2),t.y2<this.y2&&(this.y2=t.y2),this},encloses(t){return t&&this.x1<=t.x1&&this.x2>=t.x2&&this.y1<=t.y1&&this.y2>=t.y2},alignsWith(t){return t&&(this.x1==t.x1||this.x2==t.x2||this.y1==t.y1||this.y2==t.y2)},intersects(t){return t&&!(this.x2<t.x1||this.x1>t.x2||this.y2<t.y1||this.y1>t.y2)},contains(t,e){return!(t<this.x1||t>this.x2||e<this.y1||e>this.y2)},width(){return this.x2-this.x1},height(){return this.y2-this.y1}},e.inherits(st,rt),ot.prototype={pending(){return this._pending},sanitizeURL(t){var e=this;return at(e),e._loader.sanitize(t,{context:"href"}).then((function(t){return lt(e),t})).catch((function(){return lt(e),null}))},loadImage(t){const n=this,i=r.image();return at(n),n._loader.sanitize(t,{context:"image"}).then((function(t){const r=t.href;if(!r||!i)throw{url:r};const s=new i,o=e.hasOwnProperty(t,"crossOrigin")?t.crossOrigin:"anonymous";return null!=o&&(s.crossOrigin=o),s.onload=()=>lt(n),s.onerror=()=>lt(n),s.src=r,s})).catch((function(t){return lt(n),{complete:!1,width:0,height:0,src:t&&t.url||""}}))},ready(){var t=this;return new Promise((function(e){!function n(i){t.pending()?setTimeout((function(){n(!0)}),10):e(i)}(!1)}))}};const ht=m-1e-8;let ut,dt,ft,pt,gt,vt,yt,mt;const xt=(t,e)=>ut.add(t,e),_t=(t,e)=>xt(dt=t,ft=e),bt=t=>xt(t,ut.y1),kt=t=>xt(ut.x1,t),wt=(t,e)=>gt*t+yt*e,Tt=(t,e)=>vt*t+mt*e,Mt=(t,e)=>xt(wt(t,e),Tt(t,e)),Ct=(t,e)=>_t(wt(t,e),Tt(t,e));function Rt(t,e){return ut=t,e?(pt=e*v,gt=mt=Math.cos(pt),vt=Math.sin(pt),yt=-vt):(gt=mt=1,pt=vt=yt=0),At}const At={beginPath(){},closePath(){},moveTo:Ct,lineTo:Ct,rect(t,e,n,i){pt?(Mt(t+n,e),Mt(t+n,e+i),Mt(t,e+i),Ct(t,e)):(xt(t+n,e+i),_t(t,e))},quadraticCurveTo(t,e,n,i){const r=wt(t,e),s=Tt(t,e),o=wt(n,i),a=Tt(n,i);zt(dt,r,o,bt),zt(ft,s,a,kt),_t(o,a)},bezierCurveTo(t,e,n,i,r,s){const o=wt(t,e),a=Tt(t,e),l=wt(n,i),c=Tt(n,i),h=wt(r,s),u=Tt(r,s);Pt(dt,o,l,h,bt),Pt(ft,a,c,u,kt),_t(h,u)},arc(t,e,n,i,r,s){if(i+=pt,r+=pt,dt=n*Math.cos(r)+t,ft=n*Math.sin(r)+e,Math.abs(r-i)>ht)xt(t-n,e-n),xt(t+n,e+n);else{const o=i=>xt(n*Math.cos(i)+t,n*Math.sin(i)+e);let a,l;if(o(i),o(r),r!==i)if((i%=m)<0&&(i+=m),(r%=m)<0&&(r+=m),r<i&&(s=!s,a=i,i=r,r=a),s)for(r-=m,a=i-i%y,l=0;l<4&&a>r;++l,a-=y)o(a);else for(a=i-i%y+y,l=0;l<4&&a<r;++l,a+=y)o(a)}}};function zt(t,e,n,i){const r=(t-e)/(t+n-2*e);0<r&&r<1&&i(t+(e-t)*r)}function Pt(t,e,n,i,r){const s=i-t+3*e-3*n,o=t+n-2*e,a=t-e;let l,c=0,h=0;Math.abs(s)>1e-14?(l=o*o+a*s,l>=0&&(l=Math.sqrt(l),c=(-o+l)/s,h=(-o-l)/s)):c=.5*a/o,0<c&&c<1&&r(St(c,t,e,n,i)),0<h&&h<1&&r(St(h,t,e,n,i))}function St(t,e,n,i,r){const s=1-t,o=s*s,a=t*t;return o*s*e+3*o*t*n+3*s*a*i+a*t*r}var Lt=(Lt=r.canvas(1,1))?Lt.getContext("2d"):null;const Ot=new it;function Nt(t){return function(e,n){if(!Lt)return!0;t(Lt,e),Ot.clear().union(e.bounds).intersect(n).round();const{x1:i,y1:r,x2:s,y2:o}=Ot;for(let t=r;t<=o;++t)for(let e=i;e<=s;++e)if(Lt.isPointInPath(e,t))return!0;return!1}}function qt(t,e){return e.contains(t.x||0,t.y||0)}function Dt(t,e){const n=t.x||0,i=t.y||0,r=t.width||0,s=t.height||0;return e.intersects(Ot.set(n,i,n+r,i+s))}function Et(t,e){const n=t.x||0,i=t.y||0;return It(e,n,i,null!=t.x2?t.x2:n,null!=t.y2?t.y2:i)}function It(t,e,n,i,r){const{x1:s,y1:o,x2:a,y2:l}=t,c=i-e,h=r-n;let u,d,f,p,g=0,v=1;for(p=0;p<4;++p){if(0===p&&(u=-c,d=-(s-e)),1===p&&(u=c,d=a-e),2===p&&(u=-h,d=-(o-n)),3===p&&(u=h,d=l-n),Math.abs(u)<1e-10&&d<0)return!1;if(f=d/u,u<0){if(f>v)return!1;f>g&&(g=f)}else if(u>0){if(f<g)return!1;f<v&&(v=f)}}return!0}function Vt(t,e){t.globalCompositeOperation=e.blend||"source-over"}function Bt(t,e){return null==t?e:t}function $t(t,e){const n=e.length;for(let i=0;i<n;++i)t.addColorStop(e[i].offset,e[i].color);return t}function Ht(t,e,n){return l(n)?function(t,e,n){const i=n.width(),s=n.height();let o;if("radial"===e.gradient)o=t.createRadialGradient(n.x1+Bt(e.x1,.5)*i,n.y1+Bt(e.y1,.5)*s,Math.max(i,s)*Bt(e.r1,0),n.x1+Bt(e.x2,.5)*i,n.y1+Bt(e.y2,.5)*s,Math.max(i,s)*Bt(e.r2,.5));else{const a=Bt(e.x1,0),l=Bt(e.y1,0),c=Bt(e.x2,1),h=Bt(e.y2,0);if(a!==c&&l!==h&&i!==s){const n=r.canvas(Math.ceil(i),Math.ceil(s)),o=n.getContext("2d");return o.scale(i,s),o.fillStyle=$t(o.createLinearGradient(a,l,c,h),e.stops),o.fillRect(0,0,i,s),t.createPattern(n,"no-repeat")}o=t.createLinearGradient(n.x1+a*i,n.y1+l*s,n.x1+c*i,n.y1+h*s)}return $t(o,e.stops)}(t,n,e.bounds):n}function jt(t,e,n){return(n*=null==e.fillOpacity?1:e.fillOpacity)>0&&(t.globalAlpha=n,t.fillStyle=Ht(t,e,e.fill),!0)}var Gt=[];function Wt(t,e,n){var i=null!=(i=e.strokeWidth)?i:1;return!(i<=0)&&((n*=null==e.strokeOpacity?1:e.strokeOpacity)>0&&(t.globalAlpha=n,t.strokeStyle=Ht(t,e,e.stroke),t.lineWidth=i,t.lineCap=e.strokeCap||"butt",t.lineJoin=e.strokeJoin||"miter",t.miterLimit=e.strokeMiterLimit||10,t.setLineDash&&(t.setLineDash(e.strokeDash||Gt),t.lineDashOffset=e.strokeDashOffset||0),!0))}function Xt(t,e){return t.zindex-e.zindex||t.index-e.index}function Ut(t){if(!t.zdirty)return t.zitems;var e,n,i,r=t.items,s=[];for(n=0,i=r.length;n<i;++n)(e=r[n]).index=n,e.zindex&&s.push(e);return t.zdirty=!1,t.zitems=s.sort(Xt)}function Ft(t,e){var n,i,r=t.items;if(r&&r.length){var s=Ut(t);if(s&&s.length){for(n=0,i=r.length;n<i;++n)r[n].zindex||e(r[n]);r=s}for(n=0,i=r.length;n<i;++n)e(r[n])}}function Yt(t,e){var n,i,r=t.items;if(!r||!r.length)return null;var s=Ut(t);for(s&&s.length&&(r=s),i=r.length;--i>=0;)if(n=e(r[i]))return n;if(r===s)for(i=(r=t.items).length;--i>=0;)if(!r[i].zindex&&(n=e(r[i])))return n;return null}function Jt(t){return function(e,n,i){Ft(n,(function(n){i&&!i.intersects(n.bounds)||Zt(t,e,n,n)}))}}function Qt(t){return function(e,n,i){!n.items.length||i&&!i.intersects(n.bounds)||Zt(t,e,n.items[0],n.items)}}function Zt(t,e,n,i){var r=null==n.opacity?1:n.opacity;0!==r&&(t(e,i)||(Vt(e,n),n.fill&&jt(e,n,r)&&e.fill(),n.stroke&&Wt(e,n,r)&&e.stroke()))}function Kt(t){return t=t||e.truthy,function(e,n,i,r,s,o){return i*=e.pixelRatio,r*=e.pixelRatio,Yt(n,(function(n){var a=n.bounds;if((!a||a.contains(s,o))&&a)return t(e,n,i,r,s,o)?n:void 0}))}}function te(t,e){return function(n,i,r,s){var o,a,l=Array.isArray(i)?i[0]:i,c=null==e?l.fill:e,h=l.stroke&&n.isPointInStroke;return h&&(o=l.strokeWidth,a=l.strokeCap,n.lineWidth=null!=o?o:1,n.lineCap=null!=a?a:"butt"),!t(n,i)&&(c&&n.isPointInPath(r,s)||h&&n.isPointInStroke(r,s))}}function ee(t){return Kt(te(t))}function ne(t,e){return"translate("+t+","+e+")"}function ie(t){return"rotate("+t+")"}function re(t){return ne(t.x||0,t.y||0)}function se(t,e,n){function i(t,n){var i=n.x||0,r=n.y||0,s=n.angle||0;t.translate(i,r),s&&t.rotate(s*=v),t.beginPath(),e(t,n),s&&t.rotate(-s),t.translate(-i,-r)}return{type:t,tag:"path",nested:!1,attr:function(t,n){t("transform",function(t){return ne(t.x||0,t.y||0)+(t.angle?" "+ie(t.angle):"")}(n)),t("d",e(null,n))},bound:function(t,n){return e(Rt(t,n.angle),n),ct(t,n).translate(n.x||0,n.y||0)},draw:Jt(i),pick:ee(i),isect:n||Nt(i)}}var oe=se("arc",(function(t,e){return W.context(t)(e)}));function ae(t,e,n){function i(t,n){t.beginPath(),e(t,n)}var r=te(i);return{type:t,tag:"path",nested:!0,attr:function(t,n){var i=n.mark.items;i.length&&t("d",e(null,i))},bound:function(t,n){var i=n.items;return 0===i.length?t:(e(Rt(t),i),ct(t,i[0]))},draw:Qt(i),pick:function(t,e,n,i,s,o){var a=e.items,l=e.bounds;return!a||!a.length||l&&!l.contains(s,o)?null:(n*=t.pixelRatio,i*=t.pixelRatio,r(t,a,n,i)?a[0]:null)},isect:qt,tip:n}}var le=ae("area",(function(t,e){const n=e[0],i=n.interpolate||"linear";return("horizontal"===n.orient?U:X).curve(d(i,n.orient,n.tension)).context(t)(e)}),(function(t,e){for(var n,i,r="horizontal"===t[0].orient?e[1]:e[0],s="horizontal"===t[0].orient?"y":"x",o=t.length,a=1/0;--o>=0;)!1!==t[o].defined&&(i=Math.abs(t[o][s]-r))<a&&(a=i,n=t[o]);return n}));function ce(t,e){t.beginPath(),Z(e)?K(t,e,0,0):t.rect(0,0,e.width||0,e.height||0),t.clip()}function he(t){const e=Bt(t.strokeWidth,1);return null!=t.strokeOffset?t.strokeOffset:t.stroke&&e>.5&&e<1.5?.5-Math.abs(e-1):0}function ue(t,e){const n=he(e);t("d",K(null,e,n,n))}function de(t,e,n,i){const r=he(e);t.beginPath(),K(t,e,(n||0)+r,(i||0)+r)}const fe=te(de),pe=te(de,!1),ge=te(de,!0);var ve={type:"group",tag:"g",nested:!1,attr:function(t,e){t("transform",re(e))},bound:function(t,e){if(!e.clip&&e.items){const n=e.items,i=n.length;for(let e=0;e<i;++e)t.union(n[e].bounds)}return(e.clip||e.width||e.height)&&!e.noBound&&t.add(0,0).add(e.width||0,e.height||0),ct(t,e),t.translate(e.x||0,e.y||0)},draw:function(t,e,n){Ft(e,e=>{const i=e.x||0,r=e.y||0,s=e.strokeForeground,o=null==e.opacity?1:e.opacity;(e.stroke||e.fill)&&o&&(de(t,e,i,r),Vt(t,e),e.fill&&jt(t,e,o)&&t.fill(),e.stroke&&!s&&Wt(t,e,o)&&t.stroke()),t.save(),t.translate(i,r),e.clip&&ce(t,e),n&&n.translate(-i,-r),Ft(e,e=>{this.draw(t,e,n)}),n&&n.translate(i,r),t.restore(),s&&e.stroke&&o&&(de(t,e,i,r),Vt(t,e),Wt(t,e,o)&&t.stroke())})},pick:function(t,e,n,i,r,s){if(e.bounds&&!e.bounds.contains(r,s)||!e.items)return null;const o=n*t.pixelRatio,a=i*t.pixelRatio;return Yt(e,l=>{let c,h,u,d,f,p,g,v,y;if(v=l.bounds,(!v||v.contains(r,s))&&(d=l.x||0,f=l.y||0,p=d+(l.width||0),g=f+(l.height||0),y=l.clip,!y||!(r<d||r>p||s<f||s>g)))return t.save(),t.translate(d,f),d=r-d,f=s-f,y&&Z(l)&&!ge(t,l,o,a)?(t.restore(),null):(h=l.strokeForeground,u=!1!==e.interactive,u&&h&&l.stroke&&pe(t,l,o,a)?(t.restore(),l):(c=Yt(l,t=>function(t,e,n){return(!1!==t.interactive||"group"===t.marktype)&&t.bounds&&t.bounds.contains(e,n)}(t,d,f)?this.pick(t,n,i,d,f):null),!c&&u&&(l.fill||!h&&l.stroke)&&fe(t,l,o,a)&&(c=l),t.restore(),c||null))})},isect:Dt,content:function(t,e,n){t("clip-path",e.clip?nt(n,e,e):null)},background:function(t,e){t("class","background"),t("aria-hidden",!0),ue(t,e)},foreground:function(t,e){t("class","foreground"),t("aria-hidden",!0),e.strokeForeground?ue(t,e):t("d","")}},ye={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1"};function me(t,e){var n=t.image;return(!n||t.url&&t.url!==n.url)&&(n={complete:!1,width:0,height:0},e.loadImage(t.url).then(e=>{t.image=e,t.image.url=t.url})),n}function xe(t,e){return null!=t.width?t.width:e&&e.width?!1!==t.aspect&&t.height?t.height*e.width/e.height:e.width:0}function _e(t,e){return null!=t.height?t.height:e&&e.height?!1!==t.aspect&&t.width?t.width*e.height/e.width:e.height:0}function be(t,e){return"center"===t?e/2:"right"===t?e:0}function ke(t,e){return"middle"===t?e/2:"bottom"===t?e:0}var we={type:"image",tag:"image",nested:!1,attr:function(t,e,n){const i=me(e,n),r=xe(e,i),s=_e(e,i),o=(e.x||0)-be(e.align,r),a=(e.y||0)-ke(e.baseline,s);t("href",!i.src&&i.toDataURL?i.toDataURL():i.src||"",ye["xmlns:xlink"],"xlink:href"),t("transform",ne(o,a)),t("width",r),t("height",s),t("preserveAspectRatio",!1===e.aspect?"none":"xMidYMid")},bound:function(t,e){const n=e.image,i=xe(e,n),r=_e(e,n),s=(e.x||0)-be(e.align,i),o=(e.y||0)-ke(e.baseline,r);return t.set(s,o,s+i,o+r)},draw:function(t,e,n){Ft(e,e=>{if(n&&!n.intersects(e.bounds))return;let i,r,s,o,a=me(e,this),l=xe(e,a),c=_e(e,a),h=(e.x||0)-be(e.align,l),u=(e.y||0)-ke(e.baseline,c);!1!==e.aspect&&(r=a.width/a.height,s=e.width/e.height,r==r&&s==s&&r!==s&&(s<r?(o=l/r,u+=(c-o)/2,c=o):(o=c*r,h+=(l-o)/2,l=o))),(a.complete||a.toDataURL)&&(Vt(t,e),t.globalAlpha=null!=(i=e.opacity)?i:1,t.imageSmoothingEnabled=!1!==e.smooth,t.drawImage(a,h,u,l,c))})},pick:Kt(),isect:e.truthy,get:me,xOffset:be,yOffset:ke},Te=ae("line",(function(t,e){const n=e[0],i=n.interpolate||"linear";return F.curve(d(i,n.orient,n.tension)).context(t)(e)}),(function(t,e){for(var n,i,r=Math.pow(t[0].strokeWidth||1,2),s=t.length;--s>=0;)if(!1!==t[s].defined&&(n=t[s].x-e[0])*n+(i=t[s].y-e[1])*i<r)return t[s];return null}));function Me(t,e){var n=e.path;if(null==n)return!0;var i=e.x||0,r=e.y||0,s=e.scaleX||1,o=e.scaleY||1,a=(e.angle||0)*v,l=e.pathCache;l&&l.path===n||((e.pathCache=l=g(n)).path=n),a&&t.rotate&&t.translate?(t.translate(i,r),t.rotate(a),C(t,l,0,0,s,o),t.rotate(-a),t.translate(-i,-r)):C(t,l,i,r,s,o)}var Ce={type:"path",tag:"path",nested:!1,attr:function(t,e){var n=e.scaleX||1,i=e.scaleY||1;1===n&&1===i||t("vector-effect","non-scaling-stroke"),t("transform",function(t){return ne(t.x||0,t.y||0)+(t.angle?" "+ie(t.angle):"")+(t.scaleX||t.scaleY?" "+(e=t.scaleX||1,n=t.scaleY||1,"scale("+e+","+n+")"):"");var e,n}(e)),t("d",e.path)},bound:function(t,e){return Me(Rt(t,e.angle),e)?t.set(0,0,0,0):ct(t,e,!0)},draw:Jt(Me),pick:ee(Me),isect:Nt(Me)};function Re(t,e){t.beginPath(),K(t,e)}var Ae={type:"rect",tag:"path",nested:!1,attr:function(t,e){t("d",K(null,e))},bound:function(t,e){var n,i;return ct(t.set(n=e.x||0,i=e.y||0,n+e.width||0,i+e.height||0),e)},draw:Jt(Re),pick:ee(Re),isect:Dt};function ze(t,e,n){var i,r,s,o;return!(!e.stroke||!Wt(t,e,n))&&(i=e.x||0,r=e.y||0,s=null!=e.x2?e.x2:i,o=null!=e.y2?e.y2:r,t.beginPath(),t.moveTo(i,r),t.lineTo(s,o),!0)}var Pe={type:"rule",tag:"line",nested:!1,attr:function(t,e){t("transform",re(e)),t("x2",null!=e.x2?e.x2-(e.x||0):0),t("y2",null!=e.y2?e.y2-(e.y||0):0)},bound:function(t,e){var n,i;return ct(t.set(n=e.x||0,i=e.y||0,null!=e.x2?e.x2:n,null!=e.y2?e.y2:i),e)},draw:function(t,e,n){Ft(e,(function(e){if(!n||n.intersects(e.bounds)){var i=null==e.opacity?1:e.opacity;i&&ze(t,e,i)&&(Vt(t,e),t.stroke())}}))},pick:Kt((function(t,e,n,i){return!!t.isPointInStroke&&(ze(t,e,1)&&t.isPointInStroke(n,i))})),isect:Et},Se=se("shape",(function(t,e){return(e.mark.shape||e.shape).context(t)(e)})),Le=se("symbol",(function(t,e){return J.context(t)(e)}),qt);const Oe=e.lruCache();var Ne={height:Be,measureWidth:Ie,estimateWidth:De,width:De,canvas:qe};function qe(t){Ne.width=t&&Lt?Ie:De}function De(t,e){return Ee(je(t,e),Be(t))}function Ee(t,e){return~~(.8*t.length*e)}function Ie(t,e){return Be(t)<=0||!(e=je(t,e))?0:Ve(e,We(t))}function Ve(t,e){const n=`(${e}) ${t}`;let i=Oe.get(n);return void 0===i&&(Lt.font=e,i=Lt.measureText(t).width,Oe.set(n,i)),i}function Be(t){return null!=t.fontSize?+t.fontSize||0:11}function $e(t){return null!=t.lineHeight?t.lineHeight:Be(t)+2}function He(t){return n=t.lineBreak&&t.text&&!e.isArray(t.text)?t.text.split(t.lineBreak):t.text,e.isArray(n)?n.length>1?n:n[0]:n;var n}function je(t,e){const n=null==e?"":(e+"").trim();return t.limit>0&&n.length?function(t,e){var n=+t.limit,i=function(t){if(Ne.width===Ie){const e=We(t);return t=>Ve(t,e)}{const e=Be(t);return t=>Ee(t,e)}}(t);if(i(e)<n)return e;var r,s=t.ellipsis||"…",o="rtl"===t.dir,a=0,l=e.length;if(n-=i(s),o){for(;a<l;)r=a+l>>>1,i(e.slice(r))>n?a=r+1:l=r;return s+e.slice(a)}for(;a<l;)r=1+(a+l>>>1),i(e.slice(0,r))<n?a=r:l=r-1;return e.slice(0,a)+s}(t,n):n}function Ge(t,e){var n=t.font;return(e&&n?String(n).replace(/"/g,"'"):n)||"sans-serif"}function We(t,e){return(t.fontStyle?t.fontStyle+" ":"")+(t.fontVariant?t.fontVariant+" ":"")+(t.fontWeight?t.fontWeight+" ":"")+Be(t)+"px "+Ge(t,e)}function Xe(t){var e=t.baseline,n=Be(t);return Math.round("top"===e?.79*n:"middle"===e?.3*n:"bottom"===e?-.21*n:"line-top"===e?.29*n+.5*$e(t):"line-bottom"===e?.29*n-.5*$e(t):0)}qe(!0);var Ue={left:"start",center:"middle",right:"end"},Fe=new it;function Ye(t){var e,n=t.x||0,i=t.y||0,r=t.radius||0;return r&&(e=(t.theta||0)-y,n+=r*Math.cos(e),i+=r*Math.sin(e)),Fe.x1=n,Fe.y1=i,Fe}function Je(t,n,i){var r,s=Ne.height(n),o=n.align,a=Ye(n),l=a.x1,c=a.y1,h=n.dx||0,u=(n.dy||0)+Xe(n)-Math.round(.8*s),d=He(n);if(e.isArray(d)?(s+=$e(n)*(d.length-1),r=d.reduce((t,e)=>Math.max(t,Ne.width(n,e)),0)):r=Ne.width(n,d),"center"===o?h-=r/2:"right"===o&&(h-=r),t.set(h+=l,u+=c,h+r,u+s),n.angle&&!i)t.rotate(n.angle*v,l,c);else if(2===i)return t.rotatedPoints(n.angle*v,l,c);return t}var Qe={arc:oe,area:le,group:ve,image:we,line:Te,path:Ce,rect:Ae,rule:Pe,shape:Se,symbol:Le,text:{type:"text",tag:"text",nested:!1,attr:function(t,e){var n,i=e.dx||0,r=(e.dy||0)+Xe(e),s=Ye(e),o=s.x1,a=s.y1,l=e.angle||0;t("text-anchor",Ue[e.align]||"start"),l?(n=ne(o,a)+" "+ie(l),(i||r)&&(n+=" "+ne(i,r))):n=ne(o+i,a+r),t("transform",n)},bound:Je,draw:function(t,n,i){Ft(n,(function(n){var r,s,o,a,l,c,h,u=null==n.opacity?1:n.opacity;if(!(i&&!i.intersects(n.bounds)||0===u||n.fontSize<=0||null==n.text||0===n.text.length)){if(t.font=We(n),t.textAlign=n.align||"left",s=(r=Ye(n)).x1,o=r.y1,n.angle&&(t.save(),t.translate(s,o),t.rotate(n.angle*v),s=o=0),s+=n.dx||0,o+=(n.dy||0)+Xe(n),c=He(n),Vt(t,n),e.isArray(c))for(l=$e(n),a=0;a<c.length;++a)h=je(n,c[a]),n.fill&&jt(t,n,u)&&t.fillText(h,s,o),n.stroke&&Wt(t,n,u)&&t.strokeText(h,s,o),o+=l;else h=je(n,c),n.fill&&jt(t,n,u)&&t.fillText(h,s,o),n.stroke&&Wt(t,n,u)&&t.strokeText(h,s,o);n.angle&&t.restore()}}))},pick:Kt((function(t,e,n,i,r,s){if(e.fontSize<=0)return!1;if(!e.angle)return!0;var o=Ye(e),a=o.x1,l=o.y1,c=Je(Fe,e,1),h=-e.angle*v,u=Math.cos(h),d=Math.sin(h),f=u*r-d*s+(a-u*a+d*l),p=d*r+u*s+(l-d*a-u*l);return c.contains(f,p)})),isect:function(t,e){var n=Je(Fe,t,2);return It(e,n[0],n[1],n[2],n[3])||It(e,n[0],n[1],n[4],n[5])||It(e,n[4],n[5],n[6],n[7])||It(e,n[2],n[3],n[6],n[7])}},trail:ae("trail",(function(t,e){return Q.context(t)(e)}),(function(t,e){for(var n,i,r=t.length;--r>=0;)if(!1!==t[r].defined&&(n=t[r].x-e[0])*n+(i=t[r].y-e[1])*i<(n=t[r].size||1)*n)return t[r];return null}))};function Ze(t,e,n){var i=Qe[t.mark.marktype],r=e||i.bound;return i.nested&&(t=t.mark),r(t.bounds||(t.bounds=new it),t,n)}var Ke={mark:null};function tn(t,e,n){var i,r,s,o,a=Qe[t.marktype],l=a.bound,c=t.items,h=c&&c.length;if(a.nested)return h?s=c[0]:(Ke.mark=t,s=Ke),o=Ze(s,l,n),e=e&&e.union(o)||o;if(e=e||t.bounds&&t.bounds.clear()||new it,h)for(i=0,r=c.length;i<r;++i)e.union(Ze(c[i],l,n));return t.bounds=e}var en=["marktype","name","role","interactive","clip","items","zindex","x","y","width","height","align","baseline","fill","fillOpacity","opacity","blend","stroke","strokeOpacity","strokeWidth","strokeCap","strokeDash","strokeDashOffset","strokeForeground","strokeOffset","startAngle","endAngle","innerRadius","outerRadius","cornerRadius","padAngle","cornerRadiusTopLeft","cornerRadiusTopRight","cornerRadiusBottomLeft","cornerRadiusBottomRight","interpolate","tension","orient","defined","url","aspect","smooth","path","scaleX","scaleY","x2","y2","size","shape","text","angle","theta","radius","dir","dx","dy","ellipsis","limit","lineBreak","lineHeight","font","fontSize","fontWeight","fontStyle","fontVariant","description","aria","ariaRole","ariaRoleDescription"];function nn(t,e){return JSON.stringify(t,en,e)}function rn(t){return function t(e){var n,i,r,s=e.marktype,o=e.items;if(o)for(i=0,r=o.length;i<r;++i)n=s?"mark":"group",o[i][n]=e,o[i].zindex&&(o[i][n].zdirty=!0),"group"===(s||n)&&t(o[i]);s&&tn(e);return e}("string"==typeof t?JSON.parse(t):t)}function sn(t){arguments.length?this.root=rn(t):(this.root=on({marktype:"group",name:"root",role:"frame"}),this.root.items=[new st(this.root)])}function on(t,e){const n={bounds:new it,clip:!!t.clip,group:e,interactive:!1!==t.interactive,items:[],marktype:t.marktype,name:t.name||void 0,role:t.role||void 0,zindex:t.zindex||0};return null!=t.aria&&(n.aria=t.aria),t.description&&(n.description=t.description),n}function an(t,e,n){return!t&&"undefined"!=typeof document&&document.createElement&&(t=document),t?n?t.createElementNS(n,e):t.createElement(e):null}function ln(t,e){e=e.toLowerCase();for(var n=t.childNodes,i=0,r=n.length;i<r;++i)if(n[i].tagName.toLowerCase()===e)return n[i]}function cn(t,e,n,i){var r,s=t.childNodes[e];return s&&s.tagName.toLowerCase()===n.toLowerCase()||(r=s||null,s=an(t.ownerDocument,n,i),t.insertBefore(s,r)),s}function hn(t,e){for(var n=t.childNodes,i=n.length;i>e;)t.removeChild(n[--i]);return t}function un(t){return"mark-"+t.marktype+(t.role?" role-"+t.role:"")+(t.name?" "+t.name:"")}function dn(t,e){var n=e.getBoundingClientRect();return[t.clientX-n.left-(e.clientLeft||0),t.clientY-n.top-(e.clientTop||0)]}function fn(t,e){this._active=null,this._handlers={},this._loader=t||s.loader(),this._tooltip=e||pn}function pn(t,e,n,i){t.element().setAttribute("title",i||"")}function gn(t){this._el=null,this._bgcolor=null,this._loader=new ot(t)}sn.prototype={toJSON(t){return nn(this.root,t||0)},mark(t,e,n){var i=on(t,e=e||this.root.items[0]);return e.items[n]=i,i.zindex&&(i.group.zdirty=!0),i}},fn.prototype={initialize(t,e,n){return this._el=t,this._obj=n||null,this.origin(e)},element(){return this._el},canvas(){return this._el&&this._el.firstChild},origin(t){return arguments.length?(this._origin=t||[0,0],this):this._origin.slice()},scene(t){return arguments.length?(this._scene=t,this):this._scene},on(){},off(){},_handlerIndex(t,e,n){for(let i=t?t.length:0;--i>=0;)if(t[i].type===e&&(!n||t[i].handler===n))return i;return-1},handlers(t){const e=this._handlers,n=[];if(t)n.push.apply(n,e[this.eventName(t)]);else for(const t in e)n.push.apply(n,e[t]);return n},eventName(t){const e=t.indexOf(".");return e<0?t:t.slice(0,e)},handleHref(t,e,n){this._loader.sanitize(n,{context:"href"}).then(e=>{const n=new MouseEvent(t.type,t),i=an(null,"a");for(const t in e)i.setAttribute(t,e[t]);i.dispatchEvent(n)}).catch((function(){}))},handleTooltip(t,e,n){if(e&&null!=e.tooltip){e=function(t,e,n,i){var r,s,o=t&&t.mark;if(o&&(r=Qe[o.marktype]).tip){for((s=dn(e,n))[0]-=i[0],s[1]-=i[1];t=t.mark.group;)s[0]-=t.x||0,s[1]-=t.y||0;t=r.tip(o.items,s)}return t}(e,t,this.canvas(),this._origin);const i=n&&e&&e.tooltip||null;this._tooltip.call(this._obj,this,t,e,i)}},getItemBoundingClientRect(t){const e=this.canvas();if(!e)return;const n=e.getBoundingClientRect(),i=this._origin,r=t.bounds,s=r.width(),o=r.height();let a=r.x1+i[0]+n.left,l=r.y1+i[1]+n.top;for(;t.mark&&(t=t.mark.group);)a+=t.x||0,l+=t.y||0;return{x:a,y:l,width:s,height:o,left:a,top:l,right:a+s,bottom:l+o}}},gn.prototype={initialize(t,e,n,i,r){return this._el=t,this.resize(e,n,i,r)},element(){return this._el},canvas(){return this._el&&this._el.firstChild},background(t){return 0===arguments.length?this._bgcolor:(this._bgcolor=t,this)},resize(t,e,n,i){return this._width=t,this._height=e,this._origin=n||[0,0],this._scale=i||1,this},dirty(){},render(t){var e=this;return e._call=function(){e._render(t)},e._call(),e._call=null,e},_render(){},renderAsync(t){var e=this.render(t);return this._ready?this._ready.then((function(){return e})):Promise.resolve(e)},_load(t,e){var n=this,i=n._loader[t](e);if(!n._ready){var r=n._call;n._ready=n._loader.ready().then((function(t){t&&r(),n._ready=null}))}return i},sanitizeURL(t){return this._load("sanitizeURL",t)},loadImage(t){return this._load("loadImage",t)}};const vn="dragleave",yn="mousedown",mn="mousemove",xn="mouseout",_n="click",bn=["keydown","keypress","keyup","dragenter",vn,"dragover",yn,"mouseup",mn,xn,"mouseover",_n,"dblclick","wheel","mousewheel","touchstart","touchmove","touchend"],kn=mn,wn=xn,Tn=_n;function Mn(t,e){fn.call(this,t,e),this._down=null,this._touch=null,this._first=!0,this._events={}}function Cn(t,e){(t=>"touchstart"===t||"touchmove"===t||"touchend"===t?["touchstart","touchmove","touchend"]:[t])(e).forEach(e=>function(t,e){const n=t.canvas();n&&!t._events[e]&&(t._events[e]=1,n.addEventListener(e,t[e]?n=>t[e](n):n=>t.fire(e,n)))}(t,e))}function Rn(t,e,n){return function(i){const r=this._active,s=this.pickEvent(i);s===r||(r&&r.exit||this.fire(n,i),this._active=s,this.fire(e,i)),this.fire(t,i)}}function An(t){return function(e){this.fire(t,e),this._active=null}}e.inherits(Mn,fn,{initialize(t,e,n){return this._canvas=t&&ln(t,"canvas"),[_n,yn,mn,xn,vn].forEach(t=>Cn(this,t)),fn.prototype.initialize.call(this,t,e,n)},canvas(){return this._canvas},context(){return this._canvas.getContext("2d")},events:bn,DOMMouseScroll(t){this.fire("mousewheel",t)},mousemove:Rn(mn,"mouseover",xn),dragover:Rn("dragover","dragenter",vn),mouseout:An(xn),dragleave:An(vn),mousedown(t){this._down=this._active,this.fire(yn,t)},click(t){this._down===this._active&&(this.fire(_n,t),this._down=null)},touchstart(t){this._touch=this.pickEvent(t.changedTouches[0]),this._first&&(this._active=this._touch,this._first=!1),this.fire("touchstart",t,!0)},touchmove(t){this.fire("touchmove",t,!0)},touchend(t){this.fire("touchend",t,!0),this._touch=null},fire(t,e,n){const i=n?this._touch:this._active,r=this._handlers[t];if(e.vegaType=t,t===Tn&&i&&i.href?this.handleHref(e,i,i.href):t!==kn&&t!==wn||this.handleTooltip(e,i,t!==wn),r)for(let t=0,n=r.length;t<n;++t)r[t].handler.call(this._obj,e,i)},on(t,e){const n=this.eventName(t),i=this._handlers;return this._handlerIndex(i[n],t,e)<0&&(Cn(this,t),(i[n]||(i[n]=[])).push({type:t,handler:e})),this},off(t,e){const n=this.eventName(t),i=this._handlers[n],r=this._handlerIndex(i,t,e);return r>=0&&i.splice(r,1),this},pickEvent(t){const e=dn(t,this._canvas),n=this._origin;return this.pick(this._scene,e[0],e[1],e[0]-n[0],e[1]-n[1])},pick(t,e,n,i,r){const s=this.context();return Qe[t.marktype].pick.call(this,s,t,e,n,i,r)}});var zn="undefined"!=typeof window&&window.devicePixelRatio||1;function Pn(t){gn.call(this,t),this._options={},this._redraw=!1,this._dirty=new it,this._tempb=new it}const Sn=gn.prototype;function Ln(t,e){fn.call(this,t,e);const n=this;n._hrefHandler=On(n,(t,e)=>{e&&e.href&&n.handleHref(t,e,e.href)}),n._tooltipHandler=On(n,(t,e)=>{n.handleTooltip(t,e,t.type!==wn)})}e.inherits(Pn,gn,{initialize(t,e,n,i,s,o){return this._options=o||{},this._canvas=this._options.externalContext?null:r.canvas(1,1,this._options.type),t&&this._canvas&&(hn(t,0).appendChild(this._canvas),this._canvas.setAttribute("class","marks")),Sn.initialize.call(this,t,e,n,i,s)},resize(t,n,i,r){if(Sn.resize.call(this,t,n,i,r),this._canvas)!function(t,e,n,i,r,s){const o="undefined"!=typeof HTMLElement&&t instanceof HTMLElement&&null!=t.parentNode,a=t.getContext("2d"),l=o?zn:r;t.width=e*l,t.height=n*l;for(const t in s)a[t]=s[t];o&&1!==l&&(t.style.width=e+"px",t.style.height=n+"px"),a.pixelRatio=l,a.setTransform(l,0,0,l,l*i[0],l*i[1])}(this._canvas,this._width,this._height,this._origin,this._scale,this._options.context);else{const t=this._options.externalContext;t||e.error("CanvasRenderer is missing a valid canvas or context"),t.scale(this._scale,this._scale),t.translate(this._origin[0],this._origin[1])}return this._redraw=!0,this},canvas(){return this._canvas},context(){return this._options.externalContext||(this._canvas?this._canvas.getContext("2d"):null)},dirty(t){let e=this._tempb.clear().union(t.bounds),n=t.mark.group;for(;n;)e.translate(n.x||0,n.y||0),n=n.mark.group;this._dirty.union(e)},_render(t){const e=this.context(),n=this._origin,i=this._width,r=this._height,s=this._dirty,o=(a=n,l=i,c=r,(new it).set(0,0,l,c).translate(-a[0],-a[1]));var a,l,c;e.save();const h=this._redraw||s.empty()?(this._redraw=!1,o.expand(1)):function(t,e,n){return e.expand(1).round(),t.pixelRatio%1&&e.scale(t.pixelRatio).round().scale(1/t.pixelRatio),e.translate(-n[0]%1,-n[1]%1),t.beginPath(),t.rect(e.x1,e.y1,e.width(),e.height()),t.clip(),e}(e,o.intersect(s),n);return this.clear(-n[0],-n[1],i,r),this.draw(e,t,h),e.restore(),s.clear(),this},draw(t,n,i){const r=Qe[n.marktype];n.clip&&function(t,n){var i=n.clip;t.save(),e.isFunction(i)?(t.beginPath(),i(t),t.clip()):ce(t,n.group)}(t,n),r.draw.call(this,t,n,i),n.clip&&t.restore()},clear(t,e,n,i){const r=this._options,s=this.context();"pdf"===r.type||r.externalContext||s.clearRect(t,e,n,i),null!=this._bgcolor&&(s.fillStyle=this._bgcolor,s.fillRect(t,e,n,i))}});const On=(t,e)=>n=>{let i=n.target.__data__;i=Array.isArray(i)?i[0]:i,n.vegaType=n.type,e.call(t._obj,n,i)};e.inherits(Ln,fn,{initialize(t,e,n){let i=this._svg;return i&&(i.removeEventListener(Tn,this._hrefHandler),i.removeEventListener(kn,this._tooltipHandler),i.removeEventListener(wn,this._tooltipHandler)),this._svg=i=t&&ln(t,"svg"),i&&(i.addEventListener(Tn,this._hrefHandler),i.addEventListener(kn,this._tooltipHandler),i.addEventListener(wn,this._tooltipHandler)),fn.prototype.initialize.call(this,t,e,n)},canvas(){return this._svg},on(t,e){const n=this.eventName(t),i=this._handlers;if(this._handlerIndex(i[n],t,e)<0){const r={type:t,handler:e,listener:On(this,e)};(i[n]||(i[n]=[])).push(r),this._svg&&this._svg.addEventListener(n,r.listener)}return this},off(t,e){const n=this.eventName(t),i=this._handlers[n],r=this._handlerIndex(i,t,e);return r>=0&&(this._svg&&this._svg.removeEventListener(n,i[r].listener),i.splice(r,1)),this}});const Nn=(t,e,n)=>({role:t,"aria-roledescription":e,"aria-label":n||void 0}),qn=e.toSet(["axis-domain","axis-grid","axis-label","axis-tick","axis-title","legend-band","legend-entry","legend-gradient","legend-label","legend-title","legend-symbol","title"]),Dn={axis:{desc:"axis",caption:function(t){const e=t.datum,n=t.orient,i=e.title?$n(t):null,r=t.context,s=r.scales[e.scale].value,a=r.dataflow.locale(),l=s.type;return("left"===n||"right"===n?"Y":"X")+"-axis"+(i?` titled '${i}'`:"")+` for a ${o.isDiscrete(l)?"discrete":l} scale with `+o.domainCaption(a,s,t)}},legend:{desc:"legend",caption:function(t){const n=t.datum,i=n.title?$n(t):null,r=((n.type||"")+" legend").trim(),s=n.scales,a=Object.keys(s),l=t.context,c=l.scales[s[a[0]]].value,h=l.dataflow.locale();return u=r,(u.length?u[0].toUpperCase()+u.slice(1):u)+(i?` titled '${i}'`:"")+" for "+function(t){return(t=t.map(t=>t+("fill"===t||"stroke"===t?" color":""))).length<2?t[0]:t.slice(0,-1).join(", ")+" and "+e.peek(t)}(a)+" with "+o.domainCaption(h,c,t);var u}},"title-text":{desc:"title",caption:t=>`Title text '${Bn(t)}'`},"title-subtitle":{desc:"subtitle",caption:t=>`Subtitle text '${Bn(t)}'`}},En={ariaRole:"role",ariaRoleDescription:"aria-roledescription",description:"aria-label"};function In(t,e){const n=!1===e.aria;if(t("aria-hidden",n||void 0),n||null==e.description)for(const e in En)t(En[e],void 0);else{const n=e.mark.marktype;t("aria-label",e.description),t("role",e.ariaRole||("group"===n?"graphics-object":"graphics-symbol")),t("aria-roledescription",e.ariaRoleDescription||n+" mark")}}function Vn(t){return!1===t.aria?{"aria-hidden":!0}:qn[t.role]?null:Dn[t.role]?function(t,e){try{const n=t.items[0],i=e.caption||(()=>"");return Nn(e.role||"graphics-symbol",e.desc,n.description||i(n))}catch(t){return null}}(t,Dn[t.role]):function(t){const e=t.marktype,n="group"===e||"text"===e||t.items.some(t=>null!=t.description&&!1!==t.aria);return Nn(n?"graphics-object":"graphics-symbol",e+" mark container",t.description)}(t)}function Bn(t){return e.array(t.text).join(" ")}function $n(t){try{return e.array(e.peek(t.items).items[0].text).join(" ")}catch(t){return null}}const Hn=t=>(t+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");function jn(){let t="",e="",n="";const i=[],r=()=>e=n="",s=(t,n)=>{var i;return null!=n&&(e+=` ${t}="${i=n,Hn(i).replace(/"/g,"&quot;").replace(/\t/g,"&#x9;").replace(/\n/g,"&#xA;").replace(/\r/g,"&#xD;")}"`),o},o={open(a,...l){(s=>{e&&(t+=`${e}>${n}`,r()),i.push(s)})(a),e="<"+a;for(const t of l)for(const e in t)s(e,t[e]);return o},close(){const s=i.pop();return t+=e?e+(n?`>${n}</${s}>`:"/>"):`</${s}>`,r(),o},attr:s,text:t=>(n+=Hn(t),o),toString:()=>t};return o}const Gn=t=>function t(e,n){if(e.open(n.tagName),n.hasAttributes()){const t=n.attributes,i=t.length;for(let n=0;n<i;++n)e.attr(t[n].name,t[n].value)}if(n.hasChildNodes()){const i=n.childNodes,r=i.length;for(let n=0;n<r;n++){const r=i[n];3===r.nodeType?e.text(r.nodeValue):t(e,r)}}return e.close()}(jn(),t)+"";const Wn={fill:"fill",fillOpacity:"fill-opacity",stroke:"stroke",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",strokeCap:"stroke-linecap",strokeJoin:"stroke-linejoin",strokeDash:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeMiterLimit:"stroke-miterlimit",opacity:"opacity",blend:"mix-blend-mode"},Xn={fill:"none","stroke-miterlimit":10},Un=ye.xmlns;function Fn(t){gn.call(this,t),this._dirtyID=0,this._dirty=[],this._svg=null,this._root=null,this._defs=null}const Yn=gn.prototype;function Jn(t,e){for(;t&&t.dirty!==e;t=t.mark.group){if(t.dirty=e,!t.mark||t.mark.dirty===e)return;t.mark.dirty=e}}function Qn(t,e,n){let i,r,s;if("radial"===e.gradient){let i=cn(t,n++,"pattern",Un);si(i,{id:"p_"+e.id,viewBox:"0,0,1,1",width:"100%",height:"100%",preserveAspectRatio:"xMidYMid slice"}),i=cn(i,0,"rect",Un),si(i,{width:1,height:1,fill:`url(${ai()}#${e.id})`}),si(t=cn(t,n++,"radialGradient",Un),{id:e.id,fx:e.x1,fy:e.y1,fr:e.r1,cx:e.x2,cy:e.y2,r:e.r2})}else si(t=cn(t,n++,"linearGradient",Un),{id:e.id,x1:e.x1,x2:e.x2,y1:e.y1,y2:e.y2});for(i=0,r=e.stops.length;i<r;++i)s=cn(t,i,"stop",Un),s.setAttribute("offset",e.stops[i].offset),s.setAttribute("stop-color",e.stops[i].color);return hn(t,i),n}function Zn(t,e,n){let i;return(t=cn(t,n,"clipPath",Un)).setAttribute("id",e.id),e.path?(i=cn(t,0,"path",Un),i.setAttribute("d",e.path)):(i=cn(t,0,"rect",Un),si(i,{x:0,y:0,width:e.width,height:e.height})),hn(t,1),n+1}function Kn(t,e,n,i,r){let s,o=t._svg;if(!o&&(s=e.ownerDocument,o=an(s,i,Un),t._svg=o,t.mark&&(o.__data__=t,o.__values__={fill:"default"},"g"===i))){const e=an(s,"path",Un);o.appendChild(e),e.__data__=t;const n=an(s,"g",Un);o.appendChild(n),n.__data__=t;const i=an(s,"path",Un);o.appendChild(i),i.__data__=t,i.__values__={fill:"default"}}return(o.ownerSVGElement!==r||function(t,e){return t.parentNode&&t.parentNode.childNodes.length>1&&t.previousSibling!=e}(o,n))&&e.insertBefore(o,n?n.nextSibling:e.firstChild),o}e.inherits(Fn,gn,{initialize(t,e,n,i,r){return this._defs={},this._clearDefs(),t&&(this._svg=cn(t,0,"svg",Un),si(this._svg,ye),this._svg.setAttribute("class","marks"),hn(t,1),this._root=cn(this._svg,0,"g",Un),si(this._root,Xn),hn(this._svg,1)),this.background(this._bgcolor),Yn.initialize.call(this,t,e,n,i,r)},background(t){return arguments.length&&this._svg&&this._svg.style.setProperty("background-color",t),Yn.background.apply(this,arguments)},resize(t,e,n,i){return Yn.resize.call(this,t,e,n,i),this._svg&&(si(this._svg,{width:this._width*this._scale,height:this._height*this._scale,viewBox:`0 0 ${this._width} ${this._height}`}),this._root.setAttribute("transform",`translate(${this._origin})`)),this._dirty=[],this},canvas(){return this._svg},svg(){const t=this._svg,e=this._bgcolor;if(!t)return null;let n;e&&(t.removeAttribute("style"),n=cn(t,0,"rect",Un),si(n,{width:this._width,height:this._height,fill:e}));const i=Gn(t);return e&&(t.removeChild(n),this._svg.style.setProperty("background-color",e)),i},_render(t){return this._dirtyCheck()&&(this._dirtyAll&&this._clearDefs(),this.mark(this._root,t),hn(this._root,1)),this.defs(),this._dirty=[],++this._dirtyID,this},dirty(t){t.dirty!==this._dirtyID&&(t.dirty=this._dirtyID,this._dirty.push(t))},isDirty(t){return this._dirtyAll||!t._svg||t.dirty===this._dirtyID},_dirtyCheck(){this._dirtyAll=!0;const t=this._dirty;if(!t.length||!this._dirtyID)return!0;let e,n,i,r,s,o,a,l=++this._dirtyID;for(s=0,o=t.length;s<o;++s)e=t[s],n=e.mark,n.marktype!==i&&(i=n.marktype,r=Qe[i]),n.zdirty&&n.dirty!==l&&(this._dirtyAll=!1,Jn(e,l),n.items.forEach((function(t){t.dirty=l}))),n.zdirty||(e.exit?(r.nested&&n.items.length?(a=n.items[0],a._svg&&this._update(r,a._svg,a)):e._svg&&(a=e._svg.parentNode,a&&a.removeChild(e._svg)),e._svg=null):(e=r.nested?n.items[0]:e,e._update!==l&&(e._svg&&e._svg.ownerSVGElement?this._update(r,e._svg,e):(this._dirtyAll=!1,Jn(e,l)),e._update=l)));return!this._dirtyAll},mark(t,e,n){if(!this.isDirty(e))return e._svg;let i,r=this._svg,s=Qe[e.marktype],o=!1===e.interactive?"none":null,a="g"===s.tag,l=null,c=0;i=Kn(e,t,n,"g",r),i.setAttribute("class",un(e));const h=Vn(e);for(const t in h)oi(i,t,h[t]);a||oi(i,"pointer-events",o),oi(i,"clip-path",e.clip?nt(this,e,e.group):null);const u=t=>{const e=this.isDirty(t),n=Kn(t,i,l,s.tag,r);e&&(this._update(s,n,t),a&&function(t,e,n){e=e.lastChild.previousSibling;let i,r=0;Ft(n,n=>{i=t.mark(e,n,i),++r}),hn(e,1+r)}(this,n,t)),l=n,++c};return s.nested?e.items.length&&u(e.items[0]):Ft(e,u),hn(i,c),i},_update(t,e,n){ti=e,ei=e.__values__,In(ii,n),t.attr(ii,n,this);const i=ni[t.type];i&&i.call(this,t,e,n),ti&&this.style(ti,n)},style(t,e){if(null!=e)for(const n in Wn){let i="font"===n?Ge(e):e[n];if(i===ei[n])continue;const r=Wn[n];null==i?t.removeAttribute(r):(l(i)&&(i=c(i,this._defs.gradient,ai())),t.setAttribute(r,i+"")),ei[n]=i}},defs(){const t=this._svg,e=this._defs;let n=e.el,i=0;for(const r in e.gradient)n||(e.el=n=cn(t,1,"defs",Un)),i=Qn(n,e.gradient[r],i);for(const r in e.clipping)n||(e.el=n=cn(t,1,"defs",Un)),i=Zn(n,e.clipping[r],i);n&&(0===i?(t.removeChild(n),e.el=null):hn(n,i))},_clearDefs(){const t=this._defs;t.gradient={},t.clipping={}}});let ti=null,ei=null;const ni={group(t,e,n){const i=ti=e.childNodes[2];ei=i.__values__,t.foreground(ii,n,this),ei=e.__values__,ti=e.childNodes[1],t.content(ii,n,this);const r=ti=e.childNodes[0];t.background(ii,n,this);const s=!1===n.mark.interactive?"none":null;if(s!==ei.events&&(oi(i,"pointer-events",s),oi(r,"pointer-events",s),ei.events=s),n.strokeForeground&&n.stroke){const t=n.fill;oi(i,"display",null),this.style(r,n),oi(r,"stroke",null),t&&(n.fill=null),ei=i.__values__,this.style(i,n),t&&(n.fill=t),ti=null}else oi(i,"display","none")},image(t,e,n){!1===n.smooth?(ri(e,"image-rendering","optimizeSpeed"),ri(e,"image-rendering","pixelated")):ri(e,"image-rendering",null)},text(t,n,i){let r,s,o,a,l=He(i);e.isArray(l)?(s=l.map(t=>je(i,t)),r=s.join("\n"),r!==ei.text&&(hn(n,0),o=n.ownerDocument,a=$e(i),s.forEach((t,e)=>{const r=an(o,"tspan",Un);r.__data__=i,r.textContent=t,e&&(r.setAttribute("x",0),r.setAttribute("dy",a)),n.appendChild(r)}),ei.text=r)):(s=je(i,l),s!==ei.text&&(n.textContent=s,ei.text=s)),oi(n,"font-family",Ge(i)),oi(n,"font-size",Be(i)+"px"),oi(n,"font-style",i.fontStyle),oi(n,"font-variant",i.fontVariant),oi(n,"font-weight",i.fontWeight)}};function ii(t,e,n){e!==ei[t]&&(n?function(t,e,n,i){null!=n?t.setAttributeNS(i,e,n):t.removeAttributeNS(i,e)}(ti,t,e,n):oi(ti,t,e),ei[t]=e)}function ri(t,e,n){n!==ei[e]&&(null==n?t.style.removeProperty(e):t.style.setProperty(e,n+""),ei[e]=n)}function si(t,e){for(const n in e)oi(t,n,e[n])}function oi(t,e,n){null!=n?t.setAttribute(e,n):t.removeAttribute(e)}function ai(){let t;return"undefined"==typeof window?"":(t=window.location).hash?t.href.slice(0,-t.hash.length):t.href}function li(t){gn.call(this,t),this._text=null,this._defs={gradient:{},clipping:{}}}e.inherits(li,gn,{svg(){return this._text},_render(t){const n=jn();n.open("svg",e.extend({},ye,{class:"marks",width:this._width*this._scale,height:this._height*this._scale,viewBox:`0 0 ${this._width} ${this._height}`}));const i=this._bgcolor;return i&&"transparent"!==i&&"none"!==i&&n.open("rect",{width:this._width,height:this._height,fill:i}).close(),n.open("g",Xn,{transform:"translate("+this._origin+")"}),this.mark(n,t),n.close(),this.defs(n),this._text=n.close()+"",this},mark(t,n){const i=Qe[n.marktype],r=i.tag,s=[In,i.attr];t.open("g",{class:un(n),"clip-path":n.clip?nt(this,n,n.group):null},Vn(n),{"pointer-events":"g"!==r&&!1===n.interactive?"none":null});const o=o=>{const a=this.href(o);if(a&&t.open("a",a),t.open(r,this.attr(n,o,s,"g"!==r?r:null)),"text"===r){const n=He(o);if(e.isArray(n)){const e={x:0,dy:$e(o)};for(let i=0;i<n.length;++i)t.open("tspan",i?e:null).text(je(o,n[i])).close()}else t.text(je(o,n))}else if("g"===r){const e=o.strokeForeground,r=o.fill,s=o.stroke;e&&s&&(o.stroke=null),t.open("path",this.attr(n,o,i.background,"bgrect")).close(),t.open("g",this.attr(n,o,i.content)),Ft(o,e=>this.mark(t,e)),t.close(),e&&s?(r&&(o.fill=null),o.stroke=s,t.open("path",this.attr(n,o,i.foreground,"bgrect")).close(),r&&(o.fill=r)):t.open("path",this.attr(n,o,i.foreground,"bgfore")).close()}t.close(),a&&t.close()};return i.nested?n.items&&n.items.length&&o(n.items[0]):Ft(n,o),t.close()},href(t){let e,n=t.href;if(n){if(e=this._hrefs&&this._hrefs[n])return e;this.sanitizeURL(n).then(t=>{t["xlink:href"]=t.href,t.href=null,(this._hrefs||(this._hrefs={}))[n]=t})}return null},attr(t,e,n,i){const r={},s=(t,e,n,i)=>{r[i||t]=e};return Array.isArray(n)?n.forEach(t=>t(s,e,this)):n(s,e,this),i&&function(t,e,n,i,r){if(null==e)return t;"bgrect"===i&&!1===n.interactive&&(t["pointer-events"]="none");if("bgfore"===i&&(!1===n.interactive&&(t["pointer-events"]="none"),t.display="none",null!==e.fill))return t;"image"===i&&!1===e.smooth&&(t.style="image-rendering: optimizeSpeed; image-rendering: pixelated;");"text"===i&&(t["font-family"]=Ge(e),t["font-size"]=Be(e)+"px",t["font-style"]=e.fontStyle,t["font-variant"]=e.fontVariant,t["font-weight"]=e.fontWeight);for(const n in Wn){let i=e[n];const s=Wn[n];("transparent"!==i||"fill"!==s&&"stroke"!==s)&&null!=i&&(l(i)&&(i=c(i,r.gradient,"")),t[s]=i)}}(r,e,t,i,this._defs),r},defs(t){const e=this._defs.gradient,n=this._defs.clipping;if(0!==Object.keys(e).length+Object.keys(n).length){t.open("defs");for(const n in e){const i=e[n],r=i.stops;"radial"===i.gradient?(t.open("pattern",{id:"p_"+n,viewBox:"0,0,1,1",width:"100%",height:"100%",preserveAspectRatio:"xMidYMid slice"}),t.open("rect",{width:"1",height:"1",fill:"url(#"+n+")"}).close(),t.close(),t.open("radialGradient",{id:n,fx:i.x1,fy:i.y1,fr:i.r1,cx:i.x2,cy:i.y2,r:i.r2})):t.open("linearGradient",{id:n,x1:i.x1,x2:i.x2,y1:i.y1,y2:i.y2});for(let e=0;e<r.length;++e)t.open("stop",{offset:r[e].offset,"stop-color":r[e].color}).close();t.close()}for(const e in n){const i=n[e];t.open("clipPath",{id:e}),i.path?t.open("path",{d:i.path}).close():t.open("rect",{x:0,y:0,width:i.width,height:i.height}).close(),t.close()}t.close()}}});var ci={Canvas:"canvas",PNG:"png",SVG:"svg",None:"none"},hi={};function ui(t,e,n,i){if(function(t,e,n){return t.bounds&&e.intersects(t.bounds)&&("group"===t.marktype||!1!==t.interactive&&(!n||n(t)))}(t,e,n)){const r=t.items,s=t.marktype,o=r.length;let a=0;if("group"===s)for(;a<o;++a)di(r[a],e,n,i);else for(const t=Qe[s].isect;a<o;++a){let n=r[a];fi(n,e,t)&&i.push(n)}}return i}function di(t,e,n,i){n&&n(t.mark)&&fi(t,e,Qe.group.isect)&&i.push(t);const r=t.items,s=r&&r.length;if(s){const o=t.x||0,a=t.y||0;e.translate(-o,-a);for(let t=0;t<s;++t)ui(r[t],e,n,i);e.translate(o,a)}return i}function fi(t,e,n){const i=t.bounds;return e.encloses(i)||e.intersects(i)&&n(t,e)}hi.canvas=hi.png={renderer:Pn,headless:Pn,handler:Mn},hi.svg={renderer:Fn,headless:li,handler:Ln},hi.none={};const pi=new it;function gi(t,n,i){return t===n||("path"===i?vi(t,n):t instanceof Date&&n instanceof Date?+t==+n:e.isNumber(t)&&e.isNumber(n)?Math.abs(t-n)<=1e-9:t&&n&&(e.isObject(t)||e.isObject(n))?null!=t&&null!=n&&function(t,e){var n,i,r=Object.keys(t),s=Object.keys(e);if(r.length!==s.length)return!1;for(r.sort(),s.sort(),i=r.length-1;i>=0;i--)if(r[i]!=s[i])return!1;for(i=r.length-1;i>=0;i--)if(!gi(t[n=r[i]],e[n],n))return!1;return typeof t==typeof e}(t,n):t==n)}function vi(t,e){return gi(g(t),g(e))}t.Bounds=it,t.CanvasHandler=Mn,t.CanvasRenderer=Pn,t.Gradient=function(t,e){var n,i=[];return n={gradient:"linear",x1:t?t[0]:0,y1:t?t[1]:0,x2:e?e[0]:1,y2:e?e[1]:0,stops:i,stop:function(t,e){return i.push({offset:t,color:e}),n}}},t.GroupItem=st,t.Handler=fn,t.Item=rt,t.Marks=Qe,t.RenderType=ci,t.Renderer=gn,t.ResourceLoader=ot,t.SVGHandler=Ln,t.SVGRenderer=Fn,t.SVGStringRenderer=li,t.Scenegraph=sn,t.boundClip=function(t){const n=t.clip;if(e.isFunction(n))n(Rt(pi.clear()));else{if(!n)return;pi.set(0,0,t.group.width,t.group.height)}t.bounds.intersect(pi)},t.boundContext=Rt,t.boundItem=Ze,t.boundMark=tn,t.boundStroke=ct,t.domChild=cn,t.domClear=hn,t.domCreate=an,t.domFind=ln,t.font=We,t.fontFamily=Ge,t.fontSize=Be,t.intersect=function(t,n,i){const r=[],s=(new it).union(n),o=t.marktype;return o?ui(t,s,i,r):"group"===o?di(t,s,i,r):e.error("Intersect scene must be mark node or group item.")},t.intersectBoxLine=It,t.intersectPath=Nt,t.intersectPoint=qt,t.intersectRule=Et,t.lineHeight=$e,t.markup=jn,t.multiLineOffset=function(t){const n=He(t);return(e.isArray(n)?n.length-1:0)*$e(t)},t.pathCurves=d,t.pathEqual=vi,t.pathParse=g,t.pathRectangle=V,t.pathRender=C,t.pathSymbols=P,t.pathTrail=B,t.point=dn,t.renderModule=function(t,e){return t=String(t||"").toLowerCase(),arguments.length>1?(hi[t]=e,this):hi[t]},t.resetSVGClipId=et,t.resetSVGDefIds=function(){et(),a=0},t.sceneEqual=gi,t.sceneFromJSON=rn,t.scenePickVisit=Yt,t.sceneToJSON=nn,t.sceneVisit=Ft,t.sceneZOrder=Ut,t.serializeXML=Gn,t.textMetrics=Ne,Object.defineProperty(t,"__esModule",{value:!0})}));

@@ -38,3 +38,3 @@ import {resetSVGGradientId} from './src/Gradient';

export {domCreate, domFind, domChild, domClear} from './src/util/dom';
export {openTag, closeTag} from './src/util/tags';
export {markup, serializeXML} from './src/util/markup';
export {

@@ -41,0 +41,0 @@ font,

{
"name": "vega-scenegraph",
"version": "4.8.3",
"version": "4.9.0",
"description": "Vega scenegraph and renderers.",

@@ -17,3 +17,4 @@ "license": "BSD-3-Clause",

"pretest": "yarn prebuild && yarn rollup && yarn schema",
"test": "tape -r ./test/__init__ 'test/**/*-test.js'",
"test": "tape -r ./test/__init__ 'test/**/*-test.js' && yarn xmllint",
"xmllint": "xmllint --noout ./test/resources/svg/*.svg",
"prepublishOnly": "yarn test && yarn build",

@@ -25,8 +26,8 @@ "postpublish": "git push && git push --tags"

"d3-shape": "^1.3.7",
"vega-canvas": "^1.2.2",
"vega-loader": "^4.3.0",
"vega-scale": "^7.0.0",
"vega-util": "^1.14.0"
"vega-canvas": "^1.2.3",
"vega-loader": "^4.3.1",
"vega-scale": "^7.0.1",
"vega-util": "^1.15.0"
},
"gitHead": "8fe8d36961c128df8300e6bc4fe6aac1e537bbe0"
"gitHead": "28db83352e43e321dfe55fc5cb6489b211e45662"
}

@@ -5,6 +5,6 @@ import Bounds from '../Bounds';

var clipBounds = new Bounds();
const clipBounds = new Bounds();
export default function(mark) {
var clip = mark.clip;
const clip = mark.clip;

@@ -11,0 +11,0 @@ if (isFunction(clip)) {

@@ -1,38 +0,112 @@

import {Epsilon, HalfPi, Tau} from '../util/constants';
import {DegToRad, Epsilon, HalfPi, Tau} from '../util/constants';
var bounds, lx, ly,
circleThreshold = Tau - 1e-8;
const circleThreshold = Tau - 1e-8;
let bounds, lx, ly, rot, ma, mb, mc, md;
export default function context(_) {
const add = (x, y) => bounds.add(x, y);
const addL = (x, y) => add(lx = x, ly = y);
const addX = x => add(x, bounds.y1);
const addY = y => add(bounds.x1, y);
const px = (x, y) => ma * x + mc * y;
const py = (x, y) => mb * x + md * y;
const addp = (x, y) => add(px(x, y), py(x, y));
const addpL = (x, y) => addL(px(x, y), py(x, y));
export default function(_, deg) {
bounds = _;
if (deg) {
rot = deg * DegToRad;
ma = md = Math.cos(rot);
mb = Math.sin(rot);
mc = -mb;
} else {
ma = md = 1;
rot = mb = mc = 0;
}
return context;
}
function noop() {}
const context = {
beginPath() {},
closePath() {},
function add(x, y) { bounds.add(x, y); }
moveTo: addpL,
lineTo: addpL,
function addL(x, y) { add(lx = x, ly = y); }
rect(x, y, w, h) {
if (rot) {
addp(x + w, y);
addp(x + w, y + h);
addp(x, y + h);
addpL(x, y);
} else {
add(x + w, y + h);
addL(x, y);
}
},
function addX(x) { add(x, bounds.y1); }
quadraticCurveTo(x1, y1, x2, y2) {
const px1 = px(x1, y1),
py1 = py(x1, y1),
px2 = px(x2, y2),
py2 = py(x2, y2);
quadExtrema(lx, px1, px2, addX);
quadExtrema(ly, py1, py2, addY);
addL(px2, py2);
},
function addY(y) { add(bounds.x1, y); }
bezierCurveTo(x1, y1, x2, y2, x3, y3) {
const px1 = px(x1, y1),
py1 = py(x1, y1),
px2 = px(x2, y2),
py2 = py(x2, y2),
px3 = px(x3, y3),
py3 = py(x3, y3);
cubicExtrema(lx, px1, px2, px3, addX);
cubicExtrema(ly, py1, py2, py3, addY);
addL(px3, py3);
},
context.beginPath = noop;
arc(cx, cy, r, sa, ea, ccw) {
sa += rot;
ea += rot;
context.closePath = noop;
// store last point on path
lx = r * Math.cos(ea) + cx;
ly = r * Math.sin(ea) + cy;
context.moveTo = addL;
if (Math.abs(ea - sa) > circleThreshold) {
// treat as full circle
add(cx - r, cy - r);
add(cx + r, cy + r);
} else {
const update = a => add(r * Math.cos(a) + cx, r * Math.sin(a) + cy);
let s, i;
context.lineTo = addL;
// sample end points
update(sa);
update(ea);
context.rect = function(x, y, w, h) {
add(x + w, y + h);
addL(x, y);
};
// sample interior points aligned with 90 degrees
if (ea !== sa) {
sa = sa % Tau; if (sa < 0) sa += Tau;
ea = ea % Tau; if (ea < 0) ea += Tau;
context.quadraticCurveTo = function(x1, y1, x2, y2) {
quadExtrema(lx, x1, x2, addX);
quadExtrema(ly, y1, y2, addY);
addL(x2, y2);
if (ea < sa) {
ccw = !ccw; // flip direction
s = sa; sa = ea; ea = s; // swap end-points
}
if (ccw) {
ea -= Tau;
s = sa - (sa % HalfPi);
for (i=0; i<4 && s>ea; ++i, s-=HalfPi) update(s);
} else {
s = sa - (sa % HalfPi) + HalfPi;
for (i=0; i<4 && s<ea; ++i, s=s+HalfPi) update(s);
}
}
}
}
};

@@ -45,8 +119,2 @@

context.bezierCurveTo = function(x1, y1, x2, y2, x3, y3) {
cubicExtrema(lx, x1, x2, x3, addX);
cubicExtrema(ly, y1, y2, y3, addY);
addL(x3, y3);
};
function cubicExtrema(x0, x1, x2, x3, cb) {

@@ -82,40 +150,1 @@ const a = x3 - x0 + 3 * x1 - 3 * x2,

}
context.arc = function(cx, cy, r, sa, ea, ccw) {
// store last point on path
lx = r * Math.cos(ea) + cx;
ly = r * Math.sin(ea) + cy;
if (Math.abs(ea - sa) > circleThreshold) {
// treat as full circle
add(cx - r, cy - r);
add(cx + r, cy + r);
} else {
const update = a => add(r * Math.cos(a) + cx, r * Math.sin(a) + cy);
let s, i;
// sample end points
update(sa);
update(ea);
// sample interior points aligned with 90 degrees
if (ea !== sa) {
sa = sa % Tau; if (sa < 0) sa += Tau;
ea = ea % Tau; if (ea < 0) ea += Tau;
if (ea < sa) {
ccw = !ccw; // flip direction
s = sa; sa = ea; ea = s; // swap end-points
}
if (ccw) {
ea -= Tau;
s = sa - (sa % HalfPi);
for (i=0; i<4 && s>ea; ++i, s-=HalfPi) update(s);
} else {
s = sa - (sa % HalfPi) + HalfPi;
for (i=0; i<4 && s<ea; ++i, s=s+HalfPi) update(s);
}
}
}
};

@@ -6,174 +6,174 @@ export default function Bounds(b) {

var prototype = Bounds.prototype;
Bounds.prototype = {
clone() {
return new Bounds(this);
},
prototype.clone = function() {
return new Bounds(this);
};
clear() {
this.x1 = +Number.MAX_VALUE;
this.y1 = +Number.MAX_VALUE;
this.x2 = -Number.MAX_VALUE;
this.y2 = -Number.MAX_VALUE;
return this;
},
prototype.clear = function() {
this.x1 = +Number.MAX_VALUE;
this.y1 = +Number.MAX_VALUE;
this.x2 = -Number.MAX_VALUE;
this.y2 = -Number.MAX_VALUE;
return this;
};
empty() {
return (
this.x1 === +Number.MAX_VALUE &&
this.y1 === +Number.MAX_VALUE &&
this.x2 === -Number.MAX_VALUE &&
this.y2 === -Number.MAX_VALUE
);
},
prototype.empty = function() {
return (
this.x1 === +Number.MAX_VALUE &&
this.y1 === +Number.MAX_VALUE &&
this.x2 === -Number.MAX_VALUE &&
this.y2 === -Number.MAX_VALUE
);
};
equals(b) {
return (
this.x1 === b.x1 &&
this.y1 === b.y1 &&
this.x2 === b.x2 &&
this.y2 === b.y2
);
},
prototype.equals = function(b) {
return (
this.x1 === b.x1 &&
this.y1 === b.y1 &&
this.x2 === b.x2 &&
this.y2 === b.y2
);
};
set(x1, y1, x2, y2) {
if (x2 < x1) {
this.x2 = x1;
this.x1 = x2;
} else {
this.x1 = x1;
this.x2 = x2;
}
if (y2 < y1) {
this.y2 = y1;
this.y1 = y2;
} else {
this.y1 = y1;
this.y2 = y2;
}
return this;
},
prototype.set = function(x1, y1, x2, y2) {
if (x2 < x1) {
this.x2 = x1;
this.x1 = x2;
} else {
this.x1 = x1;
this.x2 = x2;
}
if (y2 < y1) {
this.y2 = y1;
this.y1 = y2;
} else {
this.y1 = y1;
this.y2 = y2;
}
return this;
};
add(x, y) {
if (x < this.x1) this.x1 = x;
if (y < this.y1) this.y1 = y;
if (x > this.x2) this.x2 = x;
if (y > this.y2) this.y2 = y;
return this;
},
prototype.add = function(x, y) {
if (x < this.x1) this.x1 = x;
if (y < this.y1) this.y1 = y;
if (x > this.x2) this.x2 = x;
if (y > this.y2) this.y2 = y;
return this;
};
expand(d) {
this.x1 -= d;
this.y1 -= d;
this.x2 += d;
this.y2 += d;
return this;
},
prototype.expand = function(d) {
this.x1 -= d;
this.y1 -= d;
this.x2 += d;
this.y2 += d;
return this;
};
round() {
this.x1 = Math.floor(this.x1);
this.y1 = Math.floor(this.y1);
this.x2 = Math.ceil(this.x2);
this.y2 = Math.ceil(this.y2);
return this;
},
prototype.round = function() {
this.x1 = Math.floor(this.x1);
this.y1 = Math.floor(this.y1);
this.x2 = Math.ceil(this.x2);
this.y2 = Math.ceil(this.y2);
return this;
};
scale(s) {
this.x1 *= s;
this.y1 *= s;
this.x2 *= s;
this.y2 *= s;
return this;
},
prototype.scale = function(s) {
this.x1 *= s;
this.y1 *= s;
this.x2 *= s;
this.y2 *= s;
return this;
};
translate(dx, dy) {
this.x1 += dx;
this.x2 += dx;
this.y1 += dy;
this.y2 += dy;
return this;
},
prototype.translate = function(dx, dy) {
this.x1 += dx;
this.x2 += dx;
this.y1 += dy;
this.y2 += dy;
return this;
};
rotate(angle, x, y) {
const p = this.rotatedPoints(angle, x, y);
return this.clear()
.add(p[0], p[1])
.add(p[2], p[3])
.add(p[4], p[5])
.add(p[6], p[7]);
},
prototype.rotate = function(angle, x, y) {
const p = this.rotatedPoints(angle, x, y);
return this.clear()
.add(p[0], p[1])
.add(p[2], p[3])
.add(p[4], p[5])
.add(p[6], p[7]);
};
rotatedPoints(angle, x, y) {
var {x1, y1, x2, y2} = this,
cos = Math.cos(angle),
sin = Math.sin(angle),
cx = x - x * cos + y * sin,
cy = y - x * sin - y * cos;
prototype.rotatedPoints = function(angle, x, y) {
var {x1, y1, x2, y2} = this,
cos = Math.cos(angle),
sin = Math.sin(angle),
cx = x - x*cos + y*sin,
cy = y - x*sin - y*cos;
return [
cos * x1 - sin * y1 + cx, sin * x1 + cos * y1 + cy,
cos * x1 - sin * y2 + cx, sin * x1 + cos * y2 + cy,
cos * x2 - sin * y1 + cx, sin * x2 + cos * y1 + cy,
cos * x2 - sin * y2 + cx, sin * x2 + cos * y2 + cy
];
},
return [
cos*x1 - sin*y1 + cx, sin*x1 + cos*y1 + cy,
cos*x1 - sin*y2 + cx, sin*x1 + cos*y2 + cy,
cos*x2 - sin*y1 + cx, sin*x2 + cos*y1 + cy,
cos*x2 - sin*y2 + cx, sin*x2 + cos*y2 + cy
];
};
union(b) {
if (b.x1 < this.x1) this.x1 = b.x1;
if (b.y1 < this.y1) this.y1 = b.y1;
if (b.x2 > this.x2) this.x2 = b.x2;
if (b.y2 > this.y2) this.y2 = b.y2;
return this;
},
prototype.union = function(b) {
if (b.x1 < this.x1) this.x1 = b.x1;
if (b.y1 < this.y1) this.y1 = b.y1;
if (b.x2 > this.x2) this.x2 = b.x2;
if (b.y2 > this.y2) this.y2 = b.y2;
return this;
};
intersect(b) {
if (b.x1 > this.x1) this.x1 = b.x1;
if (b.y1 > this.y1) this.y1 = b.y1;
if (b.x2 < this.x2) this.x2 = b.x2;
if (b.y2 < this.y2) this.y2 = b.y2;
return this;
},
prototype.intersect = function(b) {
if (b.x1 > this.x1) this.x1 = b.x1;
if (b.y1 > this.y1) this.y1 = b.y1;
if (b.x2 < this.x2) this.x2 = b.x2;
if (b.y2 < this.y2) this.y2 = b.y2;
return this;
};
encloses(b) {
return b && (
this.x1 <= b.x1 &&
this.x2 >= b.x2 &&
this.y1 <= b.y1 &&
this.y2 >= b.y2
);
},
prototype.encloses = function(b) {
return b && (
this.x1 <= b.x1 &&
this.x2 >= b.x2 &&
this.y1 <= b.y1 &&
this.y2 >= b.y2
);
};
alignsWith(b) {
return b && (
this.x1 == b.x1 ||
this.x2 == b.x2 ||
this.y1 == b.y1 ||
this.y2 == b.y2
);
},
prototype.alignsWith = function(b) {
return b && (
this.x1 == b.x1 ||
this.x2 == b.x2 ||
this.y1 == b.y1 ||
this.y2 == b.y2
);
};
intersects(b) {
return b && !(
this.x2 < b.x1 ||
this.x1 > b.x2 ||
this.y2 < b.y1 ||
this.y1 > b.y2
);
},
prototype.intersects = function(b) {
return b && !(
this.x2 < b.x1 ||
this.x1 > b.x2 ||
this.y2 < b.y1 ||
this.y1 > b.y2
);
};
contains(x, y) {
return !(
x < this.x1 ||
x > this.x2 ||
y < this.y1 ||
y > this.y2
);
},
prototype.contains = function(x, y) {
return !(
x < this.x1 ||
x > this.x2 ||
y < this.y1 ||
y > this.y2
);
};
width() {
return this.x2 - this.x1;
},
prototype.width = function() {
return this.x2 - this.x1;
height() {
return this.y2 - this.y1;
}
};
prototype.height = function() {
return this.y2 - this.y1;
};

@@ -21,14 +21,2 @@ import Handler from './Handler';

const prototype = inherits(CanvasHandler, Handler);
prototype.initialize = function(el, origin, obj) {
this._canvas = el && domFind(el, 'canvas');
// add minimal events required for proper state management
[ClickEvent, MouseDownEvent, MouseMoveEvent, MouseOutEvent, DragLeaveEvent]
.forEach(type => eventListenerCheck(this, type));
return Handler.prototype.initialize.call(this, el, origin, obj);
};
const eventBundle = type => (

@@ -58,15 +46,2 @@ type === TouchStartEvent ||

// return the backing canvas instance
prototype.canvas = function() {
return this._canvas;
};
// retrieve the current canvas context
prototype.context = function() {
return this._canvas.getContext('2d');
};
// supported events
prototype.events = Events;
function move(moveEvent, overEvent, outEvent) {

@@ -101,111 +76,136 @@ return function(evt) {

// to keep old versions of firefox happy
prototype.DOMMouseScroll = function(evt) {
this.fire(MouseWheelEvent, evt);
};
inherits(CanvasHandler, Handler, {
initialize(el, origin, obj) {
this._canvas = el && domFind(el, 'canvas');
prototype.mousemove = move(MouseMoveEvent, MouseOverEvent, MouseOutEvent);
prototype.dragover = move(DragOverEvent, DragEnterEvent, DragLeaveEvent);
// add minimal events required for proper state management
[ClickEvent, MouseDownEvent, MouseMoveEvent, MouseOutEvent, DragLeaveEvent]
.forEach(type => eventListenerCheck(this, type));
prototype.mouseout = inactive(MouseOutEvent);
prototype.dragleave = inactive(DragLeaveEvent);
return Handler.prototype.initialize.call(this, el, origin, obj);
},
prototype.mousedown = function(evt) {
this._down = this._active;
this.fire(MouseDownEvent, evt);
};
// return the backing canvas instance
canvas() {
return this._canvas;
},
prototype.click = function(evt) {
if (this._down === this._active) {
this.fire(ClickEvent, evt);
this._down = null;
}
};
// retrieve the current canvas context
context() {
return this._canvas.getContext('2d');
},
prototype.touchstart = function(evt) {
this._touch = this.pickEvent(evt.changedTouches[0]);
// supported events
events: Events,
if (this._first) {
this._active = this._touch;
this._first = false;
}
// to keep old versions of firefox happy
DOMMouseScroll(evt) {
this.fire(MouseWheelEvent, evt);
},
this.fire(TouchStartEvent, evt, true);
};
mousemove: move(MouseMoveEvent, MouseOverEvent, MouseOutEvent),
dragover: move(DragOverEvent, DragEnterEvent, DragLeaveEvent),
prototype.touchmove = function(evt) {
this.fire(TouchMoveEvent, evt, true);
};
mouseout: inactive(MouseOutEvent),
dragleave: inactive(DragLeaveEvent),
prototype.touchend = function(evt) {
this.fire(TouchEndEvent, evt, true);
this._touch = null;
};
mousedown(evt) {
this._down = this._active;
this.fire(MouseDownEvent, evt);
},
// fire an event
prototype.fire = function(type, evt, touch) {
const a = touch ? this._touch : this._active,
h = this._handlers[type];
click(evt) {
if (this._down === this._active) {
this.fire(ClickEvent, evt);
this._down = null;
}
},
// set event type relative to scenegraph items
evt.vegaType = type;
touchstart(evt) {
this._touch = this.pickEvent(evt.changedTouches[0]);
// handle hyperlinks and tooltips first
if (type === HrefEvent && a && a.href) {
this.handleHref(evt, a, a.href);
} else if (type === TooltipShowEvent || type === TooltipHideEvent) {
this.handleTooltip(evt, a, type !== TooltipHideEvent);
}
if (this._first) {
this._active = this._touch;
this._first = false;
}
// invoke all registered handlers
if (h) {
for (let i=0, len=h.length; i<len; ++i) {
h[i].handler.call(this._obj, evt, a);
this.fire(TouchStartEvent, evt, true);
},
touchmove(evt) {
this.fire(TouchMoveEvent, evt, true);
},
touchend(evt) {
this.fire(TouchEndEvent, evt, true);
this._touch = null;
},
// fire an event
fire(type, evt, touch) {
const a = touch ? this._touch : this._active,
h = this._handlers[type];
// set event type relative to scenegraph items
evt.vegaType = type;
// handle hyperlinks and tooltips first
if (type === HrefEvent && a && a.href) {
this.handleHref(evt, a, a.href);
} else if (type === TooltipShowEvent || type === TooltipHideEvent) {
this.handleTooltip(evt, a, type !== TooltipHideEvent);
}
}
};
// add an event handler
prototype.on = function(type, handler) {
const name = this.eventName(type),
h = this._handlers,
i = this._handlerIndex(h[name], type, handler);
// invoke all registered handlers
if (h) {
for (let i=0, len=h.length; i<len; ++i) {
h[i].handler.call(this._obj, evt, a);
}
}
},
if (i < 0) {
eventListenerCheck(this, type);
(h[name] || (h[name] = [])).push({
type: type,
handler: handler
});
}
// add an event handler
on(type, handler) {
const name = this.eventName(type),
h = this._handlers,
i = this._handlerIndex(h[name], type, handler);
return this;
};
if (i < 0) {
eventListenerCheck(this, type);
(h[name] || (h[name] = [])).push({
type: type,
handler: handler
});
}
// remove an event handler
prototype.off = function(type, handler) {
const name = this.eventName(type),
h = this._handlers[name],
i = this._handlerIndex(h, type, handler);
return this;
},
if (i >= 0) {
h.splice(i, 1);
}
// remove an event handler
off(type, handler) {
const name = this.eventName(type),
h = this._handlers[name],
i = this._handlerIndex(h, type, handler);
return this;
};
if (i >= 0) {
h.splice(i, 1);
}
prototype.pickEvent = function(evt) {
const p = point(evt, this._canvas),
o = this._origin;
return this.pick(this._scene, p[0], p[1], p[0] - o[0], p[1] - o[1]);
};
return this;
},
// find the scenegraph item at the current mouse position
// x, y -- the absolute x, y mouse coordinates on the canvas element
// gx, gy -- the relative coordinates within the current group
prototype.pick = function(scene, x, y, gx, gy) {
const g = this.context(),
mark = Marks[scene.marktype];
return mark.pick.call(this, g, scene, x, y, gx, gy);
};
pickEvent(evt) {
const p = point(evt, this._canvas),
o = this._origin;
return this.pick(this._scene, p[0], p[1], p[0] - o[0], p[1] - o[1]);
},
// find the scenegraph item at the current mouse position
// x, y -- the absolute x, y mouse coordinates on the canvas element
// gx, gy -- the relative coordinates within the current group
pick(scene, x, y, gx, gy) {
const g = this.context(),
mark = Marks[scene.marktype];
return mark.pick.call(this, g, scene, x, y, gx, gy);
}
});

@@ -19,61 +19,8 @@ import Renderer from './Renderer';

const prototype = inherits(CanvasRenderer, Renderer),
base = Renderer.prototype;
const base = Renderer.prototype;
prototype.initialize = function(el, width, height, origin, scaleFactor, options) {
this._options = options || {};
const viewBounds = (origin, width, height) => new Bounds()
.set(0, 0, width, height)
.translate(-origin[0], -origin[1]);
this._canvas = this._options.externalContext
? null
: canvas(1, 1, this._options.type); // instantiate a small canvas
if (el && this._canvas) {
domClear(el, 0).appendChild(this._canvas);
this._canvas.setAttribute('class', 'marks');
}
// this method will invoke resize to size the canvas appropriately
return base.initialize.call(this, el, width, height, origin, scaleFactor);
};
prototype.resize = function(width, height, origin, scaleFactor) {
base.resize.call(this, width, height, origin, scaleFactor);
if (this._canvas) {
// configure canvas size and transform
resize(this._canvas, this._width, this._height,
this._origin, this._scale, this._options.context);
} else {
// external context needs to be scaled and positioned to origin
const ctx = this._options.externalContext;
if (!ctx) error('CanvasRenderer is missing a valid canvas or context');
ctx.scale(this._scale, this._scale);
ctx.translate(this._origin[0], this._origin[1]);
}
this._redraw = true;
return this;
};
prototype.canvas = function() {
return this._canvas;
};
prototype.context = function() {
return this._options.externalContext
|| (this._canvas ? this._canvas.getContext('2d') : null);
};
prototype.dirty = function(item) {
let b = this._tempb.clear().union(item.bounds),
g = item.mark.group;
while (g) {
b.translate(g.x || 0, g.y || 0);
g = g.mark.group;
}
this._dirty.union(b);
};
function clipToBounds(g, b, origin) {

@@ -99,53 +46,107 @@ // expand bounds by 1 pixel, then round to pixel boundaries

const viewBounds = (origin, width, height) => new Bounds()
.set(0, 0, width, height)
.translate(-origin[0], -origin[1]);
inherits(CanvasRenderer, Renderer, {
initialize(el, width, height, origin, scaleFactor, options) {
this._options = options || {};
prototype._render = function(scene) {
const g = this.context(),
o = this._origin,
w = this._width,
h = this._height,
db = this._dirty,
vb = viewBounds(o, w, h);
this._canvas = this._options.externalContext
? null
: canvas(1, 1, this._options.type); // instantiate a small canvas
// setup
g.save();
const b = this._redraw || db.empty()
? (this._redraw = false, vb.expand(1))
: clipToBounds(g, vb.intersect(db), o);
if (el && this._canvas) {
domClear(el, 0).appendChild(this._canvas);
this._canvas.setAttribute('class', 'marks');
}
this.clear(-o[0], -o[1], w, h);
// this method will invoke resize to size the canvas appropriately
return base.initialize.call(this, el, width, height, origin, scaleFactor);
},
// render
this.draw(g, scene, b);
resize(width, height, origin, scaleFactor) {
base.resize.call(this, width, height, origin, scaleFactor);
// takedown
g.restore();
db.clear();
if (this._canvas) {
// configure canvas size and transform
resize(this._canvas, this._width, this._height,
this._origin, this._scale, this._options.context);
} else {
// external context needs to be scaled and positioned to origin
const ctx = this._options.externalContext;
if (!ctx) error('CanvasRenderer is missing a valid canvas or context');
ctx.scale(this._scale, this._scale);
ctx.translate(this._origin[0], this._origin[1]);
}
return this;
};
this._redraw = true;
return this;
},
prototype.draw = function(ctx, scene, bounds) {
const mark = marks[scene.marktype];
if (scene.clip) clip(ctx, scene);
mark.draw.call(this, ctx, scene, bounds);
if (scene.clip) ctx.restore();
};
canvas() {
return this._canvas;
},
prototype.clear = function(x, y, w, h) {
const opt = this._options,
g = this.context();
context() {
return this._options.externalContext
|| (this._canvas ? this._canvas.getContext('2d') : null);
},
if (opt.type !== 'pdf' && !opt.externalContext) {
// calling clear rect voids vector output in pdf mode
// and could remove external context content (#2615)
g.clearRect(x, y, w, h);
}
dirty(item) {
let b = this._tempb.clear().union(item.bounds),
g = item.mark.group;
if (this._bgcolor != null) {
g.fillStyle = this._bgcolor;
g.fillRect(x, y, w, h);
while (g) {
b.translate(g.x || 0, g.y || 0);
g = g.mark.group;
}
this._dirty.union(b);
},
_render(scene) {
const g = this.context(),
o = this._origin,
w = this._width,
h = this._height,
db = this._dirty,
vb = viewBounds(o, w, h);
// setup
g.save();
const b = this._redraw || db.empty()
? (this._redraw = false, vb.expand(1))
: clipToBounds(g, vb.intersect(db), o);
this.clear(-o[0], -o[1], w, h);
// render
this.draw(g, scene, b);
// takedown
g.restore();
db.clear();
return this;
},
draw(ctx, scene, bounds) {
const mark = marks[scene.marktype];
if (scene.clip) clip(ctx, scene);
mark.draw.call(this, ctx, scene, bounds);
if (scene.clip) ctx.restore();
},
clear(x, y, w, h) {
const opt = this._options,
g = this.context();
if (opt.type !== 'pdf' && !opt.externalContext) {
// calling clear rect voids vector output in pdf mode
// and could remove external context content (#2615)
g.clearRect(x, y, w, h);
}
if (this._bgcolor != null) {
g.fillStyle = this._bgcolor;
g.fillRect(x, y, w, h);
}
}
};
});

@@ -27,177 +27,177 @@ import {domCreate} from './util/dom';

const prototype = Handler.prototype;
Handler.prototype = {
/**
* Initialize a new Handler instance.
* @param {DOMElement} el - The containing DOM element for the display.
* @param {Array<number>} origin - The origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {object} [obj] - Optional context object that should serve as
* the "this" context for event callbacks.
* @return {Handler} - This handler instance.
*/
initialize(el, origin, obj) {
this._el = el;
this._obj = obj || null;
return this.origin(origin);
},
/**
* Initialize a new Handler instance.
* @param {DOMElement} el - The containing DOM element for the display.
* @param {Array<number>} origin - The origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {object} [obj] - Optional context object that should serve as
* the "this" context for event callbacks.
* @return {Handler} - This handler instance.
*/
prototype.initialize = function(el, origin, obj) {
this._el = el;
this._obj = obj || null;
return this.origin(origin);
};
/**
* Returns the parent container element for a visualization.
* @return {DOMElement} - The containing DOM element.
*/
element() {
return this._el;
},
/**
* Returns the parent container element for a visualization.
* @return {DOMElement} - The containing DOM element.
*/
prototype.element = function() {
return this._el;
};
/**
* Returns the scene element (e.g., canvas or SVG) of the visualization
* Subclasses must override if the first child is not the scene element.
* @return {DOMElement} - The scene (e.g., canvas or SVG) element.
*/
canvas() {
return this._el && this._el.firstChild;
},
/**
* Returns the scene element (e.g., canvas or SVG) of the visualization
* Subclasses must override if the first child is not the scene element.
* @return {DOMElement} - The scene (e.g., canvas or SVG) element.
*/
prototype.canvas = function() {
return this._el && this._el.firstChild;
};
/**
* Get / set the origin coordinates of the visualization.
*/
origin(origin) {
if (arguments.length) {
this._origin = origin || [0, 0];
return this;
} else {
return this._origin.slice();
}
},
/**
* Get / set the origin coordinates of the visualization.
*/
prototype.origin = function(origin) {
if (arguments.length) {
this._origin = origin || [0, 0];
/**
* Get / set the scenegraph root.
*/
scene(scene) {
if (!arguments.length) return this._scene;
this._scene = scene;
return this;
} else {
return this._origin.slice();
}
};
},
/**
* Get / set the scenegraph root.
*/
prototype.scene = function(scene) {
if (!arguments.length) return this._scene;
this._scene = scene;
return this;
};
/**
* Add an event handler. Subclasses should override this method.
*/
on(/*type, handler*/) {},
/**
* Add an event handler. Subclasses should override this method.
*/
prototype.on = function(/*type, handler*/) {};
/**
* Remove an event handler. Subclasses should override this method.
*/
off(/*type, handler*/) {},
/**
* Remove an event handler. Subclasses should override this method.
*/
prototype.off = function(/*type, handler*/) {};
/**
* Utility method for finding the array index of an event handler.
* @param {Array} h - An array of registered event handlers.
* @param {string} type - The event type.
* @param {function} handler - The event handler instance to find.
* @return {number} - The handler's array index or -1 if not registered.
*/
_handlerIndex(h, type, handler) {
for (let i = h ? h.length : 0; --i>=0;) {
if (h[i].type === type && (!handler || h[i].handler === handler)) {
return i;
}
}
return -1;
},
/**
* Utility method for finding the array index of an event handler.
* @param {Array} h - An array of registered event handlers.
* @param {string} type - The event type.
* @param {function} handler - The event handler instance to find.
* @return {number} - The handler's array index or -1 if not registered.
*/
prototype._handlerIndex = function(h, type, handler) {
for (let i = h ? h.length : 0; --i>=0;) {
if (h[i].type === type && (!handler || h[i].handler === handler)) {
return i;
/**
* Returns an array with registered event handlers.
* @param {string} [type] - The event type to query. Any annotations
* are ignored; for example, for the argument "click.foo", ".foo" will
* be ignored and the method returns all "click" handlers. If type is
* null or unspecified, this method returns handlers for all types.
* @return {Array} - A new array containing all registered event handlers.
*/
handlers(type) {
const h = this._handlers, a = [];
if (type) {
a.push.apply(a, h[this.eventName(type)]);
} else {
for (const k in h) { a.push.apply(a, h[k]); }
}
}
return -1;
};
return a;
},
/**
* Returns an array with registered event handlers.
* @param {string} [type] - The event type to query. Any annotations
* are ignored; for example, for the argument "click.foo", ".foo" will
* be ignored and the method returns all "click" handlers. If type is
* null or unspecified, this method returns handlers for all types.
* @return {Array} - A new array containing all registered event handlers.
*/
prototype.handlers = function(type) {
const h = this._handlers, a = [];
if (type) {
a.push.apply(a, h[this.eventName(type)]);
} else {
for (const k in h) { a.push.apply(a, h[k]); }
}
return a;
};
/**
* Parses an event name string to return the specific event type.
* For example, given "click.foo" returns "click"
* @param {string} name - The input event type string.
* @return {string} - A string with the event type only.
*/
eventName(name) {
const i = name.indexOf('.');
return i < 0 ? name : name.slice(0, i);
},
/**
* Parses an event name string to return the specific event type.
* For example, given "click.foo" returns "click"
* @param {string} name - The input event type string.
* @return {string} - A string with the event type only.
*/
prototype.eventName = function(name) {
const i = name.indexOf('.');
return i < 0 ? name : name.slice(0, i);
};
/**
* Handle hyperlink navigation in response to an item.href value.
* @param {Event} event - The event triggering hyperlink navigation.
* @param {Item} item - The scenegraph item.
* @param {string} href - The URL to navigate to.
*/
handleHref(event, item, href) {
this._loader
.sanitize(href, {context:'href'})
.then(opt => {
const e = new MouseEvent(event.type, event),
a = domCreate(null, 'a');
for (const name in opt) a.setAttribute(name, opt[name]);
a.dispatchEvent(e);
})
.catch(function() { /* do nothing */ });
},
/**
* Handle hyperlink navigation in response to an item.href value.
* @param {Event} event - The event triggering hyperlink navigation.
* @param {Item} item - The scenegraph item.
* @param {string} href - The URL to navigate to.
*/
prototype.handleHref = function(event, item, href) {
this._loader
.sanitize(href, {context:'href'})
.then(opt => {
const e = new MouseEvent(event.type, event),
a = domCreate(null, 'a');
for (const name in opt) a.setAttribute(name, opt[name]);
a.dispatchEvent(e);
})
.catch(function() { /* do nothing */ });
};
/**
* Handle tooltip display in response to an item.tooltip value.
* @param {Event} event - The event triggering tooltip display.
* @param {Item} item - The scenegraph item.
* @param {boolean} show - A boolean flag indicating whether
* to show or hide a tooltip for the given item.
*/
handleTooltip(event, item, show) {
if (item && item.tooltip != null) {
item = resolveItem(item, event, this.canvas(), this._origin);
const value = (show && item && item.tooltip) || null;
this._tooltip.call(this._obj, this, event, item, value);
}
},
/**
* Handle tooltip display in response to an item.tooltip value.
* @param {Event} event - The event triggering tooltip display.
* @param {Item} item - The scenegraph item.
* @param {boolean} show - A boolean flag indicating whether
* to show or hide a tooltip for the given item.
*/
prototype.handleTooltip = function(event, item, show) {
if (item && item.tooltip != null) {
item = resolveItem(item, event, this.canvas(), this._origin);
const value = (show && item && item.tooltip) || null;
this._tooltip.call(this._obj, this, event, item, value);
}
};
/**
* Returns the size of a scenegraph item and its position relative
* to the viewport.
* @param {Item} item - The scenegraph item.
* @return {object} - A bounding box object (compatible with the
* DOMRect type) consisting of x, y, width, heigh, top, left,
* right, and bottom properties.
*/
getItemBoundingClientRect(item) {
const el = this.canvas();
if (!el) return;
/**
* Returns the size of a scenegraph item and its position relative
* to the viewport.
* @param {Item} item - The scenegraph item.
* @return {object} - A bounding box object (compatible with the
* DOMRect type) consisting of x, y, width, heigh, top, left,
* right, and bottom properties.
*/
prototype.getItemBoundingClientRect = function(item) {
const el = this.canvas();
if (!el) return;
const rect = el.getBoundingClientRect(),
origin = this._origin,
bounds = item.bounds,
width = bounds.width(),
height = bounds.height();
const rect = el.getBoundingClientRect(),
origin = this._origin,
bounds = item.bounds,
width = bounds.width(),
height = bounds.height();
let x = bounds.x1 + origin[0] + rect.left,
y = bounds.y1 + origin[1] + rect.top;
let x = bounds.x1 + origin[0] + rect.left,
y = bounds.y1 + origin[1] + rect.top;
// translate coordinate for each parent group
while (item.mark && (item = item.mark.group)) {
x += item.x || 0;
y += item.y || 0;
}
// translate coordinate for each parent group
while (item.mark && (item = item.mark.group)) {
x += item.x || 0;
y += item.y || 0;
// return DOMRect-compatible bounding box
return {
x, y, width, height,
left: x, top: y, right: x + width, bottom: y + height
};
}
// return DOMRect-compatible bounding box
return {
x, y, width, height,
left: x, top: y, right: x + width, bottom: y + height
};
};

@@ -76,2 +76,3 @@ import {hasCornerRadius, rectangle} from '../path/shapes';

const hitForeground = hitPath(rectanglePath, false);
const hitCorner = hitPath(rectanglePath, true);

@@ -153,3 +154,3 @@ function draw(context, scene, bounds) {

// test background for rounded corner clip
if (c && hasCornerRadius(group) && !hitBackground(context, group, cx, cy)) {
if (c && hasCornerRadius(group) && !hitCorner(context, group, cx, cy)) {
context.restore();

@@ -156,0 +157,0 @@ return null;

@@ -6,3 +6,3 @@ import boundStroke from '../bound/boundStroke';

import {pickPath} from '../util/canvas/pick';
import {transformItem} from '../util/svg/transform';
import {rotateItem} from '../util/svg/transform';
import {DegToRad} from '../util/constants';

@@ -13,3 +13,3 @@

function attr(emit, item) {
emit('transform', transformItem(item));
emit('transform', rotateItem(item));
emit('d', shape(null, item));

@@ -19,12 +19,4 @@ }

function bound(bounds, item) {
var x = item.x || 0,
y = item.y || 0;
shape(context(bounds), item);
boundStroke(bounds, item).translate(x, y);
if (item.angle) {
bounds.rotate(item.angle * DegToRad, x, y);
}
return bounds;
shape(context(bounds, item.angle), item);
return boundStroke(bounds, item).translate(item.x || 0, item.y || 0);
}

@@ -31,0 +23,0 @@

@@ -48,11 +48,5 @@ import boundStroke from '../bound/boundStroke';

function bound(bounds, item) {
path(context(bounds), item)
return path(context(bounds, item.angle), item)
? bounds.set(0, 0, 0, 0)
: boundStroke(bounds, item, true);
if (item.angle) {
bounds.rotate(item.angle * DegToRad, item.x || 0, item.y || 0);
}
return bounds;
}

@@ -59,0 +53,0 @@

@@ -24,3 +24,3 @@ import {hasOwnProperty} from 'vega-util';

var lookup = {
const lookup = {
'basis': {

@@ -27,0 +27,0 @@ curve: curveBasis

// Path parsing and rendering code adapted from fabric.js -- Thanks!
var cmdlen = { m:2, l:2, h:1, v:1, c:6, s:4, q:4, t:2, a:7 },
regexp = [/([MLHVCSQTAZmlhvcsqtaz])/g, /###/, /(\d)([-+])/g, /\s|,|###/];
const cmdlen = { m:2, l:2, h:1, v:1, c:6, s:4, q:4, t:2, a:7 },
regexp = [
/([MLHVCSQTAZmlhvcsqtaz])/g,
/###/,
/(\.\d+)(\.\d)/g,
/(\d)([-+])/g,
/\s|,|###/
];
export default function(pathstr) {
var result = [],
let result = [],
path,

@@ -26,4 +32,5 @@ curr,

.trim()
.replace(regexp[2],'$1###$2')
.split(regexp[3]);
.replace(regexp[2], '$1###$2')
.replace(regexp[3], '$1###$2')
.split(regexp[4]);
cmd = curr.charAt(0);

@@ -39,4 +46,10 @@

len = cmdlen[cmd.toLowerCase()];
if (parsed.length-1 > len) {
for (j=1, m=parsed.length; j<m; j+=len) {
if (parsed.length - 1 > len) {
let j = 1, m = parsed.length;
result.push([cmd].concat(parsed.slice(j, j += len)));
// handle implicit lineTo (#2803)
cmd = cmd === 'M' ? 'L' : cmd === 'm' ? 'l' : cmd;
for (; j < m; j += len) {
result.push([cmd].concat(parsed.slice(j, j+len)));

@@ -43,0 +56,0 @@ }

@@ -62,4 +62,4 @@ import curves from './curves';

export function area(context, items) {
var item = items[0],
interp = item.interpolate || 'linear';
const item = items[0],
interp = item.interpolate || 'linear';
return (item.orient === 'horizontal' ? areahShape : areavShape)

@@ -71,4 +71,4 @@ .curve(curves(interp, item.orient, item.tension))

export function line(context, items) {
var item = items[0],
interp = item.interpolate || 'linear';
const item = items[0],
interp = item.interpolate || 'linear';
return lineShape.curve(curves(interp, item.orient, item.tension))

@@ -75,0 +75,0 @@ .context(context)(items);

@@ -16,169 +16,168 @@ import ResourceLoader from './ResourceLoader';

var prototype = Renderer.prototype;
Renderer.prototype = {
/**
* Initialize a new Renderer instance.
* @param {DOMElement} el - The containing DOM element for the display.
* @param {number} width - The coordinate width of the display, in pixels.
* @param {number} height - The coordinate height of the display, in pixels.
* @param {Array<number>} origin - The origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {number} [scaleFactor=1] - Optional scaleFactor by which to multiply
* the width and height to determine the final pixel size.
* @return {Renderer} - This renderer instance.
*/
initialize(el, width, height, origin, scaleFactor) {
this._el = el;
return this.resize(width, height, origin, scaleFactor);
},
/**
* Initialize a new Renderer instance.
* @param {DOMElement} el - The containing DOM element for the display.
* @param {number} width - The coordinate width of the display, in pixels.
* @param {number} height - The coordinate height of the display, in pixels.
* @param {Array<number>} origin - The origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {number} [scaleFactor=1] - Optional scaleFactor by which to multiply
* the width and height to determine the final pixel size.
* @return {Renderer} - This renderer instance.
*/
prototype.initialize = function(el, width, height, origin, scaleFactor) {
this._el = el;
return this.resize(width, height, origin, scaleFactor);
};
/**
* Returns the parent container element for a visualization.
* @return {DOMElement} - The containing DOM element.
*/
element() {
return this._el;
},
/**
* Returns the parent container element for a visualization.
* @return {DOMElement} - The containing DOM element.
*/
prototype.element = function() {
return this._el;
};
/**
* Returns the scene element (e.g., canvas or SVG) of the visualization
* Subclasses must override if the first child is not the scene element.
* @return {DOMElement} - The scene (e.g., canvas or SVG) element.
*/
canvas() {
return this._el && this._el.firstChild;
},
/**
* Returns the scene element (e.g., canvas or SVG) of the visualization
* Subclasses must override if the first child is not the scene element.
* @return {DOMElement} - The scene (e.g., canvas or SVG) element.
*/
prototype.canvas = function() {
return this._el && this._el.firstChild;
};
/**
* Get / set the background color.
*/
background(bgcolor) {
if (arguments.length === 0) return this._bgcolor;
this._bgcolor = bgcolor;
return this;
},
/**
* Get / set the background color.
*/
prototype.background = function(bgcolor) {
if (arguments.length === 0) return this._bgcolor;
this._bgcolor = bgcolor;
return this;
};
/**
* Resize the display.
* @param {number} width - The new coordinate width of the display, in pixels.
* @param {number} height - The new coordinate height of the display, in pixels.
* @param {Array<number>} origin - The new origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {number} [scaleFactor=1] - Optional scaleFactor by which to multiply
* the width and height to determine the final pixel size.
* @return {Renderer} - This renderer instance;
*/
resize(width, height, origin, scaleFactor) {
this._width = width;
this._height = height;
this._origin = origin || [0, 0];
this._scale = scaleFactor || 1;
return this;
},
/**
* Resize the display.
* @param {number} width - The new coordinate width of the display, in pixels.
* @param {number} height - The new coordinate height of the display, in pixels.
* @param {Array<number>} origin - The new origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {number} [scaleFactor=1] - Optional scaleFactor by which to multiply
* the width and height to determine the final pixel size.
* @return {Renderer} - This renderer instance;
*/
prototype.resize = function(width, height, origin, scaleFactor) {
this._width = width;
this._height = height;
this._origin = origin || [0, 0];
this._scale = scaleFactor || 1;
return this;
};
/**
* Report a dirty item whose bounds should be redrawn.
* This base class method does nothing. Subclasses that perform
* incremental should implement this method.
* @param {Item} item - The dirty item whose bounds should be redrawn.
*/
dirty(/*item*/) {},
/**
* Report a dirty item whose bounds should be redrawn.
* This base class method does nothing. Subclasses that perform
* incremental should implement this method.
* @param {Item} item - The dirty item whose bounds should be redrawn.
*/
prototype.dirty = function(/*item*/) {
};
/**
* Render an input scenegraph, potentially with a set of dirty items.
* This method will perform an immediate rendering with available resources.
* The renderer may also need to perform image loading to perform a complete
* render. This process can lead to asynchronous re-rendering of the scene
* after this method returns. To receive notification when rendering is
* complete, use the renderAsync method instead.
* @param {object} scene - The root mark of a scenegraph to render.
* @return {Renderer} - This renderer instance.
*/
render(scene) {
var r = this;
/**
* Render an input scenegraph, potentially with a set of dirty items.
* This method will perform an immediate rendering with available resources.
* The renderer may also need to perform image loading to perform a complete
* render. This process can lead to asynchronous re-rendering of the scene
* after this method returns. To receive notification when rendering is
* complete, use the renderAsync method instead.
* @param {object} scene - The root mark of a scenegraph to render.
* @return {Renderer} - This renderer instance.
*/
prototype.render = function(scene) {
var r = this;
// bind arguments into a render call, and cache it
// this function may be subsequently called for async redraw
r._call = function() { r._render(scene); };
// bind arguments into a render call, and cache it
// this function may be subsequently called for async redraw
r._call = function() { r._render(scene); };
// invoke the renderer
r._call();
// invoke the renderer
r._call();
// clear the cached call for garbage collection
// async redraws will stash their own copy
r._call = null;
// clear the cached call for garbage collection
// async redraws will stash their own copy
r._call = null;
return r;
},
return r;
};
/**
* Internal rendering method. Renderer subclasses should override this
* method to actually perform rendering.
* @param {object} scene - The root mark of a scenegraph to render.
*/
_render(/*scene*/) {
// subclasses to override
},
/**
* Internal rendering method. Renderer subclasses should override this
* method to actually perform rendering.
* @param {object} scene - The root mark of a scenegraph to render.
*/
prototype._render = function(/*scene*/) {
// subclasses to override
};
/**
* Asynchronous rendering method. Similar to render, but returns a Promise
* that resolves when all rendering is completed. Sometimes a renderer must
* perform image loading to get a complete rendering. The returned
* Promise will not resolve until this process completes.
* @param {object} scene - The root mark of a scenegraph to render.
* @return {Promise} - A Promise that resolves when rendering is complete.
*/
renderAsync(scene) {
var r = this.render(scene);
return this._ready
? this._ready.then(function() { return r; })
: Promise.resolve(r);
},
/**
* Asynchronous rendering method. Similar to render, but returns a Promise
* that resolves when all rendering is completed. Sometimes a renderer must
* perform image loading to get a complete rendering. The returned
* Promise will not resolve until this process completes.
* @param {object} scene - The root mark of a scenegraph to render.
* @return {Promise} - A Promise that resolves when rendering is complete.
*/
prototype.renderAsync = function(scene) {
var r = this.render(scene);
return this._ready
? this._ready.then(function() { return r; })
: Promise.resolve(r);
};
/**
* Internal method for asynchronous resource loading.
* Proxies method calls to the ImageLoader, and tracks loading
* progress to invoke a re-render once complete.
* @param {string} method - The method name to invoke on the ImageLoader.
* @param {string} uri - The URI for the requested resource.
* @return {Promise} - A Promise that resolves to the requested resource.
*/
_load(method, uri) {
var r = this,
p = r._loader[method](uri);
/**
* Internal method for asynchronous resource loading.
* Proxies method calls to the ImageLoader, and tracks loading
* progress to invoke a re-render once complete.
* @param {string} method - The method name to invoke on the ImageLoader.
* @param {string} uri - The URI for the requested resource.
* @return {Promise} - A Promise that resolves to the requested resource.
*/
prototype._load = function(method, uri) {
var r = this,
p = r._loader[method](uri);
if (!r._ready) {
// re-render the scene when loading completes
var call = r._call;
r._ready = r._loader.ready()
.then(function(redraw) {
if (redraw) call();
r._ready = null;
});
}
if (!r._ready) {
// re-render the scene when loading completes
var call = r._call;
r._ready = r._loader.ready()
.then(function(redraw) {
if (redraw) call();
r._ready = null;
});
}
return p;
},
return p;
};
/**
* Sanitize a URL to include as a hyperlink in the rendered scene.
* This method proxies a call to ImageLoader.sanitizeURL, but also tracks
* image loading progress and invokes a re-render once complete.
* @param {string} uri - The URI string to sanitize.
* @return {Promise} - A Promise that resolves to the sanitized URL.
*/
sanitizeURL(uri) {
return this._load('sanitizeURL', uri);
},
/**
* Sanitize a URL to include as a hyperlink in the rendered scene.
* This method proxies a call to ImageLoader.sanitizeURL, but also tracks
* image loading progress and invokes a re-render once complete.
* @param {string} uri - The URI string to sanitize.
* @return {Promise} - A Promise that resolves to the sanitized URL.
*/
prototype.sanitizeURL = function(uri) {
return this._load('sanitizeURL', uri);
/**
* Requests an image to include in the rendered scene.
* This method proxies a call to ImageLoader.loadImage, but also tracks
* image loading progress and invokes a re-render once complete.
* @param {string} uri - The URI string of the image.
* @return {Promise} - A Promise that resolves to the loaded Image.
*/
loadImage(uri) {
return this._load('loadImage', uri);
}
};
/**
* Requests an image to include in the rendered scene.
* This method proxies a call to ImageLoader.loadImage, but also tracks
* image loading progress and invokes a re-render once complete.
* @param {string} uri - The URI string of the image.
* @return {Promise} - A Promise that resolves to the loaded Image.
*/
prototype.loadImage = function(uri) {
return this._load('loadImage', uri);
};

@@ -10,8 +10,2 @@ import {image} from 'vega-canvas';

var prototype = ResourceLoader.prototype;
prototype.pending = function() {
return this._pending;
};
function increment(loader) {

@@ -25,57 +19,63 @@ loader._pending += 1;

prototype.sanitizeURL = function(uri) {
var loader = this;
increment(loader);
ResourceLoader.prototype = {
pending() {
return this._pending;
},
return loader._loader.sanitize(uri, {context:'href'})
.then(function(opt) {
decrement(loader);
return opt;
})
.catch(function() {
decrement(loader);
return null;
});
};
sanitizeURL(uri) {
var loader = this;
increment(loader);
prototype.loadImage = function(uri) {
const loader = this,
Image = image();
increment(loader);
return loader._loader.sanitize(uri, {context:'href'})
.then(function(opt) {
decrement(loader);
return opt;
})
.catch(function() {
decrement(loader);
return null;
});
},
return loader._loader
.sanitize(uri, {context: 'image'})
.then(function(opt) {
const url = opt.href;
if (!url || !Image) throw {url: url};
loadImage(uri) {
const loader = this,
Image = image();
increment(loader);
const img = new Image();
return loader._loader
.sanitize(uri, {context: 'image'})
.then(function(opt) {
const url = opt.href;
if (!url || !Image) throw {url: url};
// set crossOrigin only if cors is defined; empty string sets anonymous mode
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/crossOrigin
const cors = hasOwnProperty(opt, 'crossOrigin') ? opt.crossOrigin : 'anonymous';
if (cors != null) img.crossOrigin = cors;
const img = new Image();
// attempt to load image resource
img.onload = () => decrement(loader);
img.onerror = () => decrement(loader);
img.src = url;
// set crossOrigin only if cors is defined; empty string sets anonymous mode
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/crossOrigin
const cors = hasOwnProperty(opt, 'crossOrigin') ? opt.crossOrigin : 'anonymous';
if (cors != null) img.crossOrigin = cors;
return img;
})
.catch(function(e) {
decrement(loader);
return {complete: false, width: 0, height: 0, src: e && e.url || ''};
// attempt to load image resource
img.onload = () => decrement(loader);
img.onerror = () => decrement(loader);
img.src = url;
return img;
})
.catch(function(e) {
decrement(loader);
return {complete: false, width: 0, height: 0, src: e && e.url || ''};
});
},
ready() {
var loader = this;
return new Promise(function(accept) {
function poll(value) {
if (!loader.pending()) accept(value);
else setTimeout(function() { poll(true); }, 10);
}
poll(false);
});
}
};
prototype.ready = function() {
var loader = this;
return new Promise(function(accept) {
function poll(value) {
if (!loader.pending()) accept(value);
else setTimeout(function() { poll(true); }, 10);
}
poll(false);
});
};

@@ -18,16 +18,16 @@ import Bounds from './Bounds';

var prototype = Scenegraph.prototype;
Scenegraph.prototype = {
toJSON(indent) {
return sceneToJSON(this.root, indent || 0);
},
prototype.toJSON = function(indent) {
return sceneToJSON(this.root, indent || 0);
mark(markdef, group, index) {
group = group || this.root.items[0];
var mark = createMark(markdef, group);
group.items[index] = mark;
if (mark.zindex) mark.group.zdirty = true;
return mark;
}
};
prototype.mark = function(markdef, group, index) {
group = group || this.root.items[0];
var mark = createMark(markdef, group);
group.items[index] = mark;
if (mark.zindex) mark.group.zdirty = true;
return mark;
};
function createMark(def, group) {

@@ -34,0 +34,0 @@ const mark = {

@@ -17,24 +17,2 @@ import Handler from './Handler';

const prototype = inherits(SVGHandler, Handler);
prototype.initialize = function(el, origin, obj) {
let svg = this._svg;
if (svg) {
svg.removeEventListener(HrefEvent, this._hrefHandler);
svg.removeEventListener(TooltipShowEvent, this._tooltipHandler);
svg.removeEventListener(TooltipHideEvent, this._tooltipHandler);
}
this._svg = svg = el && domFind(el, 'svg');
if (svg) {
svg.addEventListener(HrefEvent, this._hrefHandler);
svg.addEventListener(TooltipShowEvent, this._tooltipHandler);
svg.addEventListener(TooltipHideEvent, this._tooltipHandler);
}
return Handler.prototype.initialize.call(this, el, origin, obj);
};
prototype.canvas = function() {
return this._svg;
};
// wrap an event listener for the SVG DOM

@@ -48,38 +26,60 @@ const listener = (context, handler) => evt => {

// add an event handler
prototype.on = function(type, handler) {
const name = this.eventName(type),
h = this._handlers,
i = this._handlerIndex(h[name], type, handler);
inherits(SVGHandler, Handler, {
initialize(el, origin, obj) {
let svg = this._svg;
if (svg) {
svg.removeEventListener(HrefEvent, this._hrefHandler);
svg.removeEventListener(TooltipShowEvent, this._tooltipHandler);
svg.removeEventListener(TooltipHideEvent, this._tooltipHandler);
}
this._svg = svg = el && domFind(el, 'svg');
if (svg) {
svg.addEventListener(HrefEvent, this._hrefHandler);
svg.addEventListener(TooltipShowEvent, this._tooltipHandler);
svg.addEventListener(TooltipHideEvent, this._tooltipHandler);
}
return Handler.prototype.initialize.call(this, el, origin, obj);
},
if (i < 0) {
const x = {
type,
handler,
listener: listener(this, handler)
};
canvas() {
return this._svg;
},
(h[name] || (h[name] = [])).push(x);
if (this._svg) {
this._svg.addEventListener(name, x.listener);
// add an event handler
on(type, handler) {
const name = this.eventName(type),
h = this._handlers,
i = this._handlerIndex(h[name], type, handler);
if (i < 0) {
const x = {
type,
handler,
listener: listener(this, handler)
};
(h[name] || (h[name] = [])).push(x);
if (this._svg) {
this._svg.addEventListener(name, x.listener);
}
}
}
return this;
};
return this;
},
// remove an event handler
prototype.off = function(type, handler) {
const name = this.eventName(type),
h = this._handlers[name],
i = this._handlerIndex(h, type, handler);
// remove an event handler
off(type, handler) {
const name = this.eventName(type),
h = this._handlers[name],
i = this._handlerIndex(h, type, handler);
if (i >= 0) {
if (this._svg) {
this._svg.removeEventListener(name, h[i].listener);
if (i >= 0) {
if (this._svg) {
this._svg.removeEventListener(name, h[i].listener);
}
h.splice(i, 1);
}
h.splice(i, 1);
return this;
}
return this;
};
});

@@ -6,3 +6,3 @@ import Renderer from './Renderer';

import {cssClass, domChild, domClear, domCreate} from './util/dom';
import {closeTag, openTag} from './util/tags';
import {serializeXML} from './util/markup';
import {fontFamily, fontSize, lineHeight, textLines, textValue} from './util/text';

@@ -27,277 +27,364 @@ import {visit} from './util/visit';

var prototype = inherits(SVGRenderer, Renderer);
var base = Renderer.prototype;
const base = Renderer.prototype;
prototype.initialize = function(el, width, height, padding) {
// create the svg definitions cache
this._defs = {
gradient: {},
clipping: {}
};
inherits(SVGRenderer, Renderer, {
/**
* Initialize a new SVGRenderer instance.
* @param {DOMElement} el - The containing DOM element for the display.
* @param {number} width - The coordinate width of the display, in pixels.
* @param {number} height - The coordinate height of the display, in pixels.
* @param {Array<number>} origin - The origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {number} [scaleFactor=1] - Optional scaleFactor by which to multiply
* the width and height to determine the final pixel size.
* @return {SVGRenderer} - This renderer instance.
*/
initialize(el, width, height, origin, scaleFactor) {
// create the svg definitions cache
this._defs = {};
this._clearDefs();
if (el) {
this._svg = domChild(el, 0, 'svg', ns);
this._svg.setAttribute('class', 'marks');
domClear(el, 1);
if (el) {
this._svg = domChild(el, 0, 'svg', ns);
setAttributes(this._svg, metadata);
this._svg.setAttribute('class', 'marks');
domClear(el, 1);
// set the svg root group
this._root = domChild(this._svg, RootIndex, 'g', ns);
for (const attr in rootAttributes) {
this._root.setAttribute(attr, rootAttributes[attr]);
// set the svg root group
this._root = domChild(this._svg, RootIndex, 'g', ns);
setAttributes(this._root, rootAttributes);
// ensure no additional child elements
domClear(this._svg, RootIndex + 1);
}
// ensure no additional child elements
domClear(this._svg, RootIndex + 1);
}
// set background color if defined
this.background(this._bgcolor);
// set background color if defined
this.background(this._bgcolor);
return base.initialize.call(this, el, width, height, origin, scaleFactor);
},
return base.initialize.call(this, el, width, height, padding);
};
/**
* Get / set the background color.
*/
background(bgcolor) {
if (arguments.length && this._svg) {
this._svg.style.setProperty('background-color', bgcolor);
}
return base.background.apply(this, arguments);
},
prototype.background = function(bgcolor) {
if (arguments.length && this._svg) {
this._svg.style.setProperty('background-color', bgcolor);
}
return base.background.apply(this, arguments);
};
/**
* Resize the display.
* @param {number} width - The new coordinate width of the display, in pixels.
* @param {number} height - The new coordinate height of the display, in pixels.
* @param {Array<number>} origin - The new origin of the display, in pixels.
* The coordinate system will be translated to this point.
* @param {number} [scaleFactor=1] - Optional scaleFactor by which to multiply
* the width and height to determine the final pixel size.
* @return {SVGRenderer} - This renderer instance;
*/
resize(width, height, origin, scaleFactor) {
base.resize.call(this, width, height, origin, scaleFactor);
prototype.resize = function(width, height, origin, scaleFactor) {
base.resize.call(this, width, height, origin, scaleFactor);
if (this._svg) {
setAttributes(this._svg, {
width: this._width * this._scale,
height: this._height * this._scale,
viewBox: `0 0 ${this._width} ${this._height}`
});
this._root.setAttribute('transform', `translate(${this._origin})`);
}
if (this._svg) {
this._svg.setAttribute('width', this._width * this._scale);
this._svg.setAttribute('height', this._height * this._scale);
this._svg.setAttribute('viewBox', '0 0 ' + this._width + ' ' + this._height);
this._root.setAttribute('transform', 'translate(' + this._origin + ')');
}
this._dirty = [];
this._dirty = [];
return this;
},
return this;
};
/**
* Returns the SVG element of the visualization.
* @return {DOMElement} - The SVG element.
*/
canvas() {
return this._svg;
},
prototype.canvas = function() {
return this._svg;
};
/**
* Returns an SVG text string for the rendered content,
* or null if this renderer is currently headless.
*/
svg() {
const svg = this._svg,
bg = this._bgcolor;
prototype.svg = function() {
if (!this._svg) return null;
if (!svg) return null;
var attr = {
class: 'marks',
width: this._width * this._scale,
height: this._height * this._scale,
viewBox: '0 0 ' + this._width + ' ' + this._height
};
for (var key in metadata) {
attr[key] = metadata[key];
}
let node;
if (bg) {
svg.removeAttribute('style');
node = domChild(svg, RootIndex, 'rect', ns);
setAttributes(node, {width: this._width, height: this._height, fill: bg});
}
var bg = !this._bgcolor ? ''
: (openTag('rect', {
width: this._width,
height: this._height,
fill: this._bgcolor
}) + closeTag('rect'));
const text = serializeXML(svg);
return openTag('svg', attr)
+ (this._defs.el ? this._defs.el.outerHTML : '')
+ bg
+ this._root.outerHTML
+ closeTag('svg');
};
if (bg) {
svg.removeChild(node);
this._svg.style.setProperty('background-color', bg);
}
return text;
},
// -- Render entry point --
/**
* Internal rendering method.
* @param {object} scene - The root mark of a scenegraph to render.
*/
_render(scene) {
// perform spot updates and re-render markup
if (this._dirtyCheck()) {
if (this._dirtyAll) this._clearDefs();
this.mark(this._root, scene);
domClear(this._root, 1);
}
prototype._render = function(scene) {
// perform spot updates and re-render markup
if (this._dirtyCheck()) {
if (this._dirtyAll) this._resetDefs();
this.draw(this._root, scene);
domClear(this._root, 1);
}
this.defs();
this.updateDefs();
this._dirty = [];
++this._dirtyID;
this._dirty = [];
++this._dirtyID;
return this;
},
return this;
};
// -- Manage rendering of items marked as dirty --
// -- Manage SVG definitions ('defs') block --
/**
* Flag a mark item as dirty.
* @param {Item} item - The mark item.
*/
dirty(item) {
if (item.dirty !== this._dirtyID) {
item.dirty = this._dirtyID;
this._dirty.push(item);
}
},
prototype.updateDefs = function() {
const svg = this._svg,
defs = this._defs;
/**
* Check if a mark item is considered dirty.
* @param {Item} item - The mark item.
*/
isDirty(item) {
return this._dirtyAll
|| !item._svg
|| item.dirty === this._dirtyID;
},
let el = defs.el,
index = 0;
/**
* Internal method to check dirty status and, if possible,
* make targetted updates without a full rendering pass.
*/
_dirtyCheck() {
this._dirtyAll = true;
const items = this._dirty;
if (!items.length || !this._dirtyID) return true;
for (const id in defs.gradient) {
if (!el) defs.el = (el = domChild(svg, RootIndex, 'defs', ns));
index = updateGradient(el, defs.gradient[id], index);
}
let id = ++this._dirtyID,
item, mark, type, mdef, i, n, o;
for (const id in defs.clipping) {
if (!el) defs.el = (el = domChild(svg, RootIndex, 'defs', ns));
index = updateClipping(el, defs.clipping[id], index);
}
for (i=0, n=items.length; i<n; ++i) {
item = items[i];
mark = item.mark;
// clean-up
if (el) {
index === 0
? (svg.removeChild(el), defs.el = null)
: domClear(el, index);
}
};
if (mark.marktype !== type) {
// memoize mark instance lookup
type = mark.marktype;
mdef = marks[type];
}
function updateGradient(el, grad, index) {
var i, n, stop;
if (mark.zdirty && mark.dirty !== id) {
this._dirtyAll = false;
dirtyParents(item, id);
mark.items.forEach(function(i) { i.dirty = id; });
}
if (mark.zdirty) continue; // handle in standard drawing pass
if (grad.gradient === 'radial') {
// SVG radial gradients automatically transform to normalized bbox
// coordinates, in a way that is cumbersome to replicate in canvas.
// We wrap the radial gradient in a pattern element, allowing us to
// maintain a circular gradient that matches what canvas provides.
var pt = domChild(el, index++, 'pattern', ns);
pt.setAttribute('id', patternPrefix + grad.id);
pt.setAttribute('viewBox', '0,0,1,1');
pt.setAttribute('width', '100%');
pt.setAttribute('height', '100%');
pt.setAttribute('preserveAspectRatio', 'xMidYMid slice');
if (item.exit) { // EXIT
if (mdef.nested && mark.items.length) {
// if nested mark with remaining points, update instead
o = mark.items[0];
if (o._svg) this._update(mdef, o._svg, o);
} else if (item._svg) {
// otherwise remove from DOM
o = item._svg.parentNode;
if (o) o.removeChild(item._svg);
}
item._svg = null;
continue;
}
pt = domChild(pt, 0, 'rect', ns);
pt.setAttribute('width', '1');
pt.setAttribute('height', '1');
pt.setAttribute('fill', 'url(' + href() + '#' + grad.id + ')');
item = (mdef.nested ? mark.items[0] : item);
if (item._update === id) continue; // already visited
el = domChild(el, index++, 'radialGradient', ns);
el.setAttribute('id', grad.id);
el.setAttribute('fx', grad.x1);
el.setAttribute('fy', grad.y1);
el.setAttribute('fr', grad.r1);
el.setAttribute('cx', grad.x2);
el.setAttribute('cy', grad.y2);
el.setAttribute( 'r', grad.r2);
} else {
el = domChild(el, index++, 'linearGradient', ns);
el.setAttribute('id', grad.id);
el.setAttribute('x1', grad.x1);
el.setAttribute('x2', grad.x2);
el.setAttribute('y1', grad.y1);
el.setAttribute('y2', grad.y2);
}
if (!item._svg || !item._svg.ownerSVGElement) {
// ENTER
this._dirtyAll = false;
dirtyParents(item, id);
} else {
// IN-PLACE UPDATE
this._update(mdef, item._svg, item);
}
item._update = id;
}
return !this._dirtyAll;
},
for (i=0, n=grad.stops.length; i<n; ++i) {
stop = domChild(el, i, 'stop', ns);
stop.setAttribute('offset', grad.stops[i].offset);
stop.setAttribute('stop-color', grad.stops[i].color);
}
domClear(el, i);
// -- Construct & maintain scenegraph to SVG mapping ---
return index;
}
/**
* Render a set of mark items.
* @param {SVGElement} el - The parent element in the SVG tree.
* @param {object} scene - The mark parent to render.
* @param {SVGElement} prev - The previous sibling in the SVG tree.
*/
mark(el, scene, prev) {
if (!this.isDirty(scene)) return scene._svg;
function updateClipping(el, clip, index) {
var mask;
let svg = this._svg,
mdef = marks[scene.marktype],
events = scene.interactive === false ? 'none' : null,
isGroup = mdef.tag === 'g',
sibling = null,
i = 0,
parent;
el = domChild(el, index, 'clipPath', ns);
el.setAttribute('id', clip.id);
parent = bind(scene, el, prev, 'g', svg);
parent.setAttribute('class', cssClass(scene));
if (clip.path) {
mask = domChild(el, 0, 'path', ns);
mask.setAttribute('d', clip.path);
} else {
mask = domChild(el, 0, 'rect', ns);
mask.setAttribute('x', 0);
mask.setAttribute('y', 0);
mask.setAttribute('width', clip.width);
mask.setAttribute('height', clip.height);
}
domClear(el, 1);
// apply aria attributes to parent container element
const aria = ariaMarkAttributes(scene);
for (const key in aria) setAttribute(parent, key, aria[key]);
return index + 1;
}
if (!isGroup) {
setAttribute(parent, 'pointer-events', events);
}
setAttribute(parent, 'clip-path',
scene.clip ? clip(this, scene, scene.group) : null);
prototype._resetDefs = function() {
var def = this._defs;
def.gradient = {};
def.clipping = {};
};
const process = item => {
const dirty = this.isDirty(item),
node = bind(item, parent, sibling, mdef.tag, svg);
if (dirty) {
this._update(mdef, node, item);
if (isGroup) recurse(this, node, item);
}
// -- Manage rendering of items marked as dirty --
sibling = node;
++i;
};
prototype.dirty = function(item) {
if (item.dirty !== this._dirtyID) {
item.dirty = this._dirtyID;
this._dirty.push(item);
}
};
if (mdef.nested) {
if (scene.items.length) process(scene.items[0]);
} else {
visit(scene, process);
}
prototype.isDirty = function(item) {
return this._dirtyAll
|| !item._svg
|| item.dirty === this._dirtyID;
};
domClear(parent, i);
return parent;
},
prototype._dirtyCheck = function() {
this._dirtyAll = true;
var items = this._dirty;
if (!items.length || !this._dirtyID) return true;
/**
* Update the attributes of an SVG element for a mark item.
* @param {object} mdef - The mark definition object
* @param {SVGElement} el - The SVG element.
* @param {Item} item - The mark item.
*/
_update(mdef, el, item) {
// set dom element and values cache
// provides access to emit method
element = el;
values = el.__values__;
var id = ++this._dirtyID,
item, mark, type, mdef, i, n, o;
// apply aria-specific properties
ariaItemAttributes(emit, item);
for (i=0, n=items.length; i<n; ++i) {
item = items[i];
mark = item.mark;
// apply svg attributes
mdef.attr(emit, item, this);
if (mark.marktype !== type) {
// memoize mark instance lookup
type = mark.marktype;
mdef = marks[type];
// some marks need special treatment
const extra = mark_extras[mdef.type];
if (extra) extra.call(this, mdef, el, item);
// apply svg style attributes
// note: element state may have been modified by 'extra' method
if (element) this.style(element, item);
},
/**
* Update the presentation attributes of an SVG element for a mark item.
* @param {SVGElement} el - The SVG element.
* @param {Item} item - The mark item.
*/
style(el, item) {
if (item == null) return;
for (const prop in styles) {
let value = prop === 'font' ? fontFamily(item) : item[prop];
if (value === values[prop]) continue;
const name = styles[prop];
if (value == null) {
el.removeAttribute(name);
} else {
if (isGradient(value)) {
value = gradientRef(value, this._defs.gradient, href());
}
el.setAttribute(name, value + '');
}
values[prop] = value;
}
},
if (mark.zdirty && mark.dirty !== id) {
this._dirtyAll = false;
dirtyParents(item, id);
mark.items.forEach(function(i) { i.dirty = id; });
/**
* Render SVG defs, as needed.
* Must be called *after* marks have been processed to ensure the
* collected state is current and accurate.
*/
defs() {
const svg = this._svg,
defs = this._defs;
let el = defs.el,
index = 0;
for (const id in defs.gradient) {
if (!el) defs.el = (el = domChild(svg, RootIndex + 1, 'defs', ns));
index = updateGradient(el, defs.gradient[id], index);
}
if (mark.zdirty) continue; // handle in standard drawing pass
if (item.exit) { // EXIT
if (mdef.nested && mark.items.length) {
// if nested mark with remaining points, update instead
o = mark.items[0];
if (o._svg) this._update(mdef, o._svg, o);
} else if (item._svg) {
// otherwise remove from DOM
o = item._svg.parentNode;
if (o) o.removeChild(item._svg);
}
item._svg = null;
continue;
for (const id in defs.clipping) {
if (!el) defs.el = (el = domChild(svg, RootIndex + 1, 'defs', ns));
index = updateClipping(el, defs.clipping[id], index);
}
item = (mdef.nested ? mark.items[0] : item);
if (item._update === id) continue; // already visited
// clean-up
if (el) {
index === 0
? (svg.removeChild(el), defs.el = null)
: domClear(el, index);
}
},
if (!item._svg || !item._svg.ownerSVGElement) {
// ENTER
this._dirtyAll = false;
dirtyParents(item, id);
} else {
// IN-PLACE UPDATE
this._update(mdef, item._svg, item);
}
item._update = id;
/**
* Clear defs caches.
*/
_clearDefs() {
const def = this._defs;
def.gradient = {};
def.clipping = {};
}
return !this._dirtyAll;
};
});
// mark ancestor chain with a dirty id
function dirtyParents(item, id) {

@@ -312,52 +399,76 @@ for (; item && item.dirty !== id; item=item.mark.group) {

// update gradient definitions
function updateGradient(el, grad, index) {
let i, n, stop;
// -- Construct & maintain scenegraph to SVG mapping ---
if (grad.gradient === 'radial') {
// SVG radial gradients automatically transform to normalized bbox
// coordinates, in a way that is cumbersome to replicate in canvas.
// We wrap the radial gradient in a pattern element, allowing us to
// maintain a circular gradient that matches what canvas provides.
let pt = domChild(el, index++, 'pattern', ns);
setAttributes(pt, {
id: patternPrefix + grad.id,
viewBox: '0,0,1,1',
width: '100%',
height: '100%',
preserveAspectRatio: 'xMidYMid slice'
});
// Draw a mark container.
prototype.draw = function(el, scene, prev) {
if (!this.isDirty(scene)) return scene._svg;
pt = domChild(pt, 0, 'rect', ns);
setAttributes(pt, {
width: 1,
height: 1,
fill: `url(${href()}#${grad.id})`
});
var svg = this._svg,
mdef = marks[scene.marktype],
events = scene.interactive === false ? 'none' : null,
isGroup = mdef.tag === 'g',
sibling = null,
i = 0,
parent;
el = domChild(el, index++, 'radialGradient', ns);
setAttributes(el, {
id: grad.id,
fx: grad.x1,
fy: grad.y1,
fr: grad.r1,
cx: grad.x2,
cy: grad.y2,
r: grad.r2
});
} else {
el = domChild(el, index++, 'linearGradient', ns);
setAttributes(el, {
id: grad.id,
x1: grad.x1,
x2: grad.x2,
y1: grad.y1,
y2: grad.y2
});
}
parent = bind(scene, el, prev, 'g', svg);
parent.setAttribute('class', cssClass(scene));
// apply aria attributes to parent container element
const aria = ariaMarkAttributes(scene);
for (const key in aria) setAttribute(parent, key, aria[key]);
if (!isGroup) {
setAttribute(parent, 'pointer-events', events);
for (i=0, n=grad.stops.length; i<n; ++i) {
stop = domChild(el, i, 'stop', ns);
stop.setAttribute('offset', grad.stops[i].offset);
stop.setAttribute('stop-color', grad.stops[i].color);
}
setAttribute(parent, 'clip-path',
scene.clip ? clip(this, scene, scene.group) : null);
domClear(el, i);
const process = item => {
const dirty = this.isDirty(item),
node = bind(item, parent, sibling, mdef.tag, svg);
return index;
}
if (dirty) {
this._update(mdef, node, item);
if (isGroup) recurse(this, node, item);
}
// update clipping path definitions
function updateClipping(el, clip, index) {
let mask;
sibling = node;
++i;
};
el = domChild(el, index, 'clipPath', ns);
el.setAttribute('id', clip.id);
if (mdef.nested) {
if (scene.items.length) process(scene.items[0]);
if (clip.path) {
mask = domChild(el, 0, 'path', ns);
mask.setAttribute('d', clip.path);
} else {
visit(scene, process);
mask = domChild(el, 0, 'rect', ns);
setAttributes(mask, {x: 0, y: 0, width: clip.width, height: clip.height});
}
domClear(el, 1);
domClear(parent, i);
return parent;
};
return index + 1;
}

@@ -370,3 +481,3 @@ // Recursively process group contents.

visit(group, item => {
prev = renderer.draw(el, item, prev);
prev = renderer.mark(el, item, prev);
++idx;

@@ -420,2 +531,3 @@ });

// check if two nodes are ordered siblings
function siblingCheck(node, sibling) {

@@ -427,11 +539,10 @@ return node.parentNode

// -- Set attributes & styles on SVG elements ---
var element = null, // temp var for current SVG element
let element = null, // temp var for current SVG element
values = null; // temp var for current values hash
// Extra configuration for certain mark types
var mark_extras = {
group: function(mdef, el, item) {
const mark_extras = {
group(mdef, el, item) {
const fg = element = el.childNodes[2];

@@ -476,3 +587,3 @@ values = fg.__values__;

},
image: function(mdef, el, item) {
image(mdef, el, item) {
if (item.smooth === false) {

@@ -485,3 +596,3 @@ setStyle(el, 'image-rendering', 'optimizeSpeed');

},
text: function(mdef, el, item) {
text(mdef, el, item) {
let tl = textLines(item),

@@ -528,34 +639,2 @@ key, value, doc, lh;

function setStyle(el, name, value) {
if (value !== values[name]) {
if (value == null) {
el.style.removeProperty(name);
} else {
el.style.setProperty(name, value + '');
}
values[name] = value;
}
}
prototype._update = function(mdef, el, item) {
// set dom element and values cache
// provides access to emit method
element = el;
values = el.__values__;
// apply aria-specific properties
ariaItemAttributes(emit, item);
// apply svg attributes
mdef.attr(emit, item, this);
// some marks need special treatment
const extra = mark_extras[mdef.type];
if (extra) extra.call(this, mdef, el, item);
// apply svg style attributes
// note: element may be modified by 'extra' method
if (element) this.style(element, item);
};
function emit(name, value, ns) {

@@ -576,2 +655,19 @@ // early exit if value is unchanged

function setStyle(el, name, value) {
if (value !== values[name]) {
if (value == null) {
el.style.removeProperty(name);
} else {
el.style.setProperty(name, value + '');
}
values[name] = value;
}
}
function setAttributes(el, attrs) {
for (const key in attrs) {
setAttribute(el, key, attrs[key]);
}
}
function setAttribute(el, name, value) {

@@ -597,23 +693,2 @@ if (value != null) {

prototype.style = function(el, o) {
if (o == null) return;
for (const prop in styles) {
let value = prop === 'font' ? fontFamily(o) : o[prop];
if (value === values[prop]) continue;
const name = styles[prop];
if (value == null) {
el.removeAttribute(name);
} else {
if (isGradient(value)) {
value = gradientRef(value, this._defs.gradient, href());
}
el.setAttribute(name, value + '');
}
values[prop] = value;
}
};
function href() {

@@ -620,0 +695,0 @@ let loc;

import Renderer from './Renderer';
import {gradientRef, isGradient, patternPrefix} from './Gradient';
import marks from './marks/index';
import Marks from './marks/index';
import {ariaItemAttributes, ariaMarkAttributes} from './util/aria';
import {cssClass} from './util/dom';
import {closeTag, openTag} from './util/tags';
import {markup} from './util/markup';
import {fontFamily, fontSize, lineHeight, textLines, textValue} from './util/text';

@@ -16,12 +16,3 @@ import {visit} from './util/visit';

Renderer.call(this, loader);
this._text = {
head: '',
bg: '',
root: '',
foot: '',
defs: '',
body: ''
};
this._text = null;
this._defs = {

@@ -33,287 +24,295 @@ gradient: {},

var prototype = inherits(SVGStringRenderer, Renderer);
var base = Renderer.prototype;
inherits(SVGStringRenderer, Renderer, {
/**
* Returns the rendered SVG text string,
* or null if rendering has not yet occurred.
*/
svg() {
return this._text;
},
prototype.resize = function(width, height, origin, scaleFactor) {
base.resize.call(this, width, height, origin, scaleFactor);
var o = this._origin,
t = this._text;
/**
* Internal rendering method.
* @param {object} scene - The root mark of a scenegraph to render.
*/
_render(scene) {
const m = markup();
var attr = {
class: 'marks',
width: this._width * this._scale,
height: this._height * this._scale,
viewBox: '0 0 ' + this._width + ' ' + this._height
};
for (var key in metadata) {
attr[key] = metadata[key];
}
// svg tag
m.open('svg', extend({}, metadata, {
class: 'marks',
width: this._width * this._scale,
height: this._height * this._scale,
viewBox: `0 0 ${this._width} ${this._height}`
}));
t.head = openTag('svg', attr);
// background, if defined
const bg = this._bgcolor;
if (bg && bg !== 'transparent' && bg !== 'none') {
m.open('rect', {
width: this._width,
height: this._height,
fill: bg
}).close();
}
var bg = this._bgcolor;
if (bg === 'transparent' || bg === 'none') bg = null;
// root content group
m.open('g', rootAttributes, {
transform: 'translate(' + this._origin + ')'
});
this.mark(m, scene);
m.close(); // </g>
if (bg) {
t.bg = openTag('rect', {
width: this._width,
height: this._height,
fill: bg
}) + closeTag('rect');
} else {
t.bg = '';
}
// defs
this.defs(m);
t.root = openTag('g', extend(
{}, rootAttributes, {transform: 'translate(' + o + ')'}
));
// get SVG text string
this._text = m.close() + '';
t.foot = closeTag('g') + closeTag('svg');
return this;
},
return this;
};
/**
* Render a set of mark items.
* @param {object} m - The markup context.
* @param {object} scene - The mark parent to render.
*/
mark(m, scene) {
const mdef = Marks[scene.marktype],
tag = mdef.tag,
attrList = [ariaItemAttributes, mdef.attr];
prototype.background = function() {
var rv = base.background.apply(this, arguments);
if (arguments.length && this._text.head) {
this.resize(this._width, this._height, this._origin, this._scale);
}
return rv;
};
// render opening group tag
m.open('g',
{
'class': cssClass(scene),
'clip-path': scene.clip ? clip(this, scene, scene.group) : null
},
ariaMarkAttributes(scene),
{
'pointer-events': tag !== 'g' && scene.interactive === false ? 'none' : null
}
);
prototype.svg = function() {
var t = this._text;
return t.head + t.defs + t.bg + t.root + t.body + t.foot;
};
// render contained elements
const process = item => {
const href = this.href(item);
if (href) m.open('a', href);
prototype._render = function(scene) {
this._text.body = this.mark(scene);
this._text.defs = this.buildDefs();
return this;
};
m.open(
tag,
this.attr(scene, item, attrList, tag !== 'g' ? tag : null)
);
prototype.buildDefs = function() {
let defs = '', tag;
if (tag === 'text') {
const tl = textLines(item);
if (isArray(tl)) {
// multi-line text
const attrs = {x: 0, dy: lineHeight(item)};
for (let i=0; i<tl.length; ++i) {
m.open('tspan', i ? attrs: null)
.text(textValue(item, tl[i]))
.close();
}
} else {
// single-line text
m.text(textValue(item, tl));
}
} else if (tag === 'g') {
const fore = item.strokeForeground,
fill = item.fill,
stroke = item.stroke;
for (const id in this._defs.gradient) {
const def = this._defs.gradient[id],
stops = def.stops;
if (fore && stroke) {
item.stroke = null;
}
if (def.gradient === 'radial') {
// SVG radial gradients automatically transform to normalized bbox
// coordinates, in a way that is cumbersome to replicate in canvas.
// We wrap the radial gradient in a pattern element, allowing us to
// maintain a circular gradient that matches what canvas provides.
m.open(
'path',
this.attr(scene, item, mdef.background, 'bgrect')
).close();
defs += openTag(tag = 'pattern', {
id: patternPrefix + id,
viewBox: '0,0,1,1',
width: '100%',
height: '100%',
preserveAspectRatio: 'xMidYMid slice'
});
// recurse for group content
m.open('g', this.attr(scene, item, mdef.content));
visit(item, scene => this.mark(m, scene));
m.close();
defs += openTag('rect', {
width: '1',
height: '1',
fill: 'url(#' + id + ')'
}) + closeTag('rect');
if (fore && stroke) {
if (fill) item.fill = null;
item.stroke = stroke;
defs += closeTag(tag);
m.open(
'path',
this.attr(scene, item, mdef.foreground, 'bgrect')
).close();
defs += openTag(tag = 'radialGradient', {
id: id,
fx: def.x1,
fy: def.y1,
fr: def.r1,
cx: def.x2,
cy: def.y2,
r: def.r2
});
if (fill) item.fill = fill;
} else {
m.open(
'path',
this.attr(scene, item, mdef.foreground, 'bgfore')
).close();
}
}
m.close(); // </tag>
if (href) m.close(); // </a>
};
if (mdef.nested) {
if (scene.items && scene.items.length) process(scene.items[0]);
} else {
defs += openTag(tag = 'linearGradient', {
id: id,
x1: def.x1,
x2: def.x2,
y1: def.y1,
y2: def.y2
});
visit(scene, process);
}
for (let i = 0; i < stops.length; ++i) {
defs += openTag('stop', {
offset: stops[i].offset,
'stop-color': stops[i].color
}) + closeTag('stop');
}
// render closing group tag
return m.close(); // </g>
},
defs += closeTag(tag);
}
/**
* Get href attributes for a hyperlinked mark item.
* @param {Item} item - The mark item.
*/
href(item) {
let href = item.href,
attr;
for (const id in this._defs.clipping) {
const def = this._defs.clipping[id];
if (href) {
if (attr = this._hrefs && this._hrefs[href]) {
return attr;
} else {
this.sanitizeURL(href).then(attr => {
// rewrite to use xlink namespace
attr['xlink:href'] = attr.href;
attr.href = null;
(this._hrefs || (this._hrefs = {}))[href] = attr;
});
}
}
return null;
},
defs += openTag('clipPath', {id: id});
/**
* Get an object of SVG attributes for a mark item.
* @param {object} scene - The mark parent.
* @param {Item} item - The mark item.
* @param {array|function} attrs - One or more attribute emitters.
* @param {string} tag - The tag being rendered.
*/
attr(scene, item, attrs, tag) {
const object = {},
emit = (name, value, ns, prefixed) => {
object[prefixed || name] = value;
};
if (def.path) {
defs += openTag('path', {
d: def.path
}) + closeTag('path');
// apply mark specific attributes
if (Array.isArray(attrs)) {
attrs.forEach(fn => fn(emit, item, this));
} else {
defs += openTag('rect', {
x: 0,
y: 0,
width: def.width,
height: def.height
}) + closeTag('rect');
attrs(emit, item, this);
}
defs += closeTag('clipPath');
}
// apply style attributes
if (tag) {
style(object, item, scene, tag, this._defs);
}
return defs ? (openTag('defs') + defs + closeTag('defs')) : '';
};
return object;
},
prototype.attr = function(scene, item, attrs, tag) {
const object = {},
emit = (name, value, ns, prefixed) => {
object[prefixed || name] = value;
};
/**
* Render SVG defs, as needed.
* Must be called *after* marks have been processed to ensure the
* collected state is current and accurate.
* @param {object} m - The markup context.
*/
defs(m) {
const gradient = this._defs.gradient,
clipping = this._defs.clipping,
count = Object.keys(gradient).length + Object.keys(clipping).length;
// apply mark specific attributes
if (Array.isArray(attrs)) {
attrs.forEach(fn => fn(emit, item, this));
} else {
attrs(emit, item, this);
}
if (count === 0) return; // nothing to do
// apply style attributes
if (tag) {
applyStyles(object, item, scene, tag, this._defs);
}
m.open('defs');
return object;
};
for (const id in gradient) {
const def = gradient[id],
stops = def.stops;
prototype.href = function(item) {
var that = this,
href = item.href,
attr;
if (def.gradient === 'radial') {
// SVG radial gradients automatically transform to normalized bbox
// coordinates, in a way that is cumbersome to replicate in canvas.
// We wrap the radial gradient in a pattern element, allowing us to
// maintain a circular gradient that matches what canvas provides.
if (href) {
if (attr = that._hrefs && that._hrefs[href]) {
return attr;
} else {
that.sanitizeURL(href).then(attr => {
// rewrite to use xlink namespace
// note that this will be deprecated in SVG 2.0
attr['xlink:href'] = attr.href;
attr.href = null;
(that._hrefs || (that._hrefs = {}))[href] = attr;
});
}
}
return null;
};
m.open('pattern', {
id: patternPrefix + id,
viewBox: '0,0,1,1',
width: '100%',
height: '100%',
preserveAspectRatio: 'xMidYMid slice'
});
prototype.mark = function(scene) {
const mdef = marks[scene.marktype],
tag = mdef.tag,
attrList = [ariaItemAttributes, mdef.attr];
m.open('rect', {
width: '1',
height: '1',
fill: 'url(#' + id + ')'
}).close();
let str = '';
m.close(); // </pattern>
// render opening group tag
str += openTag('g', extend(
{
'class': cssClass(scene),
'clip-path': scene.clip ? clip(this, scene, scene.group) : null
},
ariaMarkAttributes(scene),
{
'pointer-events': tag !== 'g' && scene.interactive === false ? 'none' : null
}
));
// render contained elements
const process = item => {
const href = this.href(item);
if (href) str += openTag('a', href);
str += openTag(
tag,
this.attr(scene, item, attrList, tag !== 'g' ? tag : null)
);
if (tag === 'text') {
const tl = textLines(item);
if (isArray(tl)) {
// multi-line text
const attrs = {x: 0, dy: lineHeight(item)};
for (let i=0; i<tl.length; ++i) {
str += openTag('tspan', i ? attrs: null)
+ escape_text(textValue(item, tl[i]))
+ closeTag('tspan');
}
m.open('radialGradient', {
id: id,
fx: def.x1,
fy: def.y1,
fr: def.r1,
cx: def.x2,
cy: def.y2,
r: def.r2
});
} else {
// single-line text
str += escape_text(textValue(item, tl));
m.open('linearGradient', {
id: id,
x1: def.x1,
x2: def.x2,
y1: def.y1,
y2: def.y2
});
}
} else if (tag === 'g') {
const fore = item.strokeForeground,
fill = item.fill,
stroke = item.stroke;
if (fore && stroke) {
item.stroke = null;
for (let i = 0; i < stops.length; ++i) {
m.open('stop', {
offset: stops[i].offset,
'stop-color': stops[i].color
}).close();
}
str += openTag(
'path',
this.attr(scene, item, mdef.background, 'bgrect')
) + closeTag('path');
m.close();
}
str += openTag('g', this.attr(scene, item, mdef.content))
+ this.markGroup(item)
+ closeTag('g');
for (const id in clipping) {
const def = clipping[id];
if (fore && stroke) {
if (fill) item.fill = null;
item.stroke = stroke;
str += openTag(
'path',
this.attr(scene, item, mdef.foreground, 'bgrect')
) + closeTag('path');
if (fill) item.fill = fill;
m.open('clipPath', {id: id});
if (def.path) {
m.open('path', {
d: def.path
}).close();
} else {
str += openTag(
'path',
this.attr(scene, item, mdef.foreground, 'bgfore')
) + closeTag('path');
m.open('rect', {
x: 0,
y: 0,
width: def.width,
height: def.height
}).close();
}
m.close();
}
str += closeTag(tag);
if (href) str += closeTag('a');
};
if (mdef.nested) {
if (scene.items && scene.items.length) process(scene.items[0]);
} else {
visit(scene, process);
m.close();
}
});
// render closing group tag
return str + closeTag('g');
};
prototype.markGroup = function(scene) {
let str = '';
visit(scene, item => { str += this.mark(item); });
return str;
};
function applyStyles(s, item, scene, tag, defs) {
// Helper function for attr for style presentation attributes
function style(s, item, scene, tag, defs) {
if (item == null) return s;

@@ -340,5 +339,5 @@

s['font-size'] = fontSize(item) + 'px';
if (item.fontStyle) s['font-style'] = item.fontStyle;
if (item.fontVariant) s['font-variant'] = item.fontVariant;
if (item.fontWeight) s['font-weight'] = item.fontWeight;
s['font-style'] = item.fontStyle;
s['font-variant'] = item.fontVariant;
s['font-weight'] = item.fontWeight;
}

@@ -363,7 +362,1 @@

}
function escape_text(s) {
return s.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
export default {
'version': '1.1',
'xmlns': 'http://www.w3.org/2000/svg',
'xmlns:xlink': 'http://www.w3.org/1999/xlink'
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
'version': '1.1'
};

@@ -17,6 +17,11 @@ export function translate(x, y) {

export function rotateItem(item) {
return translate(item.x || 0, item.y || 0)
+ (item.angle ? ' ' + rotate(item.angle) : '');
}
export function transformItem(item) {
return translate(item.x || 0, item.y || 0)
+ (item.angle ? ' ' + rotate(item.angle) : '')
+ (item.scaleX || item.scaleY ? ' ' + scale(item.scaleX || 1, item.scaleY || 1) : '');
+ (item.scaleX || item.scaleY ? ' ' + scale(item.scaleX || 1, item.scaleY || 1) : '');
}

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc