text: var app=function(exports){'use strict';function noop(){}function run(e){for(var t=arguments.length,s=Array(1<t?t-1:0),a=1;a<t;a++)s[a-1]=arguments[a];return e instanceof Function?e(...s):e}function isOneOf(e){for(var t=arguments.length,s=Array(1<t?t-1:0),a=1;a<t;a++)s[a-1]=arguments[a];for(let t of s)if(e===t)return!0;return!1}function applyDefaults(e,t){for(let s of Object.keys(t))e.hasOwnProperty(s)||(e[s]=t[s]);return e}function deepExtend(e,t,s){void 0===s&&(s=(e,t)=>e.concat(t));for(let a of Object.keys(t))a in e&&Array.isArray(e[a])&&Array.isArray(t[a])?e[a]=s(e[a],t[a]):a in e&&e[a]instanceof Object&&t[a]instanceof Object?deepExtend(e[a],t[a]):e[a]=t[a]}function clamp(e,t,s){return void 0===t&&(t=-Infinity),void 0===s&&(s=1/0),Math.min(s,Math.max(t,e))}function square(e){return e*e}function delay(e,s){return void 0===s&&(s=0),s?setTimeout(e,s):void e()}function wait(e){return new Promise(t=>setTimeout(t,e))}function defer(){let e,t;const s=new Promise((s,a)=>{e=s,t=a});return s.catch(function(e){return e}),{promise:s,resolve:e,reject:t}}function cache(e){let t=new Map;return function(){for(var s=arguments.length,a=Array(s),n=0;n<s;n++)a[n]=arguments[n];let i=a.join("--");return t.has(i)||t.set(i,e(...a)),t.get(i)}}function throttle(e,s){void 0===s&&(s=0);let a=!1,n=!1;return function(){for(var t=arguments.length,i=Array(t),o=0;o<t;o++)i[o]=arguments[o];a?n=!0:(e.apply(null,i),a=!0,setTimeout(function(){n&&e(...i),a=!1,n=!1},s))}}function _tabulateWith(e,t,s){if(!s.length)return run(e,...t);let a=s.slice(0),n=a.shift(),o=[];for(let r=0;r<n;++r)o.push(_tabulateWith(e,t.concat([r]),a));return o}function tabulate(e){for(var t=arguments.length,s=Array(1<t?t-1:0),a=1;a<t;a++)s[a-1]=arguments[a];return _tabulateWith(e,[],s)}function last(e,t){return void 0===t&&(t=0),e[e.length-1-t]}function total(e){return e.length?+e.reduce((e,t)=>e+(+t||0)):0}function zip(e,t){let s={};for(let a=0;a<e.length;++a)s[e[a]]=t[a];return s}function sortBy(e,t,s){return void 0===s&&(s=!1),e.slice(0).sort((e,a)=>e[t]<a[t]?s?1:-1:e[t]>a[t]?s?-1:1:0)}function sortByFn(e,t,s){return void 0===s&&(s=!1),e.slice(0).sort((e,a)=>{let n=t(e),i=t(a);return n<i?s?1:-1:n>i?s?-1:1:0})}function loop(e){let t=0;return()=>e[t++%e.length]}function unique(e){return e.filter((e,t,s)=>s.indexOf(e)==t)}function without(e,t){return e.filter(e=>e!==t)}function flatten(e){return e.reduce((e,t)=>e.concat(Array.isArray(t)?flatten(t):t),[])}function cumulative(e){let t=0;return e.map(e=>t+=e)}function join(){return[].concat(...arguments)}function process(e,t){return t.lowercase&&(e=e.toLowerCase()),e.split(t.split).map(t=>t.trim())}function words(e){return e?e.trim().split(/\s+/):[]}function toCamelCase(e){return e.toLowerCase().replace(/^-/,"").replace(/-(.)/g,(e,t)=>t.toUpperCase())}function repeat(e,t){void 0===t&&(t=1);let s=e;for(let a=1;a<t;++a)s+=e;return s}function stringDistance(e,t){let s=tabulate(0,e.length+1,t.length+1);for(let a=0;a<=e.length;a++)s[a][0]=a;for(let a=0;a<=t.length;a++)s[0][a]=a;for(let a=1;a<=e.length;a++)for(let n=1;n<=t.length;n++)s[a][n]=Math.min(s[a-1][n-1]+(e.charAt(a-1)===t.charAt(n-1)?0:1),s[a-1][n]+1,s[a][n-1]+1);return s[e.length][t.length]}function autocorrect(e,t){let s=e.length/2,a=t.map(t=>({w:t,d:stringDistance(e,t)})).filter((e)=>{let{d:t}=e;return t<s}),n=sortBy(a,"d")[0];return n?n.w:null}function isString(e){return e instanceof String||"string"==typeof e}function isInteger(e){return 0==e%1}function nearlyEquals(e,s,a){return void 0===a&&(a=tolerance),!(isNaN(e)||isNaN(s))&&Math.abs(e-s)<a}function isBetween(e,s,n,i){return void 0===i&&(i=tolerance),s>n&&([s,n]=[n,s]),e>s+i&&e<n-i}function addThousandSeparators(e){e=(""+e).split(".");let t=e[0];for(;NUM_REGEX.test(t);)t=t.replace(NUM_REGEX,"$1,$2");return t+(1<e.length?"."+e[1]:"")}function addPowerSuffix(e,t){if(!t)return e;const s=(""+Math.abs(Math.floor(e))).length,a=0>e?1:0;if(s<=t-a)return _round(e,t-s-a-1);const n=Math.floor(Math.log10(Math.abs(e))/3);return _round(e/Math.pow(10,3*n),t-(s%3||3)-a-1)+POWER_SUFFIX[n]}function numberFormat(e,t){return void 0===t&&(t=0),addThousandSeparators(addPowerSuffix(e,t)).replace("-","\u2013")}function parseNumber(e){return e=e.replace(/^–/,"-").trim(),!e||e.match(/[^0-9.,-]/)?NaN:SPECIAL_DECIMAL.test(e)?parseFloat(e.replace(/,/,".")):POINT_DECIMAL.test(e)?parseFloat(e.replace(/,/g,"")):COMMA_DECIMAL.test(e)?parseFloat(e.replace(/\./g,"").replace(/,/,".")):NaN}function fmt(e){let[s,a,t]=("00"+e).substr(-3);return[0===+s?"":ONES[s]+" hundred ",0===+t?TENS[a]:TENS[a]&&TENS[a]+"-"||"",ONES[a+t]||ONES[t]].join("")}function cons(e,t,s){return t?[t,s&&" "+s||""," ",e].join(""):e}function toWord(e){if(0===e)return"zero";let t="",s=0;for(;e;)t=cons(t,fmt(e%1e3),MULTIPLIERS[s]),s+=1,e=0|e/1e3;return t.trim()}function _round(e,t){void 0===t&&(t=0);let s=Math.pow(10,t);return Math.round(e*s)/s}function roundTo(e,t){return void 0===t&&(t=1),Math.round(e/t)*t}function _getSubsets(e){if(1===e.length)return[[],e];let t=e.pop(),a=_getSubsets(e),n=[];for(let i of a){let e=i.slice(0);e.push(t),n.push(i,e)}return n}function subsets(e,t){void 0===t&&(t=0);let s=e.slice(0),a=_getSubsets(s);return t&&(a=a.filter(e=>e.length===t)),a}function run$1(e){for(var t=arguments.length,s=Array(1<t?t-1:0),a=1;a<t;a++)s[a-1]=arguments[a];return e instanceof Function?e(...s):e}function clamp$1(e,t,s){return void 0===t&&(t=-Infinity),void 0===s&&(s=1/0),Math.min(s,Math.max(t,e))}function square$1(e){return e*e}function _tabulateWith$1(e,t,s){if(!s.length)return run$1(e,...t);let a=s.slice(0),n=a.shift(),o=[];for(let r=0;r<n;++r)o.push(_tabulateWith$1(e,t.concat([r]),a));return o}function tabulate$1(e){for(var t=arguments.length,s=Array(1<t?t-1:0),a=1;a<t;a++)s[a-1]=arguments[a];return _tabulateWith$1(e,[],s)}function total$1(e){return e.length?+e.reduce((e,t)=>e+(+t||0)):0}function flatten$1(e){return e.reduce((e,t)=>e.concat(Array.isArray(t)?flatten$1(t):t),[])}function toLinkedList(e){const t=e.map(e=>({val:e,next:null})),s=t.length;for(let a=0;a<s;++a)t[a].next=t[(a+1)%s];return t}function rad(e,t){void 0===t&&(t=origin);const s=Math.atan2(e.y-t.y,e.x-t.x);return(s+twoPi)%twoPi}function liesOnSegment(e,t){return nearlyEquals(e.p1.x,e.p2.x)?isBetween(t.y,e.p1.y,e.p2.y):isBetween(t.x,e.p1.x,e.p2.x)}function liesOnRay(e,t){return nearlyEquals(e.p1.x,e.p2.x)?0<(t.y-e.p1.y)/(e.p2.y-e.p1.y):0<(t.x-e.p1.x)/(e.p2.x-e.p1.x)}function lineLineIntersection(e,t){const s=e.p1.x-e.p2.x,a=e.p1.y-e.p2.y,n=t.p1.x-t.p2.x,i=t.p1.y-t.p2.y,o=s*i-a*n;if(nearlyEquals(o,0))return[];const r=e.p1.x*e.p2.y-e.p1.y*e.p2.x,l=t.p1.x*t.p2.y-t.p1.y*t.p2.x;return[new Point((r*n-s*l)/o,(r*i-a*l)/o)]}function circleCircleIntersection(e,t){const s=Point.distance(e.c,t.c);if(s>e.r+t.r)return[];if(s<Math.abs(e.r-t.r))return[];if(nearlyEquals(s,0)&&nearlyEquals(e.r,t.r))return[];if(nearlyEquals(s,e.r+t.r))return[new Line(e.c,t.c).midpoint];const n=(square$1(e.r)-square$1(t.r)+square$1(s))/(2*s),a=Math.sqrt(square$1(e.r)-square$1(n)),i=(t.c.x-e.c.x)*n/s+(t.c.y-e.c.y)*a/s+e.c.x,o=(t.c.y-e.c.y)*n/s-(t.c.x-e.c.x)*a/s+e.c.y,r=(t.c.x-e.c.x)*n/s-(t.c.y-e.c.y)*a/s+e.c.x,l=(t.c.y-e.c.y)*n/s+(t.c.x-e.c.x)*a/s+e.c.y;return[new Point(i,o),new Point(r,l)]}function lineCircleIntersection(){return[]}function intersections(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];if(2>t.length)return[];if(2<t.length)return flatten$1(subsets(t,2).map(t=>intersections(...t)));let[n,o]=t;if((o instanceof Polygon||o instanceof Rectangle)&&([n,o]=[o,n]),n instanceof Polygon||n instanceof Rectangle){const e=o instanceof Line?n.points.filter(e=>o.contains(e)):[];return[...e,...intersections(o,...n.edges)]}let i=[];return n instanceof Line&&o instanceof Line?i=lineLineIntersection(n,o):n instanceof Line&&o instanceof Circle?i=lineCircleIntersection():n instanceof Circle&&o instanceof Line?i=lineCircleIntersection():n instanceof Circle&&o instanceof Circle&&(i=circleCircleIntersection(n,o)),n instanceof Segment&&(i=i.filter(e=>liesOnSegment(n,e))),o instanceof Segment&&(i=i.filter(e=>liesOnSegment(o,e))),n instanceof Ray&&(i=i.filter(e=>liesOnRay(n,e))),o instanceof Ray&&(i=i.filter(e=>liesOnRay(o,e))),i}function shuffle(e){e=e.slice(0);for(let t=e.length-1,s;0<t;--t)s=Math.floor(Math.random()*(t+1)),[e[t],e[s]]=[e[s],e[t]];return e}function intArray(e){let t=[];for(let s=0;s<e;++s)t.push(s);return shuffle(t)}function uniform(e,t){return void 0===e&&(e=0),void 0===t&&(t=1),e+(t-e)*Math.random()}function animate(e,t){function s(){i&&(!t||n<=t)&&window.requestAnimationFrame(s);const r=Date.now()-a;e(t?Math.min(1,r/t):r,r-n,l),t&&r>=t&&o.resolve(),n=r}if(0===t)return void e();let a=Date.now(),n=0,i=!0;const o=defer(),r=o.promise.then.bind(o.promise),l=()=>{i=!1,o.reject()};return s(),{cancel:l,then:r}}function easeIn(e,a,t){return"quad"===e?a*a:"cubic"===e?a*a*a:"quart"===e?a*a*a*a:"quint"===e?a*a*a*a*a:"circ"===e?1-Math.sqrt(1-a*a):"sine"===e?1-Math.cos(a*Math.PI/2):"exp"===e?0>=a?0:Math.pow(2,10*(a-1)):"back"===e?(t||(t=1.70158),a*a*((t+1)*a-t)):"elastic"===e?(t||(t=.3),-Math.pow(2,10*(a-1))*Math.sin((2*(a-1)/t-.5)*Math.PI)):"swing"===e?.5-Math.cos(a*Math.PI)/2:"spring"===e?1-Math.cos(4.5*a*Math.PI)*Math.exp(6*-a):"bounce"===e?a<1/11?1/64-7.5625*(.5/11-a)*(.5/11-a):a<3/11?1/16-7.5625*(2/11-a)*(2/11-a):a<7/11?1/4-7.5625*(5/11-a)*(5/11-a):1-7.5625*(1-a)*(1-a):a}function ease(e,a,n){return(void 0===a&&(a=0),void 0===n&&(n=0),0===a)?0:1===a?1:(e=e.split("-"),"in"===e[1]?easeIn(e[0],a,n):"out"===e[1]?1-easeIn(e[0],1-a,n):.5>=a?easeIn(e[0],2*a,n)/2:1-easeIn(e[0],2*(1-a),n)/2)}function transition(t,s,a,n,i){if(void 0===a&&(a=400),void 0===n&&(n=0),void 0===i&&(i="ease-in-out"),!isReady)return Object.keys(s).forEach(e=>{let a=s[e];t.css(e,Array.isArray(a)?a[1]:a)}),Promise.resolve();"bounce-in"===i&&(i=BOUNCE_IN),"bounce-out"===i&&(i=BOUNCE_OUT),t._data._animation&&t._data._animation.cancel();const o={},e={},r=defer(),l=window.getComputedStyle(t._el);Object.keys(s).forEach(a=>{const i=s[a],r=toCamelCase(a);e[r]=Array.isArray(i)?i[0]:l.getPropertyValue(a),o[r]=Array.isArray(i)?i[1]:i,n&&t.css(a,e[r])});let d=o.height;"auto"===o.height&&(o.height=total(t.children.map(e=>e.outerHeight))+"px");let c=!1,p;delay(()=>{c||(p=t._el.animate([e,o],{duration:a,easing:i,fill:"forwards"}),p.onfinish=function(a){t._el&&Object.keys(s).forEach(e=>t.css(e,"height"===e?d:o[e])),r.resolve(a),p.cancel()})},n);const h={then:r.promise.then.bind(r.promise),cancel(){c=!0,t._el&&Object.keys(s).forEach(e=>t.css(e,t.css(e))),p&&p.cancel()}};return setTimeout(()=>t._data._animation=h),h}function enter(e,t,s,a){if(void 0===t&&(t="fade"),void 0===s&&(s=500),void 0===a&&(a=0),e.show(),!isReady)return Promise.resolve();if("fade"===t)return transition(e,{opacity:[0,1]},s,a);if("pop"===t){const t=e.transform.replace(/scale\([0-9.]*\)/,"").replace(cssMatrix,"translate($1px,$2px)");return transition(e,{opacity:[0,1]},s,a),transition(e,{transform:[t+" scale(0.5)",t+" scale(1)"]},s,a,"bounce-in")}if("descend"===t){return transition(e,{opacity:[0,1],transform:["translateY(-50%)","none"]},s,a)}if(t.startsWith("draw")){const n=e.strokeLength+"px";e.css({opacity:1,"stroke-dasharray":n});const i="draw-reverse"===t?"-"+n:n;return transition(e,{"stroke-dashoffset":[i,0]},s,a,"linear").then(()=>e.css("stroke-dasharray",""))}if(t.startsWith("slide")){const n={opacity:[0,1],transform:["translateY(50px)","none"]};return t.includes("down")&&(n.transform[0]="translateY(-50px)"),transition(e,n,s,a)}if(t.startsWith("reveal")){const n={opacity:[0,1],height:[0,"auto"]};return t.includes("left")&&(n.transform=["translateX(-50%)","none"]),t.includes("right")&&(n.transform=["translateX(50%)","none"]),transition(e,n,s,a)}}function exit(e,t,s,a,n){if(void 0===t&&(t="fade"),void 0===s&&(s=400),void 0===a&&(a=0),void 0===n&&(n=!1),!e._el)return Promise.resolve();if(!isReady)return e.hide(),Promise.resolve();if("none"===e.css("display"))return Promise.resolve();let i;if("fade"===t)i=transition(e,{opacity:[1,0]},s,a);else if("pop"===t){const t=e.transform.replace(/scale\([0-9.]*\)/,"");transition(e,{opacity:[1,0]},s,a),i=transition(e,{transform:[t+" scale(1)",t+" scale(0.5)"]},s,a,"bounce-out")}else if("ascend"===t){i=transition(e,{opacity:[1,0],transform:["none","translateY(-50%)"]},s,a)}else if(t.startsWith("draw")){const n=e.strokeLength+"px";e.css("stroke-dasharray",n);const o="draw-reverse"===t?"-"+n:n;i=transition(e,{"stroke-dashoffset":[0,o]},s,a,"linear")}else if(t.startsWith("slide")){const n={opacity:0,transform:"translateY(50px)"};t.includes("up")&&(n.transform="translateY(-50px)"),i=transition(e,n,s,a)}else if(t.startsWith("reveal")){const n={opacity:0,height:0};t.includes("left")&&(n.transform="translateX(-50%)"),t.includes("right")&&(n.transform="translateX(50%)"),i=transition(e,n,s,a)}return i.then(()=>n?e.remove():e.hide()),i}function effect(e,t){e.animationEnd(function(){e.removeClass("effects-"+t)}),e.addClass("effects-"+t)}function redraw(){document.body.offsetHeight}function resize(e){void 0===e&&(e=null),e?(e({width,height}),browserEvents.on("resize",e)):doResize()}function afterLoad(){if(!loaded){loaded=!0;for(let e of loadQueue)e();setTimeout(resize)}}function ready(e){loaded?e():loadQueue.push(e)}function cssTimeToNumber(e){let t=/^([\-\+]?[0-9]+(\.[0-9]+)?)(m?s)$/,s=t.exec(e.trim());return null===s?null:+s[1]*("s"===s[3]?1e3:1)}function addCSS(e){let t=document.createElement("style");t.type="text/css",t.innerHTML=e,document.head.appendChild(t)}function addCSSRule(e,t){let s=document.styleSheets[document.styleSheets.length-1],a=s.cssRules.length-1;s.insertRule?s.insertRule(e+"{"+t+"}",a):s.addRule(e,t,a)}function getCookies(){let e=document.cookie.split(";"),t={};for(let s=0,a=e.length,n;s<a;++s)n=e[s].split("="),n[0]=n[0].replace(/^\s+|\s+$/,""),t[decodeURIComponent(n[0])]=decodeURIComponent(n[1]);return t}function getCookie(e){let t=document.cookie.match(new RegExp("(^|;) ?"+e+"=([^;]*)(;|$)"));return t?t[2]:null}function setCookie(e,t,s){void 0===s&&(s=31536000),document.cookie=e+"="+t+";path=/;max-age="+s}function deleteCookie(e){setCookie(e,"",-1)}function setStorage(e,t){let s=(e||"").split("."),a=JSON.parse(window.localStorage.getItem(STORAGE_KEY))||{},n=a;for(let a=0;a<s.length-1;++a)null==n[s[a]]&&(n[s[a]]={}),n=n[s[a]];n[s[s.length-1]]=t,window.localStorage.setItem(STORAGE_KEY,JSON.stringify(a))}function getStorage(e){let t=JSON.parse(window.localStorage.getItem(STORAGE_KEY))||{};if(!e)return t;const s=(e||"").split("."),a=s.pop();for(let a of s){if(!(a in t))return null;t=t[a]}return t[a]}function deleteStorage(e){e?setStorage(e,null):window.localStorage.setItem(STORAGE_KEY,"")}function activeInput(){let e=document.activeElement;return e===document.body?void 0:$(e)}function onKey(t,s){t=words(t).map(e=>keyCodes[e]||e),document.addEventListener("keydown",function(a){let e=activeInput();e&&e.is("input, textarea, [contenteditable]")||0<=t.indexOf(a.keyCode)&&s(a)})}function replaceSvgImports(){if(polyfill){let e=Array.from(document.querySelectorAll("svg > use"));e.forEach(function(e){let t=e.getAttribute("xlink:href"),[s,a]=t.split("#");if(!s.length)return;let n=e.parentNode;n.removeChild(e),s in requests||(requests[s]=get(s));let i=requests[s];i.then(function(e){let t=document.implementation.createHTMLDocument("");t.documentElement.innerHTML=e;let s=t.getElementById(a),i=s.cloneNode(!0),o=document.createDocumentFragment();for(;i.childNodes.length;)o.appendChild(i.firstChild);n.appendChild(o)})})}}function pointerPosition(t){if("touches"in t){let e=t.targetTouches.length?t.targetTouches:t.changedTouches;return new Point(e[0].clientX,e[0].clientY)}return new Point(t.clientX,t.clientY)}function svgPointerPosn(e,t){let s=pointerPosition(e);return s.transform(t.inverseTransformMatrix)}function canvasPointerPosition(e,t){const s=pointerPosition(e),a=t.bounds,n=(s.x-a.left)*t._el.width/a.width,i=(s.y-a.top)*t._el.height/a.height;return new Point(n,i)}function makeClickEvent(t){if(t._events._click)return;if(t._events._click=!0,!navigator.userAgent.match(/iP(ad|hone|od)/g))return void t._el.addEventListener("click",function(s){t.trigger("click",s)});let s;t._el.addEventListener("touchstart",function(t){1==t.touches.length&&(s=pointerPosition(t))}),t._el.addEventListener("touchend",function(a){if(s){let e=pointerPosition(a);5>Math.abs(e.x-s.x)&&5>Math.abs(e.y-s.y)&&t.trigger("click",a),s=null}}),t._el.addEventListener("touchcancel",function(){s=null})}function makeClickOutsideEvent(t){t._events._clickOutside||(t._events._clickOutside=!0,$body.on("click",function(s){$(s.target).hasParent(t)||t.trigger("clickOutside")}))}function slide(t,s){function a(t){t.preventDefault(),t.handled||t.touches&&1<t.touches.length||(t.handled=!0,"move"in s&&l.on("pointermove",n),l.on("pointerstop",i),d=c=r(t),"start"in s&&s.start(d))}function n(t){t.preventDefault(),o||(o=!0,window.requestAnimationFrame(function(){if(o){const e=r(t);s.move(e,d,c),c=e,o=!1}}))}function i(t){t.preventDefault(),t.touches&&0<t.touches.length||(o=!1,"move"in s&&l.off("pointermove",n),l.off("pointerstop",i),"end"in s&&s.end(c,d))}let o=!1,r=pointerPosition;if("SVG"===t.tagName)r=s=>svgPointerPosn(s,t);else if("CANVAS"===t.tagName)r=s=>canvasPointerPosition(s,t);else if(t instanceof SVGElement){const s=t.parents("svg")[0];r=t=>svgPointerPosn(t,s)}let l=s.justInside?t:$body,d,c;"auto"===t.css("touch-action")&&t.css("touch-action","none"),t.on("pointerdown",a),s.justInside&&t.on("mouseleave",i)}function makeScrollEvents(e){function t(){let s=e.scrollTop;return s==o?void(i=!1):void(o=s,e.trigger("scroll",{top:o}),window.requestAnimationFrame(t))}function s(){i||window.requestAnimationFrame(t),i=!0}function a(){window.addEventListener("touchmove",s),window.addEventListener("touchend",n)}function n(){window.removeEventListener("touchmove",s),window.removeEventListener("touchend",n)}if(e._data._scrollEvents)return;e._data._scrollEvents=!0;let i=!1,o=null,r=e instanceof WindowElement?window:e._el;r.addEventListener("scroll",s),e._el.addEventListener("touchstart",function(t){t.handled||a()})}function makeHoverEvent(e,t){let s=null,a=!1,n=!1;e.on("mouseover",()=>{t.preventMouseover&&t.preventMouseover()||(clearTimeout(s),s=delay(()=>{a||(t.enter(),n=!0,a=!0)},t.delay))}),e.on("mouseout",()=>{n&&(clearTimeout(s),s=delay(()=>{a&&(t.exit&&t.exit(),a=!1)},t.delay))});const i=t.$clickTarget||e;i.on("click",()=>{a&&!n?(t.exit&&t.exit(),a=!1):!a&&(t.enter(),n=!1,a=!0)}),e.on("clickOutside",()=>{a&&(t.exit&&t.exit(),a=!1)})}function intersectionCallback(t){for(let s of t){const e=s.isIntersecting?"enterViewport":"exitViewport";setTimeout(()=>$(s.target).trigger(e))}}function makeIntersectionEvents(e){if(!e._data.intersectionEvents){if(e._data.intersectionEvents=!0,!window.IntersectionObserver){let t=!1;return void $body.on("scroll",()=>{let s=e.isInViewport;t&&!s?(e.trigger("exitViewport"),t=!1):s&&!t&&(e.trigger("enterViewport"),t=!0)})}observer||(observer=new IntersectionObserver(intersectionCallback)),observer.observe(e._el)}}function checkInside(e,t){let s=pointerPosition(e),a=document.elementFromPoint(s.x,s.y);return isOneOf(t._el,a,a.parentNode,a.parentNode.parentNode)}function makePointerPositionEvents(t){if(t._data._pointerEvents)return;t._data._pointerEvents=!0;let s=t.parent,a=null;s.on("pointerend",function(){a=null}),s.on("pointermove",function(s){let e=a;a=checkInside(s,t),null!=e&&a&&!e&&t.trigger("pointerenter",s),!a&&e&&t.trigger("pointerleave",s)})}function makeMouseEvent(t,s){s._events["_"+t]||(s._events["_"+t]=!0,s._el.addEventListener(t,function(a){touchEnabled||s.trigger(t,a)}))}function makeKeyEvent(t){t.on("keydown",s=>{if(!(s.metaKey||s.ctrlKey)&&!(Browser.isAndroid&&229===s.keyCode)){const e=(s.key||String.fromCharCode(s.which)).toLowerCase();t.trigger("key",{code:s.keyCode,key:e})}}),Browser.isAndroid&&t.on("input",s=>{const e=s.data[s.data.length-1].toLowerCase();t.trigger("key",{code:null,key:e}),t.value=""})}function createEvent(e,t,s,a){t in e._events?0>e._events[t].indexOf(s)&&e._events[t].push(s):e._events[t]=[s],t in aliases?e.on(aliases[t],s,a):t in customEvents?customEvents[t](e,s):e._el.addEventListener(t,s,a)}function removeEvent(e,t,s,a){if(t in e._events&&(e._events[t]=without(e._events[t],s)),t in aliases)e.off(aliases[t],s,a);else if(t in customEvents);else e._el.removeEventListener(t,s,a)}function drawArc(e,t,s){const a=t.x*(s.y-e.y)+e.x*(t.y-s.y)+s.x*(e.y-t.y),n=0<a?1:0,i=Point.distance(t,e);return[e.x,e.y+"A"+i,i,0,n,1,s.x,s.y].join(",")}function angleSize(e,t){return void 0===t&&(t={}),e.isRight&&!t.round?20:24+20*(1-clamp(e.rad,0,Math.PI)/Math.PI)}function drawAngle(e,t){void 0===t&&(t={});let s=e.a;const n=e.b;let i=e.c;const o=t.size||angleSize(e,t),r=Point.difference(s,n).normal,l=Point.difference(i,n).normal;s=Point.sum(n,r.scale(o)),i=Point.sum(n,l.scale(o));let h=t.fill?"M"+n.x+","+n.y+"L":"M";if(e.isRight&&!t.round){const e=Point.sum(s,l.scale(o));h+=s.x+","+s.y+"L"+e.x+","+e.y+"L"+i.x+","+i.y}else h+=drawArc(s,n,i);return t.fill&&(h+="Z"),h}function drawPath(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];return"M"+t.map(e=>e.x+","+e.y).join("L")}function drawLineMark(e,t){const s=e.perpendicularVector.scale(6),a=e.normalVector.scale(3),n=e.midpoint;return"bar"===t?drawPath(n.add(s),n.add(s.inverse)):"bar2"===t?drawPath(n.add(a).add(s),n.add(a).add(s.inverse))+drawPath(n.add(a.inverse).add(s),n.add(a.inverse).add(s.inverse)):"arrow"===t?drawPath(n.add(a.inverse).add(s),n.add(a),n.add(a.inverse).add(s.inverse)):"arrow2"===t?drawPath(n.add(a.scale(-2)).add(s),n,n.add(a.scale(-2)).add(s.inverse))+drawPath(n.add(s),n.add(a.scale(2)),n.add(s.inverse)):void 0}function arrowPath(e,t){if(!e||!t)return"";const s=t.perpendicular,n=e.add(t.scale(9)).add(s.scale(9)),a=e.add(t.scale(9)).add(s.scale(-9));return drawPath(n,e,a)}function drawLineArrows(e,t){let s="";return isOneOf(t,"start","both")&&(s+=arrowPath(e.p1,e.normalVector)),isOneOf(t,"end","both")&&(s+=arrowPath(e.p2,e.normalVector.inverse)),s}function drawArcArrows(e,t){let s="";if(isOneOf(t,"start","both")){const t=new Line(e.c,e.start).perpendicularVector.inverse;s+=arrowPath(e.start,t)}if(isOneOf(t,"end","both")){const t=new Line(e.c,e.end).perpendicularVector;s+=arrowPath(e.end,t)}return s}function drawSVG(e,t){void 0===t&&(t={});const s=e.constructor.name;if("Angle"===s)return drawAngle(e,t);if("Segment"===s){if(e.p1.equals(e.p2))return"";let s=drawPath(e.p1,e.p2);return t.mark&&(s+=drawLineMark(e,t.mark)),t.arrows&&(s+=drawLineArrows(e,t.arrows)),s}if("Ray"===s){if(!t.box)return"";const s=intersections(e,t.box)[0];return s?drawPath(e.p1,s):""}if("Line"===s){if(!t.box)return"";const s=intersections(e,t.box);if(2>s.length)return"";let a=drawPath(s[0],s[1]);return t.mark&&(a+=drawLineMark(e,t.mark)),a}if("Circle"===s)return"M "+(e.c.x-e.r)+" "+e.c.y+" a "+e.r+","+e.r+" 0 1 0 "+(2*e.r+" 0 a "+e.r+" "+e.r+" 0 1 0 "+-2*e.r+" 0");if("Arc"===s){let s="M"+drawArc(e.start,e.c,e.end);return t.arrows&&(s+=drawArcArrows(e,t.arrows)),s}return"Sector"===s?"M "+e.c.x+" "+e.c.y+" L "+drawArc(e.start,e.c,e.end)+" Z":"Polyline"===s?drawPath(...e.points):"Polygon"===s||"Triangle"===s?drawPath(...e.points)+"Z":"Rectangle"===s?drawPath(...e.polygon.points)+"Z":void 0}function drawCanvas(e,t,s){void 0===s&&(s={});const a=t.constructor.name;if(s.fill&&(e.fillStyle=s.fill),s.opacity&&(e.globalAlpha=s.opacity),s.stroke&&(e.strokeStyle=s.stroke,e.lineWidth=s.strokeWidth||1,s.lineCap&&(e.lineCap=s.lineCap),s.lineJoin&&(e.lineJoin=s.lineJoin)),e.beginPath(),"Segment"===a)e.moveTo(t.p1.x,t.p1.y),e.lineTo(t.p2.x,t.p2.y);else if("Circle"===a)e.arc(t.c.x,t.c.y,t.r,0,2*Math.PI);else if("Polygon"===a||"Triangle"===a){e.moveTo(t.points[0].x,t.points[0].y);for(let s of t.points.slice(1))e.lineTo(s.x,s.y);e.closePath()}else if("Polyline"===a){e.moveTo(t.points[0].x,t.points[0].y);for(let s of t.points.slice(1))e.lineTo(s.x,s.y)}s.fill&&e.fill(),s.stroke&&e.stroke()}function observable(e){function t(t,s){a[t]=s,t in e||Object.defineProperty(e,t,{get:()=>a[t],set(s){a[t]=s,e.update()}})}void 0===e&&(e={});let s=[],a={},i=1,o=ALPHABETH.split("").map(e=>"_"+e);for(let s of Object.keys(e))t(s,e[s]);return e.update=function(){for(let e of s)e(a)},e.watch=function(e,t){void 0===t&&(t=!1),s.push(e),t||e(a)},e.set=function(s,n){a[s]===n||(t(s,n),e.update())},e.assign=function(s){for(let e of Object.keys(s))t(e,s[e]);e.update()},e.name=function(){return o.length||(i+=1,o=ALPHABETH.split("").map(e=>repeat("_",i)+e)),o.pop()},e}function parse(t,s){void 0===s&&(s=!1);let a=t.replace(/×/g,"*");s||(a=a.replace(/"/g,"\"").replace(/\$\{([^\}]+)\}/g,(e,t)=>"\" + ("+t+") + \""),a="\""+a+"\"");try{return new Function("_vars","try {\n      with(_vars) { return "+a+" }\n    } catch(_error) {\n      if (!(_error instanceof ReferenceError)) console.warn(_error);\n      return \"\";\n    }")}catch(s){return console.warn("WHILE PARSING: ",t,"\n",s),function(){return""}}}function makeTemplate(e,t,s,a){if(void 0===a&&(a=s),0>s[t].indexOf("${"))return;let n=parse(s[t]);e.watch(()=>{a[t]=n(e)}),a[t]=n(e)}function bindObservable(e,t,s){void 0===s&&(s=!0);for(let n of e.attributes){let s=n.name.match(/^x-/)?document.createAttribute(n.name.replace(/^x-/,"")):n;makeTemplate(t,"value",n,s),s!==n&&e._el.setAttributeNode(s)}if(e.children.length)for(let a of e.childNodes)"TEXT"===a.tagName?makeTemplate(t,"text",a):s&&bindObservable(a,t);else e.html.trim()&&makeTemplate(t,"html",e)}function $(e,t){if(void 0===t&&(t=null),!e)return null;const s=t?t._el:document.documentElement,a="string"==typeof e?s.querySelector(e):e;if(!a)return null;if(a.$el)return a.$el;if(isOneOf(a,window,document.body,document.documentElement))return new WindowElement(a);const n=(a.tagName||"").toLowerCase();return 0<=svgTags.indexOf(n)?new SVGElement(a):0<=formTags.indexOf(n)?new FormElement(a):"canvas"===n?new CanvasElement(a):isOneOf(n,"video","audio")?new MediaElement(a):new Element(a)}function $$(e,t){void 0===t&&(t=null);const s=t?t._el:document.documentElement;let a=s.querySelectorAll(e||null);return Array.from(a,e=>$(e))}function $N(e,s,a){void 0===s&&(s={}),void 0===a&&(a=null);const n=0>svgTags.indexOf(e)?document.createElement(e):document.createElementNS("http://www.w3.org/2000/svg",e);for(let t of Object.keys(s))"id"===t?n.id=s.id:"html"===t?n.innerHTML=s.html:"text"===t?n.textContent=s.text:"path"===t?n.setAttribute("d",drawSVG(s.path)):n.setAttribute(t,s[t]);let t=$(n);return a&&a.append(t),t}function $$N(e){return $N("div",{html:e}).children}function toQueryString(e){let t=[];for(let s in e){let a=e[s];if(s=encodeURIComponent(s),null==a)return void t.push(s);a=Array.isArray(a)?a.join(","):""+a,a=a.replace(/(\r)?\n/g,"\r\n"),a=encodeURIComponent(a),a=a.replace(/%20/g,"+"),t.push(s+"="+a)}return t.join("&")}function fetch(e,t,s,a){void 0===s&&(s=null),void 0===a&&(a={async:!0,cache:!0});let n=new XMLHttpRequest,i=defer(),o="";return n.onreadystatechange=function(){if(!(3>=n.readyState)){let e=n.status;200<=e&&300>e||304===e?i.resolve(n.responseText):i.reject(n)}},"GET"===e?(t+=0<=t.indexOf("?")?"&xhr=1":"?xhr=1",!a.cache&&(t+="_cachebust="+Date.now()),s&&(t+=toQueryString(s)+"&"),n.open(e,t,a.async,a.user,a.password)):"POST"==e&&(n.open(e,t,a.async,a.user,a.password),n.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),n.setRequestHeader("X-CSRF-Token",window.csrfToken||""),o=isString(s)?"?"+s:Object.keys(s).map(e=>encodeURIComponent(e)+"="+encodeURIComponent(s[e])).join("&")),n.setRequestHeader("x-requested-with","XMLHttpRequest"),n.send(o),i.promise}function get(e,t){return void 0===t&&(t=null),fetch("GET",e,t)}function post(e,t){return void 0===t&&(t=null),fetch("POST",e,t)}function savePostData(e,t){POST_DATA.has(e)?deepExtend(POST_DATA.get(e),t,(e,t)=>unique(e.concat(t))):POST_DATA.set(e,t)}function sendPostData(){if(!1!==navigator.onLine)for(let[e,t]of POST_DATA)POST_DATA.delete(e),fetch("POST",e,{data:JSON.stringify(t)}).catch(()=>savePostData(e,t))}function deferredPost(e,t){savePostData(e,t),doDeferredPost()}function pad2(e){return 1===e.length?"0"+e:e}function getColourAt(e,t){t=clamp(t,0,.9999);let s=Math.floor(t*(e.length-1)),a=t*(e.length-1)-s;return Colour.mix(e[s+1],e[s],a)}function getViewParams(e,t){let s=t.regex.exec(e);return s?(s.shift(),zip(t.params,s)):null}function onLinkClick(t){if(t.metaKey||t.ctrlKey||t.shiftKey)return;if(t.defaultPrevented)return;let e=t.target;for(;e&&"A"!==e.nodeName;)e=e.parentNode;if(e&&"A"===e.nodeName&&!e.target&&e.origin===window.location.origin&&!(e.hasAttribute("download")||"external"===e.getAttribute("rel"))){let s=e.getAttribute("href");if(!(s&&-1<s.indexOf("mailto:"))){let s=this.goTo(e.pathname+e.search,e.hash);s&&t.preventDefault()}}}function renderView(e,t,s,a){e.$viewport.css("opacity",0),setTimeout(()=>{e.$viewport.removeChildren(),$body.scrollTop=0,e.$viewport.html=s,Browser.resize(),Browser.replaceSvgImports(),e.$viewport.css({opacity:1,"pointer-events":"all"}),document.title=e.$viewport.$("title").text,e.initialise(e.$viewport,a),t.enter&&t.enter(e.$viewport,a),e.trigger("afterChange",{$viewport:e.$viewport})},350)}function loadView(e,t,s,a){void 0===s&&(s={}),void 0===a&&(a=""),e.$viewport.css({opacity:.4,"pointer-events":"none"});let n=run(t.template,s)||get(a);n.then?n.then(a=>renderView(e,t,a,s)):renderView(e,t,n,s)}function applyTemplate(e,t){const s=Array.from(e.childNodes);if(t.template)e.innerHTML=t.template;else if(t.templateId){let s=document.querySelector(t.templateId);if(!s)throw new Error("Template not found:",t.templateId);for(;e.firstChild;)e.removeChild(e.firstChild);let a=document.importNode(s.content,!0);e.appendChild(a)}if(s.length){const t=e.querySelector("slot:not([name])");for(let a of s){let s=a.getAttribute?a.getAttribute("slot"):null,n=s?e.querySelector("slot[name=\""+s+"\"]"):t;n&&n.parentNode.insertBefore(a,n)}for(let t of e.querySelectorAll("slot"))t.parentNode.removeChild(t)}}function customElementChildren(e){const t=[];for(let s of Array.from(e.children))s.tagName.startsWith("X-")?t.push(s):t.push(...customElementChildren(s));return t}function registerElement(e,t,s){void 0===s&&(s={});class Constructor extends CustomHTMLElement{constructor(){super(),this.$el=new t(this),this._wasConnected=!1}static get observedAttributes(){return s.attributes||[]}}customElementOptions.set(e.toUpperCase(),s),window.customElements.define(e,Constructor)}function needsBrackets(e,t){return!!PRECEDENCE.includes(t)&&(!!(e instanceof ExprTerm)||!!(e instanceof ExprFunction)&&!!PRECEDENCE.includes(e.fn)&&PRECEDENCE.indexOf(t)>PRECEDENCE.indexOf(e.fn))}function addMFence(e,t,s){return needsBrackets(e,t)?"<mfenced>"+s+"</mfenced>":s}function addMRow(e,t){return e instanceof ExprTerm||e instanceof ExprFunction?"<mrow>"+t+"</mrow>":t}function createToken(e,t){if(!e||!t)return null;if("SPACE"===t&&1<e.length)return new ExprSpace;if("STR"===t)return new ExprString(e);if("NUM"===t){if(isNaN(+e))throw ExprError.invalidExpression();return new ExprNumber(+e)}return"VAR"===t?e in SPECIAL_IDENTIFIERS?new ExprIdentifier(SPECIAL_IDENTIFIERS[e]):e in SPECIAL_OPERATORS?new ExprOperator(SPECIAL_OPERATORS[e]):new ExprIdentifier(e):"OP"===t?e in SPECIAL_OPERATORS?new ExprOperator(SPECIAL_OPERATORS[e]):new ExprOperator(e):void 0}function tokenize(e){const t=[];let a="",n="";for(let i of e){if("\""===i){const e="STR"===n?"":"STR",s=createToken(a,n);s&&t.push(s),a="",n=e;continue}else if("STR"===n){a+=i;continue}const e=i.match(/[0-9.]/)?"NUM":IDENTIFIER_SYMBOLS.includes(i)?"VAR":OPERATOR_SYMBOLS.includes(i)?"OP":i.match(/\s/)?"SPACE":"";if(!e)throw ExprError.invalidCharacter(i);if(!n||"NUM"===n&&"NUM"!=e||"VAR"===n&&"VAR"!=e&&"NUM"!=e||"OP"===n&&!(a+i in SPECIAL_OPERATORS)||"SPACE"===n&&"SPACE"!=e){const s=createToken(a,n);s&&t.push(s),a="",n=e}a+=i}const i=createToken(a,n);return i&&t.push(i),t}function makeTerm(e){return 1<e.length?new ExprTerm(e):e[0]instanceof ExprOperator?new ExprTerm(e):e[0]}function splitArray(e,t){const s=[[]];for(let a of e)t(a)?s.push([]):last(s).push(a);return s}function isOperator(e,t){return e instanceof ExprOperator&&words(t).includes(e.o)}function removeBrackets(e){return e instanceof ExprFunction&&"("===e.fn?e.args[0]:e}function findBinaryFunction(e,t,s){if(isOperator(e[0],t))throw ExprError.startOperator(e[0]);if(isOperator(last(e),t))throw ExprError.endOperator(last(e));for(let n=1;n<e.length-1;++n){if(!isOperator(e[n],t))continue;const i=e[n-1],a=e[n+1];if(i instanceof ExprOperator)throw ExprError.consecutiveOperators(i.o,e[n].o);if(a instanceof ExprOperator)throw ExprError.consecutiveOperators(e[n].o,a.o);const o=[removeBrackets(i),removeBrackets(a)];e.splice(n-1,3,new ExprFunction(s||e[n].o,o)),n-=2}}function prepareTerm(e){return findBinaryFunction(e,"^","sup"),findBinaryFunction(e,"/"),makeTerm(e)}function matchBrackets(e){findBinaryFunction(e,"_","sub");const s=[[]];for(let a of e){const e=last(s).length?last(s)[0].o:null;if(isOperator(a,") ] }")||isOperator(a,"|")&&"|"===e){if(!isOperator(a,BRACKETS[e]))throw ExprError.conflictingBrackets(a.o);const t=s.pop(),n=last(s),i=isOperator(a,")")&&last(n)instanceof ExprIdentifier&&"\u03C0"!==last(n).i,o=i?n.pop().i:isOperator(a,"|")?"abs":t[0].o,r=splitArray(t.slice(1),e=>isOperator(e,","));n.push(new ExprFunction(o,r.map(prepareTerm)))}else isOperator(a,"( [ { |")?s.push([a]):last(s).push(a)}if(1<s.length)throw ExprError.unclosedBracket(last(s)[0].o);return prepareTerm(s[0])}function findAssociativeFunction(e,s,a){function n(){if(r)throw ExprError.invalidExpression();o.length&&(i.push(1<o.length?new ExprFunction(s[0],o):o[0]),o=[])}void 0===a&&(a=!1);const i=[];let o=[],r=!1;for(let l of e)if(isOperator(l,s)){if(r||!o.length)throw ExprError.invalidExpression();r=!0}else if(l instanceof ExprOperator)n(),i.push(l),r=!1;else{const e=!a||l instanceof ExprNumber;if(o.length&&!r&&e)throw ExprError.invalidExpression();o.push(l),r=!1}return n(),i}function collapseTerm(e){if(e=e.filter(e=>!(e instanceof ExprSpace)),!e.length)throw ExprError.invalidExpression();if(isOperator(e[0],"%!"))throw ExprError.startOperator(e[0].o);for(let t=0;t<e.length;++t)isOperator(e[t],"%!")&&(e.splice(t-1,2,new ExprFunction(e[t].o,[e[t-1]])),t-=1);if(findBinaryFunction(e,"= < > \u2264 \u2265"),findBinaryFunction(e,"// \xF7","/"),e=findAssociativeFunction(e,"\xD7 * \xB7",!0),isOperator(e[0],"\u2212 \xB1")&&e.splice(0,2,new ExprFunction(e[0].o,[e[1]])),findBinaryFunction(e,"\u2212 \xB1"),isOperator(e[0],"+")&&(e=e.slice(1)),e=findAssociativeFunction(e,"+"),1<e.length)throw ExprError.invalidExpression();return e[0]}function parse$1(e,t){void 0===t&&(t=!1);const s=matchBrackets(tokenize(e));return t?s.collapse():s}function numEquals(e,t){try{const s=unique([...e.variables,...t.variables]),n=e.collapse(),i=t.collapse();for(let e=0;5>e;++e){const e={};for(let t of s)e[t]=CONSTANTS[t]||5*Math.random();const t=n.evaluate(e),a=i.evaluate(e);if(!(isNaN(t)||isNaN(a))&&!nearlyEquals(t,a))return!1}return!0}catch(t){return!1}}function getOrigin(e){const t=0<e.xMin?e.xMin:0>e.xMax?e.xMax:0,s=0<e.yMin?e.yMin:0>e.yMax?e.yMax:0;return new Point(t,s)}function defaultSteps(e,t,s){const a=(t-e)/s,n=Math.floor(Math.log10(a)),i=Math.pow(10,n),o=GRID_STEPS.find(e=>i*e<=a)*i;return t=o*Math.ceil(t/o),e=o*Math.floor(e/o),[e,t,o]}function computeAxis(e,t,s){let[a,n,i]=e;if(a=a?+a:s[0],n=n?+n:s[1],0<a&&(a=0),0>n&&(n=0),nearlyEquals(a,n))return[a-2,n+2,1];if(e[1]||(n+=.01*(n-a)),i)return[a,n,+i];const o=Math.floor(Math.abs(t)/GRID_SPACING);return defaultSteps(a,n,o)}function getDataBounds(e){const t=Math.min(...e.map(e=>Math.min(...e.map(e=>e.y)))),s=Math.max(...e.map(e=>Math.max(...e.map(e=>e.y))));return[t,s]}function goLeft(e){const t=e.prev;t&&isOneOf(t.tagName,"MO","MI","MN")?t.insertBefore(e):t?last(t.children).append(e):!e.parent.hasClass("math")&&(e.parent.prev?e.parent.prev.append(e):e.parent.parent.insertBefore(e))}function goRight(e){const t=e.next;return t&&isOneOf(t.tagName,"MO","MI","MN")?t.insertAfter(e):void(t?t.children[0].prepend(e):e.parent.hasClass("math")||(e.parent.next?e.parent.next.prepend(e):e.parent.parent.insertAfter(e)))}function goUp(e){let t=e.parent;for(;"MFRAC"!==t.parent.tagName||!t.prev;){if(t.hasClass("math"))return;t=t.parent}t.prev.append(e)}function goDown(e){let t=e.parent;for(;"MFRAC"!==t.parent.tagName||!t.next;){if(t.hasClass("math"))return;t=t.parent}t.next.prepend(e)}function backspace(e){const t=e.prev,s=e.parent;if(t&&isOneOf(t.tagName,"MO","MI","MN"))t.remove(),1>=s.children.length&&s.addClass("empty");else if(!t&&!s.prev&&!e.parent.hasClass("math")){const t=s.parent;t.insertBefore(e);for(let e of t.children)for(let s of e.children)t.insertBefore(s);t.remove(),1>=e.parent.children.length&&e.parent.addClass("empty")}else goLeft(e)}function insertText(e,t){t.insertBefore(e),t.parent.removeClass("empty"),e.children.length&&e.children[0].append(t)}function type(e,t){"abcdefghijklmnopqrstuvwxyz\u03C0".includes(t)?insertText($N("mi",{text:t}),e):"0123456789.".includes(t)?insertText($N("mn",{text:t}),e):"+\u2212\xB1\xD7\xF7<>\u2264\u2265=%!".includes(t)?insertText($N("mo",{text:t,value:t}),e):"frac"===t?insertText($N("mfrac",{html:"<mrow class=\"empty\"></mrow><mrow class=\"empty\"></mrow>"}),e):"sqrt"===t?insertText($N("msqrt",{html:"<mrow class=\"empty\"></mrow>"}),e):isOneOf(t,"^","sup")?insertText($N("msup",{html:"<mrow class=\"empty\"></mrow>"}),e):"brackets"===t||"([{|".includes(t)?insertText($N("mfenced",{html:"<mrow class=\"empty\"></mrow>",type:"("}),e):")]}".includes(t)&&!e.next&&"MFENCED"===e.parent.parent.tagName&&e.parent.parent.insertAfter(e)}function cleanGroups(e,t){const s=e.$$(t+":first-child, *:not("+t+") + "+t);for(let a of s)if("MFRAC"!==a.parent.tagName)for(;a.next&&a.next.tagName===t.toUpperCase();)a.text+=a.next.text,a.next.remove()}function toString(e,t){if(e.hasClass("cursor"))return"";if("TEXT"===e.tagName)return e.text;const s=e.childNodes;return"MI"===e.tagName?e.text+(t?" ":""):"MFENCED"===e.tagName?"("+toString(s[0],t)+")":"MSUP"===e.tagName?"^("+toString(s[0],t)+")":"MFRAC"===e.tagName?"("+toString(s[0],t)+")/("+toString(s[1],t)+")":"MSQRT"===e.tagName?"sqrt("+toString(s[0],t)+")":s.map(e=>toString(e,t)).join("")}function parseInput(e){try{return{expr:Expression.parse(e,!0)}}catch(e){return{error:e instanceof ExprError?e.message:DEFAULT_ERROR}}}function checkVariables(e,t,s){const a=e.variables;if(t.length){const e=a.find(e=>!t.includes(e));if(e){const a=autocorrect(e,s||t);return a?"Did you mean \u201C<em>"+a+"</em>\u201D instead of \u201C<em>"+e+"</em>\u201D?":"There shouldn\u2019t be a variable called \u201C<em>"+e+"</em>\u201D."}const n=t.find(e=>!a.includes(e));if(n)return"Your expression should contain \u201C<em>"+n+"</em>\u201D."}}function checkFunctions(e,t){if(t.length){const s=e.functions.find(e=>!t.includes(e));if(s){const e=FN_NAMES[s]||"\u201C"+s+"\u201D";return"This expression should not contain "+e+"."}}}function checkNumeric(e,t,s){void 0===s&&(s=.001);try{return nearlyEquals(e.evaluate(),t.evaluate(),s)}catch(t){return!1}}function makeLabel(e,t,s){const a=e.hasClass("fill")||e.hasClass("move"),n=s||e.attr("label-colour");return $N("text",{target:e.attr("target")||"",class:e.attr("class")||"","data-when":e.data.when,fill:n||e.css(a?"fill":"stroke")},t.$labels)}function labelOverlap(e,t,s,n){let i=new Rectangle(new Point(-10,-20),20,23).rotate(s),o=t.paths.filter(t=>t.val&&t.val!==e);for(let r of n)if(o.every(e=>!intersections(i.translate(r),e.val).length))return r;return n[0]}function labelPosn(e,t,s){if(isOneOf(e.constructor.name,"Line","Ray","Segment")){let a=e.perpendicularVector,n=e.angle;0<=a.y&&(a=a.scale(-1),n+=Math.PI);let i=[];for(let t of[.5,.35,.65])for(let s of[-15,5])i.push(e.at(t).add(a.scale(s)));let o=labelOverlap(e,s,n,i);return t.hasAttr("mark")&&(o=o.add(e.normalVector.scale(12))),[o,n]}if("Arc"===e.constructor.name){const t=new Line(e.start,e.end),s=0<=t.perpendicularVector.y,a=t.angle+(s?Math.PI:0),n=e.at(.5).add(t.perpendicularVector.scale(s?14:5));return[n,a]}if("Angle"===e.constructor.name){const s=(+t.attr("size")||angleSize(e,{round:t.hasAttr("round")}))+8;return[e.b.add(e.bisector.normalVector.scale(s+5)).shift(0,3)]}if("Point"===e.constructor.name){const a=t.hasClass("move")?10:8;let n=[e.shift(a,-a),e.shift(-a,-a),e.shift(a,10+a),e.shift(-a,10+a)];return[labelOverlap(e,s,0,n)]}return"Polygon"===e.constructor.name?[e.centroid.shift(0,5)]:"Sector"===e.constructor.name?[e.at(.5).subtract(e.c).scale(.6).add(e.c).shift(0,5)]:"Circle"===e.constructor.name?[e.c.shift(0,5)]:[]}function getToolTransform(e,t,s,a){return"translate("+e.x+"px, "+(e.y-t)+"px) scale("+a/100+") rotate("+s+"rad)"}function getPosition(e,t){const s=t.positionLeft-e.positionLeft+t.width/2,a=t.positionTop-e.positionTop+t.height/2;return new Point(s,a)}function parseAttr(e){return e?new Point(...e.split(",").map(e=>+e)):null}function openLightbox(e,t,a){isOpen=!0,$activeImg=e,$lightbox.show(),$lightboxImg.show();let n=e.bounds,i=$lightboxImg.bounds,o=n.left+n.width/2-i.left-i.width/2,r=n.top+n.height/2-i.top-i.height/2,l=Math.max(n.width/i.width,n.height/i.height);transform={x:o,y:r,s:l},$lightboxImg.css("background-image","url("+a+"), url("+t+")"),$lightboxImg.transform="translate("+o+"px, "+r+"px) scale("+l+")",Browser.redraw(),$lightboxImg.addClass("transitions"),Browser.redraw(),e.css("visibility","hidden"),$lightbox.addClass("on"),$lightboxImg.transform="scale(1) translate(0,0)"}function closeLightbox(){isOpen&&(isOpen=!1,$lightbox.removeClass("on"),$lightboxImg.transform="translate("+transform.x+"px, "+transform.y+"px) scale("+transform.s+")",setTimeout(function(){$activeImg.css("visibility","visible"),$lightbox.css("display","none"),$lightboxImg.transform="none",$lightboxImg.removeClass("transitions")},400))}function getProgress(e){return"M"+e+","+e/2+"a"+e/2+","+e/2+",0,0,1,0,"+e+"A"+e/2+","+e/2+",0,0,1,"+e+","+e/2}function getCheck(e){return"M "+e+",0 C "+e/2+",0,0,"+e/2+",0,"+e+"  s "+e/2+","+e+","+e+","+e+" "+("s "+e+"-"+e/2+","+e+"-"+e+"     S "+1.5*e+",0,"+e+",0 z ")+("M "+44.6*e/50+","+76.1*e/50+" L "+19.2*e/50+","+48.8*e/50+" ")+("l "+4*e/50+"-"+4.2*e/50+"     l "+19.8*e/50+","+11.9*e/50+" ")+("l "+34.2*e/50+"-"+32.6*e/50+" l "+3.5*e/50+","+3.5*e/50+" ")+("L "+44.6*e/50+","+76.1*e/50+" z")}function confetti(e,t){void 0===e&&(e=2e3),void 0===t&&(t=150),$confetti||($confetti=$N("canvas",{style},$body)),$confetti.setAttr("width",Browser.width),$confetti.setAttr("height",Browser.height),$confetti.show();const s=$confetti.getContext(),a=tabulate(e=>new Particle(e),t);let n=animate(i=>{s.clearRect(0,0,Browser.width,Browser.height);const t=i<e;let o=0;for(let e of a)e.draw(s),e.update(i,t),e.y<Browser.height&&(o+=1);o||(n.cancel(),$confetti.hide())})}function connect(e,t,s,a){let n=new Point(e.left-15,e.top+s-15),i=new Rectangle(n,e.width+30,e.height+30),o=i.project({x:t.left+t.width/2,y:t.top+t.height/2+a}),r=new Point(t.left-15,t.top+a-15),l=new Rectangle(r,t.width+30,t.height+30),d=l.project({x:e.left+e.width/2,y:e.top+e.height/2+s});return[o,d]}function distance(e,t){return Math.abs(e[0]-t[0])+Math.abs(e[1]-t[1])}function createMsgElement(e,t,s){let{className:a,visible:n}=void 0===s?{}:s;const i=$N("div",{class:"msg-wrap","data-display":"flex"}),o=$N("div",{class:"msg "+t},i);return a&&o.addClass(a),n||i.hide(),isOneOf(t,"hint","question")?o.html=e:"img"===t?o.css("background-image","url("+e+")"):"video"==t&&$N("iframe",{src:e,allowfullscreen:!0},o),i}function formatTime(e){const t=Math.floor(+e/60),a=Math.floor(+e%60);return t+":"+(10>a?"0":"")+a}function tryClose(){$openModal&&$openModal.canClose&&$openModal.close()}function getOrCreateMethodChain(e,t){let s=instances.filter(s=>s.context==e&&s.methodName==t)[0];return s||(s=new MethodChain(e,t),instances.push(s)),s}function createFieldsObj(e,t,s,a,n,i){if(void 0===s&&(s=void 0),void 0===a&&(a=void 0),void 0===n&&(n=void 0),void 0===i&&(i=void 0),"function"==typeof a){const o=s.get("buildHitTask");return{buildHitTask:s=>{s.set(e,null,!0),s.set(t,null,!0),a(s,n,i),o(s)}}}return assign({},e,t)}function deferUntilPluginsLoaded(e,t){const s=e.get("trackingId"),a=queueMap[s]=queueMap[s]||{},n=()=>{clearTimeout(a.timeout),a.send&&MethodChain.remove(e,"send",a.send),delete queueMap[s],a.queue.forEach(e=>e())};clearTimeout(a.timeout),a.timeout=setTimeout(n,0),a.queue=a.queue||[],a.queue.push(t),a.send||(a.send=e=>function(){n(),e(...arguments)},MethodChain.add(e,"send",a.send))}function capitalize(e){return e.charAt(0).toUpperCase()+e.slice(1)}function isObject(e){return"object"==typeof e&&null!==e}function now(){return+new Date}function provide(e,t){const s=window.GoogleAnalyticsObject||"ga";window[s]=window[s]||function(){for(var e=arguments.length,t=Array(e),a=0;a<e;a++)t[a]=arguments[a];(window[s].q=window[s].q||[]).push(t)},window.gaDevIds=window.gaDevIds||[],0>window.gaDevIds.indexOf(DEV_ID)&&window.gaDevIds.push(DEV_ID),window[s]("provide",e,t),window.gaplugins=window.gaplugins||{},window.gaplugins[capitalize(e)]=t}function initStorageListener(){window.addEventListener("storage",storageListener),isListening=!0}function removeStorageListener(){window.removeEventListener("storage",storageListener),isListening=!1}function storageListener(e){const t=instances$1[e.key];if(t){const s=assign({},t.defaults_,parse$2(e.oldValue)),a=assign({},t.defaults_,parse$2(e.newValue));t.cache_=a,t.emit("externalSet",a,s)}}function parse$2(e){let t={};if(e)try{t=JSON.parse(e)}catch(e){}return t}function trackUsage(e,t){trackVersion(e),trackPlugin(e,t)}function convertHexToBin(e){return parseInt(e||"0",16).toString(2)}function convertBinToHex(e){return parseInt(e||"0",2).toString(16)}function padZeros(e,t){if(e.length<t)for(let s=t-e.length;s;)e="0"+e,s--;return e}function flipBitOn(e,t){return e.substr(0,t)+1+e.substr(t+1)}function trackPlugin(e,t){const s=e.get("&_au");let a=padZeros(convertHexToBin(s),PLUGIN_COUNT);a=flipBitOn(a,PLUGIN_COUNT-t),e.set("&_au",convertBinToHex(a))}function trackVersion(e){e.set("&_av",VERSION)}class Evented{constructor(e){let{split:t=" ",lowercase:s=!1}=void 0===e?{}:e;this._options={split:t,lowercase:s},this._events={}}on(t,s){for(let a of process(t,this._options))a in this._events||(this._events[a]=[]),this._events[a].push(s)}one(e,t){function s(){a.off(e,s),t(...arguments)}let a=this;this.on(e,s)}off(t,s){for(let a of process(t,this._options))a in this._events&&(this._events[a]=this._events[a].filter(e=>e!==s))}trigger(t){for(var s=arguments.length,a=Array(1<s?s-1:0),n=1;n<s;n++)a[n-1]=arguments[n];for(let s of process(t,this._options))s in this._events&&this._events[s].forEach(function(e){e.apply(this,a)})}}const tolerance=1e-6,NUM_REGEX=/(\d+)(\d{3})/,POWER_SUFFIX=["","k","m","b","t","q"],SPECIAL_DECIMAL=/^-?0,[0-9]+$/,POINT_DECIMAL=/^-?([0-9]+(,[0-9]{3})*)?\.?[0-9]*$/,COMMA_DECIMAL=/^-?[0-9]+(\.[0-9]{3})*,?[0-9]*$/,ONES=["","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"],TENS=["","","twenty","thirty","fourty","fifty","sixty","seventy","eighty","ninety"],MULTIPLIERS=["","thousand","million","billion","trillion","quadrillion","quintillion","sextillion"];class Point{constructor(e,t){void 0===e&&(e=0),void 0===t&&(t=0),this.x=e,this.y=t}get normal(){return this.scale(1/this.length)}get length(){return Math.sqrt(square$1(this.x)+square$1(this.y))}get inverse(){return new Point(-this.x,-this.y)}get flip(){return new Point(this.y,this.x)}get perpendicular(){return new Point(-this.y,this.x)}get array(){return[this.x,this.y]}distanceFromLine(e){return Point.distance(this,e.project(this))}clamp(e,t,s,a){return new Point(clamp$1(this.x,e,t),clamp$1(this.y,s,a))}transform(e){if(!e)return this;let t=e[0][0]*this.x+e[0][1]*this.y+e[0][2],s=e[1][0]*this.x+e[1][1]*this.y+e[1][2];return new Point(t,s)}rotate(e,t){void 0===t&&(t=origin);let s=this.x-t.x,a=this.y-t.y,n=Math.cos(e),i=Math.sin(e),o=s*n-a*i+t.x,r=s*i+a*n+t.y;return new Point(o,r)}reflect(e){let t=e.p2.x-e.p1.x,s=e.p2.y-e.p1.y,a=this.x-e.p1.x,n=this.y-e.p1.y,i=(t*n-s*a)/(t*t+s*s),o=this.x+2*i*s,r=this.y-2*i*t;return new Point(o,r)}scale(e,t){return void 0===t&&(t=e),new Point(this.x*e,this.y*t)}shift(e,t){return void 0===t&&(t=e),new Point(this.x+e,this.y+t)}translate(e){return this.shift(e.x,e.y)}changeCoordinates(e,t){const s=t.xMin+(this.x-e.xMin)/e.dx*t.dx,a=t.yMin+(this.y-e.yMin)/e.dy*t.dy;return new Point(s,a)}add(e){return Point.sum(this,e)}subtract(e){return Point.difference(this,e)}equals(e){return Point.equals(this,e)}round(e){return void 0===e&&(e=1),new Point(roundTo(this.x,e),roundTo(this.y,e))}floor(){return new Point(Math.floor(this.x),Math.floor(this.y))}mod(e,t){return void 0===t&&(t=e),new Point(this.x%e,this.y%t)}angle(e){return void 0===e&&(e=origin),rad(this,e)}static average(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];let a=total$1(t.map(e=>e.x))/t.length,n=total$1(t.map(e=>e.y))/t.length;return new Point(a,n)}static dot(e,t){return e.x*t.x+e.y*t.y}static sum(e,t){return new Point(e.x+t.x,e.y+t.y)}static difference(e,t){return new Point(e.x-t.x,e.y-t.y)}static distance(e,t){return Math.sqrt(square$1(e.x-t.x)+square$1(e.y-t.y))}static manhattan(e,t){return Math.abs(e.x-t.x)+Math.abs(e.y-t.y)}static interpolate(e,s,a){return void 0===a&&(a=.5),new Point(e.x+a*(s.x-e.x),e.y+a*(s.y-e.y))}static interpolateList(e,s){void 0===s&&(s=.5);const i=e.length-1,n=Math.floor(clamp$1(s,0,1)*i);return Point.interpolate(e[n],e[n+1],i*s-n)}static equals(e,t){return nearlyEquals(e.x,t.x)&&nearlyEquals(e.y,t.y)}static fromPolar(e,t){return void 0===t&&(t=1),new Point(t*Math.cos(e),t*Math.sin(e))}}const origin=new Point(0,0);class Bounds{constructor(e,t,s,a){this.xMin=e,this.xMax=t,this.yMin=s,this.yMax=a}get dx(){return this.xMax-this.xMin}get dy(){return this.yMax-this.yMin}}const twoPi=2*Math.PI;class Angle{constructor(e,t,s){this.a=e,this.b=t,this.c=s}transform(e){return e?new Angle(this.a.transform(e),this.b.transform(e),this.c.transform(e)):this}get rad(){let e=Math.atan2(this.a.y-this.b.y,this.a.x-this.b.x),t=Math.atan2(this.c.y-this.b.y,this.c.x-this.b.x),s=t-e;return 0>s&&(s+=twoPi),s}get deg(){return 180*this.rad/Math.PI}get isRight(){return nearlyEquals(this.rad,Math.PI/2,.01)}get bisector(){let e=Math.atan2(this.a.y-this.b.y,this.a.x-this.b.x),t=Math.atan2(this.c.y-this.b.y,this.c.x-this.b.x),s=(e+t)/2;e>t&&(s+=Math.PI);let a=Math.cos(s)+this.b.x,n=Math.sin(s)+this.b.y;return new Line(this.b,new Point(a,n))}get sup(){return this.rad<Math.PI?this:new Angle(this.c,this.b,this.a)}get arc(){return new Arc(this.b,this.a,this.rad)}}class Line{constructor(e,t){this.p1=e,this.p2=t}get length(){return Point.distance(this.p1,this.p2)}get midpoint(){return Point.average(this.p1,this.p2)}get slope(){return(this.p2.y-this.p1.y)/(this.p2.x-this.p1.x)}get intercept(){return this.p1.y+this.slope*this.p1.x}get angle(){return rad(this.p2,this.p1)}get normalVector(){let e=this.length,t=(this.p2.x-this.p1.x)/e,s=(this.p2.y-this.p1.y)/e;return new Point(t,s)}get perpendicularVector(){return new Point(this.p2.y-this.p1.y,this.p1.x-this.p2.x).normal}get perpBisector(){return this.perpendicular(this.midpoint)}parallel(e){const t=Point.sum(e,Point.difference(this.p2,this.p1));return new Line(e,t)}perpendicular(e){return new Line(e,Point.sum(e,this.perpendicularVector))}contains(e){const t=e.x*(this.p1.y-this.p2.y)+this.p1.x*(this.p2.y-e.y)+this.p2.x*(e.y-this.p1.y);return nearlyEquals(t,0)}at(e){return Point.interpolate(this.p1,this.p2,e)}project(e){const t=Point.difference(this.p2,this.p1),s=Point.difference(e,this.p1),a=t.scale(Point.dot(t,s)/square$1(this.length));return Point.sum(this.p1,a)}transform(e){return e?new this.constructor(this.p1.transform(e),this.p2.transform(e)):this}rotate(e,t){return void 0===t&&(t=origin),new this.constructor(this.p1.rotate(e,t),this.p2.rotate(e,t))}reflect(e){return new this.constructor(this.p1.reflect(e),this.p2.reflect(e))}scale(e,t){return void 0===t&&(t=e),new this.constructor(this.p1.scale(e,t),this.p2.scale(e,t))}shift(e,t){return void 0===t&&(t=e),new this.constructor(this.p1.shift(e,t),this.p2.shift(e,t))}translate(e){return new this.constructor(this.p1.translate(e),this.p2.translate(e))}equals(e){return this.constructor.equals(this,e)}static equals(e,t){return e.contains(t.p1)&&e.contains(t.p2)}}class Ray extends Line{}class Segment extends Line{contains(e){}project(e){const t=Point.difference(this.p2,this.p1),s=Point.difference(e,this.p1),a=clamp$1(Point.dot(t,s)/square$1(this.length),0,1);return Point.sum(this.p1,t.scale(a))}contract(e){return new Segment(this.at(e),this.at(1-e))}static equals(e,t,s){return void 0===s&&(s=!1),Point.equals(e.p1,t.p1)&&Point.equals(e.p2,t.p2)||!s&&Point.equals(e.p1,t.p2)&&Point.equals(e.p2,t.p1)}static intersect(e,t){const s=new Segment(e.p1,e.p2),a=new Segment(t.p1,t.p2);return intersections(s,a)[0]||null}}class Circle{constructor(e,t){void 0===e&&(e=origin),void 0===t&&(t=1),this.c=e,this.r=t}get circumference(){return 2*Math.PI*this.r}get area(){return Math.PI*square$1(this.r)}get arc(){let e=this.c.shift(this.r,0);return new Arc(this.c,e,twoPi)}transform(e){return e?new Circle(this.c.transform(e),this.r*(e[0][0]+e[1][1])/2):this}rotate(e,t){return void 0===t&&(t=origin),new Circle(this.c.rotate(e,t),this.r)}reflect(e){return new Circle(this.c.reflect(e),this.r)}scale(e,t){return void 0===t&&(t=e),new Circle(this.c.scale(e,t),this.r*(e+t)/2)}shift(e,t){return void 0===t&&(t=e),new Circle(this.c.shift(e,t),this.r)}translate(e){return new Circle(this.c.translate(e),this.r)}contains(e){return Point.distance(e,this.c)<=this.r}equals(e){return e instanceof Circle&&nearlyEquals(this.r,e.r)&&this.c.equals(e.c)}project(e){const t=Point.difference(e,this.c).normal.scale(this.r);return Point.sum(this.c,t)}at(e){const t=2*Math.PI*e;return this.c.shift(this.r*Math.cos(t),this.r*Math.sin(t))}tangentAt(e){const t=this.at(e),s=this.c.rotate(Math.PI/2,t);return new Line(t,s)}}class Arc{constructor(e,t,s){this.c=e,this.start=t,this.angle=s}get radius(){return Point.distance(this.c,this.start)}get end(){return this.start.rotate(this.angle,this.c)}transform(e){return e?new Arc(this.c.transform(e),this.start.transform(e),this.angle):this}get startAngle(){return rad(this.start,this.c)}project(e){let t=this.startAngle,s=t+this.angle,a=rad(e,this.c);return s>twoPi&&a<s-twoPi&&(a+=twoPi),a=clamp$1(a,t,s),this.c.shift(this.radius,0).rotate(a,this.c)}at(e){return this.start.rotate(this.angle*e,this.c)}contract(e){return new this.constructor(this.c,this.at(e/2),this.angle*(1-e))}get minor(){return this.angle<=Math.PI?this:new this.constructor(this.c,this.end,2*Math.PI-this.angle)}get major(){return this.angle>=Math.PI?this:new this.constructor(this.c,this.end,2*Math.PI-this.angle)}}class Sector extends Arc{}class Polygon{constructor(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];this.points=t}get circumference(){let e=0;for(let t=1;t<this.points.length;++t)e+=Point.distance(this.points[t-1],this.points[t]);return e}get signedArea(){let e=this.points,t=e.length,s=e[t-1].x*e[0].y-e[0].x*e[t-1].y;for(let a=1;a<t;++a)s+=e[a-1].x*e[a].y-e[a].x*e[a-1].y;return s/2}get area(){return Math.abs(this.signedArea)}get centroid(){let e=this.points,t=e.length,s=0;for(let a=0;a<t;++a)s+=e[a].x;let a=0;for(let s=0;s<t;++s)a+=e[s].y;return new Point(s/t,a/t)}get edges(){let e=this.points,t=e.length,s=[];for(let a=0;a<t;++a)s.push(new Segment(e[a],e[(a+1)%t]));return s}get radius(){const e=this.centroid,t=this.points.map(t=>Point.distance(t,e));return Math.max(...t)}transform(e){return e?new this.constructor(...this.points.map(t=>t.transform(e))):this}rotate(e,t){void 0===t&&(t=origin);const s=this.points.map(s=>s.rotate(e,t));return new this.constructor(...s)}reflect(e){const t=this.points.map(t=>t.reflect(e));return new this.constructor(...t)}scale(e,t){void 0===t&&(t=e);const s=this.points.map(s=>s.scale(e,t));return new this.constructor(...s)}shift(e,t){void 0===t&&(t=e);const s=this.points.map(s=>s.shift(e,t));return new this.constructor(...s)}translate(e){return this.shift(e.x,e.y)}contains(e){let t=this.points.length,s=!1;for(let a=0;a<t;++a){const n=this.points[a],i=this.points[(a+1)%t],o=n.y>e.y!=i.y>e.y,r=e.x<(i.x-n.x)*(e.y-n.y)/(i.y-n.y)+n.x;o&&r&&(s=!s)}return s}equals(e){}project(e){}at(e){return Point.interpolateList([...this.points,this.points[0]],e)}get oriented(){if(0<=this.signedArea)return this;const e=[...this.points].reverse();return new Polygon(...e)}intersect(e){const t=[toLinkedList(this.oriented.points),toLinkedList(e.oriented.points)],s=this.points.length+e.points.length,a=[];let n=0,i=t[n].find(t=>e.contains(t.val));if(!i)return null;for(;i.val!==a[0]&&a.length<s;){a.push(i.val);const e=new Segment(i.val,i.next.val);i=i.next;for(let s of t[1-n]){const t=new Segment(s.val,s.next.val),a=intersections(e,t)[0];if(a){n=1-n,i={val:a,next:s.next};break}}}return new Polygon(...a)}static collision(e,t){for(let s of e.edges)for(let e of t.edges)if(Segment.intersect(s,e))return!0;for(let s of e.points)if(t.contains(s))return!0;for(let s of t.points)if(e.contains(s))return!0;return!1}static regular(e,t){void 0===t&&(t=1);const s=2*Math.PI/e,a=Math.PI/2-s/2,n=tabulate$1(e=>Point.fromPolar(a+s*e,t),e);return new Polygon(...n)}static interpolate(e,s,a){const t=e.points.map((e,t)=>Point.interpolate(e,s.points[t],a));return new Polygon(...t)}}class Polyline extends Polygon{get edges(){let e=[];for(let t=0;t<this.points.length-1;++t)e.push(new Segment(this.points[t],this.points[t+1]));return e}}class Triangle extends Polygon{constructor(e,t,s){super(e,t,s)}get circumcircle(){const e=this.points,t=2*(e[0].x*(e[1].y-e[2].y)+e[1].x*(e[2].y-e[0].y)+e[2].x*(e[0].y-e[1].y)),s=(square$1(e[0].x)+square$1(e[0].y))*(e[1].y-e[2].y)+(square$1(e[1].x)+square$1(e[1].y))*(e[2].y-e[0].y)+(square$1(e[2].x)+square$1(e[2].y))*(e[0].y-e[1].y),a=(square$1(e[0].x)+square$1(e[0].y))*(e[2].x-e[1].x)+(square$1(e[1].x)+square$1(e[1].y))*(e[0].x-e[2].x)+(square$1(e[2].x)+square$1(e[2].y))*(e[1].x-e[0].x),n=new Point(s/t,a/t),i=Point.distance(n,this.points[0]);return new Circle(n,i)}get incircle(){const e=this.edges,t=e.map(t=>t.length),s=t[0]+t[1]+t[2],a=this.points,n=t[1]*a[0].x+t[2]*a[1].x+t[0]*a[2].x,i=t[1]*a[0].y+t[2]*a[1].y+t[0]*a[2].y,o=new Point(n/s,i/s),r=o.distanceFromLine(e[0]);return new Circle(o,r)}get orthocenter(){const[e,t,s]=this.points,a=new Line(e,t).perpendicular(s),n=new Line(e,s).perpendicular(t);return intersections(a,n)[0]}}class Rectangle{constructor(e,t,s){void 0===t&&(t=1),void 0===s&&(s=t),this.p=e,this.w=t,this.h=s}static fromCorners(e,t){const s=Math.min(e.x,t.x),a=Math.min(e.y,t.y),n=Math.abs(e.x-t.x),i=Math.abs(e.y-t.y);return new Rectangle(new Point(s,a),n,i)}get center(){return new Point(this.p.x+this.w/2,this.p.y+this.h/2)}get circumference(){return 2*Math.abs(this.w)+2*Math.abs(this.h)}get area(){return Math.abs(this.w*this.h)}get edges(){return this.polygon.edges}get points(){return this.polygon.points}get polygon(){let e=new Point(this.p.x+this.w,this.p.y),t=new Point(this.p.x+this.w,this.p.y+this.h),s=new Point(this.p.x,this.p.y+this.h);return new Polygon(this.p,e,t,s)}transform(e){return e?this.polygon.transform(e):this}rotate(e,t){return void 0===t&&(t=origin),this.polygon.rotate(e,t)}reflect(e){return this.polygon.reflect(e)}scale(e,t){return void 0===t&&(t=e),new Rectangle(this.p.scale(e,t),this.w*e,this.h*t)}shift(e,t){return void 0===t&&(t=e),new Rectangle(this.p.shift(e,t),this.w,this.h)}translate(e){return new Rectangle(this.p.translate(e),this.w,this.h)}contains(e){return isBetween(e.x,this.p.x,this.p.x+this.w)&&isBetween(e.y,this.p.y,this.p.y+this.h)}equals(e){}project(e){let t={x:this.p.x+this.w,y:this.p.y+this.h},s={x:this.p.x+this.w/2,y:this.p.y+this.h/2},a=(s.y-e.y)/(s.x-e.x);if(e.x<=s.x){let s=a*(this.p.x-e.x)+e.y;if(this.p.y<s&&s<t.y)return new Point(this.p.x,s)}if(e.x>=s.x){let s=a*(t.x-e.x)+e.y;if(this.p.y<s&&s<t.y)return new Point(t.x,s)}if(e.y<=s.y){let s=(this.p.y-e.y)/a+e.x;if(this.p.x<s&&s<t.x)return new Point(s,this.p.y)}if(e.y>=s.y){let s=(t.y-e.y)/a+e.x;if(this.p.x<s&&s<t.x)return new Point(s,t.y)}}at(e){}static intersect(e,t){return!((e.p.x+e.w<=t.x||e.p.x>t.p.x+t.w)&&(e.p.y+e.h<=t.y||e.p.y>t.p.y+t.h))}}let isReady=!1;setTimeout(function(){isReady=!0});const BOUNCE_IN="cubic-bezier(0.175, 0.885, 0.32, 1.275)",BOUNCE_OUT="cubic-bezier(0.68, -0.275, 0.825, 0.115)",cssMatrix=/matrix\([0-9.\-\s]+,[0-9.\-\s]+,[0-9.\-\s]+,[0-9.\-\s]+,([0-9.\-\s]+),([0-9.\-\s]+)\)/,browserEvents=new Evented,ua=window.navigator.userAgent.toLowerCase(),mobileRegex=/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i;let width=window.innerWidth,height=window.innerHeight;window.addEventListener("resize",()=>{let e=window.innerWidth,t=window.innerHeight;width===e&&height===t||(width=e,height=t,browserEvents.trigger("resize",{width,height}),$body.trigger("scroll",{top:$body.scrollTop}))});const doResize=throttle(function(){width=window.innerWidth,height=window.innerHeight,browserEvents.trigger("resize",{width,height})});let loadQueue=[],loaded=!1;window.onload=afterLoad,document.addEventListener("DOMContentLoaded",afterLoad);const STORAGE_KEY="_M",keyCodes={backspace:8,tab:9,enter:13,shift:16,ctrl:17,alt:18,pause:19,capslock:20,escape:27,space:32,pageup:33,pagedown:34,end:35,home:36,left:37,up:38,right:39,down:40,insert:45,delete:46},IEUA=/\bTrident\/[567]\b|\bMSIE (?:9|10)\.0\b/,webkitUA=/\bAppleWebKit\/(\d+)\b/,EdgeUA=/\bEdge\/12\.(\d+)\b/,polyfill=IEUA.test(navigator.userAgent)||10547>(navigator.userAgent.match(EdgeUA)||[])[1]||537>(navigator.userAgent.match(webkitUA)||[])[1],requests={};let isOldWebkit=!("hidden"in document)&&"webkitHidden"in document,visibilityProperty=isOldWebkit?"webkitHidden":"hidden",visibilityEvent=isOldWebkit?"webkitvisibilitychange":"visibilitychange";document.addEventListener(visibilityEvent,function(){browserEvents.trigger(document[visibilityProperty]?"focus":"blur")});const Browser={isMobile:mobileRegex.test(ua),isRetina:1<(window.devicePixelRatio||1),isTouch:"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,isChrome:!!window.chrome,isFirefox:0<=ua.indexOf("firefox"),isAndroid:0<=ua.indexOf("android"),isIOS:/iphone|ipad|ipod/i.test(ua),redraw,ready,resize,cssTimeToNumber,addCSS,addCSSRule,replaceSvgImports,on:browserEvents.on.bind(browserEvents),off:browserEvents.off.bind(browserEvents),trigger:browserEvents.trigger.bind(browserEvents),get width(){return width},get height(){return height},get hash(){return window.location.hash.slice(1)},set hash(e){let t=document.body.scrollTop;window.location.hash=e,document.body.scrollTop=t},get cookies(){return getCookies()},getCookie,setCookie,deleteCookie,setStorage,getStorage,deleteStorage,get activeInput(){return activeInput()},keyCodes,onKey};let touchEnabled=!1,observer;document.addEventListener("touchstart",()=>touchEnabled=!0);const aliases={change:"propertychange keyup input paste",scrollwheel:"DOMMouseScroll mousewheel",pointerdown:"mousedown touchstart",pointermove:"mousemove touchmove",pointerup:"mouseup touchend",pointercancel:"touchcancel",pointerstop:"mouseup touchend touchcancel"},customEvents={scroll:makeScrollEvents,hover:makeHoverEvent,click:makeClickEvent,clickOutside:makeClickOutsideEvent,key:makeKeyEvent,mousedown:makeMouseEvent.bind(null,"mousedown"),mousemove:makeMouseEvent.bind(null,"mousemove"),mouseup:makeMouseEvent.bind(null,"mouseup"),pointerenter:makePointerPositionEvents,pointerleave:makePointerPositionEvents,enterViewport:makeIntersectionEvents,exitViewport:makeIntersectionEvents},ALPHABETH="zyxwvutsrqponmlkjihgfedcba";class Element{constructor(e){this._el=e,this._data=e?e._m_data||(e._m_data={}):{},this._events=e?e._m_events||(e._m_events={}):{}}get id(){return this._el.id}get data(){return this._el.dataset}get tagName(){return this._el instanceof Text?"TEXT":this._el.tagName.toUpperCase()}getModel(){return this.parent?this.parent.model||this.parent.getModel()||observable():null}bindObservable(e,t){return void 0===t&&(t=!0),bindObservable(this,e,t),e}addClass(e){let t=words(e);if(this._el.classList)for(let e of t)this._el.classList.add(e);else this._el.className+=" "+e}removeClass(e){let t=words(e);if(this._el.classList)for(let e of t)this._el.classList.remove(e);else{let e=new RegExp("(^|\\s)"+t.join("|")+"(\\s|$)","gi");this._el.className=this._el.className.toString().replace(e," ")}}hasClass(e){let t=this._el.className;return 0<=(" "+t+" ").indexOf(" "+e.trim()+" ")}toggleClass(e){this.hasClass(e)?this.removeClass(e):this.addClass(e)}setClass(e,t){t?this.addClass(e):this.removeClass(e)}attr(e){return this._el.getAttribute(e)||""}hasAttr(e){return this._el.hasAttribute(e)}setAttr(e,t){this._el.setAttribute(e,t)}removeAttr(e){this._el.removeAttribute(e)}get attributes(){return Array.from(this._el.attributes||[])}get value(){return this._el.value}set value(e){this._el.value=e}get html(){return this._el.innerHTML||""}set html(e){this._el.innerHTML=e}get text(){return this._el.textContent||""}set text(e){this._el.textContent=e}blur(){this._el.blur()}focus(){this._el.focus()}get bounds(){return this._el.getBoundingClientRect()}get topLeftPosition(){const e=this.bounds;return new Point(e.left,e.top)}get offsetTop(){return this._el.offsetTop}get offsetLeft(){return this._el.offsetLeft}get offsetParent(){let e=this._el.offsetParent;return e?$(e):null}get width(){return this._el.offsetWidth}get height(){return this._el.offsetHeight}get innerWidth(){const e=parseFloat(this.css("padding-left")),t=parseFloat(this.css("padding-right"));return this._el.clientWidth-e-t}get innerHeight(){const e=parseFloat(this.css("padding-bottom")),t=parseFloat(this.css("padding-top"));return this._el.clientHeight-e-t}get outerWidth(){const e=parseFloat(this.css("margin-left")),t=parseFloat(this.css("margin-right"));return this.width+e+t}get outerHeight(){const e=parseFloat(this.css("margin-bottom")),t=parseFloat(this.css("margin-top"));return this.height+e+t}get positionTop(){let e=this._el,t=0;do t+=e.offsetTop;while(e=e.offsetParent);return t}get positionLeft(){let e=this._el,t=0;do t+=e.offsetLeft;while(e=e.offsetParent);return t}get boxCenter(){let e=this.bounds;return new Point(e.left+e.width/2,e.top+e.height/2)}offset(e){if(e._el===this._el.offsetParent){let t=this.offsetTop+e._el.clientTop,s=this.offsetLeft+e._el.clientLeft,a=t+this.height,n=s+this.width;return{top:t,left:s,bottom:a,right:n}}else{let t=e._el.getBoundingClientRect(),s=this._el.getBoundingClientRect();return{top:s.top-t.top,left:s.left-t.left,bottom:s.bottom-t.top,right:s.right-t.left}}}get isInViewport(){if(0===this.height)return!1;const e=this.bounds;return isBetween(e.top,-e.height,Browser.height)}get scrollWidth(){return this._el.scrollWidth}get scrollHeight(){return this._el.scrollHeight}get scrollTop(){return this._el.scrollTop}get scrollLeft(){return this._el.scrollLeft}set scrollTop(e){this._el.scrollTop=e,this.trigger("scroll",{top:e,left:this.scrollLeft})}set scrollLeft(e){this._el.scrollLeft=e,this.trigger("scroll",{top:this.scrollTop,left:e})}fixOverflowScroll(){this._data._fixOverflowScroll||(this._data._fixOverflowScroll=!0,this._el.addEventListener("touchstart",()=>{const e=this.scrollTop,t=this.scrollHeight-this.height;0>=e&&(this.scrollTop=1),e>=t&&(this.scrollTop=t-1)}))}scrollTo(e,t,s){void 0===t&&(t=1e3),void 0===s&&(s="cubic"),0>e&&(e=0);const a=this.scrollTop,n=e-a;this._data._scrollAnimation&&this._data._scrollAnimation.cancel(),this._data._scrollAnimation=animate(e=>{const t=a+n*ease(s,e);this.scrollTop=t,this.trigger("scroll",{top:t})},t)}scrollBy(e,t,s){void 0===t&&(t=1e3),void 0===s&&(s="cubic"),e&&this.scrollTo(this.scrollTop+e,t,s)}css(e,t){if(void 0!==t)this._el.style[toCamelCase(e)]=t;else if("string"==typeof e)return window.getComputedStyle(this._el).getPropertyValue(e);else{const t=Object.keys(e);for(let s of t)this._el.style[toCamelCase(s)]=e[s]}}get transition(){return this.css("transform")}set transition(e){this._el.style.transition=e}get transform(){return this.css("transform").replace("none","")}set transform(e){this._el.style.transform=e}get transformMatrix(){let e=this.css("transform");if(!e||"none"===e)return[[1,0,0],[0,1,0]];let t=e.match(/matrix\(([0-9,.\s\-]*)\)/);if(!t[1])return[[1,0,0],[0,1,0]];let s=t[1].split(",");return[[+s[0],+s[2],+s[4]],[+s[1],+s[3],+s[5]]]}get scale(){let e=this.transformMatrix;return[e[0][0],e[1][1]]}setTransform(e,s,a){void 0===s&&(s=0),void 0===a&&(a=1);let n="";e&&(n+="translate("+roundTo(e.x,.1)+"px,"+roundTo(e.y,.1)+"px)"),s&&(n+=" rotate("+s+"rad)"),a&&(n+=" scale("+a+")"),this._el.style.transform=n}translate(e,t){this.setTransform(new Point(e,t))}translateX(e){this.setTransform(new Point(e,0))}translateY(e){this.setTransform(new Point(0,e))}show(){this.hasAttr("hidden")&&this.removeAttr("hidden"),"visibility"===this.data.display?this._el.style.visibility="visible":this._el.style.display=this.data.display||"block"}hide(){"visibility"===this.data.display?this._el.style.visibility="hidden":this._el.style.display="none"}transitionEnd(e){this.one("transitionend",e)}animationEnd(e){this.one("animationend",e)}is(e){return this._el.matches?this._el.matches(e):-1<[].indexOf.call(document.querySelectorAll(e),this._el)}index(){let e=0,t=this._el;for(;null!==(t=t.previousSibling);)++e;return e}prepend(e){let t=this._el.childNodes;if("string"==typeof e){let t=$$N(e);for(let e=t.length-1;0<=e;--e)this._el.insertBefore(t[e],this._el.childNodes[0])}else t.length?this._el.insertBefore(e._el,t[0]):this._el.appendChild(e._el)}append(e){if("string"==typeof e){let t=$$N(e);for(let e of t)this._el.appendChild(e._el)}else this._el.appendChild(e._el)}insertBefore(e){let t=this.parent;if("string"==typeof e){let s=$$N(e);for(let e=s.length-1;0<=e;--e)t._el.insertBefore(s[e]._el,this._el)}else t._el.insertBefore(e._el,this._el)}insertAfter(e){let t=this.parent;if("string"==typeof e){let s=$$N(e);for(let e of s)t._el.insertAfter(this._el,e._el)}else{let s=this._el.nextSibling;s?t._el.insertBefore(e._el,s):t._el.appendChild(e._el)}}wrap(e){return"string"==typeof e&&(e=$N(e)),this.insertBefore(e),this.detach(),e.append(this),e}moveTo(e,t){void 0===t&&(t=!1),t?e.prepend(this):e.append(this)}get next(){let e=this._el.nextSibling;return e?$(e):null}get prev(){let e=this._el.previousSibling;return e?$(e):null}$(e){return $(e,this)}$$(e){return $$(e,this)}get parent(){let e=this._el.parentElement;return e?$(e):null}get siblings(){let e=[],t=this._el.parentNode.firstChild;do e.push($(t));while(t=t.nextSibling);return e}parents(e){let t=[],s=this.parent;for(;s;)(!e||s.is(e))&&t.push(s),s=s.parent;return t}hasParent(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];let a=t.map(e=>e._el),n=this._el.parentNode;for(;n;){if(isOneOf(n,...a))return!0;n=n.parentNode}return!1}hasParentTag(e){for(let t=this.parent;t;){if(t.tagName===e)return!0;t=t.parent}return!1}get children(){let e=this._el.children||[];return Array.from(e,e=>$(e))}get childNodes(){let e=this._el.childNodes||[];return Array.from(e,e=>$(e))}detach(){this._el&&this._el.parentNode&&this._el.parentNode.removeChild(this._el)}remove(){this.detach(),this._el=null}removeChildren(){for(;this._el.firstChild;)this._el.removeChild(this._el.firstChild)}replaceWith(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];for(let e of t)this.insertBefore(e);this.remove()}on(t,s,a){if(void 0===s&&(s=null),void 0===a&&(a=!1),s)for(let n of words(t))createEvent(this,n,s,a);else for(let s of Object.keys(t))createEvent(this,s,t[s])}one(t,s,a){void 0===a&&(a=!1);const n=i=>{this.off(t,n,a),s(i)};this.on(t,n,a)}off(t,s,a){void 0===a&&(a=!1);for(let n of words(t))removeEvent(this,n,s,a)}trigger(t,s){void 0===s&&(s={});for(let a of words(t)){if(!this._events[a])return;for(let e of this._events[a])e.call(this,s)}}onKeyDown(t,s){t=words(t).map(e=>Browser.keyCodes[e]||e),this._el.addEventListener("keydown",function(a){0<=t.indexOf(a.keyCode)&&s(a)})}animate(e,t,s,a){return transition(this,e,t,s,a)}enter(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];return enter(this,...t)}exit(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];return exit(this,...t)}effect(e){effect(this,e)}fadeIn(e){return void 0===e&&(e=400),enter(this,"fade",e)}fadeOut(e){return void 0===e&&(e=400),exit(this,"fade",e)}get cursor(){let e=window.getSelection();if(!e.rangeCount)return[0,0];let t=window.getSelection().getRangeAt(0),s=t.cloneRange();s.selectNodeContents(this._el),s.setEnd(t.startContainer,t.startOffset);let a=s.toString().length;s.setEnd(t.endContainer,t.endOffset);let n=s.toString().length;return[a,n]}}class WindowElement extends Element{get width(){return window.innerWidth}get height(){return window.innerHeight}get innerWidth(){return window.innerWidth}get innerHeight(){return window.innerHeight}get outerWidth(){return window.outerWidth}get outerHeight(){return window.outerHeight}get scrollWidth(){return document.body.scrollWidth}get scrollHeight(){return document.body.scrollHeight}get scrollTop(){return window.pageYOffset}get scrollLeft(){return window.pageXOffset}set scrollTop(e){document.body.scrollTop=document.documentElement.scrollTop=e,this.trigger("scroll",{top:e,left:this.scrollLeft})}set scrollLeft(e){document.body.scrollLeft=document.documentElement.scrollLeft=e,this.trigger("scroll",{top:this.scrollTop,left:e})}}class FormElement extends Element{get action(){return this._el.action}get checked(){return this._el.checked}get formData(){const e={};for(let t of Array.from(this._el.elements)){const s=t.name||t.id;s&&(e[s]=t.value)}return e}change(e){let t="";this.on("change",()=>{this.value===t||(t=this.value.trim(),e(t))})}validate(e){this.change(t=>{this.setValidity(e(t))})}setValidity(e){this._el.setCustomValidity(e||"")}get isValid(){return this._el.checkValidity()}}class SVGElement extends Element{hasClass(e){let t=this._el.className.baseVal;return 0<=(" "+t+" ").indexOf(" "+e.trim()+" ")}get $ownerSVG(){return $(this._el.ownerSVGElement)||null}get width(){return this.bounds.width}get height(){return this.bounds.height}get viewBox(){return this._el.viewBox.baseVal||{}}get svgWidth(){return this.viewBox.width||this.width}get svgHeight(){return this.viewBox.height||this.height}get positionLeft(){if(this.$ownerSVG){const e=this._el.getBBox().x+this._el.getCTM().e;return this.$ownerSVG.positionLeft+e}return parseInt(this.css("margin-left"))+this.parent.positionLeft}get positionTop(){if(this.$ownerSVG){const e=this._el.getBBox().y+this._el.getCTM().f;return this.$ownerSVG.positionTop+e}return parseInt(this.css("margin-top"))+this.parent.positionTop}get inverseTransformMatrix(){const e=this._el.getScreenCTM().inverse(),t=[[e.a,e.c,e.e],[e.b,e.d,e.f]];if(Browser.isFirefox){let e=this.transformMatrix;t[0][2]-=e[0][2],t[1][2]-=e[1][2]}return t}setTransform(e,t,s){void 0===t&&(t=0),void 0===s&&(s=1);const a=e?"translate("+roundTo(e.x,.1)+" "+roundTo(e.y,.1)+")":"",n=t?"rotate("+180*t/Math.PI+")":"",i=s?"scale("+s+")":"";this.setAttr("transform",[a,n,i].join(" "))}get strokeLength(){if("getTotalLength"in this._el)return this._el.getTotalLength();if(this._el instanceof SVGLineElement)return Math.sqrt(square(this._el.x2.baseVal.value-this._el.x1.baseVal.value)+square(this._el.y2.baseVal.value-this._el.y1.baseVal.value));else{let e=this.bounds;return 2*e.height+2*e.width}}getPointAt(e){return this._el.getPointAtLength(e*this.strokeLength)}getPointAtLength(e){return this._el.getPointAtLength(e)}get points(){let e=this.attr("d");return e?e.replace(/[MZ]/g,"").split(/[LA]/).map(e=>{let t=e.split(",");return{x:+t[t.length-2],y:+t[t.length-1]}}):[]}set points(e){let t=e.length?"M"+e.map(e=>e.x+","+e.y).join("L"):"";this.setAttr("d",t)}addPoint(e){let t=this.attr("d")+" L "+e.x+","+e.y;this.setAttr("d",t)}get center(){return new Point(+this.attr("cx"),+this.attr("cy"))}setCenter(e){this.setAttr("cx",e.x),this.setAttr("cy",e.y)}setLine(e,t){this.setAttr("x1",e.x),this.setAttr("y1",e.y),this.setAttr("x2",t.x),this.setAttr("y2",t.y)}setRect(e){this.setAttr("x",e.p.x),this.setAttr("y",e.p.y),this.setAttr("width",e.w),this.setAttr("height",e.h)}draw(e,t){void 0===t&&(t={});const s={mark:this.attr("mark"),arrows:this.attr("arrows"),size:+this.attr("size")||null,fill:this.hasClass("fill"),round:this.hasAttr("round")};this.setAttr("d",drawSVG(e,applyDefaults(t,s)))}pngImage(e){const t=e||this.svgWidth,s=e||this.svgHeight,a=new XMLSerializer().serializeToString(this._el);let n="data:image/svg+xml;utf8,"+encodeURIComponent(a);return n=n.replace("svg ","svg xmlns=\"http://www.w3.org/2000/svg\" "),new Promise(e=>{const a=new Image;a.onload=()=>{const n=$N("canvas",{width:t,height:s});n.ctx.fillStyle="#fff",n.ctx.fillRect(0,0,t,s),n.ctx.drawImage(a,0,0),e(n.pngImage)},a.src=n})}}class CanvasElement extends Element{getContext(e,t){return void 0===e&&(e="2d"),void 0===t&&(t={}),this._el.getContext(e,t)}get pngImage(){return this._el.toDataURL("image/png")}get canvasWidth(){return this._el.width}get canvasHeight(){return this._el.height}get ctx(){return this._data.ctx||(this._data.ctx=this.getContext()),this._data.ctx}draw(e,t){this.ctx.save(),drawCanvas(this.ctx,e,t),this.ctx.restore()}clear(){const e=this.ctx.canvas;this.ctx.clearRect(0,0,e.width,e.height)}}class MediaElement extends Element{play(){return this._el.play()||Promise.resolve()}pause(){this._el.pause()}}const svgTags=["path","rect","circle","ellipse","polygon","polyline","g","defs","marker","line","text","pattern","mask","svg"],formTags=["form","input","select"],$window=new WindowElement(window),$html=new WindowElement(window.document.documentElement),$body=new WindowElement(document.body);let POST_DATA=new Map;const doDeferredPost=throttle(sendPostData,5e3);window.addEventListener("online",doDeferredPost),window.onbeforeunload=sendPostData;const shortHexRegex=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,longHexRegex=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rainbow=["#31b304","#1f7aff","#b30469","#ff941f"],temperature=["#3D52A1","#3A89C9","#77B7E5","#B4DDF7","#E6F5FE","#FFFAD2","#FFE3AA","#F9BD7E","#ED875E","#D24D3E","#AE1C3E"],solar=["#FFFFE5","#FFF7BC","#FEE391","#FEC44F","#FB9A29","#EC7014","#CC4C02","#993404","#662506"];class Colour{static get red(){return"#D90000"}static get orange(){return"#F15A24"}static get yellow(){return"#edd200"}static get lime(){return"#b2d300"}static get green(){return"#00B200"}static get cyan(){return"#29ABE2"}static get blue(){return"#006DD9"}static get violet(){return"#662D91"}static get purple(){return"#9d0069"}static get pink(){return"#ED1E79"}static rainbow(e){return tabulate(t=>getColourAt(rainbow,t/(e-1)),e)}static temperature(e){let t=clamp(.1*e,0,1);return tabulate(function(s){return getColourAt(temperature,(1-t)/2+t*s/(e-1))},e)}static solar(e){return tabulate(t=>getColourAt(solar,t/(e-1)),e)}constructor(e,t,s,n){void 0===n&&(n=1),this.r=e,this.g=t,this.b=s,this.a=n}static fromHex(e){e=e.replace(shortHexRegex,function(e,t,s,a){return t+t+s+s+a+a});let t=longHexRegex.exec(e);return t?new Colour(parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)):new Colour(0,0,0)}static fromRgb(e){let t=e.replace(/rgba?\(/,"").replace(")","").split(",");return new Colour(+t[0],+t[1],+t[2],3<t.length?+t[3]:1)}get hex(){let e=[this.r,this.g,this.b].map(e=>pad2(Math.round(e).toString(16)));return"#"+e.join("")}get rgb(){let e=[this.r,this.g,this.b].map(e=>Math.round(e)).join(",");return"rgba("+e+","+this.a+")"}get hsl(){let e=this.r/255,t=this.g/255,a=this.b/255,n=Math.max(e,t,a),i=Math.min(e,t,a),o=(n+i)/2,r,l;if(n===i)r=l=0;else{let s=n-i;l=.5<o?s/(2-n-i):s/(n+i),n===e?r=(t-a)/s+(t<a?6:0):n===t?r=(a-e)/s+2:n===a?r=(e-t)/s+4:void 0,r/=6}return"hsl("+[r,l,o].join(",")+")"}toString(){return this.rgb}copy(){return new Colour(this.r,this.g,this.b,this.a)}static mix(e,t,s){return void 0===s&&(s=.5),s=clamp(s,0,1),e instanceof Colour||(e=Colour.fromHex(e)),t instanceof Colour||(t=Colour.fromHex(t)),new Colour(s*e.r+(1-s)*t.r,s*e.g+(1-s)*t.g,s*e.b+(1-s)*t.b,s*e.a+(1-s)*t.a)}}const defaultOptions={moveX:!0,moveY:!0,snap:1,useTransform:!1,margin:0,round:e=>e,responsive:!1};class Draggable extends Evented{constructor(e,t,s){void 0===s&&(s={}),super(),this.$el=e,this.position=new Point(0,0),this.options=applyDefaults(s,defaultOptions),this.disabled=!1,this.width=this.options.responsive?t.svgWidth:t.width,this.height=this.options.responsive?t.svgHeight:t.height;let a=null;slide(e,{start:()=>{this.disabled||(a=this.position,this.trigger("start"))},move:(e,t)=>{this.disabled||(this.setPosition(a.x+e.x-t.x,a.y+e.y-t.y),this.trigger("drag",this.position))},end:(e,t)=>{this.disabled||this.trigger(e.equals(t)?"click":"end")}}),Browser.resize(()=>{const e=this.width,s=this.height;this.width=this.options.responsive?t.svgWidth:t.width,this.height=this.options.responsive?t.svgHeight:t.height,this.setPosition(this.position.x*this.width/e||0,this.position.y*this.height/s||0)})}setPosition(e,t){const s=this.options.margin,a=this.options.round(new Point(e,t).clamp(s,this.width-s,s,this.height-s).round(this.options.snap));this.options.moveX||(a.x=0),this.options.moveY||(a.y=0),a.equals(this.position)||(this.position=a,this.options.useTransform?this.$el.translate(a.x,a.y):(this.options.moveX&&this.$el.css("left",a.x+"px"),this.options.moveY&&this.$el.css("top",a.y+"px")),this.trigger("move",a))}}"scrollRestoration"in history&&(history.scrollRestoration="manual");const onPopState=function(){let t=!1;return"complete"===document.readyState?t=!0:window.addEventListener("load",function(){setTimeout(function(){t=!0})}),function(s){t&&s.state&&this.goToState(s.state)}}();class _Router extends Evented{setup(e){this.$viewport=e.$viewport||$body,this.preloaded=e.preloaded||!1,this.transition=e.transition||!1,this.initialise=e.initialise||noop,this.noLoad=e.noLoad||!1,this.views=[],this.active=null,this.current="",e.click&&$body.on("click",onLinkClick.bind(this)),e.history&&window.addEventListener("popstate",onPopState.bind(this))}get hash(){return window.location.hash.slice(1)}set hash(e){window.location.hash=e,this.trigger("hashChange",e)}view(e,t){let{enter:s,exit:a,template:n}=void 0===t?{}:t,i=(e.match(/:\w+/g)||[]).map(e=>e.substr(1)),o=e.replace(/:\w+/g,"([\\w-]+)").replace("/","\\/")+"\\/?",r=new RegExp("^"+o+"$"),l={regex:r,params:i,enter:s,exit:a,template:n};this.views.push(l);let d=getViewParams(window.location.pathname,l);d&&(this.active={path:window.location.pathname,hash:window.location.hash,index:0},window.history.replaceState(this.active,"",this.active.path+this.active.hash),Browser.ready(()=>{setTimeout(()=>{this.preloaded?(this.initialise(this.$viewport,d),l.enter&&l.enter(this.$viewport,d)):loadView(this,l,d,this.location.pathname)})}))}paths(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];t.forEach(e=>{this.view(e)})}getView(e){for(let t of this.views){let s=getViewParams(e,t);if(s)return{view:t,params:s}}}load(e,t){void 0===t&&(t="");let s=this.getView(e);return e===this.active.path&&t!==this.active.hash?(console.info("[boost] Routing to "+e+t),this.trigger("hashChange",t.slice(1)),this.trigger("change",e+t),!0):!!(s&&e!==this.active.path)&&(console.info("[boost] Routing to "+e+t),this.trigger("change",e+t),window.ga&&ga("send","pageview",e+t),this.noLoad?s.view.enter&&s.view.enter(this.$viewport,s.params):loadView(this,s.view,s.params,e),!0)}goToState(e){if(e&&e.path){let t=this.load(e.path,e.hash);t&&e.index<this.active.index&&this.trigger("back"),t&&e.index>this.active.index&&this.trigger("forward"),this.active=e}}goTo(e,t){void 0===t&&(t="");let s=this.load(e,t);if(s){let s=this.active?this.active.index+1:0;this.active={path:e,hash:t,index:s},window.history.pushState(this.active,"",e+t)}return s}back(){window.history.back()}forward(){window.history.forward()}}const Router=new _Router,customElementOptions=new Map;class CustomHTMLElement extends HTMLElement{connectedCallback(){if(this._wasConnected)return void this.$el.trigger("connected");this._wasConnected=!0,this._isReady=!1,this.$el.created&&this.$el.created();const e=customElementOptions.get(this.$el.tagName);(e.template||e.templateId)&&applyTemplate(this,e);let t=customElementChildren(this).filter(e=>!e._isReady).map(e=>new Promise(t=>e.addEventListener("_ready",t)));Promise.all(t).then(()=>{this.$el.ready&&this.$el.ready(),this.dispatchEvent(new CustomEvent("_ready")),this._isReady=!0})}disconnectedCallback(){this.$el.trigger("disconnected")}attributeChangedCallback(e,t,s){this.$el.trigger("attr:"+e,{newVal:s,oldVal:t})}}class CustomElement extends Element{created(){}ready(){}}class Blank extends CustomElement{ready(){this.$target=this.$(".target");const e=this.$(".popup"),t=e.$$(".choice");this.done=!1,this.solution=t[0].html;const s=intArray(t.length);s.forEach(s=>{e.append(t[0]),t[s].on("click",()=>{this.removeClass("on"),s?(this.$target.html=t[s].html,this.addClass("invalid"),this.trigger("invalid")):(this.solve(),this.trigger("valid",this.solution))})}),this.setClass("left",this.$target.bounds.left+e.width>Browser.width-15),this.on("hover",{enter:()=>{if(this.done)return;this.addClass("on");const t=this.$target.bounds,s=e.width,a=e.height;this.setClass("left",t.left+s>Browser.width-15),this.setClass("top",t.top+t.height+a>Browser.height-10)},exit:()=>{this.removeClass("on")},delay:100,$clickTarget:this.$target})}solve(){this.done=!0,this.$target.html=this.solution,this.removeClass("on invalid"),this.addClass("done")}}class BlankInput extends CustomElement{ready(){this.$input=this.$("input"),this.$target=this.$(".target"),this.solution=this.attr("solution"),this.removeAttr("solution");let e=null;if(0<=this.solution.indexOf("\xB1")){const t=this.solution.split("\xB1");this.solution=t[0].trim(),e=+t[1]}let t=parseNumber(this.solution);isNaN(t)&&(t=this.solution);const a=isInteger(t)&&0<=t;Browser.isAndroid&&a||Browser.isIOS&&!a?this.$input.setAttr("type","number"):Browser.isIOS&&this.$input.setAttr("pattern","[0-9]*");let n="",i=0;this.$input.change(s=>{if(s.match("^[0-9]+/[0-9]+$")){const e=s.split("/");s=""+ +e[0]/+e[1]}n=parseNumber(s),isNaN(n)&&(n=s);const a=e&&Math.abs(n-t)<=e,i=(""+n).toLowerCase()===(""+t).toLowerCase();(a||n===t||i||toWord(n)===t||n===toWord(t))&&(this.solve(),this.trigger("valid",n),this.moveCursor())}),this.$input.onKeyDown("enter",()=>this.$input.blur()),this.$input.on("focus",()=>{this.addClass("on"),this.removeClass("invalid"),this.$input.setAttr("placeholder"," ")}),this.$input.on("blur",()=>{this.removeClass("on"),this.setClass("invalid",n&&!this.done),this.$input.setAttr("placeholder","???"),n&&!this.done&&(i+=1,3<=i?this.trigger("hint",this.solution):this.trigger("invalid"))})}moveCursor(){const e=this.getModel().$step,t=e?e.$$("x-blank, x-blank-input"):[],s=t[t.indexOf(this)+1];s&&!s.done&&"X-BLANK"!==s.tagName&&"hidden"!==s.css("visibility")&&s.bounds.width&&s.$input.focus()}solve(){this.done=!0,this.$input.remove(),this.$target.html=this.solution,this.addClass("done")}}registerElement("x-blank-input",BlankInput,{templateId:"#blank-input"}),registerElement("x-blank",Blank,{templateId:"#blank"});class ExprError extends Error{constructor(e,t){super(t),this.name=e}static undefinedVariable(e){return new ExprError("EvalError","Undefined variable \u201C"+e+"\u201D.")}static undefinedFunction(e){return new ExprError("EvalError","Undefined function \u201C"+e+"\u201D.")}static invalidCharacter(e){return new ExprError("SyntaxError","Unknown symbol \u201C"+e+"\u201D.")}static conflictingBrackets(e){return new ExprError("SyntaxError","Conflicting brackets \u201C"+e+"\u201D.")}static unclosedBracket(e){return new ExprError("SyntaxError","Unclosed bracket \u201C"+e+"\u201D.")}static startOperator(e){return new ExprError("SyntaxError","A term cannot start with a \u201C"+e+"\u201D.")}static endOperator(e){return new ExprError("SyntaxError","A term cannot end with a \u201C"+e+"\u201D.")}static consecutiveOperators(e,t){return new ExprError("SyntaxError","A \u201C"+e+"\u201D cannot be followed by a \u201C"+t+"\u201D.")}static invalidExpression(){return new ExprError("SyntaxError","This expression is invalid.")}}const CONSTANTS={pi:Math.PI,π:Math.PI,e:Math.E},BRACKETS={"(":")","[":"]","{":"}","|":"|"},SPECIAL_OPERATORS={"*":"\xB7","**":"\u2217","//":"//","+-":"\xB1","–":"\u2212","-":"\u2212",xx:"\xD7",sum:"\u2211",prod:"\u220F",int:"\u222B",del:"\u2202",grad:"\u2207",aleph:"\u2135",not:"\xAC",AA:"\u2200",EE:"\u2203","!=":"\u2260","<=":"\u2264",">=":"\u2265",in:"\u2208","!in":"\u2209","==":"\u2261","~=":"\u2245","~~":"\u2248",sub:"\u2282",sube:"\u2286",prop:"\u221D","<-":"\u2190","->":"\u2192","=>":"\u21D2","<=>":"\u21D4","|->":"\u21A6",uarr:"\u2191",darr:"\u2193",lArr:"\u21D0",CC:"\u2102",NN:"\u2115",QQ:"\u211A",RR:"\u211D",ZZ:"\u2124"},SPECIAL_IDENTIFIERS={Gamma:"\u0393",Delta:"\u0394",Theta:"\u0398",Lambda:"\u039B",Xi:"\u039E",Pi:"\u03A0",Sigma:"\u03A3",Phi:"\u03A6",Psi:"\u03A8",Omega:"\u03A9",alpha:"\u03B1",beta:"\u03B2",gamma:"\u03B3",delta:"\u03B4",epsilon:"\u025B",zeta:"\u03B6",eta:"\u03B7",theta:"\u03B8",iota:"\u03B9",kappa:"\u03BA",lambda:"\u03BB",mu:"\u03BC",nu:"\u03BD",xi:"\u03BE",pi:"\u03C0",rho:"\u03C1",sigma:"\u03C3",tau:"\u03C4",upsilon:"\u03C5",phi:"\u03C6",chi:"\u03C7",psi:"\u03C8",omega:"\u03C9"},ALPHABET="abcdefghijklmnopqrstuvwxyz",LOWERCASE=ALPHABET.split(""),UPPERCASE=ALPHABET.toUpperCase().split(""),GREEK=Object.values(SPECIAL_IDENTIFIERS),IDENTIFIER_SYMBOLS=[...LOWERCASE,...UPPERCASE,...GREEK],SIMPLE_SYMBOLS="|()[]{}\xF7,!<>=*/+-\u2013\u2212~^_\u2026\xB0",COMPLEX_SYMBOLS=Object.values(SPECIAL_OPERATORS),OPERATOR_SYMBOLS=[...SIMPLE_SYMBOLS,...COMPLEX_SYMBOLS];class ExprElement{evaluate(e){return void 0===e&&(e={}),null}substitute(e){return void 0===e&&(e={}),this}get simplified(){return this}get variables(){return[]}get functions(){return[]}collapse(){return this}toString(){return""}toMathML(e){return void 0===e&&(e={}),""}}class ExprNumber extends ExprElement{constructor(e){super(),this.n=e}evaluate(){return this.n}toString(){return""+this.n}toMathML(){return"<mn>"+this.n+"</mn>"}}class ExprIdentifier extends ExprElement{constructor(e){super(),this.i=e}evaluate(e){if(void 0===e&&(e={}),this.i in e)return e[this.i];if(this.i in CONSTANTS)return CONSTANTS[this.i];throw ExprError.undefinedVariable(this.i)}substitute(e){return void 0===e&&(e={}),e[this.i]||this}get variables(){return[this.i]}toString(){return this.i}toMathML(){return"<mi>"+this.i+"</mi>"}}class ExprString extends ExprElement{constructor(e){super(),this.s=e}evaluate(){throw ExprError.undefinedVariable(this.s)}toString(){return"\""+this.s+"\""}toMathML(){return"<mtext>"+this.s+"</mtext>"}}class ExprSpace extends ExprElement{toString(){return" "}toMathML(){return"<mspace/>"}}class ExprOperator extends ExprElement{constructor(e){super(),this.o=e}toString(){return this.o.replace("//","/")}toMathML(){return"<mo value=\""+this.toString()+"\">"+this.toString()+"</mo>"}get functions(){return[this.o]}}class ExprTerm extends ExprElement{constructor(e){super(),this.items=e}evaluate(e){return void 0===e&&(e={}),this.collapse().evaluate(e)}substitute(e){return void 0===e&&(e={}),this.collapse().substitute(e)}get simplified(){return this.collapse().simplified}get variables(){return unique(join(...this.items.map(e=>e.variables)))}get functions(){return this.collapse().functions}toString(){return this.items.map(e=>e.toString()).join(" ")}toMathML(e){return void 0===e&&(e={}),this.items.map(t=>t.toMathML(e)).join("")}collapse(){return collapseTerm(this.items).collapse()}}const PRECEDENCE=words("+ \u2212 * \xD7 \xB7 / \xF7 // sup sub"),COMMA="<mo value=\",\" lspace=\"0\">,</mo>";class ExprFunction extends ExprElement{constructor(e,t){void 0===t&&(t=[]),super(),this.fn=e,this.args=t}evaluate(e){void 0===e&&(e={});const t=this.args.map(t=>t.evaluate(e));if(this.fn in e)return e[this.fn](...t);switch(this.fn){case"+":return t.reduce((e,t)=>e+t,0);case"\u2212":return 1<t.length?t[0]-t[1]:-t[0];case"*":case"\xB7":case"\xD7":return t.reduce((e,t)=>e*t,1);case"/":return t[0]/t[1];case"sin":return Math.sin(t[0]);case"cos":return Math.sin(t[0]);case"tan":return Math.sin(t[0]);case"log":return Math.log(t[0])/Math.log(t[1]||Math.E);case"sup":return Math.pow(t[0],t[1]);case"sqrt":return Math.sqrt(t[0]);case"root":return Math.pow(t[0],1/t[1]);case"(":return t[0];}throw ExprError.undefinedFunction(this.fn)}substitute(e){return void 0===e&&(e={}),new ExprFunction(this.fn,this.args.map(t=>t.substitute(e)))}collapse(){return"("===this.fn?this.args[0].collapse():new ExprFunction(this.fn,this.args.map(e=>e.collapse()))}get simplified(){return this}get variables(){return unique(flatten(this.args.map(e=>e.variables)))}get functions(){return unique([this.fn,...flatten(this.args.map(e=>e.functions))])}toString(){const e=this.args.map(e=>needsBrackets(e,this.fn)?"("+e.toString()+")":e.toString());return"\u2212"===this.fn?1<e.length?e.join(" \u2212 "):"\u2212"+e[0]:"sup"===this.fn?e.join("^"):"sub"===this.fn?e.join("_"):words("+ * \xD7 \xB7 / = < > \u2264 \u2265").includes(this.fn)?e.join(" "+this.fn+" "):isOneOf(this.fn,"(","[","{")?this.fn+this.args.join(", ")+BRACKETS[this.fn]:isOneOf(this.fn,"!","%")?e[0]+this.fn:this.fn+"("+e.join(", ")+")"}toMathML(e){void 0===e&&(e={});const t=this.args.map(t=>t.toMathML(e)),s=this.args.map((e,s)=>addMFence(e,this.fn,t[s]));if(this.fn in e){const s=t.map((e,t)=>({toString:()=>e,val:this.args[t]}));return e[this.fn](...s)}if("\u2212"===this.fn)return 1<s.length?s.join("<mo value=\"\u2212\">\u2212</mo>"):"<mo rspace=\"0\" value=\"\u2212\">\u2212</mo>"+s[0];if(isOneOf(this.fn,"+","=","<",">","\u2264","\u2265"))return s.join("<mo value=\""+this.fn+"\">"+this.fn+"</mo>");if(isOneOf(this.fn,"*","\xD7","\xB7")){let e=s[0];for(let t=1;t<s.length-1;++t){const t=this.args[0]instanceof ExprNumber&&this.args[1]instanceof ExprNumber;e+=(t?"<mo value=\"\xD7\">\xD7</mo>":"")+s[1]}return e}if("//"===this.fn)return s.join("<mo value=\"/\">/</mo>");if("sqrt"===this.fn)return"<msqrt>"+s[0]+"</msqrt>";if(isOneOf(this.fn,"/","root")){const e="/"===this.fn?"mfrac":"mroot",s=this.args.map((e,s)=>addMRow(e,t[s]));return"<"+e+">"+s.join("")+"</"+e+">"}if(isOneOf(this.fn,"sup","sub")){const e=[addMRow(this.args[0],s[0]),addMRow(this.args[1],t[1])];return"<m"+this.fn+">"+e.join("")+"</m"+this.fn+">"}return isOneOf(this.fn,"(","[","{")?"<mfenced open=\""+this.fn+"\" close=\""+BRACKETS[this.fn]+"\">"+s.join(COMMA)+"</mfenced>":isOneOf(this.fn,"!","%")?s[0]+("<mo value=\""+this.fn+"\" lspace=\"0\">"+this.fn+"</mo>"):"<mi>"+this.fn+"</mi><mfenced>"+s.join(COMMA)+"</mfenced>"}}const Expression={numEquals,parse:cache(parse$1)},FUNCTION_STEP=2,GRID_SPACING=80,GRID_STEPS=[5,2,1],TICK_LENGTH=4,ANIMATION=5e3;class CoordinateSystem extends CustomElement{ready(){const e=+this.attr("width")||600,t=+this.attr("height")||400;this.css("width",e+"px");const s=this.$("svg");s.setAttr("width",e),s.setAttr("height",t),s.setAttr("viewBox","0 0 "+e+" "+t),this.$grid=$N("g",{class:"grid"},s),this.$xAxis=$N("line",{class:"axis"},s),this.$yAxis=$N("line",{class:"axis"},s),this.$plot=$N("g",{class:"plot"},s),this.$labels=$N("g",{class:"labels"},s),this.$overlay=$N("g",{},s);const a=this.hasAttr("margins")?words(this.attr("margins")):[20,20,20,20];if(this.mathBounds=new Bounds(-5,5,0,10),this.plotBounds=new Bounds(+a[3],e-a[1],t-a[2],+a[0]),this.plotOrigin=new Point(0,0),this.xAxisOptions=this.attr("x-axis").split("|"),this.yAxisOptions=this.attr("y-axis").split("|"),this.xSuffix=this.attr("x-suffix"),this.ySuffix=this.attr("y-suffix"),this.animate=this.hasAttr("animate"),this.noLabels=this.hasAttr("no-labels"),this.xLabel=this.attr("x-label"),this.yLabel=this.attr("y-label"),this.hasAttr("fns")){const e=this.attr("fns").split("|").map(e=>Expression.parse(e,!0)).map(e=>t=>e.evaluate({x:t}));this.setFunctions(...e)}this.crosshairGrid=+this.attr("crosshair-grid")||10,this.getCrosshairPosn=e=>e,this.hasAttr("no-crosshairs")||this.setupCrosshairs(s,e)}setupCrosshairs(t,s){const a=$N("g",{class:"crosshair"},t),n=$N("path",{},a),i=$N("circle",{r:4},a),o=$N("text",{},a);let r=new Point(0,0);const l=a=>{const e=this.plotToMathCoords(svgPointerPosn(a,t)),l=this.getCrosshairPosn(e);if(!l.equals(r)){r=l;const e=this.mathToPlotCoords(l);i.setCenter(e),n.points=[new Point(this.plotOrigin.x,e.y),e,new Point(e.x,this.plotOrigin.y)],o.text="("+l.x+", "+numberFormat(l.y,5)+")";const t=o.width;o.setAttr("x",e.x+8+t<s?e.x+5:e.x-t-5),o.setAttr("y",20<e.y?e.y-7:e.y+18)}};t.on("touchstart mouseover",t=>{a.show(),l(t)},{passive:!0}),t.on("touchend mouseout",()=>a.hide(),{passive:!0}),t.on("pointermove",l)}mathToPlotCoords(e){return e.changeCoordinates(this.mathBounds,this.plotBounds)}plotToMathCoords(e){return e.changeCoordinates(this.plotBounds,this.mathBounds)}setPoints(e,t){void 0===t&&(t=1);const s=e.map((e,s)=>new Point(s+t,e));this.setSeries(s)}setSeries(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];const[a,n,i]=computeAxis(this.xAxisOptions,this.plotBounds.dx,[0,Math.max(...t.map(e=>last(e).x))]);this.mathBounds.xMin=a,this.mathBounds.xMax=n;const[o,r,l]=computeAxis(this.yAxisOptions,this.plotBounds.dy,getDataBounds(t));this.mathBounds.yMin=o,this.mathBounds.yMax=r,this.drawAxes(i,l),this.$plot.removeChildren();for(let e of t)this.drawLinePlot(e);this.getCrosshairPosn=e=>t[0].reduce((t,s)=>Math.abs(s.x-e.x)<=Math.abs(t.x-e.x)?s:t)}setFunctions(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];const[a,n,i]=computeAxis(this.xAxisOptions,this.plotBounds.dx,[-5,5]);this.mathBounds.xMin=a,this.mathBounds.xMax=n;const o=t.map(()=>[]);for(let e=this.plotBounds.xMin,s;e<this.plotBounds.xMax;e+=FUNCTION_STEP){s=this.plotToMathCoords(new Point(e,0)).x;for(let e=0;e<t.length;++e)o[e].push(new Point(s,t[e](s)))}const[r,l,d]=computeAxis(this.yAxisOptions,this.plotBounds.dy,getDataBounds(o));this.mathBounds.yMin=r,this.mathBounds.yMax=l,this.drawAxes(i,d),this.$plot.removeChildren();for(let e of o)this.drawLinePlot(e);this.getCrosshairPosn=e=>{const s=roundTo(clamp(e.x,a,n),i/this.crosshairGrid);return new Point(_round(s,3),t[0](s))}}drawAxes(e,t){const[s,a]=[this.mathBounds,this.plotBounds],n=getOrigin(this.mathBounds);this.plotOrigin=this.mathToPlotCoords(n),this.$xAxis.setLine({x:a.xMin,y:this.plotOrigin.y},{x:a.xMax,y:this.plotOrigin.y}),this.$yAxis.setLine({x:this.plotOrigin.x,y:a.yMin},{x:this.plotOrigin.x,y:a.yMax}),this.$grid.removeChildren(),this.$labels.removeChildren(),this.xLabel&&$N("text",{text:this.xLabel,x:this.plotBounds.xMax-2,y:this.plotOrigin.y-12,"text-anchor":"end"},this.$labels),this.yLabel&&$N("text",{text:this.yLabel,x:this.plotOrigin.x+10,y:this.plotBounds.yMax+5},this.$labels);for(let i=s.xMin+e;i<s.xMax;i+=e){if(i===n.x)continue;const e=this.mathToPlotCoords(new Point(i,0)).x;$N("line",{x1:e,y1:a.yMin,x2:e,y2:a.yMax},this.$grid),this.noLabels||($N("text",{text:numberFormat(i,4)+this.xSuffix,x:e,y:this.plotOrigin.y+18,"text-anchor":"middle"},this.$labels),$N("line",{class:"tick",x1:e,y1:this.plotOrigin.y,x2:e,y2:this.plotOrigin.y+TICK_LENGTH},this.$grid))}for(let i=s.yMin+t;i<s.yMax;i+=t){if(i===n.y)continue;const e=this.mathToPlotCoords(new Point(0,i)).y;$N("line",{x1:a.xMin,y1:e,x2:a.xMax,y2:e},this.$grid),this.noLabels||($N("text",{text:numberFormat(i,4)+this.ySuffix,x:this.plotOrigin.x-8,y:e+4,"text-anchor":"end"},this.$labels),$N("line",{class:"tick",x1:this.plotOrigin.x,y1:e,x2:this.plotOrigin.x-TICK_LENGTH,y2:e},this.$grid))}this.noLabels||(0!==s.xMin||0!==s.yMin||this.ySuffix||this.ySuffix?0===s.yMin?$N("text",{text:numberFormat(n.x,4)+this.xSuffix,x:this.plotOrigin.x,y:this.plotOrigin.y+18,"text-anchor":"middle"},this.$labels):$N("text",{text:numberFormat(n.y,4)+this.ySuffix,x:this.plotOrigin.x-8,y:this.plotOrigin.y+4,"text-anchor":"end"},this.$labels):$N("text",{text:0,x:this.plotOrigin.x-5,y:this.plotOrigin.y+15,"text-anchor":"end"},this.$labels))}drawLinePlot(e){const t=$N("g",{},this.$plot),s=$N("path",{},t),a=this.mathBounds;e=e.filter(e=>e.y>=a.yMin&&e.y<=a.yMax);const n=e.map(e=>this.mathToPlotCoords(e));this.animate?animate(t=>{const i=a.xMin+t*(a.xMax-a.xMin),o=e.findIndex(e=>e.x>i);s.points=n.slice(0,o)},ANIMATION):s.points=n}drawPoints(e){const t=$N("g",{},this.$plot),s=this.mathBounds;for(let a of e){const e=this.mathToPlotCoords(a),n=$N("circle",{r:4,cx:e.x,cy:e.y},t);if(this.animate){n.hide();const e=ANIMATION*(a.x-s.xMin)/(s.xMax-s.xMin);setTimeout(()=>n.show(),e)}}}}registerElement("x-coordinate-system",CoordinateSystem,{templateId:"#coordinate-system"});class CoordinateSketch extends CustomElement{ready(){let e=400,t=this.$("svg"),s=t.$(".axes"),a=t.$(".validation"),n=e=>e+300,i=t=>e/2-t,o=this.attr("validate");o&&(o=o.split(":"));for(let t=50-e/2;t<e/2;t+=50)$N("line",{x1:0,x2:600,y1:i(t),y2:i(t),class:t?"axis":"axis primary"},s);for(let t=-250;300>t;t+=50)$N("line",{x1:n(t),x2:n(t),y1:e,y2:0,class:t?"axis":"axis primary"},s)}}registerElement("x-coordinate-sketch",CoordinateSketch,{templateId:"#coordinate-sketch"});const keys=Browser.keyCodes,DEFAULT_ERROR="This is not a valid mathematical expression.",PLACEHOLDERS_ERROR="Fill in all empty placeholders in the expression.",FN_NAMES={"+":"addition","×":"multiplication","/":"fractions or division","−":"subtraction",sqrt:"square roots","^":"powers"};class Equation extends CustomElement{ready(){if(this.$math=this.$(".math"),this.$textarea=this.$("textarea"),this.$cursor=this.$(".cursor"),this.$error=this.$(".error-message"),this.$step=this.getModel().$step,this.solution=Expression.parse(this.attr("solution")),this.numeric=this.hasAttr("numeric")?+this.attr("precision")||.01:null,this.vars=this.hasAttr("vars")?words(this.attr("vars")):this.solution?this.solution.variables:[],this.fns=this.hasAttr("fns")?words(this.attr("fns")):[],this.solution&&this.fns.push(...this.solution.functions),this.fns.includes("/")&&!this.fns.includes("\xD7")&&this.fns.push("\xD7"),this.hasAttr("hints")&&(this.hints=words(this.attr("hints"))),this.hasAttr("substitutions")){this.substitutions={},this.autocomplete=this.vars.slice(0);for(let e of this.attr("substitutions").split("|"))if(e.trim()){const[t,s]=e.split(":");this.autocomplete.push(t.trim()),this.substitutions[t.trim()]=Expression.parse(s)}}for(let e of["solution","precision","vars","fns","vars-required","substitutions"])this.removeAttr(e);this.shortVar=this.hasAttr("short-var"),this.isDone=!1,this.value=null,this.expr=null,this.error=null,this.lastAttempt="",this.errorCount=0;const e=words(this.attr("keys")||"+ \u2212 \xD7 \xF7 frac sup sqrt brackets"),t=this.$(".keys");for(let s of t.children)0>e.indexOf(s.data.type)?s.remove():(s.on("pointerdown",t=>t.preventDefault()),s.on("pointerup",()=>{type(this.$cursor,s.data.type),this.check()}));this.on("pointerdown",t=>this.onPointerdown(t)),this.$textarea.on("blur",()=>this.onBlur()),this.$textarea.on("key",t=>this.onKey(t))}focus(){this.trigger("pointerdown")}onPointerdown(t){if(!this.isDone){t.preventDefault&&t.preventDefault(),this.addClass("active"),this.$textarea.focus();const e=t.target?$(t.target):this;if("X-EQUATION"===e.tagName||e.hasClass("math")){const e=total(this.$math.children.map(e=>e.outerWidth))/2,s=pointerPosition(t).x<this.$math.bounds.x+e;s?this.$math.prepend(this.$cursor):this.$math.append(this.$cursor)}else if("M"===e.tagName[0]){const s=pointerPosition(t).x<e.boxCenter.x;"MROW"===e.tagName?s?e.prepend(this.$cursor):e.append(this.$cursor):s?e.insertBefore(this.$cursor):e.insertAfter(this.$cursor)}}}onKey(t){if(isOneOf(t.code,keys.enter,keys.escape))this.$textarea.blur();else if(t.code===keys.left)goLeft(this.$cursor);else if(t.code===keys.right)goRight(this.$cursor);else if(t.code===keys.up)goUp(this.$cursor);else if(t.code===keys.down)goDown(this.$cursor);else if(isOneOf(t.code,keys.backspace,keys.delete))backspace(this.$cursor),this.check();else{let e=t.key.replace("*","\xD7").replace("/","\xF7").replace("-","\u2212");type(this.$cursor,e),this.check()}}onBlur(){if(this.isDone)return;if(!this.value)return this.removeClass("active has-error");if(this.removeClass("active"),this.addClass("has-error"),this.value===this.lastAttempt)return;this.lastAttempt=this.value;const e=this.error||(this.hints||[]).shift()||"incorrect",t=this.$step.addHint(e,{className:"incorrect"});this.$error.html=t.text,this.errorCount+=1,this.trigger("error",{count:this.errorCount,msg:e}),5<=this.errorCount&&this.$step.addHint("Hmmm\u2026 maybe try "+this.solution.toMathML()+"?")}check(){if(this.error=null,this.value=toString(this.$math,this.shortVar).trim(),!!this.value){if(this.$math.$(".empty"))return this.error=PLACEHOLDERS_ERROR;const e=parseInput(this.value);if(e.error)return this.error=e.error;const t=this.substitutions?e.expr.substitute(this.substitutions):e.expr;if(this.numeric&&checkNumeric(this.solution,t,this.numeric))return this.solve();if(this.solution&&Expression.numEquals(this.solution,t))return this.complete(e.expr);const s=checkVariables(t,this.vars,this.autocomplete);if(s)return this.error=s;if(this.validate){const t=this.validate(e.expr,Expression)||{};if(t.isCorrect)return this.complete(e.expr);if(t.error)return this.error=t.error}const a=checkFunctions(t,this.fns);if(a)return this.error=a}}complete(e){this.isDone||(this.isDone=!0,this.removeClass("has-error active"),this.addClass("done"),this.$textarea.blur(),!this.shortVar&&cleanGroups(this.$math,"mi"),cleanGroups(this.$math,"mn"),this.trigger("solve",{expr:e}))}solve(){this.$math.removeClass("empty"),this.$math.html=this.solution.toMathML(),this.complete(this.solution)}}registerElement("x-equation",Equation,{templateId:"#equation"});const KEYFRAMES={opacity:[0,1],transform:["translateX(-50px)","none"]},REPEAT_ERROR={error:"You\u2019ve already had this expression before. Try simplifying it."},SOLUTION="You have to fully simplify this expression. The correct solution is $0.";class EquationSystem extends CustomElement{created(){this.$table=this.$("table tbody"),this.lastRowContent=this.$table.$("tr:last-child").html}ready(){this.$step=this.getModel().$step,this.$equation=null,this.rowCount=1,this.previousAnswers=[],this.isSolved=!1,this.maxRows=+this.attr("max-rows")||6,this.steps=this.hasAttr("steps")?this.attr("steps").split("|"):[],this.hints=this.hasAttr("hints")?this.attr("hints").split("|"):[],this.removeAttr("steps"),this.removeAttr("hints"),this.setupEquation(this.$("x-equation"))}setupEquation(e){this.$equation=e,e.one("solve",t=>this.onSolveRow(t)),e.hints=this.hints,e.validate=e=>this.previousAnswers.includes(e.toString())?REPEAT_ERROR:this.validate?this.validate(e,Expression):{}}onSolveRow(e){let{expr:t}=e;if(this.trigger("solve-row",{expr:t,$math:this.$equation.$math}),this.isFinal&&this.isFinal(t))return this.trigger("solve");if(!this.isSolved){if(this.rowCount+=1,this.previousAnswers.push(t.toString()),this.rowCount>this.maxRows){const e=this.$equation.solution.toMathML();this.$step.addHint(SOLUTION.replace("$0",e)),this.trigger("solve")}const e=$N("tr",{html:this.lastRowContent},this.$table);e.animate(KEYFRAMES,400,500),this.setupEquation(e.$("x-equation")),setTimeout(()=>this.$equation.focus(),1200)}}solve(){if(this.isSolved=!0,this.steps.length){const e=this.$table.$("tr:last-child"),t=this.lastRowContent.replace(/<x-equation.*<\/x-equation>/,"<div class=\"math\"></div>");for(let a of this.steps){const s=$N("tr",{html:t},this.$table),n=s.$(".math"),i=Expression.parse(a);n.html=i.toMathML(),e.insertBefore(s),this.trigger("solve-row",{expr:i,$math:n})}}this.$equation.solve()}}registerElement("x-equation-system",EquationSystem);class Gallery extends CustomElement{ready(){function e(e){$=e,c.translateX(e),l.trigger("move",e)}function t(e){v=e,u.forEach(function(t,s){t.setClass("on",s>=e&&s<e+C)}),h.setClass("disabled",e===f-C),g.setClass("disabled",0===e),l.trigger("change",e)}function s(){_=l.width,C=y?Math.ceil(_/y):1,A=_/C,p.forEach(function(e){e.css("width",A+"px")}),c.css("width",f*A+"px"),e(-v*A),t(v)}function a(){S=Date.now()-P,e(T+E*ease(b,S/w))}function n(){!k&&S<w&&requestAnimationFrame(n),a()}function i(e){k=!1,S=0,T=$,E=-e*A-$,P=Date.now(),t(e),n()}function o(){b="quad",v<f-C&&i(v+1)}function r(){b="quad",0<v&&i(v-1)}const l=this,d=this.$(".wrapper"),c=this.$(".panel"),p=c.children,h=this.$(".next"),g=this.$(".back"),m=this.$(".dots"),u=p.map(()=>$N("div",{class:"dot"},m));let f=p.length,y=this.attr("slide-width")||null,v=0,$=0,b="quad",w=500,k=!1,_,C,A,S,T,E,P;h.on("click",o),g.on("click",r);let M=null,I=null,L=null,O=null;slide(d,{start(e){k=!0,M=$,I=e.x,O=L=I},move(t){L=O,O=t.x;let s=M-I+t.x,a=-(f-C)*A,n=0<s?s/4:s<a?a+(s-a)/4:s;e(n),l.css("pointer-events","none")},end(){let e=O-L,t=12<e?1:-12>e?-1:0;b="quad-out",i(clamp(Math.round(-$/A-t),0,f-C)),setTimeout(()=>l.css("pointer-events","auto"))}}),Browser.resize(s),this.goNext=o,this.goBack=r}}registerElement("x-gallery",Gallery,{templateId:"#gallery"});class Gameplay extends CustomElement{ready(){this.playing=!1,this.completed=!1,this.addClass("paused");let e=this.$(".slide-template");this.slideTemplate=e.html,e.remove(),this.$progress=this.$(".progress"),this.time=+this.attr("time")||8e3,this.slideGenerator=noop,this.$currentSlide=null,this.currentAnimation=null,this.$dots=this.$(".dots"),this.goal=(this.attr("goal")||"6/8").split("/").map(e=>+e),this.$dots.css("margin-left",-8*this.goal[1]+"px");for(let e=0;e<this.goal[1];++e)$N("div",{class:"dot"},this.$dots);this.history=[],this.$(".toggle").on("click",()=>{this[this.playing?"pause":"play"]()})}score(e){if(this.$dots.children[this.history.length].addClass(e?"green":"red"),this.history.push(e),!this.completed&&total(this.history)>=this.goal[0])return this.completed=!0,this.$("x-solved").enter(),this.trigger("score"),this.pause(),!0}makeSlide(){function e(t){s.trigger("error",t),n(!1)}if(!this.playing)return;if(this.history.length>=this.goal[1]){this.history.shift(),this.$dots.animate({transform:["none","translateX(-16px)"]},300).then(()=>{this.$dots.css("transform","none")});let e=this.$dots.children[0];e.exit("fade",300).then(()=>{e.remove()});let t=$N("div",{class:"dot"},this.$dots);t.enter("fade",300)}if(this.$currentSlide){let e=this.$currentSlide;e.animate({transform:["none","translateX(-100%)"]},400).then(()=>{e.remove()})}let s=$N("div",{class:"slide",html:this.slideTemplate},this);s.animate({transform:["translateX(100%)","none"]},400);let a=this.time*(1-total(this.history)/this.goal[1]/2),t=this.$progress.animate({width:["100%","0%"]},a,400,"linear");const n=e=>{s.addClass("done");let a=this.score(e);t.cancel(),a||setTimeout(()=>this.makeSlide(),1e3)};t.then(e),this.$currentSlide=s,this.currentAnimation=t,this.slideGenerator(s,function(t){s.trigger("success",t),n(!0)},e)}setFirstSlide(e){this.$currentSlide=$N("div",{class:"slide",html:this.slideTemplate},this),e(this.$currentSlide)}play(){this.playing||(this.playing=!0,this.removeClass("paused"),this.makeSlide(),this.$("x-solved").hide())}pause(){this.playing&&(this.playing=!1,this.currentAnimation.cancel(),this.addClass("paused"))}}registerElement("x-gameplay",Gameplay,{templateId:"#gameplay"});class GeoElement{constructor(e,t,s,a){this.x=t,this.name=a||e.model.name(),this.$geopad=e,this.removed=!1,this.$el=s||this.makeEl(),e.elements.set(this.name,this),this.$el.hasAttr("label")&&this.setLabel(this.$el.attr("label")),this.val=t(e.model),this.val&&e.model.set(this.name,this.val),e.model.watch(e=>{if(!this.removed&&(this.val=this.x(e),this.$el.setClass("hidden",!this.val),(this.val||this.name in e)&&(e[this.name]=this.val),!!this.val)){const t=this.val.transform(this.$geopad.grid);this.update(t),this.$label&&this.updateLabel(e,t)}})}setLabel(e,t,s){void 0===t&&(t=null),void 0===s&&(s=null),this.$label||(this.$label=makeLabel(this.$el,this.$geopad,t)),this.labelStr=parse(e),this.labelPosition=s?parse(s,!0):null}updateLabel(e,t){this.$label.text=this.labelStr(e),this.labelPosition?this.$label.setTransform(this.labelPosition(e).shift(0,5)):this.$label.setTransform(...labelPosn(t,this.$el,this.$geopad))}remove(e){void 0===e&&(e=400),this.$label&&this.$label.exit(),this.exit(e).then(()=>{this.$geopad.elements.delete(this.name),this.removed=!0})}}class GeoPath extends GeoElement{constructor(e,t,s,a){super(e,t,s,a),this.points=[]}update(e){try{this.$el.draw(e,{box:this.$geopad.box})}catch(t){this.$el.setAttr("d","")}}makeEl(){return $N("path",{},this.$geopad.$paths)}exit(e){return this.$el.exit("draw",e)}}class GeoPoint extends GeoElement{makeEl(){return $N("circle",{r:4},this.$geopad.$points)}exit(e){return this.$el.exit("pop",e)}update(e){this.$el.setCenter(e),this.$halo&&this.$halo.setCenter(e)}addHalo(){this.$halo=$N("circle",{class:"halo",r:18},this.$geopad.$pulses),this.$halo.setCenter(this.$el.center),this.$halo.enter("pop")}removeHalo(){this.$halo&&this.$halo.exit("pop").then(()=>{this.$halo.remove(),this.$halo=null})}}class GeoMovablePoint extends GeoPoint{constructor(e,t,s,a,n){let i=!0;const o=e=>{const s=i?t:e[this.name];return n?n(e).project(s):s};super(e,o,s,a),i=!1,this.$el.hasClass("pulsate")&&this.pulsate(),this.project=t=>{n=t,e.model.update()},this.locked=!1}pulsate(){this.$pulse=$N("circle",{class:"pulse",r:8},this.$geopad.$pulses),this.$pulse.setCenter(this.$el.center),this.$el.one("mouseover pointerdown",()=>this.$pulse.remove())}lock(){this.$el.removeClass("move"),this.$el.setAttr("r",4),this.locked=!0}makeEl(){return $N("circle",{class:"move",r:8},this.$geopad.$points)}}class GeoTool{constructor(e){this.$geopad=e,this.startPoint=null,this.endPosn=null,this.pending=null}start(){}move(){}end(){}click(){}cancel(){}addMovablePoint(e){if(this.$geopad.noPoints)return{val:e};const t=new GeoMovablePoint(this.$geopad,e);return this.$geopad.trigger("add:point",t),t}}class MoveTool extends GeoTool{start(e){e&&e instanceof GeoMovablePoint&&!e.locked&&(this.startPoint=e)}move(e,t){this.startPoint&&!this.startPoint.val.equals(t)&&this.$geopad.model.set(this.startPoint.name,t)}end(){this.startPoint=null,this.$geopad.trigger("moveEnd",this.startPoint)}}class PointTool extends MoveTool{click(e,t){e||this.addMovablePoint(t)}}class DrawTool extends GeoTool{constructor(e){super(e),this.clicked=!1}start(e,t){if(!this.pending){this.startPoint=e||this.addMovablePoint(t),this.endPosn=this.startPoint.val;this.pending=new GeoPath(this.$geopad,()=>this.constructor.path(this.startPoint.val,this.endPosn)),this.pending.$el.addClass("thin"),this.$geopad.trigger("begin:path",this.pending)}}move(e,t){this.pending&&(this.endPosn=e?e.val:t,this.$geopad.model.update())}end(e,t){if(!this.pending)return;if(e===this.startPoint)return this.cancel();const s=this.pending;s.points=[this.startPoint,e||this.addMovablePoint(t)],s.$el.removeClass("thin"),s.x=()=>this.constructor.path(s.points[0].val,s.points[1].val),this.$geopad.model.update(),this.$geopad.trigger("add:path",s),this.startPoint=this.endPosn=this.pending=null,this.clicked=!1}click(e,t){return this.pending?this.clicked?void this.end(e,t):this.clicked=!0:void 0}hover(e,t){this.pending&&this.move(e,t)}cancel(){this.pending&&this.pending.remove(),this.startPoint=this.endPosn=this.pending=null,this.clicked=!1}}class LineTool extends DrawTool{static path(e,t){return new Segment(e,t)}}class CircleTool extends DrawTool{static path(e,t){const s=Point.distance(e,t);return new Circle(e,s)}}class RectangleTool extends DrawTool{static path(e,t){return new Rectangle(e,t.x-e.x,t.y-e.y)}}class PerpBisectorTool extends DrawTool{static path(e,t){return new Segment(e,t).perpBisector}}class AngleBisectorTool extends GeoTool{click(e,t){if(e||(e=this.addMovablePoint(t)),!this.startPoint)this.startPoint=[e],e.addHalo();else if(1===this.startPoint.length){this.startPoint.push(e),e.addHalo(),this.endPosn=e.val;this.pending=new GeoPath(this.$geopad,()=>new Angle(this.startPoint[0].val,this.startPoint[1].val,this.endPosn).bisector),this.$geopad.trigger("begin:path",this.pending)}else if(2===this.startPoint.length){const t=[...this.startPoint,e];this.pending.$el.removeClass("thin"),this.pending.x=()=>new Angle(...t.map(e=>e.val)).bisector,this.$geopad.model.update(),this.$geopad.trigger("add:path",this.pending);for(let e of this.startPoint)e.removeHalo();this.startPoint=this.endPosn=this.pending=null}}hover(e,t){this.pending&&(this.endPosn=e?e.val:t,this.$geopad.model.update())}cancel(){if(this.pending){this.pending.remove();for(let e of this.startPoint)e.removeHalo()}this.startPoint=this.endPosn=this.pending=null}}const COMPASS="M100,50h0l-5.2-4.9L52.6,10.2v-9C52.6.6,51.4,0,50,0s-2.6.6-2.6,1.2v9L5.2,45.1,0,50H0l6.6-3L35,25.9H65L93.4,47ZM38.4,23.5,50,14.8l11.6,8.7Z",RULER="M0,0V8H100V0ZM7,6A2,2,0,1,1,9,4,2,2,0,0,1,7,6Z",MODEL_FUNCTIONS={pi:Math.PI,point:(e,t)=>new Point(e,t),angle:(e,t,s)=>new Angle(e,t,s),line:(e,t)=>new Line(e,t),ray:(e,t)=>new Ray(e,t),segment:(e,t)=>new Segment(e,t),circle:(e,t)=>new Circle(e,t),arc:(e,t,s)=>new Arc(e,t,s),sector:(e,t,s)=>new Sector(e,t,s),polygon:function polygon(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];return new Polygon(...t)},polyline:function polyline(){for(var e=arguments.length,t=Array(e),s=0;s<e;s++)t[s]=arguments[s];return new Polyline(...t)},triangle:(e,t,s)=>new Triangle(e,t,s),rectangle:(e,t,s)=>new Rectangle(e,t,s),distance:Point.distance,round:function round(e,t){return void 0===t&&(t=0),_round(e,t)},sqrt:e=>Math.sqrt(e),intersections};class Geopad extends CustomElement{ready(){function t(e){return e.clamp(5,s-5,5,a-5).transform(i).round()}const s=+this.attr("width")||this.width,a=+this.attr("height")||+this.attr("width")||this.height;this.box=new Rectangle(new Point(0,0),s,a).polygon,this.css({width:s+"px",height:a+"px"}),this.hasClass("sticky")&&this.css("top","calc(50vh - "+a/2+"px)"),this.$svg=this.children.filter(e=>"SVG"===e.tagName)[0],this.model=this.getModel(),this.model.assign(MODEL_FUNCTIONS),this.elements=new Map,this.findIntersections=this.hasAttr("intersect"),this.noPoints=this.hasAttr("no-points"),this.cachedIntersections=null,this.model.watch(()=>this.cachedIntersections=null);const n=+this.attr("grid")||null,i=n?[[1/n,0,-.5],[0,1/n,-.5]]:null;if(this.grid=n?[[n,0,n/2],[0,n,n/2]]:null,n){const e=$N("g",{class:"grid"},this.$svg);for(let t=n/2;t<s;t+=n)$N("line",{x1:t,x2:t,y1:0,y2:a},e);for(let t=n/2;t<a;t+=n)$N("line",{x1:0,x2:s,y1:t,y2:t},e)}this.$paths=$N("g",{class:"paths"},this.$svg),this.$pulses=$N("g",{class:"pulses"},this.$svg),this.$points=$N("g",{class:"points"},this.$svg),this.$labels=$N("g",{class:"labels"},this.$svg);for(const e of this.$svg.$$("path[x], circle")){const t=e.hasAttr("x")?parse(e.attr("x"),!0):null,s=e.hasAttr("project")?parse(e.attr("project"),!0):null,a=e.attr("name")||this.model.name();"PATH"===e.tagName?(e.moveTo(this.$paths),new GeoPath(this,t,e,a)):(e.moveTo(this.$points),e.hasClass("move")?(e.setAttr("r",8),new GeoMovablePoint(this,e.center,e,a,s)):t&&(e.setAttr("r",4),new GeoPoint(this,t,e,a)))}const o={move:new MoveTool(this),point:new PointTool(this),line:new LineTool(this),circle:new CircleTool(this),perpBisector:new PerpBisectorTool(this),angleBisector:new AngleBisectorTool(this),rectangle:new RectangleTool(this)};this.$tools=this.$(".tools");let r=o[this.$tools.$active.data.tool];this.$tools.on("change",e=>r=o[e.data.tool]),slide(this.$svg,{start:e=>r.start(this.vertexAt(e),t(e)),move:e=>r.move(this.vertexAt(e),t(e)),end:(e,s)=>{const a=10>Point.distance(e,s)?"click":"end";r[a](this.vertexAt(e),t(e))}}),this.$svg.on("mousemove",s=>{if(r.hover){const e=svgPointerPosn(s,this.$svg);r.hover(this.vertexAt(e),t(e))}}),Browser.onKey("escape",()=>r.cancel())}lock(){this.$svg.css("pointer-events","none")}unlock(){this.$svg.css("pointer-events","all")}get points(){const e=Array.from(this.elements.values());return e.filter(t=>t instanceof GeoPoint&&t.val&&!t.removed)}get paths(){const e=Array.from(this.elements.values());return e.filter(t=>t instanceof GeoPath&&t.val&&!t.removed)}get intersections(){if(!this.findIntersections)return[];if(this.cachedIntersections)return this.cachedIntersections;const e=this.paths,t=[];for(let s of e)for(let a of e){if(s===a)continue;const e=intersections(s.val,a.val);for(let n=0;n<e.length;++n){const i=()=>intersections(s.val,a.val)[n];t.push({val:e[n],x:i})}}return this.cachedIntersections=t,t}vertexAt(e){let t=null,s=1/0,a=this.grid?this.grid[0][0]/2:20;const n=this.points,i=n.filter(e=>e instanceof GeoMovablePoint),o=n.filter(e=>!(e instanceof GeoMovablePoint));for(let n of[...i,...o,...this.intersections]){const i=Point.distance(e,n.val.transform(this.grid));i<a&&i<s-1&&(s=i,t=n)}return t instanceof GeoPoint?t:t?this.drawPoint(t.x,{animate:!1}):void 0}setActiveTool(e){this.$tools.makeActive(this.$(".tool[data-tool=\""+e+"\"]"))}drawPath(e,t){let{classes:s="",animate:a=0,target:n="",name:i=""}=void 0===t?{}:t;const o=$N("path",{class:s,target:n},this.$paths);isString(e)&&(e=parse(e,!0));const r=new GeoPath(this,e,o,i);return a&&o.enter(o.hasClass("fill")?"fade":"draw",a),r}drawPoint(e,t){let{classes:s="",animate:a=!0,target:n="",name:i=""}=void 0===t?{}:t;const o=$N("circle",{r:4,class:s,target:n},this.$points);isString(e)&&(e=parse(e,!0));const r=new GeoPoint(this,e,o,i);return a&&o.enter("pop"),r}drawMovablePoint(e,t){let{classes:s="",animate:a=!0,target:n="",name:i=""}=void 0===t?{}:t;const o=$N("circle",{r:4,class:s,target:n},this.$points),r=new GeoMovablePoint(this,e,o,i);return a&&o.enter("pop"),r}animatePoint(e,t,s){void 0===s&&(s=400);const a=new Line(this.model[e],t);animate(t=>this.model.set(e,a.at(t)),s)}animateConstruction(e,t){void 0===t&&(t=2e3);let s=this.elements.get(e),a=s.val;if(a instanceof Circle&&(a=a.arc),a instanceof Line){this.$ruler||(this.$ruler=$N("path",{d:RULER,class:"sketch"},this.$svg));const e=getToolTransform(a.at(-.1),12,a.angle-.3,1.2*a.length),n=getToolTransform(a.at(-.1),12,a.angle,1.2*a.length);return this.$ruler.show(),s.$el.hide(),this.$ruler.animate({opacity:[0,1],transform:[e,n]},500).then(()=>s.$el.enter("draw",t)).then(()=>this.$ruler.animate({opacity:[1,0],transform:[n,e]},500))}if(a instanceof Arc){this.$compass||(this.$compass=$N("path",{d:COMPASS,class:"sketch"},this.$svg));const e=getToolTransform(a.c,50,a.startAngle,1.5*a.radius),n=getToolTransform(a.c,50,a.startAngle,a.radius),i=getToolTransform(a.c,50,a.startAngle+a.angle,a.radius),o=getToolTransform(a.c,50,a.startAngle+a.angle,1.5*a.radius);return this.$compass.show(),s.$el.hide(),this.$compass.animate({opacity:[0,1],transform:[e,n]},500).then(()=>(s.$el.enter("draw",t),this.$compass.animate({transform:[n,i]},t,0,"linear"))).then(()=>this.$compass.animate({opacity:[1,0],transform:[i,o]},500))}}showGesture(e,t){this.$gesture||(this.$gesture=$N("x-gesture",{},this)),this.$gesture.stop(),e=parse(e,!0)(this.model),this.$gesture.from=e,t?(t=parse(t,!0)(this.model),this.$gesture.start(t.subtract(e))):this.$gesture.start(),this.one("click mouseover pointerdown",()=>this.$gesture.stop())}waitForPath(e){const t=defer(),s=()=>{for(let a of this.paths)if(e(a))return t.resolve(a),void this.off("add:path moveEnd",s)};return this.on("add:path moveEnd",s),t.promise}waitForPaths(e,t){let{onCorrect:s,onIncorrect:a,onHint:n,onComplete:o,maxErrors:r=4}=t;const l=e.map(e=>isString(e)?parse(e,!0):()=>e),d=tabulate(!1,e.length);let c=0,p=!1;this.on("add:path",e=>{if(!p){const t=l.findIndex(t=>t(this.model).equals(e.val));if(0<=t)return d[t]?e.remove(0):(d[t]=!0,s&&s(e,t),c=0,void(d.every(e=>e)&&(p=!0,o&&o(!1))));if(e.remove(),!(1>e.val.length))if(c+=1,c>=r){const e=d.findIndex(e=>!e),t=this.drawPath(l[e],{animate:1e3});d[e]=!0,n&&n(t,e),c=0,d.every(e=>e)&&(p=!0,o&&o(!0))}else a&&a(e)}})}}registerElement("x-geopad",Geopad,{templateId:"#geopad",model:!0});class Gesture extends CustomElement{created(){this.doAnimation=!1,this.from=this.$end=this.$target=null,this.slide=parseAttr(this.attr("slide")),this.offset=parseAttr(this.attr("offset"))}ready(){this.$target=$(this.attr("target")),this.$target&&(this.$target.on("click pointerdown",()=>this.stop()),this.hasAttr("start")&&this.start())}start(e){this.doAnimation||(this.doAnimation=!0,e&&(this.slide=e),this.slide||this.$end?this._runSlideAnimation():this._runClickAnimation())}startSlide(e,t){this.$target=e,this.$end=t,this.start()}stop(){this.doAnimation=!1}_runSlideAnimation(){this.show();let e=this.from||getPosition(this,this.$target);this.offset&&(e=e.add(this.offset));const t=this.slide?e.add(this.slide):getPosition(this,this.$end),s="translate("+(e.x-15)+"px,"+(e.y-10)+"px)",a="translate("+(t.x-15)+"px,"+(t.y-10)+"px)";this.animate({transform:[s+" scale(2)",s],opacity:[0,1]},300).then(()=>this.animate({transform:[s,a]},1e3)).then(()=>this.animate({transform:[a,a+" scale(2)"],opacity:[1,0]},300)).then(()=>{this.hide(),setTimeout(()=>{this.doAnimation&&this._runSlideAnimation()},1e3)})}_runClickAnimation(){this.show();let e=this.from||getPosition(this,this.$target);this.offset&&(e=e.add(this.offset));const t="translate("+(e.x-15)+"px,"+(e.y-10)+"px)";this.animate({transform:[t+" scale(2)",t],opacity:[0,1]},500).then(()=>this.animate({transform:[t,t+" scale(2)"],opacity:[1,0]},500,200)).then(()=>{this.hide(),setTimeout(()=>{this.doAnimation&&this._runClickAnimation()},1e3)})}}registerElement("x-gesture",Gesture,{templateId:"#gesture"});const glossary=JSON.parse($("#glossary").text),bios=JSON.parse($("#bios").text),WIDTH_SMALL=600,$overlay=$N("div",{class:"gloss-overlay"},$body),$floatingWrap=$N("div",{class:"gloss-floating-wrap"},$body),$floating=$N("div",{class:"gloss-floating"},$floatingWrap);let activeGloss=null;Browser.resize(()=>{activeGloss&&activeGloss.hide()});class Gloss extends CustomElement{ready(){this.xid=this.attr("xid"),this.$target=this.$(".target"),this.$popup=this.$(".popup"),this.$popup.html=this.body()||"",this.setClass("left",Browser.width>WIDTH_SMALL&&this.$target.bounds.left+this.$popup.width>Browser.width-15),this.on("hover",{enter:()=>this.show(),exit:()=>this.hide(),delay:100,$clickTarget:this.$target,preventMouseover:()=>Browser.width<=WIDTH_SMALL})}show(){if(activeGloss=this,this.addClass("on"),Browser.width<=WIDTH_SMALL)return $floating.html=this.body(),$floatingWrap.enter("pop",300),void $overlay.enter("fade",300);const e=this.$target.bounds,t=this.$popup.width,s=this.$popup.height,a=e.top+e.height+s<Browser.height-10,n=e.top-s>(window.isWebView?10:54);this.setClass("top",n&&!a),this.setClass("left",e.left+t>Browser.width-15)}hide(){activeGloss=null,this.removeClass("on"),Browser.width<=WIDTH_SMALL&&($floatingWrap.exit("pop",300),$overlay.exit("fade",300))}body(){const e=glossary[this.xid];if(!e)return console.warn("missing gloss:",this.xid);let t=e.text;if(e.image&&(t+="<img class=\"gloss-img\" src=\"/resources/shared/glossary/"+e.image+"\"/>"),e.link&&!window.isWebView){const s=location.pathname===e.link.split("#")[0];s||(t+="<p><a href=\""+e.link+"\" target=\"_blank\">Learn more\u2026</a></p>")}return t}}class Bio extends Gloss{body(){const e=bios[this.xid];if(!e)return console.warn("missing bio:",this.xid);const t="<img class=\"bio-img\" src=\"/resources/shared/bios/"+this.xid+".jpg\"/>";return t+e.bio}}registerElement("x-gloss",Gloss,{templateId:"#gloss"}),registerElement("x-bio",Bio,{templateId:"#gloss"});class IconBtn extends CustomElement{ready(){const e=this.$("use"),t=e.attr("xlink:href").replace("#xxx","#");e.setAttr("xlink:href",t+this.attr("icon")),this.on("attr:icon",(s)=>{let{newVal:a}=s;return e.setAttr("xlink:href",t+a)})}}registerElement("x-icon-btn",IconBtn,{templateId:"#icon-btn",attributes:["icon"]});let isOpen=!1,transform={},$activeImg=null;const $lightbox=$N("div",{class:"lightbox-overlay"},$body),$lightboxImg=$N("div",{class:"lightbox-img"},$lightbox);$lightbox.on("click",closeLightbox),Browser.onKey("escape",closeLightbox),$lightbox.on("scrollwheel touchmove",function(t){t.preventDefault(),t.stopPropagation()}),Browser.onKey("space up down left right pagedown pageup",function(t){isOpen&&(t.preventDefault(),t.stopPropagation())});class Media extends CustomElement{ready(){const e=this.attr("src"),t=this.$(".wrap"),s=this.attr("width"),a=this.attr("height");this.css("width",s+"px"),t.css("padding-bottom",100*(+a/+s)+"%");const n=t.$("img");n.setAttr("src",e),e.endsWith(".gif")&&n.on("click",()=>n.setAttr("src",e));const i=t.$(".credit"),o=this.attr("credit");o?i.text=o:i.remove();const r=t.$(".zoom");if(this.hasAttr("lightbox")){this.addClass("interactive");const t=e.replace(/\.(?=[^.]*$)/,"-large.");this.on("click",()=>openLightbox(this,e,t))}else r.remove()}}registerElement("x-media",Media,{templateId:"#media"});class Notepad extends CustomElement{ready(){function e(e){let{x:t,y:a}=e,i=$N("div",{contenteditable:"True"},s);i.css("left",t-6+"px"),i.css("top",a-26+"px"),i.focus(),n=i,i.on("blur",function(){i.text||i.remove()})}function t(e,t){if(!i){let e=$N("g",{},a);$N("line",{x1:t.x,y1:t.y,class:"stroke"},e),$N("line",{x1:t.x,y1:t.y,class:"halo"},e),e.on("pointerdown",function(){i=o=e,e.addClass("selected")}),e.on("clickAway",function(){e.removeClass("selected")}),i=e}i.children.forEach(t=>{t.setAttr("x2",e.x),t.setAttr("y2",e.y)})}let s=this.$(".text"),a=this.$("svg"),n=null,i=null,o=null;slide(a,{start:function start(){n&&n.blur(),n=i=null},move:function move(e,s){if(o);else 10<Point.distance(s,e)?t(e,s):i&&(i.remove(),i=null)},end:function end(t,s){!o&&10>Point.distance(s,t)&&e(t),o=null}})}}registerElement("x-notepad",Notepad,{template:"<div class=\"text\"></div><svg></svg>"});class Parallax extends CustomElement{ready(){function e(i){if(!(i.top<a||i.top>n)){const e=(i.top-a)/(n-a)*(s?50:33);t.transform="translateY("+e+"%)"}}const t=this.$(".image"),s=50>this.positionTop;let a,n;t.css({"background-image":"url(\""+this.attr("background")+"\")",height:s?"100%":"150%"});const i=(e)=>{let{height:t}=e;const s=this.positionTop;a=Math.max(0,s-t),n=s+this.height};Browser.resize(i),$body.on("scroll",e)}}registerElement("x-parallax",Parallax,{templateId:"#parallax"});class Picker extends CustomElement{ready(){const e=this.getModel().$step;this.$items=this.children,this.itemsClicked=this.$items.map(()=>!1),this.correctCount=0,this.solvedCount=0,this.isSolved=!1,this.$items.forEach((t,s)=>{const a=t.data.error,n=a?"incorrect":"correct";a||(e.goals.push("picker-"+s),this.correctCount+=1),t.one("click",()=>{this.itemsClicked[s]||this.isSolved||(e.addHint(a||"correct",{className:n}),t.addClass(n),!a&&(this.solvedCount+=1,e.score("picker-"+s),this.checkSolved()))})})}restore(e){const t=e.map(e=>+e.slice(7));for(let s of t)this.itemsClicked[s]=!0,this.$items[s].addClass("correct");this.solvedCount=t.length,this.checkSolved()}checkSolved(){this.solvedCount<this.correctCount||(this.addClass("solved"),this.isSolved=!0)}}registerElement("x-picker",Picker);class PlayBtn extends CustomElement{ready(){this.visible=!0,this.on("click",()=>{this.play(),setTimeout(()=>this.trigger("play"),400)})}play(){this.visible&&(this.visible=!1,this.exit("pop",400))}reset(){this.visible||(this.visible=!0,setTimeout(()=>this.enter("pop"),400))}}class PlayToggle extends CustomElement{ready(){this.playing=!1,this.icon=this.$("x-icon-btn"),this.$("button").on("click",()=>this.toggle())}toggle(){this.playing?this.pause():this.play()}play(){this.playing||(this.playing=!0,this.icon.setAttr("icon","pause"),this.trigger("play"))}pause(){this.playing&&(this.playing=!1,this.icon.setAttr("icon","play"),this.trigger("pause"))}}registerElement("x-play-toggle",PlayToggle,{templateId:"#play-toggle"}),registerElement("x-play-btn",PlayBtn,{templateId:"#play-btn"});class Popup extends CustomElement{ready(){this.isOpen=!1,this.animation=this.attr("animation")||"pop",this.duration="pop"===this.animation?300:200,this.$bubble=this.$(".popup-body"),this.$bubble.hide();const e=this.$(".popup-target");e.on("click",()=>this.toggle()),this.on("clickOutside",()=>this.close());for(const e of this.$bubble.$$("a"))e.on("click",()=>this.close())}toggle(){this.isOpen?this.close():this.open()}open(){this.isOpen||(this.isOpen=!0,this.addClass("active"),this.$bubble.enter(this.animation,this.duration))}close(){this.isOpen&&(this.isOpen=!1,this.removeClass("active"),this.$bubble.exit(this.animation,this.duration))}}registerElement("x-popup",Popup);const PADDING=12;class Progress extends CustomElement{ready(){this.r=+this.attr("r")||10,this.r1=this.r+PADDING,this.$svg=$N("svg",{width:2*this.r1,height:2*this.r1},this),this.completed=!1,this.$progress=$N("path",{class:"pie",d:getProgress(this.r),"stroke-width":this.r},this.$svg),this.setProgress(+this.attr("p"),!1)}setProgress(e,t){if(void 0===t&&(t=!0),.99<e)return this.complete(t);const s=Math.PI*this.r;this.$progress.css("stroke-dasharray",e*s+" "+s)}complete(e){if(void 0===e&&(e=!0),this.completed)return;if(this.completed=!0,this.$progress.setAttr("class","done"),this.$progress.setAttr("d",getCheck(this.r)),!e)return;const t=$N("g",{transform:"translate("+this.r1+" "+this.r1+")"},this.$svg),a=tabulate(()=>$N("line",{},t),18);animate(e=>{const t=this.r+PADDING*ease("quint-out",e),n=this.r+PADDING*e;for(let o=0;18>o;++o){const e=Math.cos(2*Math.PI*o/18),i=Math.sin(2*Math.PI*o/18);a[o].setLine({x:e*t,y:i*t},{x:e*n,y:i*n})}},800).then(()=>t.remove())}}registerElement("x-progress",Progress);class ScaleBox extends CustomElement{ready(){const e=this.children[0],t=+this.attr("width")||760;e.css("width",t+"px");const s=e.height;Browser.resize(()=>{const a=this.width/t;this.css("height",s*a+"px"),e.css("transform","scale("+a+")")})}}const template="<div><slot></slot></div>";registerElement("x-scale-box",ScaleBox,{template:"<div><slot></slot></div>"});class Slider extends CustomElement{ready(){this.steps=+this.attr("steps"),this.speed=+this.attr("speed")||1,this.current=0,this.playing=!1;const e=this.$(".bar"),t=this.$(".knob");this.drag=new Draggable(t,e,{moveY:!1}),this.drag.on("start",()=>this.playing=!1),this.drag.on("move",t=>{const e=Math.round(t.x/this.drag.width*this.steps);e===this.current||(this.current=e,this.trigger("move",e))}),this.drag.on("end",()=>this.trigger("slide-end"));const s=this.$(".play");this.hasAttr("no-play")?s.remove():s.on("click",()=>this.play()),this.on("attr:steps",t=>this.steps=+t.newAttr)}play(){if(this.playing)return;this.playing=!0,this.current>=this.steps&&this.set(0);const e=()=>{const t=this.drag.position.x;this.playing&&t<this.drag.width?window.requestAnimationFrame(e):this.playing&&(this.playing=!1,this.trigger("slide-end"));const s=Math.min(this.drag.width,t+2*this.speed);this.drag.setPosition(s,0)};e()}set(e){this.drag.setPosition(e*this.drag.width/this.steps,0)}moveTo(e,s){if(void 0===s&&(s=300),e===this.current)return;const a=this.current;animate(t=>this.set(a+(e-a)*t),s).then(()=>this.trigger("slide-end"))}}registerElement("x-slider",Slider,{attributes:["steps"],templateId:"#slider"});class Slideshow extends CustomElement{ready(){this.$legend=this.$(".legend-box"),this.$steps=this.$legend.children,this.$back=this.$(".back"),this.$next=this.$(".next"),this.locked=!1;const e=this.$(".dots");this.$dots=this.$steps.map(()=>$N("div",{class:"dot"},e)),this.length=this.$steps.length,this.current=0;const t=this.$steps.map(e=>words(e.data.needs||""));this.isReady=function(e){let s=t[this.current+1]||[];return s.every(t=>e.scores.has(t))},this.$back.on("click",()=>this.goBack()),this.$next.on("click",()=>this.goNext()),this.$steps[0].show(),this.$dots[0].addClass("on")}go(e){if(!(this.locked||0>e||e>this.length-1||e===this.current)){this.locked=!0,setTimeout(()=>this.locked=!1,600),this.$back.setClass("disabled",0===e),this.$next.setClass("disabled",e===this.length-1),this.$dots[this.current].removeClass("on"),this.$dots[e].addClass("on"),this.$steps[e].show();const t=this.$steps[e].height+"px";this.$steps[e].hide(),this.$steps[this.current].exit("fade",300).then(()=>this.$steps[e].enter("fade"),300),this.$legend.animate({height:t},600).then(()=>this.$legend.css("height","auto")),this.current=e,this.trigger("step",e)}}goNext(){this.locked||(this.go(this.current+1),this.trigger("next",this.current))}goBack(){this.locked||(this.go(this.current-1),this.trigger("back",this.current))}}registerElement("x-slideshow",Slideshow,{templateId:"#slideshow"});const colours=loop(Colour.rainbow(8)),images=loop(["badge","homework","laurels","lightbulb","owl","scroll","trophy"]);class Solved extends CustomElement{ready(){this.visible=!1,this.$svg=this.$("use"),this.$text=this.$(".message"),this.$step=this.getModel().$step,this.on("click",()=>this.exit())}enter(){if(this.visible)return;this.visible=!0;const e=this.$step.addHint("correct"),t=colours(),s=images();this.css("background-color",t),this.$text.text=e.text.replace(/<.*?>/g,""),this.$svg.setAttr("xlink:href","/sketch.svg#"+s),Browser.replaceSvgImports(),enter(this,"pop",300,600)}exit(){this.visible&&(this.visible=!1,exit(this,"pop",300))}}registerElement("x-solved",Solved,{templateId:"#solved"});class Sortable extends CustomElement{ready(){var e=this;this.items=this.children.map(e=>new Draggable(e,this,{moveX:!1,useTransform:!0}));const t=function(t){void 0===t&&(t=null);let s=cumulative(e.items.map(e=>e.h+10));e.items.forEach(function(e,a){e!==t&&e.setPosition(0,s[a-1]||0)})},s=()=>this.items.every((e,t)=>+e.$el.data.index===t)||this.items.every((e,t)=>+e.$el.data.index==this.items.length-t-1);for(let e of this.items)e.on("drag",()=>{this.items=sortByFn(this.items,t=>t.position.y-(t===e?10:0)),t(e)}),e.on("end",()=>{t(),s()&&this.solve()});Browser.resize(()=>{for(let e of this.items)e.h=e.$el.height;const e=total(this.items.map(e=>e.h));this.css("height",e+10*this.items.length-10+"px"),t()})}solve(){this.trigger("solve"),this.addClass("solved");for(let e of this.items)e.disabled=!0}}registerElement("x-sortable",Sortable);const colours$1=loop(["#b30469","#1f7aff","#31b304","#ff941f"]);class Particle{constructor(e){this.x=Math.random()*Browser.width,this.y=(Math.random()-1)*Browser.height,this.r=uniform(10,30),this.color=colours$1(),this.index=e,this.tilt=Math.floor(10*Math.random())-10,this.tiltAngleIncrement=.07*Math.random()+.05,this.tiltAngle=0}draw(e){e.beginPath(),e.lineWidth=this.r/2,e.strokeStyle=this.color,e.moveTo(this.x+this.tilt+this.r/4,this.y),e.lineTo(this.x+this.tilt,this.y+this.tilt+this.r/4),e.stroke()}update(e,t){this.tiltAngle+=this.tiltAngleIncrement,this.y+=(Math.cos(e)+3+this.r/2)/2,this.x+=Math.sin(e),this.tilt=15*Math.sin(this.tiltAngle-this.index/3),-20>this.x?(this.x=-20,this.y=Math.random()*Browser.height,this.tilt=Math.floor(10*Math.random())-20):this.x>Browser.width+20?(this.x=Browser.width+20,this.y=Math.random()*Browser.height,this.tilt=Math.floor(10*Math.random())-20):t&&this.y>Browser.height&&(this.x=Math.random()*Browser.width,this.y=-10,this.tilt=Math.floor(10*Math.random())-20)}}const style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 9999";let $confetti;const stepFunctions=window._stepFunctions||{};class Step extends CustomElement{created(){this.isShown=!1,this.isCompleted=!1,this.goals=words(this.attr("goals")||""),this.scores=new Set,this.initialData=null,this.model=observable({$step:this}),this.tools={confetti}}ready(){this.$course=(this.getModel()||{}).$course,this.$blanks=this.$$("x-blank, x-blank-input"),this.$blanks.forEach((e,t)=>{this.goals.push("blank-"+t),e.on("valid",()=>{this.addHint("correct"),this.score("blank-"+t)}),e.on("invalid",()=>this.addHint("incorrect")),e.on("hint",e=>this.addHint("Hmmm\u2026 maybe try "+e+"?"))}),this.$equations=this.$$("x-equation, x-equation-system").filter(e=>!e.hasParentTag("X-EQUATION-SYSTEM")),this.$equations.forEach((e,t)=>{this.goals.push("eqn-"+t),e.on("solve",()=>{this.addHint("correct"),this.score("eqn-"+t)})}),this.$reveals=this.$$(".reveal");for(let e of this.$reveals){e.data.display="visibility";const t=+e.data.duration||400,s=+e.data.delay||0;this.onScore(e.data.when,()=>{"visible"===e.css("visibility")||e.enter(e.data.animation||"fade",t,s).then(()=>e.css("opacity",""))})}this.$nextBtn=this.$$(".next-step"),this.$nextBtn.forEach((e,t)=>{this.goals.push("next-"+t),this.onScore("next-"+t,()=>e.exit("pop")),e.one("click",()=>this.score("next-"+t))});for(let e of this.$$(".check[data-when]"))this.onScore(e.data.when,()=>e.addClass("visible"));for(const e of this.$$(".step-target"))e.on("hover",{enter:()=>{const t=this.$$("[target~=\""+e.data.to+"\"]");for(let e of t)e.addClass("focus");this.addClass("focus")},exit:()=>{for(let e of this.$$(".focus"))e.removeClass("focus");this.removeClass("focus")}});this.$slides=this.$("x-slideshow"),this.$slides&&(this.goals.push(...tabulate(e=>"slide-"+e,this.$slides.length-1)),this.$slides.on("next",e=>this.score("slide-"+(e-1)))),this.$sortables=this.$$("x-sortable"),this.$sortables.forEach((e,t)=>{this.goals.push("sortable-"+t),e.on("solve",()=>{this.addHint("correct"),this.score("sortable-"+t)})}),this.$gameplay=this.$("x-gameplay"),this.$gameplay&&(this.goals.push("gameplay"),this.$gameplay.on("score",()=>this.score("gameplay"))),this.$$("x-slider").forEach((e,t)=>{this.goals.push("slider-"+t),e.on("slide-end",()=>this.score("slider-"+t))}),this.$codeChecker=this.$("x-code-checker"),this.$codeChecker&&(this.goals.push("code-checker"),this.$codeChecker.on("continue",()=>this.score("code-checker"))),this.$quill=this.$("x-quill"),this.$quill&&(this.goals.push("quill"),this.$quill.on("submit",()=>this.score("quill"))),this.$$("x-var").forEach((e,t)=>{this.goals.push("var-"+t),e.on("slide-end",()=>this.score("var-"+t))});for(let e of this.$$(".var"))e.bindObservable(this.model,!1)}show(){if(this.isShown)return;this.isShown=!0;try{const e=toCamelCase(this.id);e in stepFunctions&&stepFunctions[e](this)}catch(t){console.error(t)}this.initialData&&this.restore(this.initialData);const e=this.$$("x-gesture[target]");setTimeout(()=>{if(!this.isReady)for(let t of e)t.start()},2e3),this.$course&&this.$course.log("Step","show",this.id),this.addClass("on"),Browser.resize()}complete(){if(!this.isCompleted){this.isShown||this.show(),this.isCompleted=!0;for(let e of this.$reveals)"visible"!==e.css("visibility")&&e.enter("fade",400).then(()=>e.css("opacity",""));for(let e=0;e<this.$nextBtn.length;++e)this.score("next-"+e);this.trigger("complete")}}restore(e){this.$blanks.forEach((t,s)=>{e.scores.includes("blank-"+s)&&t.solve()}),this.$equations.forEach((t,s)=>{e.scores.includes("eqn-"+s)&&t.solve()}),this.$sortables.forEach((t,s)=>{e.scores.includes("sortable-"+s)&&t.solve()});const t=this.$("x-picker");t&&t.restore(e.scores.filter(e=>e.startsWith("picker-"))),this.$codeChecker&&e.scores.includes("code-checker")&&this.$codeChecker.solve(),this.$quill&&e.data&&e.data.quill&&this.$quill.restore(e.data.quill),e.scores.forEach(e=>this.score(e,!1))}get isReady(){return this.goals.every(e=>this.scores.has(e))}score(e,t){void 0===t&&(t=!0),this.scores.has(e)||(this.scores.add(e),this.trigger("score-"+e),this.trigger("score"),this.$course&&(this.$course.trigger("score"),this.$course.saveProgress({steps:{[this.id]:{scores:[e]}}}),this.$course.log("Step","score",this.id+"/"+e)),t&&this.isReady&&this.$course&&this.$course.isReady&&setTimeout(()=>{this.$course.$activeStep===this&&this.$course.nextStep()},1e3))}storeData(e,t){this.$course.saveProgress({steps:{[this.id]:{data:{[e]:t}}}})}onScore(e,t){if(e=words(e),e.every(e=>this.scores.has(e)))return t();if(1===e.length)return this.one("score-"+e[0],t);const s=()=>{e.every(e=>this.scores.has(e))&&(t(),this.off("score",s))};this.on("score",s)}addHint(e,t){return void 0===t&&(t={}),this.trigger("hint",e),this.$course&&this.$course.isReady?this.isInViewport?this.$course.$tutor.showHint(e,t):(this.one("enterViewport",()=>this.$course.$tutor.showHint(e,t)),this.$course.$tutor.hints[e]||e):e}getText(e){return this.$course&&this.$course.$tutor?this.$course.$tutor.hints[e]||e:e}getHelp(){}delayedHint(e,s){void 0===s&&(s=1e4);let a=setTimeout(e,s);this.on("score",()=>{clearTimeout(a),this.isCompleted||(a=setTimeout(e,2e4))}),this.on("complete",()=>clearTimeout(a))}}registerElement("x-step",Step);class Tabbox extends CustomElement{ready(){const e=this.$(".titles");this.$body=this.$(".body"),this.$tabs=this.$$(".tab"),this.$titles=[],this.active=0;for(let t=0;t<this.$tabs.length;++t){const s=this.$tabs[t].$("h3")||$N("h3");e.append(s),this.$titles.push(s),s.on("click",()=>this.makeActive(t))}this.$titles[0].addClass("active"),this.$tabs[0].show()}makeActive(e){if(this.active!==e){this.$titles[this.active].removeClass("active"),this.$titles[e].addClass("active"),this.$tabs[e].show();const t=this.$tabs[e].outerHeight+"px";this.$tabs[e].hide(),this.$tabs[this.active].exit("fade",300).then(()=>this.$tabs[e].enter("fade",300)),this.$body.animate({height:t},600).then(()=>this.$body.css("height","auto")),this.active=e,this.trigger("change",e)}}}const template$1="<div class=\"titles\"></div><div class=\"body\"><slot></slot></div>";registerElement("x-tabbox",Tabbox,{template:"<div class=\"titles\"></div><div class=\"body\"><slot></slot></div>"});const $fixed=$$("header, x-tutor, .sidebar"),$targets=$N("svg",{class:"target-body",style:"position: fixed; top: 0; left: 0; width: 100%; height: 100%;\n            display: none; pointer-events: none; z-index: 900; opacity: 0;\n            transform: translateZ(0); will-change: opacity; transition: opacity .3s;",html:"<defs>\n      <mask id=\"masking\"><rect width=\"100%\" height=\"100%\" fill=\"white\"/></mask>\n    </defs>\n    <marker id=\"arrow\" viewBox=\"0 0 10 10\" refX=\"5\" refY=\"5\" markerWidth=\"4\" markerHeight=\"4\" orient=\"auto\">\n      <path d=\"M 0 0 L 10 5 L 0 10 z\"/>\n    </marker>\n    <rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" mask=\"url(#masking)\" fill=\"white\" opacity=\"0.9\"/>\n    <path id=\"target-arrow\" stroke=\"black\" stroke-width=\"5\" marker-end=\"url(#arrow)\" opacity=\"0.3\" stroke-linecap=\"round\"/>"},$body),$mask=$targets.$("mask"),$arrow=$targets.$("#target-arrow");let active=!1,$bounds=[];class Target extends CustomElement{ready(){function t(){active=!0;let e=$$(o);if(!e.length)return;let t=e[0].hasParent(...$fixed);null==p&&(p=i.hasParent(...$fixed));let s=i.bounds,a=e.map(e=>e.bounds).filter(e=>e.width||e.height);if(d=0,!t){let e=Math.min(...a.map(e=>e.top)),t=Math.max(...a.map(e=>e.top+e.height)),s=Browser.height-12-t,n=(window.isWebView?56:12)-e;d=0>s?s:0<n?n:0}$bounds.forEach(e=>{e.remove()}),$bounds=[s].concat(a).map(function(e,t){let s=t&&!r?10:4;return $N("rect",{x:e.left-s,y:e.top-s+(t||!p?d:0),width:e.width+2*s,height:e.height+2*s,rx:4,ry:4},$mask)}),$arrow.points=connect(s,a[0],p?0:d,t?0:d)}function s(){d&&$body.scrollBy(-d,300),$targets.css("display","block"),Browser.redraw(),delay(function(){$targets.css("opacity",1)},d?300:0)}function a(t){if(active){let e="mousemove"===t.type||"pointermove"===t.type;e&&40>distance(l,[t.clientX,t.clientY])||(clearTimeout(c),active=!1,$targets.css("opacity",0),setTimeout(function(){active||$targets.css("display","none")},300),$body.off("mousewheel mousemove touchend touchmove",a),i.off("mouseleave",a))}}function n(){d&&!p?$body.on("mousemove",a):i.on("mouseleave",a),$body.on("mousewheel touchend touchmove",a)}const i=this;let o=i.attr("to"),r=i.hasAttr("no-margins"),l=null,d=null,c=null,p;i.on("mouseenter touchstart",function(a){l=[a.clientX,a.clientY],t(),c=setTimeout(s,d?50:30),n()}),i.on("click",function(t){active?(t.handled=!0,a({}),setTimeout(function(){$(o).trigger("click mousedown")})):(active=!0,d=0,s(),n())})}}registerElement("x-target",Target);const MATHS_REGEX=/[0-9+\-*/()^\s]+/g;class Tutor extends CustomElement{created(){this.recentMessages=[],this.isOpen=!1,this.queuePromise=Promise.resolve()}ready(){this.$course=(this.getModel()||{}).$course,this.hints=JSON.parse($("#hints").text)||{},this.correct=loop(shuffle(this.hints.correct||[])),this.incorrect=loop(shuffle(this.hints.incorrect||[])),this.$toasts=this.$(".toasts"),this.$chat=this.$(".chat"),this.$chatBody=this.$(".chat-body"),this.$toasts.on("click",t=>{t.handled||this.open()}),this.$(".close").on("click",()=>this.close());const e=this.$(".chat-footer");this.$query=e.$(".input"),this.$query.onKeyDown("enter",t=>{t.preventDefault(),this.askQuestion(this.$query.text.trim()),this.$query.text=""}),this.$query.on("focus",()=>e.addClass("focus")),this.$query.on("blur",()=>e.removeClass("focus")),this.$(".hint").on("click",()=>{this.queue(this.hints.tutorial1),this.queue(this.$course.user?this.hints.tutorial2:this.hints.account)})}open(){this.isOpen||(this.isOpen=!0,this.$chat.enter("slide-up",200),this.$chatBody.scrollTop=this.$chatBody.scrollHeight,this.trigger("open"))}close(){this.isOpen&&(this.isOpen=!1,this.$query.blur(),this.trigger("close"),this.$chat.exit("slide-down",200))}queue(e,t,s){this.queuePromise=this.queuePromise.then(()=>(this.display(e,t,s),wait(500)))}display(e,t,s){void 0===t&&(t="hint");let{timeout:n=8e3,toast:i=!0,className:a}=void 0===s?{}:s;if(640>Browser.width&&(n*=.7),i&&!this.isOpen){const s=createMsgElement(e,t,{className:a});this.$toasts.append(s),s.enter("reveal-right"),n&&setTimeout(()=>s.exit("reveal-right",400,0,!0),n),this.on("open",()=>s.exit("reveal",200,0,!0))}const o=createMsgElement(e,t,{className:a,visible:!this.isOpen});this.$chatBody.append(o),this.isOpen&&(o.enter("reveal",300),animate(()=>this.$chatBody.scrollTop=this.$chatBody.scrollHeight,200))}showHint(e,t){let{store:s=!0,force:a=!1,className:n=null,variables:i=null}=void 0===t?{}:t;if(isOneOf(e,"correct","incorrect")){const t="correct"===e?this.correct():this.incorrect(),s="correct"===e?3e3:5e3;return this.queue(t,"hint",{className:n||e,timeout:s}),{text:t}}let o=this.hints[e]||e;if(i)for(let e of Object.keys(i))o=o.replace(new RegExp("\\$"+e,"g"),i[e]);return!a&&0<=this.recentMessages.indexOf(e)?{text:o}:(this.recentMessages.push(e),setTimeout(()=>this.recentMessages.shift(),1e4),s&&this.$course.saveProgress({hints:[{content:o,kind:"hint"}]}),this.queue(o,"hint",{className:n}),{text:o})}askQuestion(query){if(query){this.queue(query,"question"),this.$course&&this.$course.log("Tutor","ask",query);const equation=(query.match(MATHS_REGEX)||[]).filter(e=>3<=e.length&&!e.match(/^[\s0-9]+$/));if(equation.length)try{const result=eval(equation[0].replace(/\b0+/g,"0").replace(/\^/g,"**"));return this.queue("= "+result)}catch(t){console.error("Parse Error:",equation[0])}}}}registerElement("x-tutor",Tutor,{templateId:"#tutor"});class Variable extends CustomElement{ready(){const e=this,t=e.attr("bind");if(!t)return;let[s,a,n]=t.split("|"),[i,o,r]=n.split(",").map(e=>+e),l=+a;const d=this.getModel();d.set(s,l),this.$(".content").bindObservable(d);let c=e.$(".progress");c.css("width",116*(+l-i)/(o-i)+"px");let p=0,h=0,g=Math.max((o-i)/240,r/20),m=!1;slide(e,{start(t){p=t.x,h=l,e.addClass("on"),m=!1},move(e){let t=(e.x-p)*g,a=roundTo(clamp(h+t,i,o),r);a=_round(a,2),a===l||(l=a,m=!0,d&&d.set(s,l),c.css("width",116*(l-i)/(o-i)+"px"))},end(){e.removeClass("on"),m&&e.trigger("slide-end")}})}}registerElement("x-var",Variable,{templateId:"#var",model:!0});class Video extends CustomElement{ready(){const e=this.attr("src"),t=this.$(".video-wrap"),s=this.$("video"),a=this.attr("width"),n=this.attr("height");this.css("width",a+"px"),t.css("padding-bottom",100*(+n/+a)+"%"),s.setAttr("poster",this.attr("poster")||e.replace(/mp4$/,"jpg")),this.hasAttr("loop")&&(s._el.loop=!0),this.hasAttr("audio")||(s._el.muted=!0),$N("source",{src:e,type:"video/mp4"},s),this.hasAttr("credit")&&(this.$(".credit").text=this.attr("credit"));const i=this.$(".bar"),o=this.$(".progress"),r=this.$(".buffer"),l=this.$(".timecode"),d=new Draggable(this.$(".handle"),i,{moveY:!1}),c=this._video=s._el;let p=this.width-110;Browser.resize(()=>p=this.width-110),s.on("canplay",()=>{l.text=formatTime(c.duration)}),s.on("timeupdate",()=>{const e=c.currentTime/c.duration;o.css("width",100*e+"%"),l.text=formatTime(c.currentTime),d.setPosition(e*p,0),this.trigger("timeupdate",c.currentTime)}),s.on("progress",()=>{if(0>=c.buffered.length||0>=c.duration)return;const e=c.buffered.end(c.buffered.length-1),t=100*(e/c.duration);r.css("width",t+"%")}),s.on("ended",()=>{c.pause(),this.removeClass("playing"),this.trigger("end")});const h=()=>c.paused?this.play():this.pause(),g=e=>this.setTime(e/p*c.duration);this.hasAttr("hover")?(s.on("mouseover touchstart",()=>this.play()),s.on("mouseout touchend touchcancel",()=>this.pause())):s.on("click",h),this.hasAttr("controls")&&(this.$(".controls").show(),this.$(".play-pause-btn").on("click",h),d.on("start",()=>this.pause()),d.on("drag",e=>g(e.x)),i.on("click",t=>g(t.offsetX)))}setTime(e){this._video.currentTime=e}play(){this._video.play(),this.addClass("playing"),this.trigger("play")}pause(){this._video.pause(),this.removeClass("playing")}}registerElement("x-video",Video,{templateId:"#video"});const $modalBackground=$N("div",{class:"modal-background"},$body);let $openModal=null;$modalBackground.on("click",tryClose),Browser.onKey("escape",tryClose),$modalBackground.on("scrollwheel touchmove",function(t){t.preventDefault(),t.stopPropagation()}),Browser.onKey("space up down pagedown pageup",function(t){$openModal&&(t.preventDefault(),t.stopPropagation())}),Browser.resize(()=>{$openModal&&($openModal.transform="translate(-50%, -50%)")});class Modal extends CustomElement{ready(){this.isOpen=!1,this.canClose=!this.hasAttr("no-close"),this.$iframe=this.$("iframe[data-src]");const e=$$("[data-modal="+this.id+"]");for(let t of e)t.on("click",()=>this.open());Router.on("afterChange",(e)=>{let{$viewport:t}=e;const s=t.$$("[data-modal="+this.id+"]");for(let t of s)t.on("click",()=>this.open())}),this.hasClass("open")&&!$openModal&&($modalBackground.show(),this.show(),this.isOpen=!0,$openModal=this);const t=this.$(".close");t&&t.on("click",()=>this.close())}open(){this.isOpen||($openModal?$openModal.close(!0):$modalBackground.enter("fade",250),this.isOpen=!0,$openModal=this,this.$iframe&&this.$iframe.setAttr("src",this.$iframe.data.src),this.enter("pop",250),this.trigger("open"))}close(e,t){void 0===e&&(e=!1),void 0===t&&(t=!1),this.isOpen&&(this.isOpen=!1,$openModal=null,this.$iframe&&this.$iframe.setAttr("src",""),!e&&$modalBackground.exit("fade",250),this.exit("pop",250).then(()=>this.css("transform","")),!t&&this.trigger("close"))}}registerElement("x-modal",Modal);class Select extends CustomElement{ready(){const e=this.children;this.$active=this.$(".active")||e[0],this.$active.addClass("active");for(let t of e)t.on("click",()=>this.makeActive(t));this.trigger("change",this.$active)}makeActive(e){e===this.$active||(this.$active.removeClass("active"),this.$active=e,e.addClass("active"),this.trigger("change",e))}}registerElement("x-select",Select);const VERSION="2.4.1",DEV_ID="i5iSjo",VERSION_PARAM="_av",USAGE_PARAM="_au",NULL_DIMENSION="(not set)",instances=[];class MethodChain{static add(e,t,s){getOrCreateMethodChain(e,t).add(s)}static remove(e,t,s){getOrCreateMethodChain(e,t).remove(s)}constructor(e,t){var s=this;this.context=e,this.methodName=t,this.isTask=/Task$/.test(t),this.originalMethodReference=this.isTask?e.get(t):e[t],this.methodChain=[],this.boundMethodChain=[],this.wrappedMethod=function(){const e=s.boundMethodChain[s.boundMethodChain.length-1];return e(...arguments)},this.isTask?e.set(t,this.wrappedMethod):e[t]=this.wrappedMethod}add(e){this.methodChain.push(e),this.rebindMethodChain()}remove(e){const t=this.methodChain.indexOf(e);-1<t&&(this.methodChain.splice(t,1),0<this.methodChain.length?this.rebindMethodChain():this.destroy())}rebindMethodChain(){this.boundMethodChain=[];for(let e=0,t;t=this.methodChain[e];e++){const s=this.boundMethodChain[e-1]||this.originalMethodReference.bind(this.context);this.boundMethodChain.push(t(s))}}destroy(){const e=instances.indexOf(this);-1<e&&(instances.splice(e,1),this.isTask?this.context.set(this.methodName,this.originalMethodReference):this.context[this.methodName]=this.originalMethodReference)}}const proto=window.Element.prototype,nativeMatches=proto.matches||proto.matchesSelector||proto.webkitMatchesSelector||proto.mozMatchesSelector||proto.msMatchesSelector||proto.oMatchesSelector,a=document.createElement("a"),queueMap={},assign=Object.assign||function(e){for(let t=0,s=1>=arguments.length?0:arguments.length-1;t<s;t++){const s=Object(1>t+1||arguments.length<=t+1?void 0:arguments[t+1]);for(let t in s)Object.prototype.hasOwnProperty.call(s,t)&&(e[t]=s[t])}return e},uuid=function e(t){return t?(t^16*Math.random()>>t/4).toString(16):"10000000-1000-4000-8000-100000000000".replace(/[018]/g,e)};class EventEmitter{constructor(){this.registry_={}}on(e,t){this.getRegistry_(e).push(t)}off(e,t){if(void 0===e&&(e=void 0),void 0===t&&(t=void 0),e&&t){const s=this.getRegistry_(e),a=s.indexOf(t);-1<a&&s.splice(a,1)}else this.registry_={}}emit(e){for(var t=arguments.length,s=Array(1<t?t-1:0),a=1;a<t;a++)s[a-1]=arguments[a];this.getRegistry_(e).forEach(e=>e(...s))}getEventCount(){let e=0;return Object.keys(this.registry_).forEach(t=>{e+=this.getRegistry_(t).length}),e}getRegistry_(e){return this.registry_[e]=this.registry_[e]||[]}}const AUTOTRACK_PREFIX="autotrack",instances$1={};let isListening=!1,browserSupportsLocalStorage;class Store extends EventEmitter{static getOrCreate(e,t,s){const a=[AUTOTRACK_PREFIX,e,t].join(":");return instances$1[a]||(instances$1[a]=new Store(a,s),!isListening&&initStorageListener()),instances$1[a]}static isSupported_(){if(null!=browserSupportsLocalStorage)return browserSupportsLocalStorage;try{window.localStorage.setItem(AUTOTRACK_PREFIX,AUTOTRACK_PREFIX),window.localStorage.removeItem(AUTOTRACK_PREFIX),browserSupportsLocalStorage=!0}catch(e){browserSupportsLocalStorage=!1}return browserSupportsLocalStorage}static get_(e){return window.localStorage.getItem(e)}static set_(e,t){window.localStorage.setItem(e,t)}static clear_(e){window.localStorage.removeItem(e)}constructor(e,t){void 0===t&&(t={}),super(),this.key_=e,this.defaults_=t,this.cache_=null}get(){if(this.cache_)return this.cache_;if(Store.isSupported_())try{this.cache_=parse$2(Store.get_(this.key_))}catch(e){}return this.cache_=assign({},this.defaults_,this.cache_)}set(e){if(this.cache_=assign({},this.defaults_,this.cache_,e),Store.isSupported_())try{Store.set_(this.key_,JSON.stringify(this.cache_))}catch(e){}}clear(){if(this.cache_={},Store.isSupported_())try{Store.clear_(this.key_)}catch(e){}}destroy(){delete instances$1[this.key_],Object.keys(instances$1).length||removeStorageListener()}}const SECONDS=1e3,MINUTES=60000,instances$2={};class Session{static getOrCreate(e,t,s){const a=e.get("trackingId");return instances$2[a]?instances$2[a]:instances$2[a]=new Session(e,t,s)}constructor(e,t,s){this.tracker=e,this.timeout=t||Session.DEFAULT_TIMEOUT,this.timeZone=s,this.sendHitTaskOverride=this.sendHitTaskOverride.bind(this),MethodChain.add(e,"sendHitTask",this.sendHitTaskOverride);try{this.dateTimeFormatter=new Intl.DateTimeFormat("en-US",{timeZone:this.timeZone})}catch(e){}this.store=Store.getOrCreate(e.get("trackingId"),"session",{hitTime:0,isExpired:!1}),this.store.get().id||this.store.set({id:uuid()})}getId(){return this.store.get().id}isExpired(e){if(void 0===e&&(e=this.getId()),e!=this.getId())return!0;const t=this.store.get();if(t.isExpired)return!0;const s=t.hitTime;if(s){const e=new Date,t=new Date(s);if(e-t>this.timeout*MINUTES||this.datesAreDifferentInTimezone(e,t))return!0}return!1}datesAreDifferentInTimezone(e,t){return!!this.dateTimeFormatter&&this.dateTimeFormatter.format(e)!=this.dateTimeFormatter.format(t)}sendHitTaskOverride(e){return t=>{e(t);const s=t.get("sessionControl"),a="start"==s||this.isExpired(),n=this.store.get();n.hitTime=now(),a&&(n.isExpired=!1,n.id=uuid()),"end"==s&&(n.isExpired=!0),this.store.set(n)}}destroy(){MethodChain.remove(this.tracker,"sendHitTask",this.sendHitTaskOverride),this.store.destroy(),delete instances$2[this.tracker.get("trackingId")]}}Session.DEFAULT_TIMEOUT=30;const plugins={CLEAN_URL_TRACKER:1,EVENT_TRACKER:2,IMPRESSION_TRACKER:3,MEDIA_QUERY_TRACKER:4,OUTBOUND_FORM_TRACKER:5,OUTBOUND_LINK_TRACKER:6,PAGE_VISIBILITY_TRACKER:7,SOCIAL_WIDGET_TRACKER:8,URL_CHANGE_TRACKER:9,MAX_SCROLL_TRACKER:10},PLUGIN_COUNT=Object.keys(plugins).length,HIDDEN="hidden",VISIBLE="visible",PAGE_ID=uuid(),SECONDS$1=1e3;class PageVisibilityTracker{constructor(e,t){if(trackUsage(e,plugins.PAGE_VISIBILITY_TRACKER),!!document.visibilityState){const s={sessionTimeout:Session.DEFAULT_TIMEOUT,visibleThreshold:5*SECONDS$1,sendInitialPageview:!1,fieldsObj:{}};this.opts=assign(s,t),this.tracker=e,this.lastPageState=document.visibilityState,this.visibleThresholdTimeout_=null,this.isInitialPageviewSent_=!1,this.trackerSetOverride=this.trackerSetOverride.bind(this),this.handleChange=this.handleChange.bind(this),this.handleWindowUnload=this.handleWindowUnload.bind(this),this.handleExternalStoreSet=this.handleExternalStoreSet.bind(this),this.store=Store.getOrCreate(e.get("trackingId"),"plugins/page-visibility-tracker"),this.store.on("externalSet",this.handleExternalStoreSet),this.session=Session.getOrCreate(e,this.opts.sessionTimeout,this.opts.timeZone),MethodChain.add(e,"set",this.trackerSetOverride),window.addEventListener("unload",this.handleWindowUnload),document.addEventListener("visibilitychange",this.handleChange),deferUntilPluginsLoaded(this.tracker,()=>{document.visibilityState==VISIBLE?(this.opts.sendInitialPageview&&(this.sendPageview({isPageLoad:!0}),this.isInitialPageviewSent_=!0),this.store.set({time:now(),state:VISIBLE,pageId:PAGE_ID,sessionId:this.session.getId()})):this.opts.sendInitialPageview&&this.opts.pageLoadsMetricIndex&&this.sendPageLoad()})}}handleChange(){if(document.visibilityState!=VISIBLE&&document.visibilityState!=HIDDEN)return;const e=this.getAndValidateChangeData(),t={time:now(),state:document.visibilityState,pageId:PAGE_ID,sessionId:this.session.getId()};document.visibilityState==VISIBLE&&this.opts.sendInitialPageview&&!this.isInitialPageviewSent_&&(this.sendPageview(),this.isInitialPageviewSent_=!0),document.visibilityState==HIDDEN&&this.visibleThresholdTimeout_&&clearTimeout(this.visibleThresholdTimeout_),this.session.isExpired(e.sessionId)?(this.store.clear(),this.lastPageState==HIDDEN&&document.visibilityState==VISIBLE&&(clearTimeout(this.visibleThresholdTimeout_),this.visibleThresholdTimeout_=setTimeout(()=>{this.store.set(t),this.sendPageview({hitTime:t.time})},this.opts.visibleThreshold))):(e.pageId==PAGE_ID&&e.state==VISIBLE&&this.sendPageVisibilityEvent(e),this.store.set(t)),this.lastPageState=document.visibilityState}getAndValidateChangeData(){const e=this.store.get();return this.lastPageState==VISIBLE&&e.state==HIDDEN&&e.pageId!=PAGE_ID&&(e.state=VISIBLE,e.pageId=PAGE_ID,this.store.set(e)),e}sendPageVisibilityEvent(e,t){let{hitTime:s}=void 0===t?{}:t;const a=this.getTimeSinceLastStoredChange(e,{hitTime:s});if(a&&a>=this.opts.visibleThreshold){const e=Math.round(a/SECONDS$1),t={transport:"beacon",nonInteraction:!0,eventCategory:"Page Visibility",eventAction:"track",eventValue:e,eventLabel:NULL_DIMENSION};s&&(t.queueTime=now()-s),this.opts.visibleMetricIndex&&(t["metric"+this.opts.visibleMetricIndex]=e),this.tracker.send("event",createFieldsObj(t,this.opts.fieldsObj,this.tracker,this.opts.hitFilter))}}sendPageLoad(){const e={transport:"beacon",eventCategory:"Page Visibility",eventAction:"page load",eventLabel:NULL_DIMENSION,["metric"+this.opts.pageLoadsMetricIndex]:1,nonInteraction:!0};this.tracker.send("event",createFieldsObj(e,this.opts.fieldsObj,this.tracker,this.opts.hitFilter))}sendPageview(e){let{hitTime:t,isPageLoad:s}=void 0===e?{}:e;const a={transport:"beacon"};t&&(a.queueTime=now()-t),s&&this.opts.pageLoadsMetricIndex&&(a["metric"+this.opts.pageLoadsMetricIndex]=1),this.tracker.send("pageview",createFieldsObj(a,this.opts.fieldsObj,this.tracker,this.opts.hitFilter))}trackerSetOverride(e){return(t,s)=>{const a=isObject(t)?t:{[t]:s};a.page&&a.page!==this.tracker.get("page")&&this.lastPageState==VISIBLE&&this.handleChange(),e(t,s)}}getTimeSinceLastStoredChange(e,t){let{hitTime:s}=void 0===t?{}:t;return e.time?(s||now())-e.time:0}handleExternalStoreSet(e,t){e.time!=t.time&&(t.pageId!=PAGE_ID||t.state!=VISIBLE||this.session.isExpired(t.sessionId)||this.sendPageVisibilityEvent(t,{hitTime:e.time}))}handleWindowUnload(){this.lastPageState!=HIDDEN&&this.handleChange()}remove(){this.store.destroy(),this.session.destroy(),MethodChain.remove(this.tracker,"set",this.trackerSetOverride),window.removeEventListener("unload",this.handleWindowUnload),document.removeEventListener("visibilitychange",this.handleChange)}}provide("pageVisibilityTracker",PageVisibilityTracker),window.$=$,window.$$=$$,window.Browser=Browser,Browser.replaceSvgImports(),setTimeout(()=>{$html.addClass("ready")}),$html.addClass((Browser.isMobile?"is":"not")+"-mobile");class Course extends CustomElement{created(){this.model={$course:this},this.user=window.user,this.isCompleted=!1,this.isReady=!1,this.glossary=JSON.parse(this.$("#glossary").text)||{},this.userData=JSON.parse(this.$("#userdata").text)||{},this.$steps=this.$$("x-step");for(let e of this.$steps)e.on("score",()=>this.trigger("score")),e.initialData=(this.userData.steps||{})[e.id]||null;this.$activeStep=null}ready(){this.$footer=this.$("footer"),this.$skipStep=this.$footer.$(".skip-step"),this.$progress=this.$(".sidebar-row.on x-progress"),this.$tutor=this.$("x-tutor");const e=this.$(".sidebar");e&&(this.$(".sidebar-toggle").on("click",()=>e.addClass("open")),this.$(".sidebar-shadow").on("pointerdown",()=>e.removeClass("open")));const t=this.findStep(Browser.hash),s=this.findStep(this.userData.activeStep);this.$activeStep=s||this.$steps[0];for(let e of this.$steps){if(e.show(),e===this.$activeStep)break;e.complete()}if(this.userData.completed||"full"===Browser.hash)this.complete();else for(;this.$activeStep&&this.$activeStep.isReady&&!this.isCompleted;)this.nextStep();(t||s)&&this.goToStep(t||s,!1),this.$(".section-dev")&&this.complete();const a=this.$(".show-all-steps");setTimeout(()=>{this.isCompleted||(a.removeClass("off"),a.one("click",()=>this.complete()),this.on("score complete",()=>a.addClass("off")))},2e3),Browser.onKey("space",t=>{t.preventDefault(),this.nextStep(),a.addClass("off")}),this.$footer.$(".skip").on("click",()=>this.nextStep()),this.$footer.$(".show-all").on("click",()=>this.complete()),this.isReady=!0,setTimeout(()=>this.addClass("ready"))}nextStep(){if(this.isCompleted)return;let e=this.$activeStep;this.animateSkipStepBanner();do{if(e.complete(),e=this.$steps[this.$steps.indexOf(e)+1],!e)return this.complete(!0);e.show()}while(e.isReady);this.$activeStep=e,this.saveProgress({activeStep:e.id})}goToStep(e,t){void 0===t&&(t=!0),t&&this.animateSkipStepBanner();for(let s of this.$steps){if(s.isShown||(this.$activeStep=s),s.show(),e.isShown&&!s.isReady)break;s.complete()}const s=e.positionTop-Math.max(50,(Browser.height-e.height)/2);t?$body.scrollTo(s):$body.scrollTop=s;const a=last(this.$steps);return a.isShown&&a.isReady?this.complete():void(this.$activeStep&&this.saveProgress({activeStep:this.$activeStep.id}))}complete(e){if(void 0===e&&(e=!1),!this.isCompleted){this.isCompleted=!0,this.$steps.forEach(e=>e.complete()),this.$activeStep=null;const t=this.$footer.$(".next-section");e?(this.$skipStep.exit("fade",200),t&&t.enter("pop")):(this.$skipStep.hide(),t&&t.show()),this.trigger("complete"),this.saveProgress({completed:!0}),this.log("Course","complete")}}findStep(e){for(let t of this.$steps)if(t.id===e)return t}animateSkipStepBanner(){this.$skipStep.css({top:this.$skipStep.bounds.top+"px",width:this.$skipStep.width+"px"}),this.$skipStep.addClass("fixed"),this.$skipStep.animate({transform:"translateY(100px)"}).then(()=>{this.$skipStep.removeClass("fixed"),this.$skipStep.css({top:"",width:"",transform:""})})}saveProgress(e){}log(e,t,s){void 0===s&&(s=null)}}return registerElement("x-course",Course),exports.Course=Course,exports}({});
  