Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hanzi-writer

Package Overview
Dependencies
Maintainers
1
Versions
69
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hanzi-writer - npm Package Compare versions

Comparing version 3.4.1 to 3.4.2

4

dist/hanzi-writer.min.js
/**
* Hanzi Writer v3.4.1 | https://chanind.github.io/hanzi-writer
* Hanzi Writer v3.4.2 | https://chanind.github.io/hanzi-writer
*/
var HanziWriter=function(){"use strict";var t;const e="undefined"==typeof window?global:window,i=e.performance&&(()=>e.performance.now())||(()=>Date.now()),r=e.requestAnimationFrame||(t=>setTimeout(()=>t(i()),1e3/60)),s=e.cancelAnimationFrame||clearTimeout;function o(t){return t[t.length-1]}const n=(t,e)=>t<0?e+t:t;function a(t,e){const i={...t};for(const r in e){const s=t[r],o=e[r];s!==o&&(s&&o&&"object"==typeof s&&"object"==typeof o&&!Array.isArray(o)?i[r]=a(s,o):i[r]=o)}return i}let h=0;function l(){return h++,h}function c(t){return t.reduce((t,e)=>e+t,0)/t.length}function d(t){const e=t.toUpperCase().trim();if(/^#([A-F0-9]{3}){1,2}$/.test(e)){let t=e.substring(1).split("");3===t.length&&(t=[t[0],t[0],t[1],t[1],t[2],t[2]]);const i=""+t.join("");return{r:parseInt(i.slice(0,2),16),g:parseInt(i.slice(2,4),16),b:parseInt(i.slice(4,6),16),a:1}}const i=e.match(/^RGBA?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*(\d*\.?\d+))?\)$/);if(i)return{r:parseInt(i[1],10),g:parseInt(i[2],10),b:parseInt(i[3],10),a:parseFloat(i[4]||1,10)};throw new Error("Invalid color: "+t)}function u(t,e){const i={};for(let r=0;r<e;r++)i[r]=t;return i}function _(t,e){const i={};for(let r=0;r<t;r++)i[r]=e(r);return i}const p=(null===(t=e.navigator)||void 0===t?void 0:t.userAgent)||"",g=p.indexOf("MSIE ")>0||p.indexOf("Trident/")>0||p.indexOf("Edge/")>0,k=()=>{};class m{constructor(t,e,i=k){this._mutationChains=[],this._onStateChange=i,this.state={options:{drawingFadeDuration:e.drawingFadeDuration,drawingWidth:e.drawingWidth,drawingColor:d(e.drawingColor),strokeColor:d(e.strokeColor),outlineColor:d(e.outlineColor),radicalColor:d(e.radicalColor||e.strokeColor),highlightColor:d(e.highlightColor)},character:{main:{opacity:e.showCharacter?1:0,strokes:{}},outline:{opacity:e.showOutline?1:0,strokes:{}},highlight:{opacity:1,strokes:{}}},userStrokes:null};for(let e=0;e<t.strokes.length;e++)this.state.character.main.strokes[e]={opacity:1,displayPortion:1},this.state.character.outline.strokes[e]={opacity:1,displayPortion:1},this.state.character.highlight.strokes[e]={opacity:0,displayPortion:1}}overwriteOnStateChange(t){this._onStateChange=t}updateState(t){const e=a(this.state,t);this._onStateChange(e,this.state),this.state=e}run(t,e={}){const i=t.map(t=>t.scope);return this.cancelMutations(i),new Promise(r=>{const s={_isActive:!0,_index:0,_resolve:r,_mutations:t,_loop:e.loop,_scopes:i};this._mutationChains.push(s),this._run(s)})}_run(t){if(!t._isActive)return;const e=t._mutations;if(t._index>=e.length){if(!t._loop)return t._isActive=!1,this._mutationChains=this._mutationChains.filter(e=>e!==t),void t._resolve({canceled:!1});t._index=0}t._mutations[t._index].run(this).then(()=>{t._isActive&&(t._index++,this._run(t))})}_getActiveMutations(){return this._mutationChains.map(t=>t._mutations[t._index])}pauseAll(){this._getActiveMutations().forEach(t=>t.pause())}resumeAll(){this._getActiveMutations().forEach(t=>t.resume())}cancelMutations(t){for(const e of this._mutationChains)for(const i of e._scopes)for(const r of t)(i.startsWith(r)||r.startsWith(i))&&this._cancelMutationChain(e)}cancelAll(){this.cancelMutations([""])}_cancelMutationChain(t){var e;t._isActive=!1;for(let e=t._index;e<t._mutations.length;e++)t._mutations[e].cancel(this);null===(e=t._resolve)||void 0===e||e.call(t,{canceled:!0}),this._mutationChains=this._mutationChains.filter(e=>e!==t)}}const f=(t,e)=>({x:t.x-e.x,y:t.y-e.y}),v=t=>Math.sqrt(Math.pow(t.x,2)+Math.pow(t.y,2)),y=(t,e)=>v(f(t,e)),C=(t,e=1)=>{const i=10*e;return{x:Math.round(i*t.x)/i,y:Math.round(i*t.y)/i}},w=t=>{let e=t[0];return t.slice(1).reduce((t,i)=>{const r=y(i,e);return e=i,t+r},0)},S=(t,e,i)=>{const r=f(e,t),s=i/v(r);return{x:e.x+s*r.x,y:e.y+s*r.y}},P=t=>{const e=((t,e=30)=>{const i=w(t)/(e-1),r=[t[0]],s=o(t),n=t.slice(1);for(let t=0;t<e-2;t++){let t=o(r),e=i,s=!1;for(;!s;){const i=y(t,n[0]);if(i<e)e-=i,t=n.shift();else{const o=S(t,n[0],e-i);r.push(o),s=!0}}}return r.push(s),r})(t),i={x:c(e.map(t=>t.x)),y:c(e.map(t=>t.y))},r=e.map(t=>f(t,i)),s=Math.sqrt(c([Math.pow(r[0].x,2)+Math.pow(r[0].y,2),Math.pow(o(r).x,2)+Math.pow(o(r).y,2)]));return((t,e=.05)=>{const i=t.slice(0,1);for(const r of t.slice(1)){const t=i[i.length-1],s=y(r,t);if(s>e){const o=Math.ceil(s/e),n=s/o;for(let e=0;e<o;e++)i.push(S(r,t,-1*n*(e+1)))}else i.push(r)}return i})(r.map(t=>({x:t.x/s,y:t.y/s})))};function D(t,e=!1){const i=C(t[0]),r=t.slice(1);let s=`M ${i.x} ${i.y}`;return r.forEach(t=>{const e=C(t);s+=` L ${e.x} ${e.y}`}),e&&(s+="Z"),s}const x=(t,e)=>{const i=(t=>{if(t.length<3)return t;const e=[t[0],t[1]];return t.slice(2).forEach(t=>{const i=e.length,r=f(t,e[i-1]),s=f(e[i-1],e[i-2]);r.y*s.x-r.x*s.y==0&&e.pop(),e.push(t)}),e})(t);if(i.length<2)return i;const r=i[1],s=i[0],o=S(r,s,e),n=i.slice(1);return n.unshift(o),n};class M{constructor(t,e,i,r=!1){this.path=t,this.points=e,this.strokeNum=i,this.isInRadical=r}getStartingPoint(){return this.points[0]}getEndingPoint(){return this.points[this.points.length-1]}getLength(){return w(this.points)}getVectors(){let t=this.points[0];return this.points.slice(1).map(e=>{const i=f(e,t);return t=e,i})}getDistance(t){const e=this.points.map(e=>y(e,t));return Math.min(...e)}getAverageDistance(t){return t.reduce((t,e)=>t+this.getDistance(e),0)/t.length}}class R{constructor(t,e){this.symbol=t,this.strokes=e}}function T({radStrokes:t,strokes:e,medians:i}){return e.map((e,r)=>{const s=i[r].map(t=>{const[e,i]=t;return{x:e,y:i}});return new M(e,s,r,(o=r,(null!==(n=null==t?void 0:t.indexOf(o))&&void 0!==n?n:-1)>=0));var o,n})}const[A,O]=[{x:0,y:-124},{x:1024,y:900}],b=O.x-A.x,$=O.y-A.y;class L{constructor(t){const{padding:e,width:i,height:r}=t;this.padding=e,this.width=i,this.height=r;const s=i-2*e,o=r-2*e,n=s/b,a=o/$;this.scale=Math.min(n,a);const h=e+(s-this.scale*b)/2,l=e+(o-this.scale*$)/2;this.xOffset=-1*A.x*this.scale+h,this.yOffset=-1*A.y*this.scale+l}convertExternalPoint(t){return{x:(t.x-this.xOffset)/this.scale,y:(this.height-this.yOffset-t.y)/this.scale}}}const z=(t,e)=>{const i=(t=>{const e=[];let i=t[0];return t.slice(1).forEach(t=>{e.push(f(t,i)),i=t}),e})(t),r=e.getVectors();return c(i.map(t=>{const e=r.map(e=>{return r=t,((i=e).x*r.x+i.y*r.y)/v(i)/v(r);var i,r});return Math.max(...e)}))>0},E=t=>{if(t.length<2)return t;const[e,...i]=t,r=[e];for(const t of i)s=t,o=r[r.length-1],(s.x!==o.x||s.y!==o.y)&&r.push(t);var s,o;return r},W=[Math.PI/16,Math.PI/32,0,-1*Math.PI/32,-1*Math.PI/16],F=(t,e,i)=>{const r=P(t),s=P(e);let o=1/0;return W.forEach(t=>{const e=((t,e)=>{const i=t.length>=e.length?t:e,r=t.length>=e.length?e:t,s=(t,e,s,o)=>{if(0===t&&0===e)return y(i[0],r[0]);if(t>0&&0===e)return Math.max(s[0],y(i[t],r[0]));const n=o[o.length-1];return 0===t&&e>0?Math.max(n,y(i[0],r[e])):Math.max(Math.min(s[e],s[e-1],n),y(i[t],r[e]))};let o=[];for(let t=0;t<i.length;t++){const e=[];for(let i=0;i<r.length;i++)e.push(s(t,i,o,e));o=e}return o[r.length-1]})(r,((t,e)=>t.map(t=>({x:Math.cos(e)*t.x-Math.sin(e)*t.y,y:Math.sin(e)*t.x+Math.cos(e)*t.y})))(s,t));e<o&&(o=e)}),o<=.4*i},H=(t,e,i)=>{const{leniency:r=1,isOutlineVisible:s=!1,checkBackwards:o=!0}=i,n=e.getAverageDistance(t),a=n<=350*(s||e.strokeNum>0?.5:1)*r;if(!a)return{isMatch:!1,avgDist:n,meta:{isStrokeBackwards:!1}};const h=((t,e,i)=>{const r=y(e.getStartingPoint(),t[0]),s=y(e.getEndingPoint(),t[t.length-1]);return r<=250*i&&s<=250*i})(t,e,r),l=z(t,e),c=F(t,e.points,r),d=((t,e,i)=>i*(w(t)+25)/(e.getLength()+25)>=.35)(t,e,r),u=a&&h&&l&&c&&d;if(o&&!u){if(H([...t].reverse(),e,{...i,checkBackwards:!1}).isMatch)return{isMatch:u,avgDist:n,meta:{isStrokeBackwards:!0}}}return{isMatch:u,avgDist:n,meta:{isStrokeBackwards:!1}}};class I{constructor(t,e,i){this.id=t,this.points=[e],this.externalPoints=[i]}appendPoint(t,e){this.points.push(t),this.externalPoints.push(e)}}class B{constructor(t,e,i={}){this._tick=t=>{if(null!==this._startPauseTime)return;const e=Math.min(1,(t-this._startTime-this._pausedDuration)/this._duration);if(1===e)this._renderState.updateState(this._values),this._frameHandle=void 0,this.cancel(this._renderState);else{const t=j(e),i=q(this._startState,this._values,t);this._renderState.updateState(i),this._frameHandle=r(this._tick)}},this.scope=t,this._valuesOrCallable=e,this._duration=i.duration||0,this._force=i.force,this._pausedDuration=0,this._startPauseTime=null}run(t){return this._values||this._inflateValues(t),0===this._duration&&t.updateState(this._values),0===this._duration||N(t.state,this._values)?Promise.resolve():(this._renderState=t,this._startState=t.state,this._startTime=performance.now(),this._frameHandle=r(this._tick),new Promise(t=>{this._resolve=t}))}_inflateValues(t){let e=this._valuesOrCallable;"function"==typeof this._valuesOrCallable&&(e=this._valuesOrCallable(t.state)),this._values=function(t,e){const i=t.split("."),r={};let s=r;for(let t=0;t<i.length;t++){const r=t===i.length-1?e:{};s[i[t]]=r,s=r}return r}(this.scope,e)}pause(){null===this._startPauseTime&&(this._frameHandle&&s(this._frameHandle),this._startPauseTime=performance.now())}resume(){null!==this._startPauseTime&&(this._frameHandle=r(this._tick),this._pausedDuration+=performance.now()-this._startPauseTime,this._startPauseTime=null)}cancel(t){var e;null===(e=this._resolve)||void 0===e||e.call(this),this._resolve=void 0,s(this._frameHandle||-1),this._frameHandle=void 0,this._force&&(this._values||this._inflateValues(t),t.updateState(this._values))}}function q(t,e,i){const r={};for(const s in e){const o=e[s],n=null==t?void 0:t[s];r[s]="number"==typeof n&&"number"==typeof o&&o>=0?i*(o-n)+n:q(n,o,i)}return r}function N(t,e){for(const i in e){const r=e[i],s=null==t?void 0:t[i];if(r>=0){if(r!==s)return!1}else if(!N(s,r))return!1}return!0}B.Delay=class{constructor(t){this._duration=t,this._startTime=null,this._paused=!1,this.scope="delay."+t}run(){return this._startTime=i(),this._runningPromise=new Promise(t=>{this._resolve=t,this._timeout=setTimeout(()=>this.cancel(),this._duration)}),this._runningPromise}pause(){if(this._paused)return;const t=performance.now()-(this._startTime||0);this._duration=Math.max(0,this._duration-t),clearTimeout(this._timeout),this._paused=!0}resume(){this._paused&&(this._startTime=performance.now(),this._timeout=setTimeout(()=>this.cancel(),this._duration),this._paused=!1)}cancel(){clearTimeout(this._timeout),this._resolve&&this._resolve(),this._resolve=void 0}};const j=t=>-Math.cos(t*Math.PI)/2+.5,U=(t,e,i)=>[new B(`character.${t}.strokes`,u({opacity:1,displayPortion:1},e.strokes.length),{duration:i,force:!0})],V=(t,e,i)=>[new B("character."+t,{opacity:1,strokes:u({opacity:1,displayPortion:1},e.strokes.length)},{duration:i,force:!0})],Q=(t,e,i)=>[new B(`character.${t}.opacity`,0,{duration:i,force:!0}),...U(t,e,0)],G=(t,e,i)=>[new B("options."+t,e,{duration:i})],X=(t,e,i)=>{const r=t.strokeNum,s=(t.getLength()+600)/(3*i);return[new B("options.highlightColor",e),new B("character.highlight",{opacity:1,strokes:{[r]:{displayPortion:0,opacity:0}}}),new B("character.highlight.strokes."+r,{displayPortion:1,opacity:1},{duration:s}),new B(`character.highlight.strokes.${r}.opacity`,0,{duration:s})]},K=(t,e,i)=>{const r=e.strokeNum,s=(e.getLength()+600)/(3*i);return[new B("character."+t,{opacity:1,strokes:{[r]:{displayPortion:0,opacity:1}}}),new B(`character.${t}.strokes.${r}.displayPortion`,1,{duration:s})]},Y=(t,e,i,r,s)=>{let o=Q(t,e,i);return o=o.concat(U(t,e,0)),o.push(new B("character."+t,{opacity:1,strokes:u({opacity:0},e.strokes.length)},{force:!0})),e.strokes.forEach((e,i)=>{i>0&&o.push(new B.Delay(s)),o=o.concat(K(t,e,r))}),o},J=(t,e)=>[new B(`userStrokes.${t}.opacity`,0,{duration:e}),new B("userStrokes."+t,null,{force:!0})];class Z{constructor(t,e,i){this._currentStrokeIndex=0,this._mistakesOnStroke=0,this._totalMistakes=0,this._character=t,this._renderState=e,this._isActive=!1,this._positioner=i}startQuiz(t){this._isActive=!0,this._options=t;const e=n(t.quizStartStrokeNum,this._character.strokes.length);return this._currentStrokeIndex=Math.min(e,this._character.strokes.length-1),this._mistakesOnStroke=0,this._totalMistakes=0,this._renderState.run((i=this._character,r=t.strokeFadeDuration,s=this._currentStrokeIndex,[...Q("main",i,r),new B("character.highlight",{opacity:1,strokes:u({opacity:0},i.strokes.length)},{force:!0}),new B("character.main",{opacity:1,strokes:_(i.strokes.length,t=>({opacity:t<s?1:0}))},{force:!0})]));var i,r,s}startUserStroke(t){if(!this._isActive)return null;if(this._userStroke)return this.endUserStroke();const e=this._positioner.convertExternalPoint(t),i=l();return this._userStroke=new I(i,e,t),this._renderState.run(((t,e)=>[new B("quiz.activeUserStrokeId",t,{force:!0}),new B("userStrokes."+t,{points:[e],opacity:1},{force:!0})])(i,e))}continueUserStroke(t){if(!this._userStroke)return Promise.resolve();const e=this._positioner.convertExternalPoint(t);this._userStroke.appendPoint(e,t);const i=this._userStroke.points.slice(0);return this._renderState.run((r=this._userStroke.id,[new B(`userStrokes.${r}.points`,i,{force:!0})]));var r}setPositioner(t){this._positioner=t}endUserStroke(){var t;if(!this._userStroke)return;if(this._renderState.run(J(this._userStroke.id,null!==(t=this._options.drawingFadeDuration)&&void 0!==t?t:300)),1===this._userStroke.points.length)return void(this._userStroke=void 0);const{acceptBackwardsStrokes:e}=this._options,i=this._getCurrentStroke(),{isMatch:r,meta:s}=function(t,e,i,r={}){const s=e.strokes,o=E(t.points);if(o.length<2)return{isMatch:!1,meta:{isStrokeBackwards:!1}};const{isMatch:n,meta:a,avgDist:h}=H(o,s[i],r);if(!n)return{isMatch:n,meta:a};const l=s.slice(i+1);let c=h;for(let t=0;t<l.length;t++){const{isMatch:e,avgDist:i}=H(o,l[t],{...r,checkBackwards:!1});e&&i<c&&(c=i)}if(c<h){const t=.6*(c+h)/(2*h),{isMatch:e,meta:n}=H(o,s[i],{...r,leniency:(r.leniency||1)*t});return{isMatch:e,meta:n}}return{isMatch:n,meta:a}}(this._userStroke,this._character,this._currentStrokeIndex,{isOutlineVisible:this._renderState.state.character.outline.opacity>0,leniency:this._options.leniency});if(r||s.isStrokeBackwards&&e)this._handleSuccess(s);else{this._handleFailure(s);const{showHintAfterMisses:t,highlightColor:e,strokeHighlightSpeed:r}=this._options;!1!==t&&this._mistakesOnStroke>=t&&this._renderState.run(X(i,d(e),r))}this._userStroke=void 0}cancel(){this._isActive=!1,this._userStroke&&this._renderState.run(J(this._userStroke.id,this._options.drawingFadeDuration))}_getStrokeData({isCorrect:t,meta:e}){return{character:this._character.symbol,strokeNum:this._currentStrokeIndex,mistakesOnStroke:this._mistakesOnStroke,totalMistakes:this._totalMistakes,strokesRemaining:this._character.strokes.length-this._currentStrokeIndex-(t?1:0),drawnPath:(i=this._userStroke,{pathString:D(i.externalPoints),points:i.points.map(t=>C(t))}),isBackwards:e.isStrokeBackwards};var i}_handleSuccess(t){if(!this._options)return;const{strokes:e,symbol:i}=this._character,{onCorrectStroke:r,onComplete:s,highlightOnComplete:o,strokeFadeDuration:n,highlightCompleteColor:a,highlightColor:h,strokeHighlightDuration:l}=this._options;null==r||r({...this._getStrokeData({isCorrect:!0,meta:t})});let c=(u="main",_=this._currentStrokeIndex,[new B(`character.${u}.strokes.${_}`,{displayPortion:1,opacity:1},{duration:n,force:!0})]);var u,_;this._mistakesOnStroke=0,this._currentStrokeIndex+=1;this._currentStrokeIndex===e.length&&(this._isActive=!1,null==s||s({character:i,totalMistakes:this._totalMistakes}),o&&(c=c.concat(((t,e,i)=>[new B("options.highlightColor",e),...Q("highlight",t),...V("highlight",t,i/2),...Q("highlight",t,i/2)])(this._character,d(a||h),2*(l||0))))),this._renderState.run(c)}_handleFailure(t){var e,i;this._mistakesOnStroke+=1,this._totalMistakes+=1,null===(e=(i=this._options).onMistake)||void 0===e||e.call(i,this._getStrokeData({isCorrect:!1,meta:t}))}_getCurrentStroke(){return this._character.strokes[this._currentStrokeIndex]}}function tt(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function et(t,e,i){t.setAttributeNS(null,e,i)}function it(t,e){Object.keys(e).forEach(i=>et(t,i,e[i]))}function rt(t){var e;null==t||null===(e=t.parentNode)||void 0===e||e.removeChild(t)}class st{constructor(t){this.stroke=t,this._pathLength=t.getLength()+st.STROKE_WIDTH/2}_getStrokeDashoffset(t){return.999*this._pathLength*(1-t)}_getColor({strokeColor:t,radicalColor:e}){return e&&this.stroke.isInRadical?e:t}}st.STROKE_WIDTH=200;class ot extends st{constructor(t){super(t),this._oldProps=void 0}mount(t){this._animationPath=tt("path"),this._clip=tt("clipPath"),this._strokePath=tt("path");const e="mask-"+l();et(this._clip,"id",e),et(this._strokePath,"d",this.stroke.path),this._animationPath.style.opacity="0",et(this._animationPath,"clip-path",function(t){let e="";return window.location&&window.location.href&&(e=window.location.href.replace(/#[^#]*$/,"").replace(/"/gi,"%22")),`url("${e}#${t}")`}(e));const i=x(this.stroke.points,100);return et(this._animationPath,"d",D(i)),it(this._animationPath,{stroke:"#FFFFFF","stroke-width":200..toString(),fill:"none","stroke-linecap":"round","stroke-linejoin":"miter","stroke-dasharray":`${this._pathLength},${this._pathLength}`}),this._clip.appendChild(this._strokePath),t.defs.appendChild(this._clip),t.svg.appendChild(this._animationPath),this}render(t){var e,i;if(t===this._oldProps||!this._animationPath)return;t.displayPortion!==(null===(e=this._oldProps)||void 0===e?void 0:e.displayPortion)&&(this._animationPath.style.strokeDashoffset=this._getStrokeDashoffset(t.displayPortion).toString());const r=this._getColor(t);if(!this._oldProps||r!==this._getColor(this._oldProps)){const{r:t,g:e,b:i,a:s}=r;it(this._animationPath,{stroke:`rgba(${t},${e},${i},${s})`})}t.opacity!==(null===(i=this._oldProps)||void 0===i?void 0:i.opacity)&&(this._animationPath.style.opacity=t.opacity.toString()),this._oldProps=t}}class nt{constructor(t){this._oldProps=void 0,this._strokeRenderers=t.strokes.map(t=>new ot(t))}mount(t){const e=t.createSubRenderTarget();this._group=e.svg,this._strokeRenderers.forEach(t=>{t.mount(e)})}render(t){var e,i;if(t===this._oldProps||!this._group)return;const{opacity:r,strokes:s,strokeColor:o,radicalColor:n=null}=t;var a;r!==(null===(e=this._oldProps)||void 0===e?void 0:e.opacity)&&(this._group.style.opacity=r.toString(),g||(0===r?this._group.style.display="none":0===(null===(a=this._oldProps)||void 0===a?void 0:a.opacity)&&this._group.style.removeProperty("display")));const h=!this._oldProps||o!==this._oldProps.strokeColor||n!==this._oldProps.radicalColor;if(h||s!==(null===(i=this._oldProps)||void 0===i?void 0:i.strokes))for(let t=0;t<this._strokeRenderers.length;t++){var l;!h&&null!==(l=this._oldProps)&&void 0!==l&&l.strokes&&s[t]===this._oldProps.strokes[t]||this._strokeRenderers[t].render({strokeColor:o,radicalColor:n,opacity:s[t].opacity,displayPortion:s[t].displayPortion})}this._oldProps=t}}class at{constructor(){this._oldProps=void 0}mount(t){this._path=tt("path"),t.svg.appendChild(this._path)}render(t){var e,i,r,s;if(this._path&&t!==this._oldProps){if(t.strokeColor!==(null===(e=this._oldProps)||void 0===e?void 0:e.strokeColor)||t.strokeWidth!==(null===(i=this._oldProps)||void 0===i?void 0:i.strokeWidth)){const{r:e,g:i,b:r,a:s}=t.strokeColor;it(this._path,{fill:"none",stroke:`rgba(${e},${i},${r},${s})`,"stroke-width":t.strokeWidth.toString(),"stroke-linecap":"round","stroke-linejoin":"round"})}t.opacity!==(null===(r=this._oldProps)||void 0===r?void 0:r.opacity)&&et(this._path,"opacity",t.opacity.toString()),t.points!==(null===(s=this._oldProps)||void 0===s?void 0:s.points)&&et(this._path,"d",D(t.points)),this._oldProps=t}}destroy(){rt(this._path)}}class ht{constructor(t){this.node=t}addPointerStartListener(t){this.node.addEventListener("mousedown",e=>{t(this._eventify(e,this._getMousePoint))}),this.node.addEventListener("touchstart",e=>{t(this._eventify(e,this._getTouchPoint))})}addPointerMoveListener(t){this.node.addEventListener("mousemove",e=>{t(this._eventify(e,this._getMousePoint))}),this.node.addEventListener("touchmove",e=>{t(this._eventify(e,this._getTouchPoint))})}addPointerEndListener(t){document.addEventListener("mouseup",t),document.addEventListener("touchend",t)}getBoundingClientRect(){return this.node.getBoundingClientRect()}updateDimensions(t,e){this.node.setAttribute("width",""+t),this.node.setAttribute("height",""+e)}_eventify(t,e){return{getPoint:()=>e.call(this,t),preventDefault:()=>t.preventDefault()}}_getMousePoint(t){const{left:e,top:i}=this.getBoundingClientRect();return{x:t.clientX-e,y:t.clientY-i}}_getTouchPoint(t){const{left:e,top:i}=this.getBoundingClientRect();return{x:t.touches[0].clientX-e,y:t.touches[0].clientY-i}}}class lt extends ht{constructor(t,e){super(t),this.svg=t,this.defs=e,"createSVGPoint"in t&&(this._pt=t.createSVGPoint())}static init(t,e="100%",i="100%"){const r="string"==typeof t?document.getElementById(t):t;if(!r)throw new Error("HanziWriter target element not found: "+t);const s=r.nodeName.toUpperCase(),o=(()=>{if("SVG"===s||"G"===s)return r;{const t=tt("svg");return r.appendChild(t),t}})();it(o,{width:e,height:i});const n=tt("defs");return o.appendChild(n),new lt(o,n)}createSubRenderTarget(){const t=tt("g");return this.svg.appendChild(t),new lt(t,this.defs)}_getMousePoint(t){if(this._pt&&(this._pt.x=t.clientX,this._pt.y=t.clientY,"getScreenCTM"in this.node)){var e;const t=this._pt.matrixTransform(null===(e=this.node.getScreenCTM())||void 0===e?void 0:e.inverse());return{x:t.x,y:t.y}}return super._getMousePoint.call(this,t)}_getTouchPoint(t){if(this._pt&&(this._pt.x=t.touches[0].clientX,this._pt.y=t.touches[0].clientY,"getScreenCTM"in this.node)){var e;const t=this._pt.matrixTransform(null===(e=this.node.getScreenCTM())||void 0===e?void 0:e.inverse());return{x:t.x,y:t.y}}return super._getTouchPoint(t)}}var ct={HanziWriterRenderer:class{constructor(t,e){this._character=t,this._positioner=e,this._mainCharRenderer=new nt(t),this._outlineCharRenderer=new nt(t),this._highlightCharRenderer=new nt(t),this._userStrokeRenderers={}}mount(t){const e=t.createSubRenderTarget(),i=e.svg,{xOffset:r,yOffset:s,height:o,scale:n}=this._positioner;et(i,"transform",`translate(${r}, ${o-s}) scale(${n}, ${-1*n})`),this._outlineCharRenderer.mount(e),this._mainCharRenderer.mount(e),this._highlightCharRenderer.mount(e),this._positionedTarget=e}render(t){const{main:e,outline:i,highlight:r}=t.character,{outlineColor:s,radicalColor:o,highlightColor:n,strokeColor:a,drawingWidth:h,drawingColor:l}=t.options;this._outlineCharRenderer.render({opacity:i.opacity,strokes:i.strokes,strokeColor:s}),this._mainCharRenderer.render({opacity:e.opacity,strokes:e.strokes,strokeColor:a,radicalColor:o}),this._highlightCharRenderer.render({opacity:r.opacity,strokes:r.strokes,strokeColor:n});const c=t.userStrokes||{};for(const t in this._userStrokeRenderers){var d;if(!c[t])null===(d=this._userStrokeRenderers[t])||void 0===d||d.destroy(),delete this._userStrokeRenderers[t]}for(const t in c){const e=c[t];if(!e)continue;const i={strokeWidth:h,strokeColor:l,...e};(()=>{if(this._userStrokeRenderers[t])return this._userStrokeRenderers[t];const e=new at;return e.mount(this._positionedTarget),this._userStrokeRenderers[t]=e,e})().render(i)}}destroy(){rt(this._positionedTarget.svg),this._positionedTarget.defs.innerHTML=""}},createRenderTarget:lt.init};const dt=(t,e)=>{t.beginPath();const i=e[0],r=e.slice(1);t.moveTo(i.x,i.y);for(const e of r)t.lineTo(e.x,e.y);t.stroke()};class ut extends st{constructor(t,e=!0){super(t),e&&Path2D?this._path2D=new Path2D(this.stroke.path):this._pathCmd=(t=>{const e=t.split(/(^|\s+)(?=[A-Z])/).filter(t=>" "!==t),i=[t=>t.beginPath()];for(const t of e){const[e,...r]=t.split(/\s+/),s=r.map(t=>parseFloat(t));"M"===e?i.push(t=>t.moveTo(...s)):"L"===e?i.push(t=>t.lineTo(...s)):"C"===e?i.push(t=>t.bezierCurveTo(...s)):"Q"===e&&i.push(t=>t.quadraticCurveTo(...s))}return t=>i.forEach(e=>e(t))})(this.stroke.path),this._extendedMaskPoints=x(this.stroke.points,st.STROKE_WIDTH/2)}render(t,e){if(e.opacity<.05)return;var i;(t.save(),this._path2D)?t.clip(this._path2D):(null===(i=this._pathCmd)||void 0===i||i.call(this,t),t.globalAlpha=0,t.stroke(),t.clip());const{r:r,g:s,b:o,a:n}=this._getColor(e),a=1===n?`rgb(${r},${s},${o})`:`rgb(${r},${s},${o},${n})`,h=this._getStrokeDashoffset(e.displayPortion);t.globalAlpha=e.opacity,t.strokeStyle=a,t.fillStyle=a,t.lineWidth=st.STROKE_WIDTH,t.lineCap="round",t.lineJoin="round",t.setLineDash([this._pathLength,this._pathLength],h),t.lineDashOffset=h,dt(t,this._extendedMaskPoints),t.restore()}}class _t{constructor(t){this._strokeRenderers=t.strokes.map(t=>new ut(t))}render(t,e){if(e.opacity<.05)return;const{opacity:i,strokeColor:r,radicalColor:s,strokes:o}=e;for(let e=0;e<this._strokeRenderers.length;e++)this._strokeRenderers[e].render(t,{strokeColor:r,radicalColor:s,opacity:o[e].opacity*i,displayPortion:o[e].displayPortion||0})}}function pt(t,e){if(e.opacity<.05)return;const{opacity:i,strokeWidth:r,strokeColor:s,points:o}=e,{r:n,g:a,b:h,a:l}=s;t.save(),t.globalAlpha=i,t.lineWidth=r,t.strokeStyle=`rgba(${n},${a},${h},${l})`,t.lineCap="round",t.lineJoin="round",dt(t,o),t.restore()}class gt extends ht{constructor(t){super(t)}static init(t,e="100%",i="100%"){const r="string"==typeof t?document.getElementById(t):t;if(!r)throw new Error("HanziWriter target element not found: "+t);const s=r.nodeName.toUpperCase(),o=(()=>{if("CANVAS"===s)return r;const t=document.createElement("canvas");return r.appendChild(t),t})();return o.setAttribute("width",e),o.setAttribute("height",i),new gt(o)}getContext(){return this.node.getContext("2d")}}var kt={HanziWriterRenderer:class{constructor(t,e){this.destroy=k,this._character=t,this._positioner=e,this._mainCharRenderer=new _t(t),this._outlineCharRenderer=new _t(t),this._highlightCharRenderer=new _t(t)}mount(t){this._target=t}_animationFrame(t){const{width:e,height:i,scale:r,xOffset:s,yOffset:o}=this._positioner,n=this._target.getContext();n.clearRect(0,0,e,i),n.save(),n.translate(s,i-o),n.transform(1,0,0,-1,0,0),n.scale(r,r),t(n),n.restore(),n.draw&&n.draw()}render(t){const{outline:e,main:i,highlight:r}=t.character,{outlineColor:s,strokeColor:o,radicalColor:n,highlightColor:a,drawingColor:h,drawingWidth:l}=t.options;this._animationFrame(c=>{this._outlineCharRenderer.render(c,{opacity:e.opacity,strokes:e.strokes,strokeColor:s}),this._mainCharRenderer.render(c,{opacity:i.opacity,strokes:i.strokes,strokeColor:o,radicalColor:n}),this._highlightCharRenderer.render(c,{opacity:r.opacity,strokes:r.strokes,strokeColor:a});const d=t.userStrokes||{};for(const t in d){const e=d[t];if(e){pt(c,{strokeWidth:l,strokeColor:h,...e})}}})}},createRenderTarget:gt.init};const mt={charDataLoader:(t,e,i)=>{const r=new XMLHttpRequest;r.overrideMimeType&&r.overrideMimeType("application/json"),r.open("GET",(t=>`https://cdn.jsdelivr.net/npm/hanzi-writer-data@2.0/${t}.json`)(t),!0),r.onerror=t=>{i(r,t)},r.onreadystatechange=()=>{4===r.readyState&&(200===r.status?e(JSON.parse(r.responseText)):0!==r.status&&i&&i(r))},r.send(null)},onLoadCharDataError:null,onLoadCharDataSuccess:null,showOutline:!0,showCharacter:!0,renderer:"svg",width:0,height:0,padding:20,strokeAnimationSpeed:1,strokeFadeDuration:400,strokeHighlightDuration:200,strokeHighlightSpeed:2,delayBetweenStrokes:1e3,delayBetweenLoops:2e3,strokeColor:"#555",radicalColor:null,highlightColor:"#AAF",outlineColor:"#DDD",drawingColor:"#333",leniency:1,showHintAfterMisses:3,highlightOnComplete:!0,highlightCompleteColor:null,acceptBackwardsStrokes:!1,quizStartStrokeNum:0,drawingFadeDuration:300,drawingWidth:4,strokeWidth:2,outlineWidth:2,rendererOverride:{}};class ft{constructor(t){this._loadCounter=0,this._isLoading=!1,this.loadingFailed=!1,this._options=t}_debouncedLoad(t,e){const i=t=>{var i;e===this._loadCounter&&(null===(i=this._resolve)||void 0===i||i.call(this,t))},r=t=>{var i;e===this._loadCounter&&(null===(i=this._reject)||void 0===i||i.call(this,t))},s=this._options.charDataLoader(t,i,r);s&&("then"in s?s.then(i).catch(r):i(s))}_setupLoadingPromise(){return new Promise((t,e)=>{this._resolve=t,this._reject=e}).then(t=>{var e,i;return this._isLoading=!1,null===(e=(i=this._options).onLoadCharDataSuccess)||void 0===e||e.call(i,t),t}).catch(t=>{if(this._isLoading=!1,this.loadingFailed=!0,this._options.onLoadCharDataError)return void this._options.onLoadCharDataError(t);if(t instanceof Error)throw t;const e=new Error("Failed to load char data for "+this._loadingChar);throw e.reason=t,e})}loadCharData(t){this._loadingChar=t;const e=this._setupLoadingPromise();return this.loadingFailed=!1,this._isLoading=!0,this._loadCounter++,this._debouncedLoad(t,this._loadCounter),e}}class vt{constructor(t,e={}){const{HanziWriterRenderer:i,createRenderTarget:r}="canvas"===e.renderer?kt:ct,s=e.rendererOverride||{};this._renderer={HanziWriterRenderer:s.HanziWriterRenderer||i,createRenderTarget:s.createRenderTarget||r},this.target=this._renderer.createRenderTarget(t,e.width,e.height),this._options=this._assignOptions(e),this._loadingManager=new ft(this._options),this._setupListeners()}static create(t,e,i){const r=new vt(t,i);return r.setCharacter(e),r}static loadCharacterData(t,e={}){const i=(()=>{const{_loadingManager:i,_loadingOptions:r}=vt;return(null==i?void 0:i._loadingChar)===t&&r===e?i:new ft({...mt,...e})})();return vt._loadingManager=i,vt._loadingOptions=e,i.loadCharData(t)}static getScalingTransform(t,e,i=0){const r=new L({width:t,height:e,padding:i});return{x:r.xOffset,y:r.yOffset,scale:r.scale,transform:(s=`\n translate(${r.xOffset}, ${r.height-r.yOffset})\n scale(${r.scale}, ${-1*r.scale})\n `,s.replace(/^\s+/,"").replace(/\s+$/,"")).replace(/\s+/g," ")};var s}showCharacter(t={}){return this._options.showCharacter=!0,this._withData(()=>{var e;return null===(e=this._renderState)||void 0===e?void 0:e.run(V("main",this._character,"number"==typeof t.duration?t.duration:this._options.strokeFadeDuration)).then(e=>{var i;return null===(i=t.onComplete)||void 0===i||i.call(t,e),e})})}hideCharacter(t={}){return this._options.showCharacter=!1,this._withData(()=>{var e;return null===(e=this._renderState)||void 0===e?void 0:e.run(Q("main",this._character,"number"==typeof t.duration?t.duration:this._options.strokeFadeDuration)).then(e=>{var i;return null===(i=t.onComplete)||void 0===i||i.call(t,e),e})})}animateCharacter(t={}){return this.cancelQuiz(),this._withData(()=>{var e;return null===(e=this._renderState)||void 0===e?void 0:e.run(Y("main",this._character,this._options.strokeFadeDuration,this._options.strokeAnimationSpeed,this._options.delayBetweenStrokes)).then(e=>{var i;return null===(i=t.onComplete)||void 0===i||i.call(t,e),e})})}animateStroke(t,e={}){return this.cancelQuiz(),this._withData(()=>{var i;return null===(i=this._renderState)||void 0===i?void 0:i.run(((t,e,i,r)=>{const s=e.strokes[i];return[new B("character."+t,i=>{const r=i.character[t],s={opacity:1,strokes:{}};for(let t=0;t<e.strokes.length;t++)s.strokes[t]={opacity:r.opacity*r.strokes[t].opacity};return s}),...K(t,s,r)]})("main",this._character,n(t,this._character.strokes.length),this._options.strokeAnimationSpeed)).then(t=>{var i;return null===(i=e.onComplete)||void 0===i||i.call(e,t),t})})}highlightStroke(t,e={}){return this._withData(()=>{var i,r;if(this._character&&this._renderState)return this._renderState.run(X((i=this._character.strokes,r=t,i[n(r,i.length)]),d(this._options.highlightColor),this._options.strokeHighlightSpeed)).then(t=>{var i;return null===(i=e.onComplete)||void 0===i||i.call(e,t),t})})}async loopCharacterAnimation(){return this.cancelQuiz(),this._withData(()=>this._renderState.run(((t,e,i,r,s,o)=>{const n=Y(t,e,i,r,s);return n.push(new B.Delay(o)),n})("main",this._character,this._options.strokeFadeDuration,this._options.strokeAnimationSpeed,this._options.delayBetweenStrokes,this._options.delayBetweenLoops),{loop:!0}))}pauseAnimation(){return this._withData(()=>{var t;return null===(t=this._renderState)||void 0===t?void 0:t.pauseAll()})}resumeAnimation(){return this._withData(()=>{var t;return null===(t=this._renderState)||void 0===t?void 0:t.resumeAll()})}showOutline(t={}){return this._options.showOutline=!0,this._withData(()=>{var e;return null===(e=this._renderState)||void 0===e?void 0:e.run(V("outline",this._character,"number"==typeof t.duration?t.duration:this._options.strokeFadeDuration)).then(e=>{var i;return null===(i=t.onComplete)||void 0===i||i.call(t,e),e})})}hideOutline(t={}){return this._options.showOutline=!1,this._withData(()=>{var e;return null===(e=this._renderState)||void 0===e?void 0:e.run(Q("outline",this._character,"number"==typeof t.duration?t.duration:this._options.strokeFadeDuration)).then(e=>{var i;return null===(i=t.onComplete)||void 0===i||i.call(t,e),e})})}updateDimensions({width:t,height:e,padding:i}){if(void 0!==t&&(this._options.width=t),void 0!==e&&(this._options.height=e),void 0!==i&&(this._options.padding=i),this.target.updateDimensions(this._options.width,this._options.height),this._character&&this._renderState&&this._hanziWriterRenderer&&this._positioner){this._hanziWriterRenderer.destroy();const t=this._initAndMountHanziWriterRenderer(this._character);this._renderState.overwriteOnStateChange(e=>t.render(e)),t.render(this._renderState.state),this._quiz&&this._quiz.setPositioner(this._positioner)}}updateColor(t,e,i={}){var r;let s=[];const o=d((()=>"radicalColor"!==t||e?e:this._options.strokeColor)());this._options[t]=e;const n=null!==(r=i.duration)&&void 0!==r?r:this._options.strokeFadeDuration;return s=s.concat(G(t,o,n)),"radicalColor"!==t||e||(s=s.concat(G(t,null,0))),this._withData(()=>{var t;return null===(t=this._renderState)||void 0===t?void 0:t.run(s).then(t=>{var e;return null===(e=i.onComplete)||void 0===e||e.call(i,t),t})})}quiz(t={}){return this._withData(async()=>{this._character&&this._renderState&&this._positioner&&(this.cancelQuiz(),this._quiz=new Z(this._character,this._renderState,this._positioner),this._options={...this._options,...t},this._quiz.startQuiz(this._options))})}cancelQuiz(){this._quiz&&(this._quiz.cancel(),this._quiz=void 0)}setCharacter(t){return this.cancelQuiz(),this._char=t,this._hanziWriterRenderer&&this._hanziWriterRenderer.destroy(),this._renderState&&this._renderState.cancelAll(),this._hanziWriterRenderer=null,this._withDataPromise=this._loadingManager.loadCharData(t).then(e=>{if(!e||this._loadingManager.loadingFailed)return;this._character=function(t,e){const i=T(e);return new R(t,i)}(t,e),this._renderState=new m(this._character,this._options,t=>i.render(t));const i=this._initAndMountHanziWriterRenderer(this._character);i.render(this._renderState.state)}),this._withDataPromise}_initAndMountHanziWriterRenderer(t){const{width:e,height:i,padding:r}=this._options;this._positioner=new L({width:e,height:i,padding:r});const s=new this._renderer.HanziWriterRenderer(t,this._positioner);return s.mount(this.target),this._hanziWriterRenderer=s,s}async getCharacterData(){if(!this._char)throw new Error("setCharacter() must be called before calling getCharacterData()");return await this._withData(()=>this._character)}_assignOptions(t){const e={...mt,...t};return t.strokeAnimationDuration&&!t.strokeAnimationSpeed&&(e.strokeAnimationSpeed=500/t.strokeAnimationDuration),t.strokeHighlightDuration&&!t.strokeHighlightSpeed&&(e.strokeHighlightSpeed=500/e.strokeHighlightDuration),t.highlightCompleteColor||(e.highlightCompleteColor=e.highlightColor),this._fillWidthAndHeight(e)}_fillWidthAndHeight(t){const e={...t};if(e.width&&!e.height)e.height=e.width;else if(e.height&&!e.width)e.width=e.height;else if(!e.width&&!e.height){const{width:t,height:i}=this.target.getBoundingClientRect(),r=Math.min(t,i);e.width=r,e.height=r}return e}_withData(t){if(this._loadingManager.loadingFailed)throw Error("Failed to load character data. Call setCharacter and try again.");return this._withDataPromise?this._withDataPromise.then(()=>{if(!this._loadingManager.loadingFailed)return t()}):Promise.resolve().then(t)}_setupListeners(){this.target.addPointerStartListener(t=>{this._quiz&&(t.preventDefault(),this._quiz.startUserStroke(t.getPoint()))}),this.target.addPointerMoveListener(t=>{this._quiz&&(t.preventDefault(),this._quiz.continueUserStroke(t.getPoint()))}),this.target.addPointerEndListener(()=>{var t;null===(t=this._quiz)||void 0===t||t.endUserStroke()})}}return vt._loadingManager=null,vt._loadingOptions=null,vt}();
var HanziWriter=function(){"use strict";var t;const e="undefined"==typeof window?global:window,i=e.performance&&(()=>e.performance.now())||(()=>Date.now()),r=e.requestAnimationFrame||(t=>setTimeout(()=>t(i()),1e3/60)),s=e.cancelAnimationFrame||clearTimeout;function o(t){return t[t.length-1]}const n=(t,e)=>t<0?e+t:t;function a(t,e){const i={...t};for(const r in e){const s=t[r],o=e[r];s!==o&&(s&&o&&"object"==typeof s&&"object"==typeof o&&!Array.isArray(o)?i[r]=a(s,o):i[r]=o)}return i}let h=0;function l(){return h++,h}function c(t){return t.reduce((t,e)=>e+t,0)/t.length}function d(t){const e=t.toUpperCase().trim();if(/^#([A-F0-9]{3}){1,2}$/.test(e)){let t=e.substring(1).split("");3===t.length&&(t=[t[0],t[0],t[1],t[1],t[2],t[2]]);const i=""+t.join("");return{r:parseInt(i.slice(0,2),16),g:parseInt(i.slice(2,4),16),b:parseInt(i.slice(4,6),16),a:1}}const i=e.match(/^RGBA?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*(\d*\.?\d+))?\)$/);if(i)return{r:parseInt(i[1],10),g:parseInt(i[2],10),b:parseInt(i[3],10),a:parseFloat(i[4]||1,10)};throw new Error("Invalid color: "+t)}function u(t,e){const i={};for(let r=0;r<e;r++)i[r]=t;return i}function _(t,e){const i={};for(let r=0;r<t;r++)i[r]=e(r);return i}const p=(null===(t=e.navigator)||void 0===t?void 0:t.userAgent)||"",g=p.indexOf("MSIE ")>0||p.indexOf("Trident/")>0||p.indexOf("Edge/")>0,k=()=>{};class m{constructor(t,e,i=k){this._mutationChains=[],this._onStateChange=i,this.state={options:{drawingFadeDuration:e.drawingFadeDuration,drawingWidth:e.drawingWidth,drawingColor:d(e.drawingColor),strokeColor:d(e.strokeColor),outlineColor:d(e.outlineColor),radicalColor:d(e.radicalColor||e.strokeColor),highlightColor:d(e.highlightColor)},character:{main:{opacity:e.showCharacter?1:0,strokes:{}},outline:{opacity:e.showOutline?1:0,strokes:{}},highlight:{opacity:1,strokes:{}}},userStrokes:null};for(let e=0;e<t.strokes.length;e++)this.state.character.main.strokes[e]={opacity:1,displayPortion:1},this.state.character.outline.strokes[e]={opacity:1,displayPortion:1},this.state.character.highlight.strokes[e]={opacity:0,displayPortion:1}}overwriteOnStateChange(t){this._onStateChange=t}updateState(t){const e=a(this.state,t);this._onStateChange(e,this.state),this.state=e}run(t,e={}){const i=t.map(t=>t.scope);return this.cancelMutations(i),new Promise(r=>{const s={_isActive:!0,_index:0,_resolve:r,_mutations:t,_loop:e.loop,_scopes:i};this._mutationChains.push(s),this._run(s)})}_run(t){if(!t._isActive)return;const e=t._mutations;if(t._index>=e.length){if(!t._loop)return t._isActive=!1,this._mutationChains=this._mutationChains.filter(e=>e!==t),void t._resolve({canceled:!1});t._index=0}t._mutations[t._index].run(this).then(()=>{t._isActive&&(t._index++,this._run(t))})}_getActiveMutations(){return this._mutationChains.map(t=>t._mutations[t._index])}pauseAll(){this._getActiveMutations().forEach(t=>t.pause())}resumeAll(){this._getActiveMutations().forEach(t=>t.resume())}cancelMutations(t){for(const e of this._mutationChains)for(const i of e._scopes)for(const r of t)(i.startsWith(r)||r.startsWith(i))&&this._cancelMutationChain(e)}cancelAll(){this.cancelMutations([""])}_cancelMutationChain(t){var e;t._isActive=!1;for(let e=t._index;e<t._mutations.length;e++)t._mutations[e].cancel(this);null===(e=t._resolve)||void 0===e||e.call(t,{canceled:!0}),this._mutationChains=this._mutationChains.filter(e=>e!==t)}}const f=(t,e)=>({x:t.x-e.x,y:t.y-e.y}),v=t=>Math.sqrt(Math.pow(t.x,2)+Math.pow(t.y,2)),y=(t,e)=>v(f(t,e)),C=(t,e=1)=>{const i=10*e;return{x:Math.round(i*t.x)/i,y:Math.round(i*t.y)/i}},w=t=>{let e=t[0];return t.slice(1).reduce((t,i)=>{const r=y(i,e);return e=i,t+r},0)},S=(t,e,i)=>{const r=f(e,t),s=i/v(r);return{x:e.x+s*r.x,y:e.y+s*r.y}},P=t=>{const e=((t,e=30)=>{const i=w(t)/(e-1),r=[t[0]],s=o(t),n=t.slice(1);for(let t=0;t<e-2;t++){let t=o(r),e=i,s=!1;for(;!s;){const i=y(t,n[0]);if(i<e)e-=i,t=n.shift();else{const o=S(t,n[0],e-i);r.push(o),s=!0}}}return r.push(s),r})(t),i={x:c(e.map(t=>t.x)),y:c(e.map(t=>t.y))},r=e.map(t=>f(t,i)),s=Math.sqrt(c([Math.pow(r[0].x,2)+Math.pow(r[0].y,2),Math.pow(o(r).x,2)+Math.pow(o(r).y,2)]));return((t,e=.05)=>{const i=t.slice(0,1);for(const r of t.slice(1)){const t=i[i.length-1],s=y(r,t);if(s>e){const o=Math.ceil(s/e),n=s/o;for(let e=0;e<o;e++)i.push(S(r,t,-1*n*(e+1)))}else i.push(r)}return i})(r.map(t=>({x:t.x/s,y:t.y/s})))};function D(t,e=!1){const i=C(t[0]),r=t.slice(1);let s=`M ${i.x} ${i.y}`;return r.forEach(t=>{const e=C(t);s+=` L ${e.x} ${e.y}`}),e&&(s+="Z"),s}const x=(t,e)=>{const i=(t=>{if(t.length<3)return t;const e=[t[0],t[1]];return t.slice(2).forEach(t=>{const i=e.length,r=f(t,e[i-1]),s=f(e[i-1],e[i-2]);r.y*s.x-r.x*s.y==0&&e.pop(),e.push(t)}),e})(t);if(i.length<2)return i;const r=i[1],s=i[0],o=S(r,s,e),n=i.slice(1);return n.unshift(o),n};class M{constructor(t,e,i,r=!1){this.path=t,this.points=e,this.strokeNum=i,this.isInRadical=r}getStartingPoint(){return this.points[0]}getEndingPoint(){return this.points[this.points.length-1]}getLength(){return w(this.points)}getVectors(){let t=this.points[0];return this.points.slice(1).map(e=>{const i=f(e,t);return t=e,i})}getDistance(t){const e=this.points.map(e=>y(e,t));return Math.min(...e)}getAverageDistance(t){return t.reduce((t,e)=>t+this.getDistance(e),0)/t.length}}class R{constructor(t,e){this.symbol=t,this.strokes=e}}function T({radStrokes:t,strokes:e,medians:i}){return e.map((e,r)=>{const s=i[r].map(t=>{const[e,i]=t;return{x:e,y:i}});return new M(e,s,r,(o=r,(null!==(n=null==t?void 0:t.indexOf(o))&&void 0!==n?n:-1)>=0));var o,n})}const[A,O]=[{x:0,y:-124},{x:1024,y:900}],b=O.x-A.x,$=O.y-A.y;class L{constructor(t){const{padding:e,width:i,height:r}=t;this.padding=e,this.width=i,this.height=r;const s=i-2*e,o=r-2*e,n=s/b,a=o/$;this.scale=Math.min(n,a);const h=e+(s-this.scale*b)/2,l=e+(o-this.scale*$)/2;this.xOffset=-1*A.x*this.scale+h,this.yOffset=-1*A.y*this.scale+l}convertExternalPoint(t){return{x:(t.x-this.xOffset)/this.scale,y:(this.height-this.yOffset-t.y)/this.scale}}}const z=(t,e)=>{const i=(t=>{const e=[];let i=t[0];return t.slice(1).forEach(t=>{e.push(f(t,i)),i=t}),e})(t),r=e.getVectors();return c(i.map(t=>{const e=r.map(e=>{return r=t,((i=e).x*r.x+i.y*r.y)/v(i)/v(r);var i,r});return Math.max(...e)}))>0},E=t=>{if(t.length<2)return t;const[e,...i]=t,r=[e];for(const t of i)s=t,o=r[r.length-1],(s.x!==o.x||s.y!==o.y)&&r.push(t);var s,o;return r},W=[Math.PI/16,Math.PI/32,0,-1*Math.PI/32,-1*Math.PI/16],F=(t,e,i)=>{const r=P(t),s=P(e);let o=1/0;return W.forEach(t=>{const e=((t,e)=>{const i=t.length>=e.length?t:e,r=t.length>=e.length?e:t,s=(t,e,s,o)=>{if(0===t&&0===e)return y(i[0],r[0]);if(t>0&&0===e)return Math.max(s[0],y(i[t],r[0]));const n=o[o.length-1];return 0===t&&e>0?Math.max(n,y(i[0],r[e])):Math.max(Math.min(s[e],s[e-1],n),y(i[t],r[e]))};let o=[];for(let t=0;t<i.length;t++){const e=[];for(let i=0;i<r.length;i++)e.push(s(t,i,o,e));o=e}return o[r.length-1]})(r,((t,e)=>t.map(t=>({x:Math.cos(e)*t.x-Math.sin(e)*t.y,y:Math.sin(e)*t.x+Math.cos(e)*t.y})))(s,t));e<o&&(o=e)}),o<=.4*i},H=(t,e,i)=>{const{leniency:r=1,isOutlineVisible:s=!1,checkBackwards:o=!0}=i,n=e.getAverageDistance(t),a=n<=350*(s||e.strokeNum>0?.5:1)*r;if(!a)return{isMatch:!1,avgDist:n,meta:{isStrokeBackwards:!1}};const h=((t,e,i)=>{const r=y(e.getStartingPoint(),t[0]),s=y(e.getEndingPoint(),t[t.length-1]);return r<=250*i&&s<=250*i})(t,e,r),l=z(t,e),c=F(t,e.points,r),d=((t,e,i)=>i*(w(t)+25)/(e.getLength()+25)>=.35)(t,e,r),u=a&&h&&l&&c&&d;if(o&&!u){if(H([...t].reverse(),e,{...i,checkBackwards:!1}).isMatch)return{isMatch:u,avgDist:n,meta:{isStrokeBackwards:!0}}}return{isMatch:u,avgDist:n,meta:{isStrokeBackwards:!1}}};class I{constructor(t,e,i){this.id=t,this.points=[e],this.externalPoints=[i]}appendPoint(t,e){this.points.push(t),this.externalPoints.push(e)}}class B{constructor(t,e,i={}){this._tick=t=>{if(null!==this._startPauseTime)return;const e=Math.min(1,(t-this._startTime-this._pausedDuration)/this._duration);if(1===e)this._renderState.updateState(this._values),this._frameHandle=void 0,this.cancel(this._renderState);else{const t=j(e),i=q(this._startState,this._values,t);this._renderState.updateState(i),this._frameHandle=r(this._tick)}},this.scope=t,this._valuesOrCallable=e,this._duration=i.duration||0,this._force=i.force,this._pausedDuration=0,this._startPauseTime=null}run(t){return this._values||this._inflateValues(t),0===this._duration&&t.updateState(this._values),0===this._duration||N(t.state,this._values)?Promise.resolve():(this._renderState=t,this._startState=t.state,this._startTime=performance.now(),this._frameHandle=r(this._tick),new Promise(t=>{this._resolve=t}))}_inflateValues(t){let e=this._valuesOrCallable;"function"==typeof this._valuesOrCallable&&(e=this._valuesOrCallable(t.state)),this._values=function(t,e){const i=t.split("."),r={};let s=r;for(let t=0;t<i.length;t++){const r=t===i.length-1?e:{};s[i[t]]=r,s=r}return r}(this.scope,e)}pause(){null===this._startPauseTime&&(this._frameHandle&&s(this._frameHandle),this._startPauseTime=performance.now())}resume(){null!==this._startPauseTime&&(this._frameHandle=r(this._tick),this._pausedDuration+=performance.now()-this._startPauseTime,this._startPauseTime=null)}cancel(t){var e;null===(e=this._resolve)||void 0===e||e.call(this),this._resolve=void 0,s(this._frameHandle||-1),this._frameHandle=void 0,this._force&&(this._values||this._inflateValues(t),t.updateState(this._values))}}function q(t,e,i){const r={};for(const s in e){const o=e[s],n=null==t?void 0:t[s];r[s]="number"==typeof n&&"number"==typeof o&&o>=0?i*(o-n)+n:q(n,o,i)}return r}function N(t,e){for(const i in e){const r=e[i],s=null==t?void 0:t[i];if(r>=0){if(r!==s)return!1}else if(!N(s,r))return!1}return!0}B.Delay=class{constructor(t){this._duration=t,this._startTime=null,this._paused=!1,this.scope="delay."+t}run(){return this._startTime=i(),this._runningPromise=new Promise(t=>{this._resolve=t,this._timeout=setTimeout(()=>this.cancel(),this._duration)}),this._runningPromise}pause(){if(this._paused)return;const t=performance.now()-(this._startTime||0);this._duration=Math.max(0,this._duration-t),clearTimeout(this._timeout),this._paused=!0}resume(){this._paused&&(this._startTime=performance.now(),this._timeout=setTimeout(()=>this.cancel(),this._duration),this._paused=!1)}cancel(){clearTimeout(this._timeout),this._resolve&&this._resolve(),this._resolve=void 0}};const j=t=>-Math.cos(t*Math.PI)/2+.5,U=(t,e,i)=>[new B(`character.${t}.strokes`,u({opacity:1,displayPortion:1},e.strokes.length),{duration:i,force:!0})],V=(t,e,i)=>[new B("character."+t,{opacity:1,strokes:u({opacity:1,displayPortion:1},e.strokes.length)},{duration:i,force:!0})],Q=(t,e,i)=>[new B(`character.${t}.opacity`,0,{duration:i,force:!0}),...U(t,e,0)],G=(t,e,i)=>[new B("options."+t,e,{duration:i})],X=(t,e,i)=>{const r=t.strokeNum,s=(t.getLength()+600)/(3*i);return[new B("options.highlightColor",e),new B("character.highlight",{opacity:1,strokes:{[r]:{displayPortion:0,opacity:0}}}),new B("character.highlight.strokes."+r,{displayPortion:1,opacity:1},{duration:s}),new B(`character.highlight.strokes.${r}.opacity`,0,{duration:s,force:!0})]},K=(t,e,i)=>{const r=e.strokeNum,s=(e.getLength()+600)/(3*i);return[new B("character."+t,{opacity:1,strokes:{[r]:{displayPortion:0,opacity:1}}}),new B(`character.${t}.strokes.${r}.displayPortion`,1,{duration:s})]},Y=(t,e,i,r,s)=>{let o=Q(t,e,i);return o=o.concat(U(t,e,0)),o.push(new B("character."+t,{opacity:1,strokes:u({opacity:0},e.strokes.length)},{force:!0})),e.strokes.forEach((e,i)=>{i>0&&o.push(new B.Delay(s)),o=o.concat(K(t,e,r))}),o},J=(t,e)=>[new B(`userStrokes.${t}.opacity`,0,{duration:e}),new B("userStrokes."+t,null,{force:!0})];class Z{constructor(t,e,i){this._currentStrokeIndex=0,this._mistakesOnStroke=0,this._totalMistakes=0,this._character=t,this._renderState=e,this._isActive=!1,this._positioner=i}startQuiz(t){this._isActive=!0,this._options=t;const e=n(t.quizStartStrokeNum,this._character.strokes.length);return this._currentStrokeIndex=Math.min(e,this._character.strokes.length-1),this._mistakesOnStroke=0,this._totalMistakes=0,this._renderState.run((i=this._character,r=t.strokeFadeDuration,s=this._currentStrokeIndex,[...Q("main",i,r),new B("character.highlight",{opacity:1,strokes:u({opacity:0},i.strokes.length)},{force:!0}),new B("character.main",{opacity:1,strokes:_(i.strokes.length,t=>({opacity:t<s?1:0}))},{force:!0})]));var i,r,s}startUserStroke(t){if(!this._isActive)return null;if(this._userStroke)return this.endUserStroke();const e=this._positioner.convertExternalPoint(t),i=l();return this._userStroke=new I(i,e,t),this._renderState.run(((t,e)=>[new B("quiz.activeUserStrokeId",t,{force:!0}),new B("userStrokes."+t,{points:[e],opacity:1},{force:!0})])(i,e))}continueUserStroke(t){if(!this._userStroke)return Promise.resolve();const e=this._positioner.convertExternalPoint(t);this._userStroke.appendPoint(e,t);const i=this._userStroke.points.slice(0);return this._renderState.run((r=this._userStroke.id,[new B(`userStrokes.${r}.points`,i,{force:!0})]));var r}setPositioner(t){this._positioner=t}endUserStroke(){var t;if(!this._userStroke)return;if(this._renderState.run(J(this._userStroke.id,null!==(t=this._options.drawingFadeDuration)&&void 0!==t?t:300)),1===this._userStroke.points.length)return void(this._userStroke=void 0);const{acceptBackwardsStrokes:e}=this._options,i=this._getCurrentStroke(),{isMatch:r,meta:s}=function(t,e,i,r={}){const s=e.strokes,o=E(t.points);if(o.length<2)return{isMatch:!1,meta:{isStrokeBackwards:!1}};const{isMatch:n,meta:a,avgDist:h}=H(o,s[i],r);if(!n)return{isMatch:n,meta:a};const l=s.slice(i+1);let c=h;for(let t=0;t<l.length;t++){const{isMatch:e,avgDist:i}=H(o,l[t],{...r,checkBackwards:!1});e&&i<c&&(c=i)}if(c<h){const t=.6*(c+h)/(2*h),{isMatch:e,meta:n}=H(o,s[i],{...r,leniency:(r.leniency||1)*t});return{isMatch:e,meta:n}}return{isMatch:n,meta:a}}(this._userStroke,this._character,this._currentStrokeIndex,{isOutlineVisible:this._renderState.state.character.outline.opacity>0,leniency:this._options.leniency});if(r||s.isStrokeBackwards&&e)this._handleSuccess(s);else{this._handleFailure(s);const{showHintAfterMisses:t,highlightColor:e,strokeHighlightSpeed:r}=this._options;!1!==t&&this._mistakesOnStroke>=t&&this._renderState.run(X(i,d(e),r))}this._userStroke=void 0}cancel(){this._isActive=!1,this._userStroke&&this._renderState.run(J(this._userStroke.id,this._options.drawingFadeDuration))}_getStrokeData({isCorrect:t,meta:e}){return{character:this._character.symbol,strokeNum:this._currentStrokeIndex,mistakesOnStroke:this._mistakesOnStroke,totalMistakes:this._totalMistakes,strokesRemaining:this._character.strokes.length-this._currentStrokeIndex-(t?1:0),drawnPath:(i=this._userStroke,{pathString:D(i.externalPoints),points:i.points.map(t=>C(t))}),isBackwards:e.isStrokeBackwards};var i}_handleSuccess(t){if(!this._options)return;const{strokes:e,symbol:i}=this._character,{onCorrectStroke:r,onComplete:s,highlightOnComplete:o,strokeFadeDuration:n,highlightCompleteColor:a,highlightColor:h,strokeHighlightDuration:l}=this._options;null==r||r({...this._getStrokeData({isCorrect:!0,meta:t})});let c=(u="main",_=this._currentStrokeIndex,[new B(`character.${u}.strokes.${_}`,{displayPortion:1,opacity:1},{duration:n,force:!0})]);var u,_;this._mistakesOnStroke=0,this._currentStrokeIndex+=1;this._currentStrokeIndex===e.length&&(this._isActive=!1,null==s||s({character:i,totalMistakes:this._totalMistakes}),o&&(c=c.concat(((t,e,i)=>[new B("options.highlightColor",e),...Q("highlight",t),...V("highlight",t,i/2),...Q("highlight",t,i/2)])(this._character,d(a||h),2*(l||0))))),this._renderState.run(c)}_handleFailure(t){var e,i;this._mistakesOnStroke+=1,this._totalMistakes+=1,null===(e=(i=this._options).onMistake)||void 0===e||e.call(i,this._getStrokeData({isCorrect:!1,meta:t}))}_getCurrentStroke(){return this._character.strokes[this._currentStrokeIndex]}}function tt(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function et(t,e,i){t.setAttributeNS(null,e,i)}function it(t,e){Object.keys(e).forEach(i=>et(t,i,e[i]))}function rt(t){var e;null==t||null===(e=t.parentNode)||void 0===e||e.removeChild(t)}class st{constructor(t){this.stroke=t,this._pathLength=t.getLength()+st.STROKE_WIDTH/2}_getStrokeDashoffset(t){return.999*this._pathLength*(1-t)}_getColor({strokeColor:t,radicalColor:e}){return e&&this.stroke.isInRadical?e:t}}st.STROKE_WIDTH=200;class ot extends st{constructor(t){super(t),this._oldProps=void 0}mount(t){this._animationPath=tt("path"),this._clip=tt("clipPath"),this._strokePath=tt("path");const e="mask-"+l();et(this._clip,"id",e),et(this._strokePath,"d",this.stroke.path),this._animationPath.style.opacity="0",et(this._animationPath,"clip-path",function(t){let e="";return window.location&&window.location.href&&(e=window.location.href.replace(/#[^#]*$/,"").replace(/"/gi,"%22")),`url("${e}#${t}")`}(e));const i=x(this.stroke.points,100);return et(this._animationPath,"d",D(i)),it(this._animationPath,{stroke:"#FFFFFF","stroke-width":200..toString(),fill:"none","stroke-linecap":"round","stroke-linejoin":"miter","stroke-dasharray":`${this._pathLength},${this._pathLength}`}),this._clip.appendChild(this._strokePath),t.defs.appendChild(this._clip),t.svg.appendChild(this._animationPath),this}render(t){var e,i;if(t===this._oldProps||!this._animationPath)return;t.displayPortion!==(null===(e=this._oldProps)||void 0===e?void 0:e.displayPortion)&&(this._animationPath.style.strokeDashoffset=this._getStrokeDashoffset(t.displayPortion).toString());const r=this._getColor(t);if(!this._oldProps||r!==this._getColor(this._oldProps)){const{r:t,g:e,b:i,a:s}=r;it(this._animationPath,{stroke:`rgba(${t},${e},${i},${s})`})}t.opacity!==(null===(i=this._oldProps)||void 0===i?void 0:i.opacity)&&(this._animationPath.style.opacity=t.opacity.toString()),this._oldProps=t}}class nt{constructor(t){this._oldProps=void 0,this._strokeRenderers=t.strokes.map(t=>new ot(t))}mount(t){const e=t.createSubRenderTarget();this._group=e.svg,this._strokeRenderers.forEach(t=>{t.mount(e)})}render(t){var e,i;if(t===this._oldProps||!this._group)return;const{opacity:r,strokes:s,strokeColor:o,radicalColor:n=null}=t;var a;r!==(null===(e=this._oldProps)||void 0===e?void 0:e.opacity)&&(this._group.style.opacity=r.toString(),g||(0===r?this._group.style.display="none":0===(null===(a=this._oldProps)||void 0===a?void 0:a.opacity)&&this._group.style.removeProperty("display")));const h=!this._oldProps||o!==this._oldProps.strokeColor||n!==this._oldProps.radicalColor;if(h||s!==(null===(i=this._oldProps)||void 0===i?void 0:i.strokes))for(let t=0;t<this._strokeRenderers.length;t++){var l;!h&&null!==(l=this._oldProps)&&void 0!==l&&l.strokes&&s[t]===this._oldProps.strokes[t]||this._strokeRenderers[t].render({strokeColor:o,radicalColor:n,opacity:s[t].opacity,displayPortion:s[t].displayPortion})}this._oldProps=t}}class at{constructor(){this._oldProps=void 0}mount(t){this._path=tt("path"),t.svg.appendChild(this._path)}render(t){var e,i,r,s;if(this._path&&t!==this._oldProps){if(t.strokeColor!==(null===(e=this._oldProps)||void 0===e?void 0:e.strokeColor)||t.strokeWidth!==(null===(i=this._oldProps)||void 0===i?void 0:i.strokeWidth)){const{r:e,g:i,b:r,a:s}=t.strokeColor;it(this._path,{fill:"none",stroke:`rgba(${e},${i},${r},${s})`,"stroke-width":t.strokeWidth.toString(),"stroke-linecap":"round","stroke-linejoin":"round"})}t.opacity!==(null===(r=this._oldProps)||void 0===r?void 0:r.opacity)&&et(this._path,"opacity",t.opacity.toString()),t.points!==(null===(s=this._oldProps)||void 0===s?void 0:s.points)&&et(this._path,"d",D(t.points)),this._oldProps=t}}destroy(){rt(this._path)}}class ht{constructor(t){this.node=t}addPointerStartListener(t){this.node.addEventListener("mousedown",e=>{t(this._eventify(e,this._getMousePoint))}),this.node.addEventListener("touchstart",e=>{t(this._eventify(e,this._getTouchPoint))})}addPointerMoveListener(t){this.node.addEventListener("mousemove",e=>{t(this._eventify(e,this._getMousePoint))}),this.node.addEventListener("touchmove",e=>{t(this._eventify(e,this._getTouchPoint))})}addPointerEndListener(t){document.addEventListener("mouseup",t),document.addEventListener("touchend",t)}getBoundingClientRect(){return this.node.getBoundingClientRect()}updateDimensions(t,e){this.node.setAttribute("width",""+t),this.node.setAttribute("height",""+e)}_eventify(t,e){return{getPoint:()=>e.call(this,t),preventDefault:()=>t.preventDefault()}}_getMousePoint(t){const{left:e,top:i}=this.getBoundingClientRect();return{x:t.clientX-e,y:t.clientY-i}}_getTouchPoint(t){const{left:e,top:i}=this.getBoundingClientRect();return{x:t.touches[0].clientX-e,y:t.touches[0].clientY-i}}}class lt extends ht{constructor(t,e){super(t),this.svg=t,this.defs=e,"createSVGPoint"in t&&(this._pt=t.createSVGPoint())}static init(t,e="100%",i="100%"){const r="string"==typeof t?document.getElementById(t):t;if(!r)throw new Error("HanziWriter target element not found: "+t);const s=r.nodeName.toUpperCase(),o=(()=>{if("SVG"===s||"G"===s)return r;{const t=tt("svg");return r.appendChild(t),t}})();it(o,{width:e,height:i});const n=tt("defs");return o.appendChild(n),new lt(o,n)}createSubRenderTarget(){const t=tt("g");return this.svg.appendChild(t),new lt(t,this.defs)}_getMousePoint(t){if(this._pt&&(this._pt.x=t.clientX,this._pt.y=t.clientY,"getScreenCTM"in this.node)){var e;const t=this._pt.matrixTransform(null===(e=this.node.getScreenCTM())||void 0===e?void 0:e.inverse());return{x:t.x,y:t.y}}return super._getMousePoint.call(this,t)}_getTouchPoint(t){if(this._pt&&(this._pt.x=t.touches[0].clientX,this._pt.y=t.touches[0].clientY,"getScreenCTM"in this.node)){var e;const t=this._pt.matrixTransform(null===(e=this.node.getScreenCTM())||void 0===e?void 0:e.inverse());return{x:t.x,y:t.y}}return super._getTouchPoint(t)}}var ct={HanziWriterRenderer:class{constructor(t,e){this._character=t,this._positioner=e,this._mainCharRenderer=new nt(t),this._outlineCharRenderer=new nt(t),this._highlightCharRenderer=new nt(t),this._userStrokeRenderers={}}mount(t){const e=t.createSubRenderTarget(),i=e.svg,{xOffset:r,yOffset:s,height:o,scale:n}=this._positioner;et(i,"transform",`translate(${r}, ${o-s}) scale(${n}, ${-1*n})`),this._outlineCharRenderer.mount(e),this._mainCharRenderer.mount(e),this._highlightCharRenderer.mount(e),this._positionedTarget=e}render(t){const{main:e,outline:i,highlight:r}=t.character,{outlineColor:s,radicalColor:o,highlightColor:n,strokeColor:a,drawingWidth:h,drawingColor:l}=t.options;this._outlineCharRenderer.render({opacity:i.opacity,strokes:i.strokes,strokeColor:s}),this._mainCharRenderer.render({opacity:e.opacity,strokes:e.strokes,strokeColor:a,radicalColor:o}),this._highlightCharRenderer.render({opacity:r.opacity,strokes:r.strokes,strokeColor:n});const c=t.userStrokes||{};for(const t in this._userStrokeRenderers){var d;if(!c[t])null===(d=this._userStrokeRenderers[t])||void 0===d||d.destroy(),delete this._userStrokeRenderers[t]}for(const t in c){const e=c[t];if(!e)continue;const i={strokeWidth:h,strokeColor:l,...e};(()=>{if(this._userStrokeRenderers[t])return this._userStrokeRenderers[t];const e=new at;return e.mount(this._positionedTarget),this._userStrokeRenderers[t]=e,e})().render(i)}}destroy(){rt(this._positionedTarget.svg),this._positionedTarget.defs.innerHTML=""}},createRenderTarget:lt.init};const dt=(t,e)=>{t.beginPath();const i=e[0],r=e.slice(1);t.moveTo(i.x,i.y);for(const e of r)t.lineTo(e.x,e.y);t.stroke()};class ut extends st{constructor(t,e=!0){super(t),e&&Path2D?this._path2D=new Path2D(this.stroke.path):this._pathCmd=(t=>{const e=t.split(/(^|\s+)(?=[A-Z])/).filter(t=>" "!==t),i=[t=>t.beginPath()];for(const t of e){const[e,...r]=t.split(/\s+/),s=r.map(t=>parseFloat(t));"M"===e?i.push(t=>t.moveTo(...s)):"L"===e?i.push(t=>t.lineTo(...s)):"C"===e?i.push(t=>t.bezierCurveTo(...s)):"Q"===e&&i.push(t=>t.quadraticCurveTo(...s))}return t=>i.forEach(e=>e(t))})(this.stroke.path),this._extendedMaskPoints=x(this.stroke.points,st.STROKE_WIDTH/2)}render(t,e){if(e.opacity<.05)return;var i;(t.save(),this._path2D)?t.clip(this._path2D):(null===(i=this._pathCmd)||void 0===i||i.call(this,t),t.globalAlpha=0,t.stroke(),t.clip());const{r:r,g:s,b:o,a:n}=this._getColor(e),a=1===n?`rgb(${r},${s},${o})`:`rgb(${r},${s},${o},${n})`,h=this._getStrokeDashoffset(e.displayPortion);t.globalAlpha=e.opacity,t.strokeStyle=a,t.fillStyle=a,t.lineWidth=st.STROKE_WIDTH,t.lineCap="round",t.lineJoin="round",t.setLineDash([this._pathLength,this._pathLength],h),t.lineDashOffset=h,dt(t,this._extendedMaskPoints),t.restore()}}class _t{constructor(t){this._strokeRenderers=t.strokes.map(t=>new ut(t))}render(t,e){if(e.opacity<.05)return;const{opacity:i,strokeColor:r,radicalColor:s,strokes:o}=e;for(let e=0;e<this._strokeRenderers.length;e++)this._strokeRenderers[e].render(t,{strokeColor:r,radicalColor:s,opacity:o[e].opacity*i,displayPortion:o[e].displayPortion||0})}}function pt(t,e){if(e.opacity<.05)return;const{opacity:i,strokeWidth:r,strokeColor:s,points:o}=e,{r:n,g:a,b:h,a:l}=s;t.save(),t.globalAlpha=i,t.lineWidth=r,t.strokeStyle=`rgba(${n},${a},${h},${l})`,t.lineCap="round",t.lineJoin="round",dt(t,o),t.restore()}class gt extends ht{constructor(t){super(t)}static init(t,e="100%",i="100%"){const r="string"==typeof t?document.getElementById(t):t;if(!r)throw new Error("HanziWriter target element not found: "+t);const s=r.nodeName.toUpperCase(),o=(()=>{if("CANVAS"===s)return r;const t=document.createElement("canvas");return r.appendChild(t),t})();return o.setAttribute("width",e),o.setAttribute("height",i),new gt(o)}getContext(){return this.node.getContext("2d")}}var kt={HanziWriterRenderer:class{constructor(t,e){this.destroy=k,this._character=t,this._positioner=e,this._mainCharRenderer=new _t(t),this._outlineCharRenderer=new _t(t),this._highlightCharRenderer=new _t(t)}mount(t){this._target=t}_animationFrame(t){const{width:e,height:i,scale:r,xOffset:s,yOffset:o}=this._positioner,n=this._target.getContext();n.clearRect(0,0,e,i),n.save(),n.translate(s,i-o),n.transform(1,0,0,-1,0,0),n.scale(r,r),t(n),n.restore(),n.draw&&n.draw()}render(t){const{outline:e,main:i,highlight:r}=t.character,{outlineColor:s,strokeColor:o,radicalColor:n,highlightColor:a,drawingColor:h,drawingWidth:l}=t.options;this._animationFrame(c=>{this._outlineCharRenderer.render(c,{opacity:e.opacity,strokes:e.strokes,strokeColor:s}),this._mainCharRenderer.render(c,{opacity:i.opacity,strokes:i.strokes,strokeColor:o,radicalColor:n}),this._highlightCharRenderer.render(c,{opacity:r.opacity,strokes:r.strokes,strokeColor:a});const d=t.userStrokes||{};for(const t in d){const e=d[t];if(e){pt(c,{strokeWidth:l,strokeColor:h,...e})}}})}},createRenderTarget:gt.init};const mt={charDataLoader:(t,e,i)=>{const r=new XMLHttpRequest;r.overrideMimeType&&r.overrideMimeType("application/json"),r.open("GET",(t=>`https://cdn.jsdelivr.net/npm/hanzi-writer-data@2.0/${t}.json`)(t),!0),r.onerror=t=>{i(r,t)},r.onreadystatechange=()=>{4===r.readyState&&(200===r.status?e(JSON.parse(r.responseText)):0!==r.status&&i&&i(r))},r.send(null)},onLoadCharDataError:null,onLoadCharDataSuccess:null,showOutline:!0,showCharacter:!0,renderer:"svg",width:0,height:0,padding:20,strokeAnimationSpeed:1,strokeFadeDuration:400,strokeHighlightDuration:200,strokeHighlightSpeed:2,delayBetweenStrokes:1e3,delayBetweenLoops:2e3,strokeColor:"#555",radicalColor:null,highlightColor:"#AAF",outlineColor:"#DDD",drawingColor:"#333",leniency:1,showHintAfterMisses:3,highlightOnComplete:!0,highlightCompleteColor:null,acceptBackwardsStrokes:!1,quizStartStrokeNum:0,drawingFadeDuration:300,drawingWidth:4,strokeWidth:2,outlineWidth:2,rendererOverride:{}};class ft{constructor(t){this._loadCounter=0,this._isLoading=!1,this.loadingFailed=!1,this._options=t}_debouncedLoad(t,e){const i=t=>{var i;e===this._loadCounter&&(null===(i=this._resolve)||void 0===i||i.call(this,t))},r=t=>{var i;e===this._loadCounter&&(null===(i=this._reject)||void 0===i||i.call(this,t))},s=this._options.charDataLoader(t,i,r);s&&("then"in s?s.then(i).catch(r):i(s))}_setupLoadingPromise(){return new Promise((t,e)=>{this._resolve=t,this._reject=e}).then(t=>{var e,i;return this._isLoading=!1,null===(e=(i=this._options).onLoadCharDataSuccess)||void 0===e||e.call(i,t),t}).catch(t=>{if(this._isLoading=!1,this.loadingFailed=!0,this._options.onLoadCharDataError)return void this._options.onLoadCharDataError(t);if(t instanceof Error)throw t;const e=new Error("Failed to load char data for "+this._loadingChar);throw e.reason=t,e})}loadCharData(t){this._loadingChar=t;const e=this._setupLoadingPromise();return this.loadingFailed=!1,this._isLoading=!0,this._loadCounter++,this._debouncedLoad(t,this._loadCounter),e}}class vt{constructor(t,e={}){const{HanziWriterRenderer:i,createRenderTarget:r}="canvas"===e.renderer?kt:ct,s=e.rendererOverride||{};this._renderer={HanziWriterRenderer:s.HanziWriterRenderer||i,createRenderTarget:s.createRenderTarget||r},this.target=this._renderer.createRenderTarget(t,e.width,e.height),this._options=this._assignOptions(e),this._loadingManager=new ft(this._options),this._setupListeners()}static create(t,e,i){const r=new vt(t,i);return r.setCharacter(e),r}static loadCharacterData(t,e={}){const i=(()=>{const{_loadingManager:i,_loadingOptions:r}=vt;return(null==i?void 0:i._loadingChar)===t&&r===e?i:new ft({...mt,...e})})();return vt._loadingManager=i,vt._loadingOptions=e,i.loadCharData(t)}static getScalingTransform(t,e,i=0){const r=new L({width:t,height:e,padding:i});return{x:r.xOffset,y:r.yOffset,scale:r.scale,transform:(s=`\n translate(${r.xOffset}, ${r.height-r.yOffset})\n scale(${r.scale}, ${-1*r.scale})\n `,s.replace(/^\s+/,"").replace(/\s+$/,"")).replace(/\s+/g," ")};var s}showCharacter(t={}){return this._options.showCharacter=!0,this._withData(()=>{var e;return null===(e=this._renderState)||void 0===e?void 0:e.run(V("main",this._character,"number"==typeof t.duration?t.duration:this._options.strokeFadeDuration)).then(e=>{var i;return null===(i=t.onComplete)||void 0===i||i.call(t,e),e})})}hideCharacter(t={}){return this._options.showCharacter=!1,this._withData(()=>{var e;return null===(e=this._renderState)||void 0===e?void 0:e.run(Q("main",this._character,"number"==typeof t.duration?t.duration:this._options.strokeFadeDuration)).then(e=>{var i;return null===(i=t.onComplete)||void 0===i||i.call(t,e),e})})}animateCharacter(t={}){return this.cancelQuiz(),this._withData(()=>{var e;return null===(e=this._renderState)||void 0===e?void 0:e.run(Y("main",this._character,this._options.strokeFadeDuration,this._options.strokeAnimationSpeed,this._options.delayBetweenStrokes)).then(e=>{var i;return null===(i=t.onComplete)||void 0===i||i.call(t,e),e})})}animateStroke(t,e={}){return this.cancelQuiz(),this._withData(()=>{var i;return null===(i=this._renderState)||void 0===i?void 0:i.run(((t,e,i,r)=>{const s=e.strokes[i];return[new B("character."+t,i=>{const r=i.character[t],s={opacity:1,strokes:{}};for(let t=0;t<e.strokes.length;t++)s.strokes[t]={opacity:r.opacity*r.strokes[t].opacity};return s}),...K(t,s,r)]})("main",this._character,n(t,this._character.strokes.length),this._options.strokeAnimationSpeed)).then(t=>{var i;return null===(i=e.onComplete)||void 0===i||i.call(e,t),t})})}highlightStroke(t,e={}){return this._withData(()=>{var i,r;if(this._character&&this._renderState)return this._renderState.run(X((i=this._character.strokes,r=t,i[n(r,i.length)]),d(this._options.highlightColor),this._options.strokeHighlightSpeed)).then(t=>{var i;return null===(i=e.onComplete)||void 0===i||i.call(e,t),t})})}async loopCharacterAnimation(){return this.cancelQuiz(),this._withData(()=>this._renderState.run(((t,e,i,r,s,o)=>{const n=Y(t,e,i,r,s);return n.push(new B.Delay(o)),n})("main",this._character,this._options.strokeFadeDuration,this._options.strokeAnimationSpeed,this._options.delayBetweenStrokes,this._options.delayBetweenLoops),{loop:!0}))}pauseAnimation(){return this._withData(()=>{var t;return null===(t=this._renderState)||void 0===t?void 0:t.pauseAll()})}resumeAnimation(){return this._withData(()=>{var t;return null===(t=this._renderState)||void 0===t?void 0:t.resumeAll()})}showOutline(t={}){return this._options.showOutline=!0,this._withData(()=>{var e;return null===(e=this._renderState)||void 0===e?void 0:e.run(V("outline",this._character,"number"==typeof t.duration?t.duration:this._options.strokeFadeDuration)).then(e=>{var i;return null===(i=t.onComplete)||void 0===i||i.call(t,e),e})})}hideOutline(t={}){return this._options.showOutline=!1,this._withData(()=>{var e;return null===(e=this._renderState)||void 0===e?void 0:e.run(Q("outline",this._character,"number"==typeof t.duration?t.duration:this._options.strokeFadeDuration)).then(e=>{var i;return null===(i=t.onComplete)||void 0===i||i.call(t,e),e})})}updateDimensions({width:t,height:e,padding:i}){if(void 0!==t&&(this._options.width=t),void 0!==e&&(this._options.height=e),void 0!==i&&(this._options.padding=i),this.target.updateDimensions(this._options.width,this._options.height),this._character&&this._renderState&&this._hanziWriterRenderer&&this._positioner){this._hanziWriterRenderer.destroy();const t=this._initAndMountHanziWriterRenderer(this._character);this._renderState.overwriteOnStateChange(e=>t.render(e)),t.render(this._renderState.state),this._quiz&&this._quiz.setPositioner(this._positioner)}}updateColor(t,e,i={}){var r;let s=[];const o=d((()=>"radicalColor"!==t||e?e:this._options.strokeColor)());this._options[t]=e;const n=null!==(r=i.duration)&&void 0!==r?r:this._options.strokeFadeDuration;return s=s.concat(G(t,o,n)),"radicalColor"!==t||e||(s=s.concat(G(t,null,0))),this._withData(()=>{var t;return null===(t=this._renderState)||void 0===t?void 0:t.run(s).then(t=>{var e;return null===(e=i.onComplete)||void 0===e||e.call(i,t),t})})}quiz(t={}){return this._withData(async()=>{this._character&&this._renderState&&this._positioner&&(this.cancelQuiz(),this._quiz=new Z(this._character,this._renderState,this._positioner),this._options={...this._options,...t},this._quiz.startQuiz(this._options))})}cancelQuiz(){this._quiz&&(this._quiz.cancel(),this._quiz=void 0)}setCharacter(t){return this.cancelQuiz(),this._char=t,this._hanziWriterRenderer&&this._hanziWriterRenderer.destroy(),this._renderState&&this._renderState.cancelAll(),this._hanziWriterRenderer=null,this._withDataPromise=this._loadingManager.loadCharData(t).then(e=>{if(!e||this._loadingManager.loadingFailed)return;this._character=function(t,e){const i=T(e);return new R(t,i)}(t,e),this._renderState=new m(this._character,this._options,t=>i.render(t));const i=this._initAndMountHanziWriterRenderer(this._character);i.render(this._renderState.state)}),this._withDataPromise}_initAndMountHanziWriterRenderer(t){const{width:e,height:i,padding:r}=this._options;this._positioner=new L({width:e,height:i,padding:r});const s=new this._renderer.HanziWriterRenderer(t,this._positioner);return s.mount(this.target),this._hanziWriterRenderer=s,s}async getCharacterData(){if(!this._char)throw new Error("setCharacter() must be called before calling getCharacterData()");return await this._withData(()=>this._character)}_assignOptions(t){const e={...mt,...t};return t.strokeAnimationDuration&&!t.strokeAnimationSpeed&&(e.strokeAnimationSpeed=500/t.strokeAnimationDuration),t.strokeHighlightDuration&&!t.strokeHighlightSpeed&&(e.strokeHighlightSpeed=500/e.strokeHighlightDuration),t.highlightCompleteColor||(e.highlightCompleteColor=e.highlightColor),this._fillWidthAndHeight(e)}_fillWidthAndHeight(t){const e={...t};if(e.width&&!e.height)e.height=e.width;else if(e.height&&!e.width)e.width=e.height;else if(!e.width&&!e.height){const{width:t,height:i}=this.target.getBoundingClientRect(),r=Math.min(t,i);e.width=r,e.height=r}return e}_withData(t){if(this._loadingManager.loadingFailed)throw Error("Failed to load character data. Call setCharacter and try again.");return this._withDataPromise?this._withDataPromise.then(()=>{if(!this._loadingManager.loadingFailed)return t()}):Promise.resolve().then(t)}_setupListeners(){this.target.addPointerStartListener(t=>{this._quiz&&(t.preventDefault(),this._quiz.startUserStroke(t.getPoint()))}),this.target.addPointerMoveListener(t=>{this._quiz&&(t.preventDefault(),this._quiz.continueUserStroke(t.getPoint()))}),this.target.addPointerEndListener(()=>{var t;null===(t=this._quiz)||void 0===t||t.endUserStroke()})}}return vt._loadingManager=null,vt._loadingOptions=null,vt}();
//# sourceMappingURL=hanzi-writer.min.js.map
{
"name": "hanzi-writer",
"version": "3.4.1",
"version": "3.4.2",
"author": "David Chanin <chanindav@gmail.com> (http://chanind.github.io/hanzi-writer/)",

@@ -5,0 +5,0 @@ "description": "Hanzi Writer is a free and open-source javascript library for both animating simplified Chinese characters and quizzing users on character stroke order.",

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

Sorry, the diff of this file is not supported yet

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

Sorry, the diff of this file is not supported yet

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

Sorry, the diff of this file is not supported yet

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