@khanacademy/perseus 85.0.0 → 85.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/index.css +9 -3
- package/dist/es/index.css.map +1 -1
- package/dist/es/index.js +24 -20
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +9 -3
- package/dist/index.css.map +1 -1
- package/dist/index.js +21 -17
- package/dist/index.js.map +1 -1
- package/dist/interactive2/wrapped-ellipse.d.ts +5 -0
- package/dist/widgets/explanation/explanation.d.ts +3 -5
- package/dist/widgets/expression/expression.d.ts +2 -2
- package/dist/widgets/grapher/function-type-icon.d.ts +8 -0
- package/dist/widgets/numeric-input/utils.d.ts +2 -2
- package/dist/widgets/radio/radio-widget.d.ts +2 -2
- package/dist/widgets/sorter/index.d.ts +73 -1
- package/dist/widgets/sorter/sorter.d.ts +15 -20
- package/package.json +7 -7
package/dist/es/index.js
CHANGED
|
@@ -2,17 +2,17 @@ import * as React from 'react';
|
|
|
2
2
|
import React__default, { useContext, forwardRef, useId, useRef, useEffect, useCallback, useImperativeHandle, useState, useMemo, createContext, useLayoutEffect, createElement } from 'react';
|
|
3
3
|
import { KeypadContext } from '@khanacademy/keypad-context';
|
|
4
4
|
import { MathInputI18nContext, DesktopKeypad, getCursorContext, CursorContext, getKeyTranslator, createMathField, convertDotToTimesByLocale, mathQuillInstance, KeypadInput, keypadElementPropType } from '@khanacademy/math-input';
|
|
5
|
-
import { View, RenderStateRoot, useOnMountEffect,
|
|
5
|
+
import { View, RenderStateRoot, useOnMountEffect, useLatestRef, Text as Text$2 } from '@khanacademy/wonder-blocks-core';
|
|
6
6
|
import { Heading, BodyText } from '@khanacademy/wonder-blocks-typography';
|
|
7
7
|
import { StyleSheet, css } from 'aphrodite';
|
|
8
8
|
import Clickable from '@khanacademy/wonder-blocks-clickable';
|
|
9
9
|
import { Popover, PopoverContentCore } from '@khanacademy/wonder-blocks-popover';
|
|
10
|
-
import { semanticColor, sizing,
|
|
10
|
+
import { semanticColor, sizing, border as border$1, color, tokenValue, spacing, font, boxShadow } from '@khanacademy/wonder-blocks-tokens';
|
|
11
11
|
import classNames$2 from 'classnames';
|
|
12
12
|
import { v4 } from 'uuid';
|
|
13
13
|
import PropTypes from 'prop-types';
|
|
14
14
|
import * as PerseusLinter from '@khanacademy/perseus-linter';
|
|
15
|
-
import { Rule
|
|
15
|
+
import { Rule } from '@khanacademy/perseus-linter';
|
|
16
16
|
import Tooltip, { TooltipContent } from '@khanacademy/wonder-blocks-tooltip';
|
|
17
17
|
import { PerseusError, Errors, isLabeledSVG, getDataUrl, getSvgUrl, getBaseUrl, getRealImageUrl, getImageSizeModern, CoreWidgetRegistry, approximateDeepEqual, pluck, getWidgetIdsFromContentByType, Registry, mapObject, excludeDenylistKeys, applyDefaultsToWidgets, splitPerseusItem, getDefaultAnswerArea, isFeatureOn, shuffle, usesNumCorrect, approximateEqual, lockedFigureColors, lockedFigureFillStyles, GrapherUtil as GrapherUtil$1, convertGrapherOptionsToInteractiveGraph, convertGrapherUserInputToInteractiveGraph, convertInteractiveGraphUserInputToGrapher, deepClone, shuffleMatcher, getMatrixSize, makeSafeUrl, shuffleSorter } from '@khanacademy/perseus-core';
|
|
18
18
|
import { TextField, TextArea } from '@khanacademy/wonder-blocks-form';
|
|
@@ -1414,7 +1414,7 @@ var a11y = StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,mar
|
|
|
1414
1414
|
|
|
1415
1415
|
const debounce=(func,delay)=>{let timer=null;return (...args)=>{if(timer){clearTimeout(timer);}timer=window.setTimeout(()=>{func(...args);},delay);}};
|
|
1416
1416
|
|
|
1417
|
-
class InnerMathInput extends React.Component{componentDidMount(){this.mathField()?.latex(this.props.value);}componentDidUpdate(prevProps){if(prevProps.value!==this.props.value){if(this.state.focused){return}const field=this.mathField();if(!field){return}const current=field.latex();if(this.props.value!==current){field.latex(this.props.value);}}}openKeypad(){if(this.props.buttonsVisible==="never"){return}this.setState({keypadOpen:true});}closeKeypad(){this.setState({keypadOpen:false});}render(){let className=classNames$2({"perseus-math-input":true,"mq-editable-field":true,"mq-math-mode":true});const popoverContentUniqueId=v4().slice(0,8);if(this.props.className){className=className+" "+this.props.className;}return jsxRuntimeExports.jsx(View,{style:[styles$D.outerWrapper,this.state.focused&&styles$D.wrapperFocused],children:jsxRuntimeExports.jsxs("div",{style:{display:"flex",padding:1},onClick:e=>{e.stopPropagation();const mathField=this.mathField();if(!mathField){return}this.setState({cursorContext:getCursorContext(mathField)});},children:[jsxRuntimeExports.jsx("span",{className:className,ref:ref=>this.__mathFieldWrapperRef=ref,onFocus:()=>this.focus(),onBlur:()=>this.blur()}),jsxRuntimeExports.jsx(Popover,{opened:this.state.keypadOpen,dismissEnabled:true,rootBoundary:"document","aria-label":this.context.strings.mathInputTitle,"aria-describedby":`popover-content-${popoverContentUniqueId}`,onClose:()=>this.closeKeypad(),content:()=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{size:"large",id:`popover-content-${popoverContentUniqueId}`,style:a11y.srOnly,children:this.context.strings.mathInputDescription}),jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$D.popoverContent,children:jsxRuntimeExports.jsx(DesktopKeypad,{onAnalyticsEvent:this.props.onAnalyticsEvent,extraKeys:this.props.extraKeys,onClickKey:this.handleKeypadPress,cursorContext:this.state.cursorContext,convertDotToTimes:this.props.convertDotToTimes,...this.props.keypadButtonSets??mapButtonSets(this.props?.buttonSets),showDismiss:true})})]}),children:this.props.buttonsVisible==="never"?jsxRuntimeExports.jsx(MathInputIcon,{hovered:false,focused:false,active:false}):jsxRuntimeExports.jsx(Clickable,{"aria-label":this.state.keypadOpen?this.context.strings.closeKeypad:this.context.strings.openKeypad,role:"button",onClick:()=>this.state.keypadOpen?this.closeKeypad():this.openKeypad(),children:props=>jsxRuntimeExports.jsx(MathInputIcon,{active:this.state.keypadOpen,...props})})})]})})}constructor(...args){super(...args),this.__mathFieldWrapperRef=null,this.__mathField=null,this.state={focused:false,keypadOpen:this.props.buttonsVisible==="always"
|
|
1417
|
+
class InnerMathInput extends React.Component{componentDidMount(){this.mathField()?.latex(this.props.value);}componentDidUpdate(prevProps){if(prevProps.value!==this.props.value){if(this.state.focused){return}const field=this.mathField();if(!field){return}const current=field.latex();if(this.props.value!==current){field.latex(this.props.value);}}}openKeypad(){if(this.props.buttonsVisible==="never"){return}this.setState({keypadOpen:true});}closeKeypad(){this.setState({keypadOpen:false});}render(){let className=classNames$2({"perseus-math-input":true,"mq-editable-field":true,"mq-math-mode":true});const popoverContentUniqueId=v4().slice(0,8);if(this.props.className){className=className+" "+this.props.className;}return jsxRuntimeExports.jsx(View,{style:[styles$D.outerWrapper,this.state.focused&&styles$D.wrapperFocused],children:jsxRuntimeExports.jsxs("div",{style:{display:"flex",alignItems:"center",padding:1},onClick:e=>{e.stopPropagation();const mathField=this.mathField();if(!mathField){return}this.setState({cursorContext:getCursorContext(mathField)});},children:[jsxRuntimeExports.jsx("span",{className:className,ref:ref=>this.__mathFieldWrapperRef=ref,onFocus:()=>this.focus(),onBlur:()=>this.blur()}),jsxRuntimeExports.jsx(Popover,{opened:this.state.keypadOpen,dismissEnabled:true,rootBoundary:"document","aria-label":this.context.strings.mathInputTitle,"aria-describedby":`popover-content-${popoverContentUniqueId}`,onClose:()=>this.closeKeypad(),content:()=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{size:"large",id:`popover-content-${popoverContentUniqueId}`,style:a11y.srOnly,children:this.context.strings.mathInputDescription}),jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$D.popoverContent,children:jsxRuntimeExports.jsx(DesktopKeypad,{onAnalyticsEvent:this.props.onAnalyticsEvent,extraKeys:this.props.extraKeys,onClickKey:this.handleKeypadPress,cursorContext:this.state.cursorContext,convertDotToTimes:this.props.convertDotToTimes,...this.props.keypadButtonSets??mapButtonSets(this.props?.buttonSets),showDismiss:true})})]}),children:this.props.buttonsVisible==="never"?jsxRuntimeExports.jsx(MathInputIcon,{hovered:false,focused:false,active:false,pressed:false}):jsxRuntimeExports.jsx(Clickable,{"aria-label":this.state.keypadOpen?this.context.strings.closeKeypad:this.context.strings.openKeypad,role:"button",hideDefaultFocusRing:true,onClick:()=>this.state.keypadOpen?this.closeKeypad():this.openKeypad(),children:props=>jsxRuntimeExports.jsx(MathInputIcon,{active:this.state.keypadOpen,...props})})})]})})}constructor(...args){super(...args),this.__mathFieldWrapperRef=null,this.__mathField=null,this.state={focused:false,keypadOpen:this.props.buttonsVisible==="always",cursorContext:CursorContext.NONE},this.insert=value=>{const input=this.mathField();const{locale}=this.context;const customKeyTranslator={...getKeyTranslator(locale,this.context.strings),FRAC:mathQuill=>{const contents=mathQuill.latex();mathQuill.typedText("/");if(mathQuill.latex()===contents){mathQuill.cmd("\\frac");}}};const inputModifier=customKeyTranslator[value];if(inputModifier){inputModifier(input,value);input?.focus();return}if(typeof value==="function"){value(input);}else if(value[0]==="\\"){input?.cmd(value).focus();}else {input?.write(value).focus();}input?.focus();},this.mathField=()=>{if(!this.__mathField&&this.__mathFieldWrapperRef){const{locale}=this.context;this.__mathField=createMathField(this.__mathFieldWrapperRef,locale,this.props.mathInputStrings,baseConfig=>({...baseConfig,handlers:{edit:debounce(mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(convertDotToTimesByLocale(locale,this.props.convertDotToTimes)){value=value.replace(/\\cdot/g,"\\times");const left=mathField.cursor()[mathQuillInstance.L];if(left&&left.ctrlSeq==="\\cdot "){mathField.controller().backspace();mathField.cmd("\\times");}}else {value=value.replace(/\\times/g,"\\cdot");}if(this.props.value!==value){this.props.onChange(value);}this.setState({cursorContext:getCursorContext(mathField)});},100),enter:()=>{if(this.__mathFieldWrapperRef){this.__mathFieldWrapperRef.dispatchEvent(new Event("submit",{bubbles:true,cancelable:true}));}},upOutOf:mathField=>{mathField.typedText("^");}}}));}this.__mathField?.setAriaLabel(this.props.ariaLabel);return this.__mathField},this.focus=()=>{this.mathField()?.focus();this.setState({focused:true});},this.blur=()=>this.setState({focused:false}),this.handleKeypadPress=(key,e)=>{if(key==="DISMISS"){this.closeKeypad();return}const{locale}=this.context;const translator=getKeyTranslator(locale,this.context.strings)[key];const mathField=this.mathField();if(mathField){if(translator){translator(mathField,key);}this.setState({cursorContext:getCursorContext(mathField)});}if(e?.type==="click"){this.focus();}};}}InnerMathInput.contextType=PerseusI18nContext;InnerMathInput.defaultProps={value:"",convertDotToTimes:false};class MathInput extends React.Component{blur(){this.inputRef.current?.blur();}focus(){this.inputRef.current?.focus();}insert(value){this.inputRef.current?.insert(value);}render(){return jsxRuntimeExports.jsx(InnerMathInput,{...this.props,ref:this.inputRef,mathInputStrings:this.context.strings})}constructor(...args){super(...args),this.inputRef=React.createRef();}}MathInput.contextType=MathInputI18nContext;MathInput.defaultProps={ariaLabel:"Math input"};const MathInputIcon=({hovered,focused,pressed,active})=>{let fillColor;switch(true){case focused||pressed||active:fillColor=semanticColor.core.foreground.knockout.default;break;case hovered:fillColor=semanticColor.core.foreground.instructive.strong;break;default:fillColor=semanticColor.core.foreground.neutral.default;break}let dynamicClass;switch(true){case focused||pressed:dynamicClass=styles$D.iconActive;break;case active:dynamicClass=styles$D.iconExpanded;break;case hovered:dynamicClass=styles$D.iconHovered;break;default:dynamicClass=styles$D.iconInactive;}return jsxRuntimeExports.jsx(View,{style:[styles$D.iconContainer,dynamicClass],children:jsxRuntimeExports.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",fill:fillColor,viewBox:"0 0 256 256",children:jsxRuntimeExports.jsx("path",{d:"M112,72a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16h64A8,8,0,0,1,112,72Zm-8,104H80V152a8,8,0,0,0-16,0v24H40a8,8,0,0,0,0,16H64v24a8,8,0,0,0,16,0V192h24a8,8,0,0,0,0-16Zm48,0h64a8,8,0,0,0,0-16H152a8,8,0,0,0,0,16Zm64,16H152a8,8,0,0,0,0,16h64a8,8,0,0,0,0-16Zm-61.66-90.34a8,8,0,0,0,11.32,0L184,83.31l18.34,18.35a8,8,0,0,0,11.32-11.32L195.31,72l18.35-18.34a8,8,0,0,0-11.32-11.32L184,60.69,165.66,42.34a8,8,0,0,0-11.32,11.32L172.69,72,154.34,90.34A8,8,0,0,0,154.34,101.66Z"})})})};const mapButtonSets=buttonSets=>{const keypadButtonSets={};if(!buttonSets){return keypadButtonSets}buttonSets.forEach(buttonSet=>{switch(buttonSet){case "advanced relations":keypadButtonSets.advancedRelations=true;break;case "basic relations":keypadButtonSets.basicRelations=true;break;case "basic+div":keypadButtonSets.divisionKey=true;break;case "logarithms":keypadButtonSets.logarithms=true;break;case "prealgebra":keypadButtonSets.preAlgebra=true;break;case "trig":keypadButtonSets.trigonometry=true;break;case "scientific":keypadButtonSets.scientific=true;break;}});return keypadButtonSets};const inputFocused={borderColor:semanticColor.core.border.instructive.default};const styles$D=StyleSheet.create({iconContainer:{display:"flex",justifyContent:"center",height:"100%",padding:sizing.size_060,borderRadius:border$1.radius.radius_040,borderWidth:border$1.width.medium,borderStyle:"solid"},iconInactive:{borderColor:semanticColor.core.transparent,backgroundColor:semanticColor.core.background.neutral.subtle},iconActive:{borderColor:semanticColor.focus.outer,boxShadow:`inset 0 0 0 ${border$1.width.medium} ${semanticColor.focus.inner}`,backgroundColor:semanticColor.core.background.neutral.default},iconExpanded:{borderColor:semanticColor.core.transparent,backgroundColor:semanticColor.core.background.neutral.default},iconHovered:{borderColor:semanticColor.core.transparent,backgroundColor:semanticColor.core.background.neutral.subtle},outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:border$1.width.thin,borderColor:semanticColor.core.border.neutral.default,borderRadius:border$1.radius.radius_040,background:semanticColor.core.background.base.default,":hover":inputFocused},wrapperFocused:inputFocused,popoverContent:{padding:0,paddingBlockEnd:sizing.size_060,maxInlineSize:"initial"}});
|
|
1418
1418
|
|
|
1419
1419
|
let _dependencies=null;const setDependencies=dependencies=>{_dependencies=dependencies;};const getDependencies=()=>{if(_dependencies){return _dependencies}throw new Error(["Perseus has not been provided required dependencies.","setDependencies(dependencies) must be called first.","Make sure Perseus is being imported from javascript/perseus/perseus.js."].join("\n"))};const DependenciesContext=React.createContext({analytics:{onAnalyticsEvent:async()=>{}},generateUrl:()=>{throw new Error("generateUrl dependency not provided in Perseus dependencies")},useVideo:()=>{throw new Error("useVideo dependency not provided in Perseus dependencies")}});const useDependencies=()=>{const deps=React.useContext(DependenciesContext);return deps};
|
|
1420
1420
|
|
|
@@ -1485,7 +1485,7 @@ const GifImage=props=>{const{alt,width,height,scale,isPlaying,onLoop,onLoad,gifF
|
|
|
1485
1485
|
|
|
1486
1486
|
function getKey$2(eventName,id){return eventName+":"+id}function getEventName$2(key){return key.split(":")[0]}const MovableHelperMethods={_fireEvent:function(listeners,...args){for(const listener of listeners){listener.call(this,...args);}},_applyConstraints:function(current,previous,extraOptions){let skipRemaining=false;return _.reduce(this.state.constraints,(memo,constraint)=>{if(memo===false){return false}if(skipRemaining){return memo}const result=constraint.call(this,memo,previous,{onSkipRemaining:()=>{skipRemaining=true;},...extraOptions});if(result===false){return false}if(point.is(result,2)){return result}if(result===true||result==null){return memo}throw new PerseusError("Constraint returned invalid result: "+result,Errors.Internal)},current,this)},draw:function(){const currState=this.cloneState();MovableHelperMethods._fireEvent.call(this,this.state.draw,currState,this.prevState);this.prevState=currState;},listen:function(eventName,id,func){this._listenerMap=this._listenerMap||{};const key=getKey$2(eventName,id);const index=this._listenerMap[key]=this._listenerMap[key]||this.state[eventName].length;this.state[eventName][index]=func;},unlisten:function(eventName,id){this._listenerMap=this._listenerMap||{};const key=getKey$2(eventName,id);const index=this._listenerMap[key];if(index!==undefined){this.state[eventName].splice(index,1);delete this._listenerMap[key];const keys=Object.keys(this._listenerMap);_.each(keys,function(key){if(getEventName$2(key)===eventName&&this._listenerMap[key]>index){this._listenerMap[key]--;}},this);}}};
|
|
1487
1487
|
|
|
1488
|
-
let prefixedTransform=null;function computePrefixedTransform(){const el=document.createElement("div");const prefixes=["transform","msTransform","MozTransform","WebkitTransform","OTransform"];let correctPrefix=null;_.each(prefixes,function(prefix){if(typeof el.style[prefix]!=="undefined"){correctPrefix=prefix;}});return correctPrefix}let canUse3dTransform=null;function computeCanUse3dTransform(){const el=document.createElement("div");const prefix=InteractiveUtil.getPrefixedTransform();el.style[prefix]="translateZ(0px)";return !!el.style[prefix]}const FUNCTION_ARRAY_OPTIONS=["add","modify","draw","remove","constraints","onMoveStart","onMove","onMoveEnd","onClick"];const InteractiveUtil={assert:function(isTrue,message){if(!isTrue){throw new PerseusError("Assertion Error"+(message?": "+message:""),Errors.Internal)}},createGettersFor:function(Class,defaults){_.each(Object.keys(defaults),function(key){if(Class.prototype[key]===undefined){Class.prototype[key]=function(){return this.state[key]};}});},addMovableHelperMethodsTo:function(Class){_.each(MovableHelperMethods,function(methodFunc,methodName){if(Class.prototype[methodName]===undefined){Class.prototype[methodName]=methodFunc;}});},arrayify:function(funcOrArray){if(funcOrArray==null){return []}if(Array.isArray(funcOrArray)){return _.filter(_.flatten(funcOrArray),
|
|
1488
|
+
let prefixedTransform=null;function computePrefixedTransform(){const el=document.createElement("div");const prefixes=["transform","msTransform","MozTransform","WebkitTransform","OTransform"];let correctPrefix=null;_.each(prefixes,function(prefix){if(typeof el.style[prefix]!=="undefined"){correctPrefix=prefix;}});return correctPrefix}let canUse3dTransform=null;function computeCanUse3dTransform(){const el=document.createElement("div");const prefix=InteractiveUtil.getPrefixedTransform();el.style[prefix]="translateZ(0px)";return !!el.style[prefix]}const FUNCTION_ARRAY_OPTIONS=["add","modify","draw","remove","constraints","onMoveStart","onMove","onMoveEnd","onClick"];const InteractiveUtil={assert:function(isTrue,message){if(!isTrue){throw new PerseusError("Assertion Error"+(message?": "+message:""),Errors.Internal)}},createGettersFor:function(Class,defaults){_.each(Object.keys(defaults),function(key){if(Class.prototype[key]===undefined){Class.prototype[key]=function(){return this.state[key]};}});},addMovableHelperMethodsTo:function(Class){_.each(MovableHelperMethods,function(methodFunc,methodName){if(Class.prototype[methodName]===undefined){Class.prototype[methodName]=methodFunc;}});},arrayify:function(funcOrArray){if(funcOrArray==null){return []}if(Array.isArray(funcOrArray)){return _.filter(_.flatten(funcOrArray),x=>x)}return [funcOrArray]},normalizeOptions:function(options){const result={...options};FUNCTION_ARRAY_OPTIONS.forEach(function(eventName){if(options[eventName]!==undefined){result[eventName]=InteractiveUtil.arrayify(options[eventName]);}});return result},getPrefixedTransform:function(){prefixedTransform=prefixedTransform||computePrefixedTransform();return prefixedTransform},getCanUse3dTransform:function(){if(canUse3dTransform==null){canUse3dTransform=computeCanUse3dTransform();}return canUse3dTransform}};
|
|
1489
1489
|
|
|
1490
1490
|
function _class_private_field_loose_base(receiver, privateKey) {
|
|
1491
1491
|
if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
|
|
@@ -1566,13 +1566,13 @@ const DEFAULT_OPTIONS$2={center:null,createPath:null,mouselayer:false};class Wra
|
|
|
1566
1566
|
|
|
1567
1567
|
let Arrowhead$1 = class Arrowhead extends WrappedPath{toCoordAtAngle(coord,angle){const clipPoint=this.graphie.scalePoint(getClipPoint(this.graphie,coord,angle));this.transform("translateX("+(clipPoint[0]+Arrowhead.scale*this.center[0])+"px) "+"translateY("+(clipPoint[1]+Arrowhead.scale*this.center[1])+"px) "+"translateZ(0) "+"rotate("+(360-KhanMath.bound(angle))+"deg)");}constructor(graphie,style){const center=[.75,0];const points=[[-3,4],[-2.75,2.5],[0,.25],center,[0,-0.25],[-2.75,-2.5],[-3,-4]].map(point=>{const pv=vector$3.subtract(point,center);const pvScaled=vector$3.scale(pv,Arrowhead.scale);return vector$3.add(center,pvScaled)});const unscaledPoints=points.map(graphie.unscalePoint);super(graphie,unscaledPoints,{center:graphie.unscalePoint(center),createPath:createCubicPath});this.center=center;this.attr(_.extend({"stroke-linejoin":"round","stroke-linecap":"round","stroke-dasharray":""},style));}};Arrowhead$1.scale=1.4;const createCubicPath=function(points){let path="M"+points[0][0]+" "+points[0][1];for(let i=1;i<points.length;i+=3){path+="C"+points[i][0]+" "+points[i][1]+" "+points[i+1][0]+" "+points[i+1][1]+" "+points[i+2][0]+" "+points[i+2][1];}return path};
|
|
1568
1568
|
|
|
1569
|
-
const DEFAULT_OPTIONS$1={maxScale:1,mouselayer:false,shadow:false,disableMouseEventsOnWrapper:false};class WrappedEllipse extends WrappedDrawing{constructor(graphie,center,radii,options){super(graphie,center);options=_.extend({},DEFAULT_OPTIONS$1,options);const fixedEllipse=graphie.fixedEllipse(center,radii,options.maxScale,options.padding);this.visibleShape=fixedEllipse.visibleShape;this.wrapper=fixedEllipse.wrapper;this.graphie=graphie;this.initialPoint=center;if(options.interactiveKindForTesting){this.wrapper.setAttribute("data-interactive-kind-for-testing",options.interactiveKindForTesting);}if(options.mouselayer){this.wrapper.style.touchAction="none";this.graphie.addToMouseLayerWrapper(this.wrapper);}else {this.graphie.addToVisibleLayerWrapper(this.wrapper);}
|
|
1569
|
+
const DEFAULT_OPTIONS$1={maxScale:1,mouselayer:false,shadow:false,disableMouseEventsOnWrapper:false};const wrappedEllipseShadow=`drop-shadow(0px 0px 2px ${semanticColor.core.foreground.instructive.default})`;class WrappedEllipse extends WrappedDrawing{setShadow(shadow){this.wrapper.style.filter=shadow?wrappedEllipseShadow:"";}constructor(graphie,center,radii,options){super(graphie,center);options=_.extend({},DEFAULT_OPTIONS$1,options);const fixedEllipse=graphie.fixedEllipse(center,radii,options.maxScale,options.padding);this.visibleShape=fixedEllipse.visibleShape;this.wrapper=fixedEllipse.wrapper;this.graphie=graphie;this.initialPoint=center;if(options.interactiveKindForTesting){this.wrapper.setAttribute("data-interactive-kind-for-testing",options.interactiveKindForTesting);}if(options.mouselayer){this.wrapper.style.touchAction="none";this.graphie.addToMouseLayerWrapper(this.wrapper);}else {this.graphie.addToVisibleLayerWrapper(this.wrapper);}this.setShadow(options.shadow);if(options.disableMouseEventsOnWrapper){this.wrapper.style.pointerEvents="none";this.visibleShape.node.style.pointerEvents="auto";}}}
|
|
1570
1570
|
|
|
1571
1571
|
const DEFAULT_OPTIONS={thickness:2,mouselayer:false};class WrappedLine extends WrappedDrawing{getMouseTarget(){return this.wrapper}moveTo(start,end){const scaledStart=this.graphie.scalePoint(start);const scaledEnd=this.graphie.scalePoint(end);const polarDiff=vector$3.polarDegFromCart(vector$3.subtract(scaledEnd,scaledStart));const lineLength=polarDiff[0];const angle=KhanMath.bound(polarDiff[1]);const delta=vector$3.subtract(scaledStart,this.initialPoint);const scale=KhanMath.bound(lineLength/this.initialLength);const do3dTransform=InteractiveUtil.getCanUse3dTransform();const transformation="translateX("+delta[0]+"px) "+"translateY("+delta[1]+"px) "+(do3dTransform?" translateZ(0)":"")+"rotate("+angle+"deg) "+"scaleX("+scale+") scaleY(1)";this.transform(transformation);}constructor(graphie,start,end,options){const initialStart=[graphie.range[0][0],0];const initialEnd=[graphie.range[0][1],0];const initialPoint=graphie.scalePoint(initialStart);super(graphie,initialPoint);options=_.extend({},DEFAULT_OPTIONS,options);const fixedLine=graphie.fixedLine(initialStart,initialEnd,options.thickness);this.wrapper=fixedLine.wrapper;this.visibleShape=fixedLine.visibleShape;if(options.interactiveKindForTesting){this.wrapper.setAttribute("data-interactive-kind-for-testing",options.interactiveKindForTesting);}this.visibleShape.attr(options.normalStyle);this.initialPoint=initialPoint;this.initialLength=point.distanceToPoint(graphie.scalePoint(initialStart),graphie.scalePoint(initialEnd));if(options.mouselayer){this.wrapper.style.touchAction="none";this.graphie.addToMouseLayerWrapper(this.wrapper);}else {this.graphie.addToVisibleLayerWrapper(this.wrapper);}this.moveTo(start,end);}}
|
|
1572
1572
|
|
|
1573
1573
|
const{clockwise: clockwise$3,reverseVector: reverseVector$1}=geometry;function scaledDistanceFromAngle(angle){const a=3.51470560176242*20;const b=.5687298702748785*20;const c=-0.037587715462826674;return (a-b)*Math.exp(c*angle)+b}function scaledPolarRad(radius,radians){return [radius*Math.cos(radians),radius*Math.sin(radians)*-1]}function scaledPolarDeg(radius,degrees){const radians=degrees*Math.PI/180;return scaledPolarRad(radius,radians)}let dragging=false;const InteractiveUtils={bogusShape:{animate:function(){},attr:function(){},remove:function(){}}};_.extend(GraphUtils.Graphie.prototype,{labelAngle:function(options){const graphie=this;_.defaults(options,{point1:[0,0],vertex:[0,0],point3:[0,0],label:null,numArcs:1,showRightAngleMarker:true,pushOut:0,clockwise:false,style:{}});let text=options.text===undefined?"":options.text;const vertex=options.vertex;const sVertex=graphie.scalePoint(vertex);let p1;let p3;if(options.clockwise){p1=options.point1;p3=options.point3;}else {p1=options.point3;p3=options.point1;}const startAngle=GraphUtils.findAngleDeprecated(p1,vertex);const endAngle=GraphUtils.findAngleDeprecated(p3,vertex);const angle=(endAngle+360-startAngle)%360;const halfAngle=(startAngle+angle/2)%360;const sPadding=5*options.pushOut;let sRadius=sPadding+scaledDistanceFromAngle(angle);const temp=[];if(Math.abs(angle-90)<1e-9&&options.showRightAngleMarker){const v1=vector$3.add(sVertex,scaledPolarDeg(sRadius,startAngle));const v2=vector$3.add(sVertex,scaledPolarDeg(sRadius,endAngle));sRadius*=Math.SQRT2;const v3=vector$3.add(sVertex,scaledPolarDeg(sRadius,halfAngle));[v1,v2].forEach(function(v){temp.push(graphie.scaledPath([v,v3],options.style));});}else {for(let i=0;i<options.numArcs;i++){temp.push(graphie.arc(vertex,graphie.unscaleVector(sRadius),startAngle,endAngle,options.style));sRadius+=3;}}if(text){const match=text.match(/\$deg(\d)?/);if(match){const precision=match[1]||1;text=text.replace(match[0],KhanMath.toFixedApprox(angle,precision)+"^{\\circ}");}const sOffset=scaledPolarDeg(sRadius+15,halfAngle);const sPosition=vector$3.add(sVertex,sOffset);const position=graphie.unscalePoint(sPosition);if(options.label){options.label.setPosition(position);options.label.processMath(text,true);}else {graphie.label(position,text,"center",options.style);}}return temp},labelSide:function(options){const graphie=this;_.defaults(options,{point1:[0,0],point2:[0,0],label:null,text:"",numTicks:0,numArrows:0,clockwise:false,style:{}});let p1;let p2;if(options.clockwise){p1=options.point1;p2=options.point2;}else {p1=options.point2;p2=options.point1;}const midpoint=[(p1[0]+p2[0])/2,(p1[1]+p2[1])/2];const sMidpoint=graphie.scalePoint(midpoint);const parallelAngle=Math.atan2(p2[1]-p1[1],p2[0]-p1[0]);const perpendicularAngle=parallelAngle+Math.PI/2;const temp=[];let sCumulativeOffset=0;if(options.numTicks){const n=options.numTicks;const sSpacing=5;const sHeight=5;const style={...options.style,strokeWidth:2};for(let i=0;i<n;i++){const sOffset=sSpacing*(i-(n-1)/2);const sOffsetVector=scaledPolarRad(sOffset,parallelAngle);const sHeightVector=scaledPolarRad(sHeight,perpendicularAngle);const sPath=[vector$3.add(sMidpoint,sOffsetVector,sHeightVector),vector$3.add(sMidpoint,sOffsetVector,reverseVector$1(sHeightVector))];temp.push(graphie.scaledPath(sPath,style));}sCumulativeOffset+=sSpacing*(n-1)+15;}if(options.numArrows){const n=options.numArrows;const start=[p1,p2].sort(function(a,b){if(a[1]===b[1]){return a[0]-b[0]}return a[1]-b[1]})[0];const sStart=graphie.scalePoint(start);const style={...options.style,arrows:"->",strokeWidth:2};const sSpacing=5;for(let i=0;i<n;i++){const sOffset=sCumulativeOffset+sSpacing*i;let sOffsetVector=scaledPolarRad(sOffset,parallelAngle);if(start!==p1){sOffsetVector=reverseVector$1(sOffsetVector);}const sEnd=vector$3.add(sMidpoint,sOffsetVector);temp.push(graphie.scaledPath([sStart,sEnd],style));}}let text=options.text;if(text){const match=text.match(/\$len(\d)?/);if(match){const distance=GraphUtils.getDistance(p1,p2);const precision=match[1]||1;text=text.replace(match[0],KhanMath.toFixedApprox(distance,precision));}const sOffset=20;const sOffsetVector=scaledPolarRad(sOffset,perpendicularAngle);const sPosition=vector$3.add(sMidpoint,sOffsetVector);const position=graphie.unscalePoint(sPosition);if(options.label){options.label.setPosition(position);options.label.processMath(text,true);}else {graphie.label(position,text,"center",options.style);}}return temp},labelVertex:function(options){const graphie=this;_.defaults(options,{point1:null,vertex:[0,0],point3:null,label:null,text:"",clockwise:false,style:{}});if(!options.text){return}const vertex=options.vertex;const sVertex=graphie.scalePoint(vertex);let p1;let p3;if(options.clockwise){p1=options.point1;p3=options.point3;}else {p1=options.point3;p3=options.point1;}let angle=135;let halfAngle;if(p1&&p3){const startAngle=GraphUtils.findAngleDeprecated(p1,vertex);const endAngle=GraphUtils.findAngleDeprecated(p3,vertex);angle=(endAngle+360-startAngle)%360;halfAngle=(startAngle+angle/2+180)%360;}else if(p1){const parallelAngle=GraphUtils.findAngleDeprecated(vertex,p1);halfAngle=parallelAngle+90;}else if(p3){const parallelAngle=GraphUtils.findAngleDeprecated(p3,vertex);halfAngle=parallelAngle+90;}else {halfAngle=135;}const sRadius=10+scaledDistanceFromAngle(360-angle);const sOffsetVector=scaledPolarDeg(sRadius,halfAngle);const sPosition=vector$3.add(sVertex,sOffsetVector);const position=graphie.unscalePoint(sPosition);if(options.label){options.label.setPosition(position);options.label.processMath(options.text,true);}else {graphie.label(position,options.text,"center",options.style);}},addMovablePoint:function(options){const movablePoint=$.extend(true,{graph:this,coord:[0,0],snapX:0,snapY:0,pointSize:4,highlight:false,dragging:false,visible:true,bounded:true,constraints:{fixed:false,constrainX:false,constrainY:false,fixedAngle:{},fixedDistance:{}},lineStarts:[],lineEnds:[],polygonVertices:[],normalStyle:{},highlightStyle:{fill:KhanColors.INTERACTING,stroke:KhanColors.INTERACTING},labelStyle:{color:KhanColors.INTERACTIVE},vertexLabel:"",mouseTarget:null},options);const normalColor=movablePoint.constraints.fixed?KhanColors.DYNAMIC:KhanColors.INTERACTIVE;movablePoint.normalStyle={fill:normalColor,stroke:normalColor,...options.normalStyle};if(options.coordX!==undefined){movablePoint.coord[0]=options.coordX;}if(options.coordY!==undefined){movablePoint.coord[1]=options.coordY;}const graph=movablePoint.graph;const applySnapAndConstraints=function(coord){if(movablePoint.visible&&movablePoint.bounded&&!movablePoint.constraints.fixed){coord=graph.constrainToBounds(coord,10);}let coordX=coord[0];let coordY=coord[1];if(movablePoint.snapX!==0){coordX=Math.round(coordX/movablePoint.snapX)*movablePoint.snapX;}if(movablePoint.snapY!==0){coordY=Math.round(coordY/movablePoint.snapY)*movablePoint.snapY;}if(movablePoint.constraints.fixedDistance.snapPoints){const mouse=graph.scalePoint(coord);let mouseX=mouse[0];let mouseY=mouse[1];const snapRadians=2*Math.PI/movablePoint.constraints.fixedDistance.snapPoints;const radius=movablePoint.constraints.fixedDistance.dist;const centerCoord=movablePoint.constraints.fixedDistance.point;const centerX=(centerCoord[0]-graph.range[0][0])*graph.scale[0];const centerY=(-centerCoord[1]+graph.range[1][1])*graph.scale[1];let mouseXrel=mouseX-centerX;let mouseYrel=-mouseY+centerY;let radians=Math.atan(mouseYrel/mouseXrel);const outsideArcTanRange=mouseXrel<0;if(outsideArcTanRange){radians+=Math.PI;}radians=Math.round(radians/snapRadians)*snapRadians;mouseXrel=radius*Math.cos(radians);mouseYrel=radius*Math.sin(radians);mouseX=mouseXrel+centerX;mouseY=-mouseYrel+centerY;coordX=KhanMath.roundTo(5,mouseX/graph.scale[0]+graph.range[0][0]);coordY=KhanMath.roundTo(5,graph.range[1][1]-mouseY/graph.scale[1]);}const result=movablePoint.applyConstraint([coordX,coordY]);return result};movablePoint.applyConstraint=function(coord,extraConstraints,override){let newCoord=coord.slice();const constraints={};if(override){$.extend(constraints,{fixed:false,constrainX:false,constrainY:false,fixedAngle:{},fixedDistance:{}},extraConstraints);}else {$.extend(constraints,this.constraints,extraConstraints);}if(constraints.constrainX){newCoord=[this.coord[0],coord[1]];}else if(constraints.constrainY){newCoord=[coord[0],this.coord[1]];}else if(typeof constraints.fixedAngle.angle==="number"&&typeof constraints.fixedDistance.dist==="number"){const vertex=constraints.fixedAngle.vertex.coord||constraints.fixedAngle.vertex;const ref=constraints.fixedAngle.ref.coord||constraints.fixedAngle.ref;const distPoint=constraints.fixedDistance.point.coord||constraints.fixedDistance.point;const constrainedAngle=(constraints.fixedAngle.angle+GraphUtils.findAngleDeprecated(ref,vertex))*Math.PI/180;const length=constraints.fixedDistance.dist;newCoord[0]=length*Math.cos(constrainedAngle)+distPoint[0];newCoord[1]=length*Math.sin(constrainedAngle)+distPoint[1];}else if(typeof constraints.fixedAngle.angle==="number"){const vertex=constraints.fixedAngle.vertex.coord||constraints.fixedAngle.vertex;const ref=constraints.fixedAngle.ref.coord||constraints.fixedAngle.ref;const constrainedAngle=(constraints.fixedAngle.angle+GraphUtils.findAngleDeprecated(ref,vertex))*Math.PI/180;const angle=GraphUtils.findAngleDeprecated(coord,vertex)*Math.PI/180;const distance=GraphUtils.getDistance(coord,vertex);let length=distance*Math.cos(constrainedAngle-angle);length=length<1?1:length;newCoord[0]=length*Math.cos(constrainedAngle)+vertex[0];newCoord[1]=length*Math.sin(constrainedAngle)+vertex[1];}else if(typeof constraints.fixedDistance.dist==="number"){const distPoint=constraints.fixedDistance.point.coord||constraints.fixedDistance.point;let angle=GraphUtils.findAngleDeprecated(coord,distPoint);const length=constraints.fixedDistance.dist;angle=angle*Math.PI/180;newCoord[0]=length*Math.cos(angle)+distPoint[0];newCoord[1]=length*Math.sin(angle)+distPoint[1];}else if(constraints.fixed){newCoord=movablePoint.coord;}return newCoord};movablePoint.coord=applySnapAndConstraints(movablePoint.coord);const highlightScale=2;if(movablePoint.visible){graph.style(movablePoint.normalStyle,function(){const radii=[movablePoint.pointSize/graph.scale[0],movablePoint.pointSize/graph.scale[1]];const options={maxScale:highlightScale,padding:2};movablePoint.visibleShape=new WrappedEllipse(graph,movablePoint.coord,radii,options);const{scale,...styleWithoutScale}=movablePoint.normalStyle;movablePoint.visibleShape.attr(styleWithoutScale);movablePoint.visibleShape.toFront();});}movablePoint.normalStyle.scale=1;movablePoint.highlightStyle.scale=highlightScale;if(movablePoint.vertexLabel){movablePoint.labeledVertex=this.label([0,0],"","center",movablePoint.labelStyle);}movablePoint.drawLabel=function(){if(movablePoint.vertexLabel){movablePoint.graph.labelVertex({vertex:movablePoint.coord,label:movablePoint.labeledVertex,text:movablePoint.vertexLabel,style:movablePoint.labelStyle});}};movablePoint.drawLabel();movablePoint.grab=function(offset){offset=offset||[0,0];$(document).on("vmousemove.point vmouseup.point",function(event){event.preventDefault();movablePoint.dragging=true;dragging=true;let coord=vector$3.add(graph.getMouseCoord(event),offset);coord=applySnapAndConstraints(coord);let coordX=coord[0];let coordY=coord[1];let mouseX;let mouseY;if(event.type==="vmousemove"){let doMove=true;if(typeof movablePoint.onMove==="function"){const result=movablePoint.onMove(coordX,coordY);if(result===false){doMove=false;}if(Array.isArray(result)){coordX=result[0];coordY=result[1];}}mouseX=(coordX-graph.range[0][0])*graph.scale[0];mouseY=(-coordY+graph.range[1][1])*graph.scale[1];if(doMove){const point=graph.unscalePoint([mouseX,mouseY]);movablePoint.visibleShape.moveTo(point);movablePoint.mouseTarget.moveTo(point);movablePoint.coord=[coordX,coordY];movablePoint.updateLineEnds();$(movablePoint).trigger("move");}movablePoint.drawLabel();}else if(event.type==="vmouseup"){$(document).unbind(".point");movablePoint.dragging=false;dragging=false;if(typeof movablePoint.onMoveEnd==="function"){const result=movablePoint.onMoveEnd(coordX,coordY);if(Array.isArray(result)){coordX=result[0];coordY=result[1];mouseX=(coordX-graph.range[0][0])*graph.scale[0];mouseY=(-coordY+graph.range[1][1])*graph.scale[1];const point=graph.unscalePoint([mouseX,mouseY]);movablePoint.visibleShape.moveTo(point);movablePoint.mouseTarget.moveTo(point);movablePoint.coord=[coordX,coordY];}}if(!movablePoint.highlight){movablePoint.visibleShape.animate(movablePoint.normalStyle,50);if(movablePoint.onUnhighlight){movablePoint.onUnhighlight();}}}});};if(movablePoint.visible&&!movablePoint.constraints.fixed){if(!movablePoint.mouseTarget){const radii=graph.unscaleVector(16);const options={mouselayer:true,padding:0,disableMouseEventsOnWrapper:true,interactiveKindForTesting:"movable-point"};movablePoint.mouseTarget=new WrappedEllipse(graph,movablePoint.coord,radii,options);movablePoint.mouseTarget.attr({fill:"#000",opacity:0});}const $mouseTarget=$(movablePoint.mouseTarget.getMouseTarget());$mouseTarget.css("cursor","move");$mouseTarget.on("vmousedown vmouseover vmouseout",function(event){if(event.type==="vmouseover"){movablePoint.highlight=true;if(!dragging){movablePoint.visibleShape.animate(movablePoint.highlightStyle,50);if(movablePoint.onHighlight){movablePoint.onHighlight();}}}else if(event.type==="vmouseout"){movablePoint.highlight=false;if(!movablePoint.dragging&&!dragging){movablePoint.visibleShape.animate(movablePoint.normalStyle,50);if(movablePoint.onUnhighlight){movablePoint.onUnhighlight();}}}else if(event.type==="vmousedown"&&(event.which===1||event.which===0)){event.preventDefault();const startCoord=movablePoint.coord;const startMouseCoord=graph.getMouseCoord(event);const isMouse=!("ontouchstart"in window);const touchOffset=isMouse?[0,0]:vector$3.subtract(startCoord,startMouseCoord);movablePoint.grab(touchOffset);}});}movablePoint.moveTo=function(coordX,coordY,updateLines){const distance=GraphUtils.getDistance(this.graph.scalePoint([coordX,coordY]),this.graph.scalePoint(this.coord));const time=distance*5;const cb=updateLines&&function(coord){movablePoint.coord=coord;movablePoint.updateLineEnds();};this.visibleShape.animateTo([coordX,coordY],time,cb);this.mouseTarget.animateTo([coordX,coordY],time,cb);this.coord=[coordX,coordY];if(typeof this.onMove==="function"){this.onMove(coordX,coordY);}};movablePoint.updateLineEnds=function(){$(this.lineStarts).each(function(){this.coordA=movablePoint.coord;this.transform();});$(this.lineEnds).each(function(){this.coordZ=movablePoint.coord;this.transform();});$(this.polygonVertices).each(function(){this.transform();});};movablePoint.setCoord=function(coord){if(this.visible){this.visibleShape.moveTo(coord);if(this.mouseTarget!=null){this.mouseTarget.moveTo(coord);}}this.coord=coord.slice();};movablePoint.setCoordConstrained=function(coord){this.setCoord(applySnapAndConstraints(coord));};movablePoint.toBack=function(){if(this.visible){if(this.mouseTarget!=null){this.mouseTarget.toBack();}this.visibleShape.toBack();}};movablePoint.toFront=function(){if(this.visible){if(this.mouseTarget!=null){this.mouseTarget.toFront();}this.visibleShape.toFront();}};movablePoint.remove=function(){if(this.visibleShape){this.visibleShape.remove();}if(this.mouseTarget){this.mouseTarget.remove();}if(this.labeledVertex){this.labeledVertex.remove();}};return movablePoint},addMovableLineSegment:function(options){const lineSegment=$.extend({graph:this,coordA:[0,0],coordZ:[1,1],snapX:0,snapY:0,fixed:false,ticks:0,normalStyle:{},highlightStyle:{stroke:tokenValue(semanticColor.core.border.instructive.default),"stroke-width":6},labelStyle:{stroke:KhanColors.INTERACTIVE,color:KhanColors.INTERACTIVE},highlight:false,dragging:false,tick:[],extendLine:false,extendRay:false,constraints:{fixed:false,constrainX:false,constrainY:false},sideLabel:"",vertexLabels:[],numArrows:0,numTicks:0,movePointsWithLine:false},options);const normalColor=lineSegment.fixed?KhanColors.DYNAMIC:KhanColors.INTERACTIVE;lineSegment.normalStyle={"stroke-width":2,stroke:normalColor,...options.normalStyle};lineSegment.arrowStyle={...lineSegment.normalStyle,color:lineSegment.normalStyle.stroke};if(options.pointA!==undefined){lineSegment.coordA=options.pointA.coord;lineSegment.pointA.lineStarts.push(lineSegment);}else if(options.coordA!==undefined){lineSegment.coordA=options.coordA.slice();}if(options.pointZ!==undefined){lineSegment.coordZ=options.pointZ.coord;lineSegment.pointZ.lineEnds.push(lineSegment);}else if(options.coordA!==undefined){lineSegment.coordA=lineSegment.coordA.slice();}const graph=lineSegment.graph;graph.style(lineSegment.normalStyle);for(let i=0;i<lineSegment.ticks;++i){lineSegment.tick[i]=InteractiveUtils.bogusShape;}let path=GraphUtils.unscaledSvgPath([[0,0],[1,0]]);for(let i=0;i<lineSegment.ticks;++i){const tickoffset=.5-(lineSegment.ticks-1+i*2)/graph.scale[0];path+=GraphUtils.unscaledSvgPath([[tickoffset,-7],[tickoffset,7]]);}options={thickness:Math.max(lineSegment.normalStyle["stroke-width"],lineSegment.highlightStyle["stroke-width"])};lineSegment.visibleLine=new WrappedLine(graph,[0,0],[1,0],options);lineSegment.visibleLine.attr(lineSegment.normalStyle);if(!lineSegment.fixed){const options={thickness:30,mouselayer:true,interactiveKindForTesting:"movable-line"};lineSegment.mouseTarget=new WrappedLine(graph,[0,0],[1,0],options);lineSegment.mouseTarget.attr({fill:"#000",opacity:0});}lineSegment.transform=function(syncToPoints){if(syncToPoints){if(typeof this.pointA==="object"){this.coordA=this.pointA.coord;}if(typeof this.pointZ==="object"){this.coordZ=this.pointZ.coord;}}const getScaledAngle=function(line){const scaledA=line.graph.scalePoint(line.coordA);const scaledZ=line.graph.scalePoint(line.coordZ);return vector$3.polarDegFromCart(vector$3.subtract(scaledZ,scaledA))[1]};const getClipPoint=function(graph,coord,angle){graph=lineSegment.graph;const xExtent=graph.range[0][1]-graph.range[0][0];const yExtent=graph.range[1][1]-graph.range[1][0];const distance=xExtent+yExtent;const angleVec=graph.unscaleVector(vector$3.cartFromPolarDeg(1,angle));const distVec=vector$3.scale(vector$3.normalize(angleVec),distance);const farCoord=vector$3.add(coord,distVec);const scaledAngle=vector$3.polarDegFromCart(angleVec)[1];const clipPoint=graph.constrainToBoundsOnAngle(farCoord,4,scaledAngle*Math.PI/180);return clipPoint};const angle=getScaledAngle(this);let start=this.coordA;let end=this.coordZ;if(this.extendLine){start=getClipPoint(graph,start,360-angle);end=getClipPoint(graph,end,(540-angle)%360);}else if(this.extendRay){end=getClipPoint(graph,start,360-angle);}const elements=[this.visibleLine];if(!this.fixed){elements.push(this.mouseTarget);}elements.forEach(function(element){element.moveTo(start,end);});if(this._arrows==null){this._arrows=[];if(this.extendLine){this._arrows.push(new Arrowhead$1(graph,this.normalStyle));this._arrows.push(new Arrowhead$1(graph,this.normalStyle));}else if(this.extendRay){this._arrows.push(new Arrowhead$1(graph,this.normalStyle));}}const coordForArrow=[this.coordA,this.coordZ];const angleForArrow=[360-angle,(540-angle)%360];this._arrows.forEach(function(arrow,i){arrow.toCoordAtAngle(coordForArrow[i],angleForArrow[i]);});_.invoke(this.temp,"remove");this.temp=[];const isClockwise=this.coordA[0]<this.coordZ[0]||this.coordA[0]===this.coordZ[0]&&this.coordA[1]>this.coordZ[1];if(this.sideLabel){this.temp.push(this.graph.labelSide({point1:this.coordA,point2:this.coordZ,label:this.labeledSide,text:this.sideLabel,numArrows:this.numArrows,numTicks:this.numTicks,clockwise:isClockwise,style:this.labelStyle}));}if(this.vertexLabels.length){this.graph.labelVertex({vertex:this.coordA,point3:this.coordZ,label:this.labeledVertices[0],text:this.vertexLabels[0],clockwise:isClockwise,style:this.labelStyle});this.graph.labelVertex({point1:this.coordA,vertex:this.coordZ,label:this.labeledVertices[1],text:this.vertexLabels[1],clockwise:isClockwise,style:this.labelStyle});}this.temp=this.temp.flat(Infinity);};lineSegment.toBack=function(){if(!lineSegment.fixed){lineSegment.mouseTarget.toBack();}lineSegment.visibleLine.toBack();};lineSegment.toFront=function(){if(!lineSegment.fixed){lineSegment.mouseTarget.toFront();}lineSegment.visibleLine.toFront();};lineSegment.remove=function(){if(!lineSegment.fixed){lineSegment.mouseTarget.remove();}lineSegment.visibleLine.remove();if(lineSegment.labeledSide){lineSegment.labeledSide.remove();}if(lineSegment.labeledVertices){_.invoke(lineSegment.labeledVertices,"remove");}if(lineSegment._arrows){_.invoke(lineSegment._arrows,"remove");}if(lineSegment.temp.length){_.invoke(lineSegment.temp,"remove");}};lineSegment.hide=function(){lineSegment.visibleLine.hide();if(lineSegment.temp.length){_.invoke(lineSegment.temp,"hide");}if(lineSegment._arrows){_.invoke(lineSegment._arrows,"hide");}};lineSegment.show=function(){lineSegment.visibleLine.show();if(lineSegment.temp.length){_.invoke(lineSegment.temp,"show");}if(lineSegment._arrows){_.invoke(lineSegment._arrows,"show");}};if(lineSegment.sideLabel){lineSegment.labeledSide=this.label([0,0],"","center",lineSegment.labelStyle);}if(lineSegment.vertexLabels.length){lineSegment.labeledVertices=lineSegment.vertexLabels.map(label=>{return this.label([0,0],"","center",lineSegment.labelStyle)});}if(!lineSegment.fixed&&!lineSegment.constraints.fixed){const $mouseTarget=$(lineSegment.mouseTarget.getMouseTarget());$mouseTarget.css("cursor","move");$mouseTarget.on("vmousedown vmouseover vmouseout",function(event){if(event.type==="vmouseover"){if(!dragging){lineSegment.highlight=true;lineSegment.visibleLine.animate(lineSegment.highlightStyle,50);lineSegment.arrowStyle={...lineSegment.arrowStyle,color:lineSegment.highlightStyle.stroke,stroke:lineSegment.highlightStyle.stroke};lineSegment.transform();}}else if(event.type==="vmouseout"){lineSegment.highlight=false;if(!lineSegment.dragging){lineSegment.visibleLine.animate(lineSegment.normalStyle,50);lineSegment.arrowStyle={...lineSegment.arrowStyle,color:lineSegment.normalStyle.stroke,stroke:lineSegment.normalStyle.stroke};lineSegment.transform();}}else if(event.type==="vmousedown"&&(event.which===1||event.which===0)){event.preventDefault();let coordX=(event.pageX-$(graph.raphael.canvas.parentNode).offset().left)/graph.scale[0]+graph.range[0][0];let coordY=graph.range[1][1]-(event.pageY-$(graph.raphael.canvas.parentNode).offset().top)/graph.scale[1];if(lineSegment.snapX>0){coordX=Math.round(coordX/lineSegment.snapX)*lineSegment.snapX;}if(lineSegment.snapY>0){coordY=Math.round(coordY/lineSegment.snapY)*lineSegment.snapY;}const mouseOffsetA=[lineSegment.coordA[0]-coordX,lineSegment.coordA[1]-coordY];const mouseOffsetZ=[lineSegment.coordZ[0]-coordX,lineSegment.coordZ[1]-coordY];const offsetLeft=-Math.min(graph.scaleVector(mouseOffsetA)[0],graph.scaleVector(mouseOffsetZ)[0]);const offsetRight=Math.max(graph.scaleVector(mouseOffsetA)[0],graph.scaleVector(mouseOffsetZ)[0]);const offsetTop=Math.max(graph.scaleVector(mouseOffsetA)[1],graph.scaleVector(mouseOffsetZ)[1]);const offsetBottom=-Math.min(graph.scaleVector(mouseOffsetA)[1],graph.scaleVector(mouseOffsetZ)[1]);$(document).on("vmousemove.lineSegment vmouseup.lineSegment",function(event){event.preventDefault();lineSegment.dragging=true;dragging=true;let mouseX=event.pageX-$(graph.raphael.canvas.parentNode).offset().left;let mouseY=event.pageY-$(graph.raphael.canvas.parentNode).offset().top;mouseX=Math.max(offsetLeft+10,Math.min(graph.xpixels-10-offsetRight,mouseX));mouseY=Math.max(offsetTop+10,Math.min(graph.ypixels-10-offsetBottom,mouseY));let coordX=mouseX/graph.scale[0]+graph.range[0][0];let coordY=graph.range[1][1]-mouseY/graph.scale[1];if(lineSegment.snapX>0){coordX=Math.round(coordX/lineSegment.snapX)*lineSegment.snapX;}if(lineSegment.snapY>0){coordY=Math.round(coordY/lineSegment.snapY)*lineSegment.snapY;}if(event.type==="vmousemove"){if(lineSegment.constraints.constrainX){coordX=lineSegment.coordA[0]-mouseOffsetA[0];}if(lineSegment.constraints.constrainY){coordY=lineSegment.coordA[1]-mouseOffsetA[1];}const dX=coordX+mouseOffsetA[0]-lineSegment.coordA[0];const dY=coordY+mouseOffsetA[1]-lineSegment.coordA[1];lineSegment.coordA=[coordX+mouseOffsetA[0],coordY+mouseOffsetA[1]];lineSegment.coordZ=[coordX+mouseOffsetZ[0],coordY+mouseOffsetZ[1]];lineSegment.transform();if(lineSegment.movePointsWithLine){if(typeof lineSegment.pointA==="object"){lineSegment.pointA.setCoord([lineSegment.pointA.coord[0]+dX,lineSegment.pointA.coord[1]+dY]);}if(typeof lineSegment.pointZ==="object"){lineSegment.pointZ.setCoord([lineSegment.pointZ.coord[0]+dX,lineSegment.pointZ.coord[1]+dY]);}}if(typeof lineSegment.onMove==="function"){lineSegment.onMove(dX,dY);}}else if(event.type==="vmouseup"){$(document).unbind(".lineSegment");lineSegment.dragging=false;dragging=false;if(!lineSegment.highlight){lineSegment.visibleLine.animate(lineSegment.normalStyle,50);lineSegment.arrowStyle={...lineSegment.arrowStyle,color:lineSegment.normalStyle.stroke,stroke:lineSegment.normalStyle.stroke};lineSegment.transform();}if(typeof lineSegment.onMoveEnd==="function"){lineSegment.onMoveEnd();}}$(lineSegment).trigger("move");});}});}if(lineSegment.pointA!==undefined){lineSegment.pointA.toFront();}if(lineSegment.pointZ!==undefined){lineSegment.pointZ.toFront();}lineSegment.transform();return lineSegment},addMovablePolygon:function(options){const graphie=this;const{points,...optionsWithoutPoints}=options;const polygon=$.extend({snapX:0,snapY:0,fixed:false,constrainToGraph:true,normalStyle:{},highlightStyle:{stroke:KhanColors.INTERACTING,"stroke-width":2,fill:KhanColors.INTERACTING,"fill-opacity":.05},pointHighlightStyle:{fill:KhanColors.INTERACTING,stroke:KhanColors.INTERACTING},labelStyle:{stroke:KhanColors.DYNAMIC,"stroke-width":1,color:KhanColors.DYNAMIC},angleLabels:[],showRightAngleMarkers:[],sideLabels:[],vertexLabels:[],numArcs:[],numArrows:[],numTicks:[],updateOnPointMove:true,closed:true},optionsWithoutPoints);const normalColor=polygon.fixed?KhanColors.DYNAMIC:KhanColors.INTERACTIVE;polygon.normalStyle={"stroke-width":2,"fill-opacity":0,fill:normalColor,stroke:normalColor,...options.normalStyle};polygon.points=options.points;const isPoint=function(coordOrPoint){return !Array.isArray(coordOrPoint)};polygon.update=function(){const n=polygon.points.length;polygon.coords=polygon.points.map(function(coordOrPoint,i){if(isPoint(coordOrPoint)){return coordOrPoint.coord}return coordOrPoint});polygon.left=Math.min(...polygon.coords.map(coord=>coord[0]));polygon.right=Math.max(...polygon.coords.map(coord=>coord[0]));polygon.top=Math.max(...polygon.coords.map(coord=>coord[1]));polygon.bottom=Math.min(...polygon.coords.map(coord=>coord[1]));let scaledCoords=polygon.coords.map(function(coord){return graphie.scalePoint(coord)});if(polygon.closed){scaledCoords.push(true);}else {scaledCoords=scaledCoords.concat([...scaledCoords].reverse());}polygon.path=GraphUtils.unscaledSvgPath(scaledCoords);_.invoke(polygon.temp,"remove");polygon.temp=[];const isClockwise=clockwise$3(polygon.coords);if(polygon.angleLabels.length||polygon.showRightAngleMarkers.length){polygon.labeledAngles.forEach(function(label,i){polygon.temp.push(graphie.labelAngle({point1:polygon.coords[(i-1+n)%n],vertex:polygon.coords[i],point3:polygon.coords[(i+1)%n],label:label,text:polygon.angleLabels[i],showRightAngleMarker:polygon.showRightAngleMarkers[i],numArcs:polygon.numArcs[i],clockwise:isClockwise,style:polygon.labelStyle}));});}if(polygon.sideLabels.length){polygon.labeledSides.forEach(function(label,i){polygon.temp.push(graphie.labelSide({point1:polygon.coords[i],point2:polygon.coords[(i+1)%n],label:label,text:polygon.sideLabels[i],numArrows:polygon.numArrows[i],numTicks:polygon.numTicks[i],clockwise:isClockwise,style:polygon.labelStyle}));});}if(polygon.vertexLabels.length){polygon.labeledVertices.forEach(function(label,i){graphie.labelVertex({point1:polygon.coords[(i-1+n)%n],vertex:polygon.coords[i],point3:polygon.coords[(i+1)%n],label:label,text:polygon.vertexLabels[i],clockwise:isClockwise,style:polygon.labelStyle});});}polygon.temp=polygon.temp.flat(Infinity);};polygon.transform=function(){polygon.update();polygon.visibleShape.attr({path:polygon.path});if(!polygon.fixed){polygon.mouseTarget.attr({path:polygon.path});}};polygon.remove=function(){polygon.visibleShape.remove();if(!polygon.fixed){polygon.mouseTarget.remove();}if(polygon.labeledAngles){_.invoke(polygon.labeledAngles,"remove");}if(polygon.labeledSides){_.invoke(polygon.labeledSides,"remove");}if(polygon.labeledVertices){_.invoke(polygon.labeledVertices,"remove");}if(polygon.temp.length){_.invoke(polygon.temp,"remove");}};polygon.toBack=function(){if(!polygon.fixed){polygon.mouseTarget.toBack();}polygon.visibleShape.toBack();};polygon.toFront=function(){if(!polygon.fixed){polygon.mouseTarget.toFront();}polygon.visibleShape.toFront();};if(polygon.updateOnPointMove){polygon.points.filter(isPoint).forEach(function(coordOrPoint){coordOrPoint.polygonVertices.push(polygon);});}polygon.coords=new Array(polygon.points.length);if(polygon.angleLabels.length){const numLabels=Math.max(polygon.angleLabels.length,polygon.showRightAngleMarkers.length);polygon.labeledAngles=Array.from({length:numLabels},()=>{return this.label([0,0],"","center",polygon.labelStyle)});}if(polygon.sideLabels.length){polygon.labeledSides=polygon.sideLabels.map(label=>{return this.label([0,0],"","center",polygon.labelStyle)});}if(polygon.vertexLabels.length){polygon.labeledVertices=polygon.vertexLabels.map(label=>{return this.label([0,0],"","center",polygon.labelStyle)});}polygon.update();polygon.visibleShape=graphie.raphael.path(polygon.path);polygon.visibleShape.attr(polygon.normalStyle);if(!polygon.fixed){polygon.mouseTarget=graphie.mouselayer.path(polygon.path);polygon.mouseTarget.attr({fill:"#000",opacity:0,cursor:"move"});$(polygon.mouseTarget[0]).on("vmousedown vmouseover vmouseout",function(event){if(event.type==="vmouseover"){if(!dragging||polygon.dragging){polygon.highlight=true;polygon.visibleShape.animate(polygon.highlightStyle,50);polygon.points.filter(isPoint).forEach(function(point){point.visibleShape.animate(polygon.pointHighlightStyle,50);});}}else if(event.type==="vmouseout"){polygon.highlight=false;if(!polygon.dragging){polygon.visibleShape.animate(polygon.normalStyle,50);const points=polygon.points.filter(isPoint);if(!points.some(point=>point.dragging)){points.forEach(function(point){point.visibleShape.animate(point.normalStyle,50);});}}}else if(event.type==="vmousedown"&&(event.which===1||event.which===0)){event.preventDefault();polygon.points.filter(isPoint).forEach(function(point){point.dragging=true;});let startX=(event.pageX-$(graphie.raphael.canvas.parentNode).offset().left)/graphie.scale[0]+graphie.range[0][0];let startY=graphie.range[1][1]-(event.pageY-$(graphie.raphael.canvas.parentNode).offset().top)/graphie.scale[1];if(polygon.snapX>0){startX=Math.round(startX/polygon.snapX)*polygon.snapX;}if(polygon.snapY>0){startY=Math.round(startY/polygon.snapY)*polygon.snapY;}let lastX=startX;let lastY=startY;const polygonCoords=polygon.coords.slice();const offsetLeft=(startX-polygon.left)*graphie.scale[0];const offsetRight=(polygon.right-startX)*graphie.scale[0];const offsetTop=(polygon.top-startY)*graphie.scale[1];const offsetBottom=(startY-polygon.bottom)*graphie.scale[1];$(document).on("vmousemove.polygon vmouseup.polygon",function(event){event.preventDefault();polygon.dragging=true;dragging=true;let mouseX=event.pageX-$(graphie.raphael.canvas.parentNode).offset().left;let mouseY=event.pageY-$(graphie.raphael.canvas.parentNode).offset().top;if(polygon.constrainToGraph){mouseX=Math.max(offsetLeft+10,Math.min(graphie.xpixels-10-offsetRight,mouseX));mouseY=Math.max(offsetTop+10,Math.min(graphie.ypixels-10-offsetBottom,mouseY));}let currentX=mouseX/graphie.scale[0]+graphie.range[0][0];let currentY=graphie.range[1][1]-mouseY/graphie.scale[1];if(polygon.snapX>0){currentX=Math.round(currentX/polygon.snapX)*polygon.snapX;}if(polygon.snapY>0){currentY=Math.round(currentY/polygon.snapY)*polygon.snapY;}if(event.type==="vmousemove"){let dX=currentX-startX;let dY=currentY-startY;let doMove=true;if(typeof polygon.onMove==="function"){const onMoveResult=polygon.onMove(dX,dY);if(onMoveResult===false){doMove=false;}else if(Array.isArray(onMoveResult)){dX=onMoveResult[0];dY=onMoveResult[1];currentX=startX+dX;currentY=startY+dY;}}const increment=function(i){return [polygonCoords[i][0]+dX,polygonCoords[i][1]+dY]};if(doMove){polygon.points.forEach(function(coordOrPoint,i){if(isPoint(coordOrPoint)){coordOrPoint.setCoord(increment(i));}else {polygon.points[i]=increment(i);}});polygon.transform();$(polygon).trigger("move");lastX=currentX;lastY=currentY;}}else if(event.type==="vmouseup"){$(document).unbind(".polygon");const points=polygon.points.filter(isPoint);points.forEach(function(point){point.dragging=false;});polygon.dragging=false;dragging=false;if(!polygon.highlight){polygon.visibleShape.animate(polygon.normalStyle,50);points.forEach(function(point){point.visibleShape.animate(point.normalStyle,50);});}if(typeof polygon.onMoveEnd==="function"){polygon.onMoveEnd(lastX-startX,lastY-startY);}}});}});}_.invoke(polygon.points.filter(isPoint),"toFront");return polygon},constrainToBounds:function(point,padding){const lower=this.unscalePoint([padding,this.ypixels-padding]);const upper=this.unscalePoint([this.xpixels-padding,padding]);const coordX=Math.max(lower[0],Math.min(upper[0],point[0]));const coordY=Math.max(lower[1],Math.min(upper[1],point[1]));return [coordX,coordY]},constrainToBoundsOnAngle:function(point,padding,angle){const lower=this.unscalePoint([padding,this.ypixels-padding]);const upper=this.unscalePoint([this.xpixels-padding,padding]);let result=point.slice();if(result[0]<lower[0]){result=[lower[0],result[1]+(lower[0]-result[0])*Math.tan(angle)];}else if(result[0]>upper[0]){result=[upper[0],result[1]-(result[0]-upper[0])*Math.tan(angle)];}if(result[1]<lower[1]){result=[result[0]+(lower[1]-result[1])/Math.tan(angle),lower[1]];}else if(result[1]>upper[1]){result=[result[0]-(result[1]-upper[1])/Math.tan(angle),upper[1]];}return result},addMovableAngle:function(options){return new MovableAngle(this,options)},addCircleGraph:function(options){const graphie=this;const circle=$.extend({center:[0,0],radius:2,snapX:.5,snapY:.5,snapRadius:.5,minRadius:1,centerConstraints:{},centerNormalStyle:{},centerHighlightStyle:{stroke:KhanColors.INTERACTING,fill:KhanColors.INTERACTING},circleNormalStyle:{stroke:KhanColors.INTERACTIVE,"fill-opacity":0},circleHighlightStyle:{stroke:KhanColors.INTERACTING,fill:KhanColors.INTERACTING,"fill-opacity":.05}},options);const normalColor=circle.centerConstraints.fixed?KhanColors.DYNAMIC:KhanColors.INTERACTIVE;const centerNormalStyle=options?options.centerNormalStyle:null;circle.centerNormalStyle={fill:normalColor,stroke:normalColor,...centerNormalStyle};circle.centerPoint=graphie.addMovablePoint({graph:graphie,coord:circle.center,normalStyle:circle.centerNormalStyle,snapX:circle.snapX,snapY:circle.snapY,constraints:circle.centerConstraints});circle.circ=graphie.circle(circle.center,circle.radius,circle.circleNormalStyle);circle.perim=graphie.mouselayer.circle(graphie.scalePoint(circle.center)[0],graphie.scalePoint(circle.center)[1],graphie.scaleVector(circle.radius)[0]).attr({"stroke-width":20,opacity:.002});if(!circle.centerConstraints.fixed){$(circle.centerPoint.mouseTarget.getMouseTarget()).on("vmouseover vmouseout",function(event){if(circle.centerPoint.highlight||circle.centerPoint.dragging){circle.circ.animate(circle.circleHighlightStyle,50);}else {circle.circ.animate(circle.circleNormalStyle,50);}});}circle.toFront=function(){circle.circ.toFront();circle.perim.toFront();circle.centerPoint.visibleShape.toFront();if(!circle.centerConstraints.fixed){circle.centerPoint.mouseTarget.toFront();}};circle.centerPoint.onMove=function(x,y){circle.toFront();circle.circ.attr({cx:graphie.scalePoint(x)[0],cy:graphie.scalePoint(y)[1]});circle.perim.attr({cx:graphie.scalePoint(x)[0],cy:graphie.scalePoint(y)[1]});if(circle.onMove){circle.onMove(x,y);}};$(circle.centerPoint).on("move",function(){circle.center=this.coord;$(circle).trigger("move");});circle.setCenter=function(x,y){circle.centerPoint.setCoord([x,y]);circle.centerPoint.onMove(x,y);circle.center=[x,y];};circle.setRadius=function(r){circle.radius=r;circle.perim.attr({r:graphie.scaleVector(r)[0]});circle.circ.attr({rx:graphie.scaleVector(r)[0],ry:graphie.scaleVector(r)[1]});};circle.remove=function(){circle.centerPoint.remove();circle.circ.remove();circle.perim.remove();};const cursorAxes=[[Math.PI*-1,Math.PI*-0.875,"ew-resize"],[Math.PI*-0.875,Math.PI*-0.625,"nesw-resize"],[Math.PI*-0.625,Math.PI*-0.375,"ns-resize"],[Math.PI*-0.375,Math.PI*-0.125,"nwse-resize"],[Math.PI*-0.125,Math.PI*.125,"ew-resize"],[Math.PI*.125,Math.PI*.375,"nesw-resize"],[Math.PI*.375,Math.PI*.625,"ns-resize"],[Math.PI*.625,Math.PI*.875,"nwse-resize"],[Math.PI*.875,Math.PI*1,"ew-resize"]];$(circle.perim.node).on("vmousemove",event=>{let[x,y]=this.getMouseCoord(event);x-=circle.center[0];y-=circle.center[1];const theta=Math.atan2(y,x);cursorAxes.forEach(function(axes){const[min,max,cursorName]=axes;if(theta>=min&&theta<max){$(circle.perim.node).css("cursor",cursorName);}});});$(circle.perim.node).css("cursor","nesw-resize");circle.perim.node.addEventListener("touchstart",function(event){event.preventDefault();},{passive:false});$(circle.perim.node).on("vmouseover vmouseout vmousedown",function(event){if(event.type==="vmouseover"){circle.highlight=true;if(!dragging){circle.circ.animate(circle.circleHighlightStyle,50);circle.centerPoint.visibleShape.animate(circle.centerHighlightStyle,50);}}else if(event.type==="vmouseout"){circle.highlight=false;if(!circle.dragging&&!circle.centerPoint.dragging){circle.circ.animate(circle.circleNormalStyle,50);circle.centerPoint.visibleShape.animate(circle.centerNormalStyle,50);}}else if(event.type==="vmousedown"&&(event.which===1||event.which===0)){event.preventDefault();circle.toFront();const startRadius=circle.radius;$(document).on("vmousemove vmouseup",function(event){event.preventDefault();circle.dragging=true;dragging=true;if(event.type==="vmousemove"){const coord=graphie.constrainToBounds(graphie.getMouseCoord(event),10);let radius=GraphUtils.getDistance(circle.centerPoint.coord,coord);radius=Math.max(circle.minRadius,Math.round(radius/circle.snapRadius)*circle.snapRadius);const oldRadius=circle.radius;let doResize=true;if(circle.onResize){const onResizeResult=circle.onResize(radius,oldRadius);if(typeof onResizeResult==="number"){radius=onResizeResult;}else if(onResizeResult===false){doResize=false;}}if(doResize){circle.setRadius(radius);$(circle).trigger("move");}}else if(event.type==="vmouseup"){$(document).off("vmousemove vmouseup");circle.dragging=false;dragging=false;if(circle.onResizeEnd){circle.onResizeEnd(circle.radius,startRadius);}}});}});return circle},addRotateHandle:function(){const drawRotateHandle=function(graphie,center,radius,halfWidth,lengthAngle,angle,interacting){const getRotateHandlePoint=function(offset,distanceFromArrowMidline){const distFromRotationCenter=radius+distanceFromArrowMidline;const vec=vector$3.cartFromPolarDeg(distFromRotationCenter,angle+offset);const absolute=vector$3.add(center,vec);const pixels=graphie.scalePoint(absolute);return pixels[0]+","+pixels[1]};const innerR=graphie.scaleVector(radius-halfWidth);const outerR=graphie.scaleVector(radius+halfWidth);return graphie.raphael.path(" M"+getRotateHandlePoint(lengthAngle,-halfWidth)+" L"+getRotateHandlePoint(lengthAngle,-3*halfWidth)+" L"+getRotateHandlePoint(2*lengthAngle,0)+" L"+getRotateHandlePoint(lengthAngle,3*halfWidth)+" L"+getRotateHandlePoint(lengthAngle,halfWidth)+" A"+outerR[0]+","+outerR[1]+",0,0,1,"+getRotateHandlePoint(-lengthAngle,halfWidth)+" L"+getRotateHandlePoint(-lengthAngle,3*halfWidth)+" L"+getRotateHandlePoint(-2*lengthAngle,0)+" L"+getRotateHandlePoint(-lengthAngle,-3*halfWidth)+" L"+getRotateHandlePoint(-lengthAngle,-halfWidth)+" A"+innerR[0]+","+innerR[1]+",0,0,0,"+getRotateHandlePoint(lengthAngle,-halfWidth)+" Z").attr({stroke:null,fill:interacting?KhanColors.INTERACTING:KhanColors.INTERACTIVE})};return function(options){const graph=this;let rotatePoint=options.center;const radius=options.radius;const lengthAngle=options.lengthAngle||30;const hideArrow=options.hideArrow||false;const mouseTarget=options.mouseTarget;const id=_.uniqueId("rotateHandle");if(Array.isArray(rotatePoint)){rotatePoint={coord:rotatePoint};}const rotateHandle=graph.addMovablePoint({coord:point.addVector(rotatePoint.coord,vector$3.cartFromPolarDeg(radius,options.angleDeg||0)),constraints:{fixedDistance:{dist:radius,point:rotatePoint}},mouseTarget:mouseTarget});rotatePoint.toFront();let rotatePointPrevCoord=rotatePoint.coord;let rotateHandlePrevCoord=rotateHandle.coord;let rotateHandleStartCoord=rotateHandlePrevCoord;let isRotating=false;let isHovering=false;let drawnRotateHandle;const redrawRotateHandle=function(handleCoord){if(hideArrow){return}const handleVec=vector$3.subtract(handleCoord,rotatePoint.coord);const handlePolar=vector$3.polarDegFromCart(handleVec);const angle=handlePolar[1];if(drawnRotateHandle){drawnRotateHandle.remove();}drawnRotateHandle=drawRotateHandle(graph,rotatePoint.coord,options.radius,isRotating||isHovering?options.hoverWidth/2:options.width/2,lengthAngle,angle,isRotating||isHovering);};$(rotatePoint).on("move."+id,function(){const delta=vector$3.subtract(rotatePoint.coord,rotatePointPrevCoord);rotateHandle.setCoord(vector$3.add(rotateHandle.coord,delta));redrawRotateHandle(rotateHandle.coord);rotatePointPrevCoord=rotatePoint.coord;rotateHandle.constraints.fixedDistance.point=rotatePoint;rotateHandlePrevCoord=rotateHandle.coord;});rotateHandle.onMove=function(x,y){if(!isRotating){rotateHandleStartCoord=rotateHandlePrevCoord;isRotating=true;}let coord=[x,y];if(options.onMove){const oldPolar=vector$3.polarDegFromCart(vector$3.subtract(rotateHandlePrevCoord,rotatePoint.coord));const newPolar=vector$3.polarDegFromCart(vector$3.subtract(coord,rotatePoint.coord));const oldAngle=oldPolar[1];const newAngle=newPolar[1];let result=options.onMove(newAngle,oldAngle);if(result!=null&&result!==true){if(result===false){result=oldAngle;}coord=vector$3.add(rotatePoint.coord,vector$3.cartFromPolarDeg(oldPolar[0],result));}}redrawRotateHandle(coord);rotateHandlePrevCoord=coord;return coord};rotateHandle.onMoveEnd=function(){isRotating=false;redrawRotateHandle(rotateHandle.coord);if(options.onMoveEnd){const oldPolar=vector$3.polarDegFromCart(vector$3.subtract(rotateHandleStartCoord,rotatePoint.coord));const newPolar=vector$3.polarDegFromCart(vector$3.subtract(rotateHandle.coord,rotatePoint.coord));options.onMoveEnd(newPolar[1],oldPolar[1]);}};rotateHandle.visibleShape.remove();if(!mouseTarget){rotateHandle.mouseTarget.attr({scale:2});}const $mouseTarget=$(rotateHandle.mouseTarget.getMouseTarget());$mouseTarget.on("vmouseover",function(e){isHovering=true;redrawRotateHandle(rotateHandle.coord);});$mouseTarget.on("vmouseout",function(e){isHovering=false;redrawRotateHandle(rotateHandle.coord);});redrawRotateHandle(rotateHandle.coord);const oldRemove=rotateHandle.remove;rotateHandle.remove=function(){oldRemove.call(rotateHandle);if(drawnRotateHandle){drawnRotateHandle.remove();}$(rotatePoint).off("move."+id);};rotateHandle.update=function(){redrawRotateHandle(rotateHandle.coord);};return rotateHandle}}(),addReflectButton:function(){const drawButton=function(graphie,buttonCoord,lineCoords,size,distanceFromCenter,leftStyle,rightStyle){if(point.equal(lineCoords[0],lineCoords[1])){lineCoords=[lineCoords[0],point.addVector(lineCoords[0],[1,1])];}const lineDirection=vector$3.normalize(vector$3.subtract(lineCoords[1],lineCoords[0]));const lineVec=vector$3.scale(lineDirection,size/2);const centerVec=vector$3.scale(lineDirection,distanceFromCenter);const leftCenterVec=vector$3.rotateDeg(centerVec,90);const rightCenterVec=vector$3.rotateDeg(centerVec,-90);const negLineVec=vector$3.negate(lineVec);const leftVec=vector$3.rotateDeg(lineVec,90);const rightVec=vector$3.rotateDeg(lineVec,-90);const leftCenter=point.addVectors(buttonCoord,leftCenterVec);const rightCenter=point.addVectors(buttonCoord,rightCenterVec);const leftCoord1=point.addVectors(buttonCoord,leftCenterVec,lineVec,leftVec);const leftCoord2=point.addVectors(buttonCoord,leftCenterVec,negLineVec,leftVec);const rightCoord1=point.addVectors(buttonCoord,rightCenterVec,lineVec,rightVec);const rightCoord2=point.addVectors(buttonCoord,rightCenterVec,negLineVec,rightVec);const leftButton=graphie.path([leftCenter,leftCoord1,leftCoord2,true],leftStyle);const rightButton=graphie.path([rightCenter,rightCoord1,rightCoord2,true],rightStyle);return {remove:function(){leftButton.remove();rightButton.remove();}}};return function(options){const graphie=this;const line$1=options.line;const button=graphie.addMovablePoint({constraints:options.constraints,coord:line.midpoint([line$1.pointA.coord,line$1.pointZ.coord]),snapX:graphie.snap[0],snapY:graphie.snap[1],onMove:function(x,y){return false},onMoveEnd:function(x,y){if(options.onMoveEnd){options.onMoveEnd.call(this,x,y);}}});let isHovering=false;let isFlipped=false;let currentlyDrawnButton;const isHighlight=function(){return isHovering};const styles=[0,1].map(function(isHighlight){const baseStyle=isHighlight?options.highlightStyle:options.normalStyle;return [0,1].map(function(opacity){return _.defaults({"fill-opacity":opacity},baseStyle)})});const getStyle=function(isRight){if(isFlipped){isRight=!isRight;}return styles[+isHighlight()][+isRight]};const redraw=function(coord,lineCoords){if(currentlyDrawnButton){currentlyDrawnButton.remove();}currentlyDrawnButton=drawButton(graphie,coord,lineCoords,isHighlight()?options.size*1.5:options.size,isHighlight()?options.size*.125:.25,getStyle(0),getStyle(1));};const update=function(coordA,coordZ){coordA=coordA||line$1.pointA.coord;coordZ=coordZ||line$1.pointZ.coord;const buttonCoord=line.midpoint([coordA,coordZ]);button.setCoord(buttonCoord);redraw(buttonCoord,[coordA,coordZ]);};$(line$1).on("move",()=>update(null,null));const $mouseTarget=$(button.mouseTarget.getMouseTarget());$mouseTarget.on("vclick",function(){const result=options.onClick();if(result!==false){isFlipped=!isFlipped;redraw(button.coord,[line$1.pointA.coord,line$1.pointZ.coord]);}});line$1.pointA.toFront();line$1.pointZ.toFront();button.visibleShape.remove();const pointScale=graphie.scaleVector(options.size)[0]/20;button.mouseTarget.attr({scale:1.5*pointScale});$mouseTarget.css("cursor","pointer");$mouseTarget.on("vmouseover",function(e){isHovering=true;redraw(button.coord,[line$1.pointA.coord,line$1.pointZ.coord]);});$mouseTarget.on("vmouseout",function(e){isHovering=false;redraw(button.coord,[line$1.pointA.coord,line$1.pointZ.coord]);});const oldButtonRemove=button.remove;button.remove=function(){currentlyDrawnButton.remove();oldButtonRemove.call(button);};button.update=update;button.isFlipped=function(){return isFlipped};update();return button}}(),protractor:function(center){return new Protractor$1(this,center)},ruler:function(options){return new Ruler(this,options||{})},addPoints:vector$3.add});function Protractor$1(graph,center){this.set=graph.raphael.set();this.cx=center[0];this.cy=center[1];const pro=this;const r=graph.unscaleVector(180.5)[0];const imgPos=graph.scalePoint([this.cx-r,this.cy+r-graph.unscaleVector(10.5)[1]]);const image=graph.mouselayer.image("https://ka-perseus-graphie.s3.amazonaws.com/e9d032f2ab8b95979f674fbfa67056442ba1ff6a.png",imgPos[0],imgPos[1],360,180);this.set.push(image);image.node.addEventListener("touchstart",function(event){event.preventDefault();},{passive:false});const arrowHelper=function(angle,pixelsFromEdge){const scaledRadius=graph.scaleVector(r);scaledRadius[0]-=16;scaledRadius[1]-=16;const scaledCenter=graph.scalePoint(center);const x=Math.sin((angle+90)*Math.PI/180)*(scaledRadius[0]+pixelsFromEdge)+scaledCenter[0];const y=Math.cos((angle+90)*Math.PI/180)*(scaledRadius[1]+pixelsFromEdge)+scaledCenter[1];return x+","+y};const arrow=graph.raphael.path(" M"+arrowHelper(180,6)+" L"+arrowHelper(180,2)+" L"+arrowHelper(183,10)+" L"+arrowHelper(180,18)+" L"+arrowHelper(180,14)+" A"+(graph.scaleVector(r)[0]+10)+","+(graph.scaleVector(r)[1]+10)+",0,0,1,"+arrowHelper(170,14)+" L"+arrowHelper(170,18)+" L"+arrowHelper(167,10)+" L"+arrowHelper(170,2)+" L"+arrowHelper(170,6)+" A"+(graph.scaleVector(r)[0]+10)+","+(graph.scaleVector(r)[1]+10)+",0,0,0,"+arrowHelper(180,6)+" Z").attr({stroke:null,fill:KhanColors.INTERACTIVE});this.set.push(arrow);this.centerPoint=graph.addMovablePoint({coord:center,visible:false});this.rotateHandle=graph.addMovablePoint({bounded:false,coord:[Math.sin(275*Math.PI/180)*r+this.cx,Math.cos(275*Math.PI/180)*r+this.cy],onMove:function(x,y){const angle=Math.atan2(pro.centerPoint.coord[1]-y,pro.centerPoint.coord[0]-x)*180/Math.PI;pro.rotate(-angle-5,true);}});this.rotateHandle.constraints.fixedDistance.dist=r;this.rotateHandle.constraints.fixedDistance.point=this.centerPoint;this.rotateHandle.visibleShape.remove();this.rotateHandle.mouseTarget.attr({scale:2});let isDragging=false;let isHovering=false;const isHighlight=function(){return isHovering||isDragging};const self=this;const $mouseTarget=$(self.rotateHandle.mouseTarget.getMouseTarget());$mouseTarget.on("vmousedown",function(event){isDragging=true;$mouseTarget.css("cursor","-webkit-grabbing");$mouseTarget.css("cursor","grabbing");arrow.animate({scale:1.5,fill:KhanColors.INTERACTING},50);$(document).on("vmouseup.rotateHandle",function(event){isDragging=false;$mouseTarget.css("cursor","-webkit-grab");$mouseTarget.css("cursor","grab");if(!isHighlight()){arrow.animate({scale:1,fill:KhanColors.INTERACTIVE},50);}$(document).unbind("vmouseup.rotateHandle");});});$mouseTarget.on("vmouseover",function(event){isHovering=true;arrow.animate({scale:1.5,fill:KhanColors.INTERACTING},50);});$mouseTarget.on("vmouseout",function(event){isHovering=false;if(!isHighlight()){arrow.animate({scale:1,fill:KhanColors.INTERACTIVE},50);}});const setNodes=$.map(this.set,function(el){return el.node});this.makeTranslatable=function makeTranslatable(){$(setNodes).css("cursor","move");$mouseTarget.css("cursor","-webkit-grab");$mouseTarget.css("cursor","grab");$(setNodes).on("vmousedown",function(event){event.preventDefault();let startx=event.pageX-$(graph.raphael.canvas.parentNode).offset().left;let starty=event.pageY-$(graph.raphael.canvas.parentNode).offset().top;$(document).on("vmousemove.protractor",function(event){let mouseX=event.pageX-$(graph.raphael.canvas.parentNode).offset().left;let mouseY=event.pageY-$(graph.raphael.canvas.parentNode).offset().top;mouseX=Math.max(10,Math.min(graph.xpixels-10,mouseX));mouseY=Math.max(10,Math.min(graph.ypixels-10,mouseY));const dx=mouseX-startx;const dy=mouseY-starty;$.each(pro.set.items,function(){this.translate(dx,dy);});pro.centerPoint.setCoord([pro.centerPoint.coord[0]+dx/graph.scale[0],pro.centerPoint.coord[1]-dy/graph.scale[1]]);pro.rotateHandle.setCoord([pro.rotateHandle.coord[0]+dx/graph.scale[0],pro.rotateHandle.coord[1]-dy/graph.scale[1]]);startx=mouseX;starty=mouseY;});$(document).one("vmouseup",function(event){$(document).unbind("vmousemove.protractor");});});};this.rotation=0;this.rotate=function(offset,absolute){const center=graph.scalePoint(this.centerPoint.coord);if(absolute){this.rotation=0;}this.set.rotate(this.rotation+offset,center[0],center[1]);this.rotation=this.rotation+offset;return this};this.moveTo=function moveTo(x,y){const start=graph.scalePoint(pro.centerPoint.coord);const end=graph.scalePoint([x,y]);const time=GraphUtils.getDistance(start,end)*2;$({x:start[0],y:start[1]}).animate({x:end[0],y:end[1]},{duration:time,step:function(now,fx){let dx=0;let dy=0;if(fx.prop==="x"){dx=now-graph.scalePoint(pro.centerPoint.coord)[0];}else if(fx.prop==="y"){dy=now-graph.scalePoint(pro.centerPoint.coord)[1];}$.each(pro.set.items,function(){this.translate(dx,dy);});pro.centerPoint.setCoord([pro.centerPoint.coord[0]+dx/graph.scale[0],pro.centerPoint.coord[1]-dy/graph.scale[1]]);pro.rotateHandle.setCoord([pro.rotateHandle.coord[0]+dx/graph.scale[0],pro.rotateHandle.coord[1]-dy/graph.scale[1]]);}});};this.rotateTo=function rotateTo(angle){if(Math.abs(this.rotation-angle)>180){this.rotation+=360;}const time=Math.abs(this.rotation-angle)*5;$({0:this.rotation}).animate({0:angle},{duration:time,step:function(now,fx){pro.rotate(now,true);pro.rotateHandle.setCoord([Math.sin((now+275)*Math.PI/180)*r+pro.centerPoint.coord[0],Math.cos((now+275)*Math.PI/180)*r+pro.centerPoint.coord[1]]);}});};this.remove=function(){this.set.remove();};this.makeTranslatable();return this}function Ruler(graphie,options){_.defaults(options,{center:[0,0],pixelsPerUnit:40,ticksPerUnit:10,units:10,label:"",style:{fill:null,stroke:KhanColors.GRAY}});const light={...options.style,strokeWidth:1};const bold={...options.style,strokeWidth:2};const width=options.units*options.pixelsPerUnit;const height=50;const leftBottom=graphie.unscalePoint(vector$3.subtract(graphie.scalePoint(options.center),vector$3.scale([width,-50],.5)));const graphieUnitsPerUnit=options.pixelsPerUnit/graphie.scale[0];const graphieUnitsHeight=height/graphie.scale[0];const rightTop=vector$3.add(leftBottom,[options.units*graphieUnitsPerUnit,graphieUnitsHeight]);const tickHeight=1;let tickHeightMap;if(options.ticksPerUnit===10){tickHeightMap={10:tickHeight,5:tickHeight*.55,1:tickHeight*.35};}else {const sizes=[1,.6,.45,.3];tickHeightMap={};for(let i=options.ticksPerUnit;i>=1;i/=2){tickHeightMap[i]=tickHeight*(sizes.shift()||.2);}}const tickFrequencies=Object.keys(tickHeightMap).sort(function(a,b){return b-a});function getTickHeight(i){for(let k=0;k<tickFrequencies.length;k++){const key=tickFrequencies[k];if(i%key===0){return tickHeightMap[key]}}return 0}const left=leftBottom[0];const bottom=leftBottom[1];const right=rightTop[0];const top=rightTop[1];const numTicks=options.units*options.ticksPerUnit+1;const set=graphie.raphael.set();const px=1/graphie.scale[0];set.push(graphie.line([left-px,bottom],[right+px,bottom],bold));set.push(graphie.line([left-px,top],[right+px,top],bold));for(let i=0;i<numTicks;i++){const n=i/options.ticksPerUnit;const x=left+n*graphieUnitsPerUnit;const height=getTickHeight(i)*graphieUnitsHeight;const style=i===0||i===numTicks-1?bold:light;set.push(graphie.line([x,bottom],[x,bottom+height],style));if(n%1===0){const coord=graphie.scalePoint([x,top]);let text;let offset;if(n===0){text=options.label;offset=({mm:13,cm:11,m:8,km:11,in:8,ft:8,yd:10,mi:10})[text]||3*text.toString().length;}else {text=n;offset=-3*(n.toString().length+1);}const label=graphie.raphael.text(coord[0]+offset,coord[1]+10,text);label.attr({"font-family":"KaTeX_Main","font-size":"12px",color:"#444"});set.push(label);}}const mouseTarget=graphie.mouselayer.path(graphie.svgPath([leftBottom,[left,top],rightTop,[right,bottom],true]));mouseTarget.attr({fill:"#000",opacity:0,stroke:"#000","stroke-width":2});set.push(mouseTarget);mouseTarget.node.addEventListener("touchstart",function(event){event.preventDefault();},{passive:false});const setNodes=$.map(set,function(el){return el.node});$(setNodes).css("cursor","move");$(setNodes).on("vmousedown",function(event){event.preventDefault();let startx=event.pageX-$(graphie.raphael.canvas.parentNode).offset().left;let starty=event.pageY-$(graphie.raphael.canvas.parentNode).offset().top;$(document).on("vmousemove.ruler",function(event){let mouseX=event.pageX-$(graphie.raphael.canvas.parentNode).offset().left;let mouseY=event.pageY-$(graphie.raphael.canvas.parentNode).offset().top;mouseX=Math.max(10,Math.min(graphie.xpixels-10,mouseX));mouseY=Math.max(10,Math.min(graphie.ypixels-10,mouseY));const dx=mouseX-startx;const dy=mouseY-starty;set.translate(dx,dy);leftBottomHandle.setCoord([leftBottomHandle.coord[0]+dx/graphie.scale[0],leftBottomHandle.coord[1]-dy/graphie.scale[1]]);rightBottomHandle.setCoord([rightBottomHandle.coord[0]+dx/graphie.scale[0],rightBottomHandle.coord[1]-dy/graphie.scale[1]]);startx=mouseX;starty=mouseY;});$(document).one("vmouseup",function(event){$(document).unbind("vmousemove.ruler");});});const leftBottomHandle=graphie.addMovablePoint({coord:leftBottom,normalStyle:{fill:KhanColors.INTERACTIVE,"fill-opacity":0,stroke:KhanColors.INTERACTIVE},highlightStyle:{fill:KhanColors.INTERACTING,"fill-opacity":.1,stroke:KhanColors.INTERACTING},pointSize:6,onMove:function(x,y){const dy=rightBottomHandle.coord[1]-y;const dx=rightBottomHandle.coord[0]-x;const angle=Math.atan2(dy,dx)*180/Math.PI;const center=vector$3.scale(vector$3.add([x,y],rightBottomHandle.coord),.5);const scaledCenter=graphie.scalePoint(center);const oldCenter=vector$3.scale(vector$3.add(leftBottomHandle.coord,rightBottomHandle.coord),.5);const scaledOldCenter=graphie.scalePoint(oldCenter);const diff=vector$3.subtract(scaledCenter,scaledOldCenter);set.rotate(-angle,scaledOldCenter[0],scaledOldCenter[1]);set.translate(diff[0],diff[1]);}});const rightBottomHandle=graphie.addMovablePoint({coord:[right,bottom],normalStyle:{fill:KhanColors.INTERACTIVE,"fill-opacity":0,stroke:KhanColors.INTERACTIVE},highlightStyle:{fill:KhanColors.INTERACTING,"fill-opacity":.1,stroke:KhanColors.INTERACTING},pointSize:6,onMove:function(x,y){const dy=y-leftBottomHandle.coord[1];const dx=x-leftBottomHandle.coord[0];const angle=Math.atan2(dy,dx)*180/Math.PI;const center=vector$3.scale(vector$3.add([x,y],leftBottomHandle.coord),.5);const scaledCenter=graphie.scalePoint(center);const oldCenter=vector$3.scale(vector$3.add(leftBottomHandle.coord,rightBottomHandle.coord),.5);const scaledOldCenter=graphie.scalePoint(oldCenter);const diff=vector$3.subtract(scaledCenter,scaledOldCenter);set.rotate(-angle,scaledOldCenter[0],scaledOldCenter[1]);set.translate(diff[0],diff[1]);}});leftBottomHandle.constraints.fixedDistance.dist=width/graphie.scale[0];leftBottomHandle.constraints.fixedDistance.point=rightBottomHandle;rightBottomHandle.constraints.fixedDistance.dist=width/graphie.scale[0];rightBottomHandle.constraints.fixedDistance.point=leftBottomHandle;this.remove=function(){set.remove();leftBottomHandle.remove();rightBottomHandle.remove();};return this}function MovableAngle(graphie,options){this.graphie=graphie;Object.assign(this,options);_.defaults(this,{normalStyle:{stroke:KhanColors.INTERACTIVE,"stroke-width":2,fill:KhanColors.INTERACTIVE},highlightStyle:{stroke:KhanColors.INTERACTING,"stroke-width":2,fill:KhanColors.INTERACTING},labelStyle:{stroke:KhanColors.DYNAMIC,"stroke-width":1,color:KhanColors.DYNAMIC},angleStyle:{stroke:KhanColors.DYNAMIC,"stroke-width":1,color:KhanColors.DYNAMIC},allowReflex:true});if(!this.points||this.points.length!==3){throw new PerseusError("MovableAngle requires 3 points",Errors.InvalidInput)}this.points=options.points.map(point=>{if(Array.isArray(point)){return graphie.addMovablePoint({coord:point,visible:false,constraints:{fixed:true},normalStyle:this.normalStyle})}return point});this.coords=this.points.map(point=>point.coord);if(this.reflex==null){if(this.allowReflex){this.reflex=this._getClockwiseAngle(this.coords)>180;}else {this.reflex=false;}}this.rays=[0,2].map(i=>{return graphie.addMovableLineSegment({pointA:this.points[1],pointZ:this.points[i],fixed:true,extendRay:true})});this.temp=[];this.labeledAngle=graphie.label([0,0],"","center",this.labelStyle);if(!this.fixed){this.addMoveHandlers();this.addHighlightHandlers();}this.update();}_.extend(MovableAngle.prototype,{points:[],snapDegrees:0,snapOffsetDeg:0,angleLabel:"",numArcs:1,pushOut:0,fixed:false,addMoveHandlers:function(){const graphie=this.graphie;function tooClose(point1,point2){const safeDistance=30;const distance=GraphUtils.getDistance(graphie.scalePoint(point1),graphie.scalePoint(point2));return distance<safeDistance}const points=this.points;points[1].onMove=function(x,y){const oldVertex=points[1].coord;const newVertex=[x,y];const delta=vector$3.add(newVertex,reverseVector$1(oldVertex));let valid=true;const newPoints={};[0,2].forEach(function(i){const oldPoint=points[i].coord;let newPoint=vector$3.add(oldPoint,delta);let angle=GraphUtils.findAngleDeprecated(newVertex,newPoint);angle*=Math.PI/180;newPoint=graphie.constrainToBoundsOnAngle(newPoint,10,angle);newPoints[i]=newPoint;if(tooClose(newVertex,newPoint)){valid=false;}});if(valid){Object.entries(newPoints).forEach(function([i,newPoint]){points[i].setCoord(newPoint);});}return valid};const snap=this.snapDegrees;const snapOffset=this.snapOffsetDeg;[0,2].forEach(function(i){points[i].onMove=function(x,y){const newPoint=[x,y];const vertex=points[1].coord;if(tooClose(vertex,newPoint)){return false}if(snap){let angle=GraphUtils.findAngleDeprecated(newPoint,vertex);angle=Math.round((angle-snapOffset)/snap)*snap+snapOffset;const distance=GraphUtils.getDistance(newPoint,vertex);return vector$3.add(vertex,polar$2(distance,angle))}return true};});$(points).on("move",()=>{this.update();$(this).trigger("move");});},addHighlightHandlers:function(){const vertex=this.points[1];vertex.onHighlight=()=>{this.points.forEach(point=>{point.visibleShape.animate(this.highlightStyle,50);});this.rays.forEach(ray=>{ray.visibleLine.animate(this.highlightStyle,50);ray.arrowStyle={...ray.arrowStyle,color:this.highlightStyle.stroke,stroke:this.highlightStyle.stroke};});this.angleStyle={...this.angleStyle,color:this.highlightStyle.stroke,stroke:this.highlightStyle.stroke};this.update();};vertex.onUnhighlight=()=>{this.points.forEach(point=>{point.visibleShape.animate(this.normalStyle,50);});this.rays.forEach(ray=>{ray.visibleLine.animate(ray.normalStyle,50);ray.arrowStyle={...ray.arrowStyle,color:ray.normalStyle.stroke,stroke:ray.normalStyle.stroke};});this.angleStyle={...this.angleStyle,color:KhanColors.DYNAMIC,stroke:KhanColors.DYNAMIC};this.update();};},_getClockwiseAngle:function(coords){const rawAngle=GraphUtils.findAngleDeprecated(coords[2],coords[0],coords[1]);const clockwiseAngle=rawAngle+360%360;return clockwiseAngle},isReflex:function(){return this.reflex},isClockwise:function(){const clockwiseReflexive=this._getClockwiseAngle(this.coords)>180;return clockwiseReflexive===this.reflex},getClockwiseCoords:function(){if(this.isClockwise()){return [...this.coords]}return [...this.coords].reverse()},update:function(shouldChangeReflexivity){const prevCoords=this.coords;this.coords=this.points.map(point=>point.coord);_.invoke(this.points,"updateLineEnds");const prevAngle=this._getClockwiseAngle(prevCoords);const angle=this._getClockwiseAngle(this.coords);const prevClockwiseReflexive=prevAngle>180;const clockwiseReflexive=angle>180;if(this.allowReflex){if(shouldChangeReflexivity==null){shouldChangeReflexivity=prevClockwiseReflexive!==clockwiseReflexive&&Math.abs(angle-prevAngle)<180;}if(shouldChangeReflexivity){this.reflex=!this.reflex;}}_.invoke(this.temp,"remove");this.temp=this.graphie.labelAngle({point1:this.coords[0],vertex:this.coords[1],point3:this.coords[2],label:this.labeledAngle,text:this.angleLabel,numArcs:this.numArcs,pushOut:this.pushOut,clockwise:this.reflex===clockwiseReflexive,style:this.angleStyle});},remove:function(){_.invoke(this.rays,"remove");_.invoke(this.temp,"remove");this.labeledAngle.remove();}});
|
|
1574
1574
|
|
|
1575
|
-
const nestedMap$1=Util.nestedMap;function GraphieMovable$1(descriptor){_.extend(this,descriptor);}const abstractMethod=function(){throw new PerseusError("Abstract method! Must be implemented by Graphie Movable"+this.constructor.displayName,Errors.NotAllowed)};_.extend(GraphieMovable$1.prototype,{movableProps:[],add:abstractMethod,modify:abstractMethod,remove:abstractMethod,toFront:function(){},componentDidMount:function(){}});const rewriteProps=function(props,childrenArray){return _.extend({},props,{children:_.filter(_.flatten(childrenArray),
|
|
1575
|
+
const nestedMap$1=Util.nestedMap;function GraphieMovable$1(descriptor){_.extend(this,descriptor);}const abstractMethod=function(){throw new PerseusError("Abstract method! Must be implemented by Graphie Movable"+this.constructor.displayName,Errors.NotAllowed)};_.extend(GraphieMovable$1.prototype,{movableProps:[],add:abstractMethod,modify:abstractMethod,remove:abstractMethod,toFront:function(){},componentDidMount:function(){}});const rewriteProps=function(props,childrenArray){return _.extend({},props,{children:_.filter(_.flatten(childrenArray),c=>c)})};const createClass=function(spec){const GraphieClass=function(props){if(!(this instanceof GraphieClass)){throw new PerseusError("Use createElement or JSX with graphie movables",Errors.NotAllowed)}this.props=rewriteProps(props,props.children||[]);return this};spec.displayName=spec.displayName||_.uniqueId("GraphieClass");GraphieClass.displayName=spec.displayName;GraphieClass.prototype=new GraphieMovable$1(spec);GraphieClass.prototype.constructor=GraphieClass;return GraphieClass};const createSimpleClass=function(addFunction){return createClass({displayName:addFunction.name||_.uniqueId("GraphieSimpleClass"),movableProps:["children"],add:function(graphie){this._elements=addFunction(graphie,this.props);this._prevProps=this.props;},modify:function(graphie){if(!approximateDeepEqual(this.props,this._prevProps)){this.remove();this.add(graphie);this._prevProps=this.props;return "reordered"}},remove:function(){nestedMap$1(this._elements,elem=>{if(elem){elem.remove();}});this._elements=null;this._prevProps=null;},toFront:function(){nestedMap$1(this._elements,elem=>{if(elem&&typeof elem.toFront==="function"){elem.toFront();}});}})};var GraphieClasses = {GraphieMovable:GraphieMovable$1,createClass:createClass,createSimpleClass:createSimpleClass};
|
|
1576
1576
|
|
|
1577
1577
|
const normalizeOptions$3=InteractiveUtil.normalizeOptions;const assert$6=InteractiveUtil.assert;const DEFAULT_PROPS$3={cursor:null};const DEFAULT_STATE$3={added:false,isHovering:false,isMouseOver:false,isDragging:false,mouseTarget:null};class Movable{modify(options){this.update({...this._createDefaultState(),...options});}_createDefaultState(){return {id:this.state.id,add:[],modify:[],draw:[],remove:[],onMoveStart:[],onMove:[],onMoveEnd:[],onClick:[],...DEFAULT_PROPS$3}}update(options){const graphie=this.graphie;const prevState=this.cloneState();const state=Object.assign(this.state,normalizeOptions$3(options));if(state.mouseTarget&&!prevState.mouseTarget){let $mouseTarget;if(state.mouseTarget.getMouseTarget){$mouseTarget=$(state.mouseTarget.getMouseTarget());}else {$mouseTarget=$(state.mouseTarget[0]);}const isMouse=!("ontouchstart"in window);if(isMouse){$mouseTarget.on("vmouseover",()=>{state.isMouseOver=true;if(!graphie.isDragging){state.isHovering=true;}if(this.state.added){this.draw();}});$mouseTarget.on("vmouseout",()=>{state.isMouseOver=false;if(!state.isDragging){state.isHovering=false;}if(this.state.added){this.draw();}});}$mouseTarget[0].addEventListener("touchstart",function(event){event.preventDefault();},{passive:false});$mouseTarget.on("vmousedown",e=>{if(e.which!==0&&e.which!==1){return}e.preventDefault();const mouseCoord=graphie.getMouseCoord(e);this.grab(mouseCoord);});}if(state.mouseTarget&&state.cursor!==undefined){let $mouseTarget;if(state.mouseTarget.getMouseTarget){$mouseTarget=$(state.mouseTarget.getMouseTarget());}else {$mouseTarget=$(state.mouseTarget[0]);}$mouseTarget.css("cursor",state.cursor||"");}if(!state.added){this._fireEvent(state.modify,this.cloneState(),{});state.added=true;this.prevState=this.cloneState();}this._fireEvent(state.modify,this.cloneState(),this.prevState);}cloneState(){return {...this.state}}_fireEvent(listeners,...args){if(listeners==null){return}for(const listener of listeners){listener.call(this,...args);}}draw(){const currState=this.cloneState();this._fireEvent(this.state.draw,currState,this.prevState);this.prevState=currState;}grab(coord){assert$6(point.is(coord));const graphie=this.graphie;const state=this.state;state.isHovering=true;state.isDragging=true;graphie.isDragging=true;const startMouseCoord=coord;let prevMouseCoord=startMouseCoord;this._fireEvent(state.onMoveStart,startMouseCoord,startMouseCoord);const moveHandler=e=>{e.preventDefault();const mouseCoord=graphie.getMouseCoord(e);this._fireEvent(state.onMove,mouseCoord,prevMouseCoord);this.draw();prevMouseCoord=mouseCoord;};const upHandler=()=>{$(document).unbind("vmousemove",moveHandler);$(document).unbind("vmouseup",upHandler);if(state.isHovering){this._fireEvent(state.onClick,prevMouseCoord,startMouseCoord);}state.isHovering=this.state.isMouseOver;state.isDragging=false;graphie.isDragging=false;this._fireEvent(state.onMoveEnd,prevMouseCoord,startMouseCoord);this.draw();};$(document).on("vmousemove",moveHandler);$(document).on("vmouseup",upHandler);}_applyConstraints(current,previous,extraOptions){let skipRemaining=false;return (this.state.constraints??[]).reduce((memo,constraint)=>{if(memo===false){return false}if(skipRemaining){return memo}const result=constraint.call(this,memo,previous,{onSkipRemaining:()=>{skipRemaining=true;},...extraOptions});if(result===false){return false}if(point.is(result,2)){return result}if(result===true||result==null){return memo}throw new PerseusError("Constraint returned invalid result: "+result,Errors.Internal)},current)}toBack(){if(this.state.mouseTarget){this.state.mouseTarget.toBack();}}toFront(){if(this.state.mouseTarget){this.state.mouseTarget.toFront();}}listen(eventName,id,func){this._listenerMap=this._listenerMap||{};const key=getKey$1(eventName,id);const index=this._listenerMap[key]=this._listenerMap[key]||this.state[eventName].length;this.state[eventName][index]=func;}unlisten(eventName,id){this._listenerMap=this._listenerMap||{};const key=getKey$1(eventName,id);const index=this._listenerMap[key];if(index!==undefined){this.state[eventName].splice(index,1);delete this._listenerMap[key];const keys=Object.keys(this._listenerMap);keys.forEach(key=>{if(getEventName$1(key)===eventName&&this._listenerMap[key]>index){this._listenerMap[key]--;}});}}remove(){this.state.added=false;this._fireEvent(this.state.remove);if(this.state.mouseTarget){$(this.state.mouseTarget).off();this.state.mouseTarget.remove();this.state.mouseTarget=null;}}cursor(){return this.state.cursor}added(){return this.state.added}isHovering(){return this.state.isHovering}isMouseOver(){return this.state.isMouseOver}isDragging(){return this.state.isDragging}mouseTarget(){return this.state.mouseTarget}constructor(graphie,options){this._listenerMap={};this.graphie=graphie;this.state={id:_.uniqueId("movable")};this.modify({...DEFAULT_STATE$3,...options});}}function getKey$1(eventName,id){return eventName+":"+id}function getEventName$1(key){return key.split(":")[0]}
|
|
1578
1578
|
|
|
@@ -1584,9 +1584,9 @@ const InlineIcon=({path,width,height,style={},title})=>jsxRuntimeExports.jsxs("s
|
|
|
1584
1584
|
|
|
1585
1585
|
const iconCheck={path:`M8.70710678,12.2928932 C8.31658249,11.9023689 7.68341751,11.9023689 7.29289322,12.2928932 C6.90236893,12.6834175 6.90236893,13.3165825 7.29289322,13.7071068 L9.82842712,16.2426407 C10.2207367,16.6349502 10.8574274,16.6328935 11.2471942,16.2380576 L16.7116603,10.7025237 C17.0996535,10.3094846 17.0955629,9.67633279 16.7025237,9.28833966 C16.3094846,8.90034653 15.6763328,8.90443714 15.2883397,9.29747629 L10.5309507,14.1167372 L8.70710678,12.2928932 Z`,width:24,height:24};const iconChevronDown={path:"M99.669 13.048q0 3.36-2.352 5.712l-41.664 41.664q-2.408 2.408-5.88 2.408t-5.712-2.408l-41.664-41.664q-2.408-2.24-2.408-5.712t2.408-5.88l4.76-4.816q2.52-2.352 5.88-2.352t5.656 2.352l31.136 31.136 31.08-31.136q2.352-2.352 5.712-2.352t5.88 2.352l4.816 4.816q2.352 2.52 2.352 5.88z",width:100,height:63.034};const iconCircle={path:"M100.035 50.046q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",width:100,height:100};const iconCircleThin={path:"M50.046 8.322q-8.493 0-16.188 3.306-15.561 6.669-22.173 22.23-3.363 7.695-3.363 16.188t3.306 16.188 8.949 13.281q5.586 5.586 13.281 8.892t16.188 3.306 16.188-3.306 13.281-8.892 8.892-13.281 3.306-16.188-3.306-16.188-8.892-13.281-13.281-8.949q-7.695-3.306-16.188-3.306zm0 91.713q-13.623 0-25.137-6.726t-18.183-18.183q-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.126q-11.514 6.726-25.08 6.726z",width:100,height:99.944};const iconOk={path:"M37.964 76.048q-2.576 0-4.368-1.792l-31.864-31.864q-1.792-1.792-1.792-4.368t1.792-4.368l8.736-8.68q1.792-1.792 4.368-1.792t4.312 1.792l18.816 18.872 42-42.056q1.792-1.792 4.368-1.792t4.312 1.792l8.736 8.736q1.792 1.792 1.792 4.368t-1.792 4.312l-55.048 55.048q-1.792 1.792-4.368 1.792z",width:100,height:76.637};const iconRemove={path:"M100.464 80.808q0 3.404-2.368 5.772l-11.47 11.544q-2.368 2.368-5.772 2.368t-5.698-2.368l-24.864-24.864-24.864 24.864q-2.368 2.368-5.772 2.368t-5.772-2.368l-11.47-11.544q-2.368-2.368-2.368-5.772t2.368-5.698l24.864-24.864-24.864-24.864q-2.368-2.368-2.368-5.772t2.368-5.772l11.47-11.47q2.368-2.368 5.772-2.368t5.772 2.368l24.864 24.864 24.864-24.864q2.294-2.368 5.698-2.368t5.772 2.368l11.47 11.47q2.368 2.368 2.368 5.772t-2.368 5.772l-24.864 24.864 24.864 24.864q2.368 2.294 2.368 5.698z",width:100,height:100};const iconStar={path:"M15.1052249,9.55978547 L22.0028147,9.55978545 C23.6568673,9.55978545 23.9349557,10.3753626 22.6181351,11.3858845 L16.9943688,15.7015366 L19.2518801,22.8294455 C19.7526645,24.4106317 19.0984455,24.8825885 17.769353,23.8673293 L12.0490577,19.4977438 L6.5116497,23.8422153 C5.20921411,24.8640642 4.53299569,24.4067544 5.00266927,22.8160582 L7.10332364,15.7015366 L1.42794544,11.3634306 C0.110226041,10.3562014 0.383967283,9.54239221 2.0409646,9.54574013 L8.9924676,9.55978547 L11.1485117,2.72669438 C11.6458693,1.15043244 12.4548928,1.15900049 12.9494787,2.72669438 L15.1052249,9.55978547 Z",width:24,height:24};const iconTryAgain={path:"M3.74890556,17.9799506 C2.19251241,16.1970909 1.10103636,13.4971457 1.13090903,11.1491783 C1.17160478,7.95052637 4.01704076,0.865059407 11.7028044,0.865059407 C19.388568,0.865059407 22.3026521,7.35203035 22.3026521,11.5879453 C22.3026521,15.8238603 19.386629,20.5574509 13.6832464,21.7131548 L13.6757539,17.3722171 C17.0812986,16.2190517 18.331158,14.1944123 18.3311578,11.5879451 C18.3311574,8.16554692 15.6664205,5.03476549 11.7028048,5.20494205 C7.73918903,5.37511861 5.59244567,8.66930079 5.59244567,11.1491783 C5.59244567,12.9090077 6.11128139,14.1753512 6.93640437,15.3053215 L8.14052356,14.2949456 C8.98559348,13.5858477 9.6994861,13.9070448 9.73489556,15.0076413 L9.91284941,20.5388014 C9.94832683,21.6415103 9.09967118,22.3514475 8.02194403,22.1254594 L2.60571602,20.9897332 C1.5259204,20.7633114 1.34338662,19.9984207 2.18070755,19.295825 L3.74890556,17.9799506 Z",width:23,height:23};const iconTrash={path:"M31.293 37.506q2.052 0 2.052 2.109l0 37.506q0 1.995-2.052 2.109l-4.218 0q-.912-.057-1.482-.627t-.57-1.482l0-37.506q0-2.109 2.052-2.109l4.218 0zm18.753 2.109l0 37.506q0 .912-.57 1.482t-1.539.627l-4.161 0q-1.995 0-2.109-2.109l0-37.506q.057-.912.627-1.482t1.482-.627l4.161 0q.969.057 1.539.627t.57 1.482zm14.592-2.109q2.052 0 2.052 2.109l0 37.506q0 1.995-2.052 2.109l-4.161 0q-.969-.057-1.539-.627t-.57-1.482l0-37.506q0-2.109 2.109-2.109l4.161 0zm10.431 49.248l0-61.731l-58.368 0l0 61.731q.057 2.679.969 3.819t1.083 1.14l54.207 0q.171 0 1.14-1.083t.969-3.876zm-43.776-70.11l29.184 0l-3.135-7.581q-.456-.57-1.14-.741l-20.634 0q-.627.114-1.083.741zm-31.293 2.109q0-1.995 2.109-2.109l20.121 0l4.56-10.83q.969-2.394 3.477-4.104 2.565-1.71 5.187-1.71l20.805 0q2.622 0 5.187 1.71t3.477 4.104l4.56 10.83l20.178 0q.912.057 1.482.627t.57 1.482l0 4.161q0 1.995-2.052 2.109l-6.27 0l0 61.731q0 5.415-3.078 9.348t-7.353 3.933l-54.207 0q-4.275 0-7.353-3.819t-3.078-9.177l0-62.016l-6.213 0q-.969 0-1.539-.57t-.57-1.539l0-4.161z",width:91.681,height:100};const iconMinus={path:`M8,13 L16,13 C16.5522847,13 17,12.5522847 17,12 C17,11.4477153 16.5522847,11 16,11 L8,11 C7.44771525,11 7,11.4477153 7,12 C7,12.5522847 7.44771525,13 8,13 Z`,width:24,height:24};
|
|
1586
1586
|
|
|
1587
|
-
const add$1={constrain:function(){this.constrain();}};add$1.standard=[add$1.constrain];const modify$1={draw:function(){this.draw();}};modify$1.standard=[modify$1.draw];const draw$1={basic:function(state,prevState){const graphie=this.graphie;if(!this.state.visibleShape){const radii=[this.pointSize()/graphie.scale[0],this.pointSize()/graphie.scale[1]];const options={maxScale:Math.max(this.highlightStyle().scale,this.normalStyle().scale),padding:10,shadow:state.shadow};this.state.visibleShape=new WrappedEllipse(graphie,this.coord(),radii,options);this.state.visibleShape.attr(_.omit(this.normalStyle(),"scale"));this.state.visibleShape.toFront();if(this.mouseTarget()){this.mouseTarget().toFront();}}if(state.normalStyle!==prevState.normalStyle&&!_.isEqual(state.normalStyle,prevState.normalStyle)){this.state.visibleShape.attr(this.normalStyle());}this.state.visibleShape.moveTo(this.coord());if(this.mouseTarget()){this.mouseTarget().moveTo(this.coord());}},highlight:function(state,prevState){if(state.isHovering&&!prevState.isHovering){state.visibleShape.animate(this.highlightStyle(),50);}else if(!state.isHovering&&prevState.isHovering){state.visibleShape.animate(this.normalStyle(),50);}}};draw$1.standard=[draw$1.basic,draw$1.highlight];const remove$1={basic:function(){if(this.state.visibleShape){this.state.visibleShape.remove();this.state.visibleShape=null;}}};remove$1.standard=remove$1.basic;const constraints$1={fixed:function(){return function(){return false}},snap:function(snap){return function(coord){if(snap===null){return true}return point.roundTo(coord,snap||this.graphie.snap)}},bound:function(range,snap,optionalPaddingPx){const paddingPx=(()=>{if(optionalPaddingPx===undefined){if(range===undefined){return 10}else {return 0}}else {return optionalPaddingPx}})();return function(coord,prev,options){const graphie=this.graphie;range=range||graphie.range;if(snap===undefined){snap=graphie.snap;}let lower=graphie.unscalePoint([paddingPx,graphie.ypixels-paddingPx]);let upper=graphie.unscalePoint([graphie.xpixels-paddingPx,paddingPx]);if(snap){lower=point.ceilTo(lower,snap);upper=point.floorTo(upper,snap);}if(!!options&&!!options.onOutOfBounds){if(coord[0]>upper[0]||coord[0]<lower[0]||coord[1]>upper[1]||coord[1]<lower[1]){options.onSkipRemaining();options.onOutOfBounds();}return coord}const coordX=Math.max(lower[0],Math.min(upper[0],coord[0]));const coordY=Math.max(lower[1],Math.min(upper[1],coord[1]));return [coordX,coordY]}}};constraints$1.standard=null;var MovablePointOptions = {add:add$1,modify:modify$1,draw:draw$1,remove:remove$1,onMoveStart:{standard:null},constraints:constraints$1,onMove:{standard:null},onMoveEnd:{standard:null},onClick:{standard:null}};
|
|
1587
|
+
const add$1={constrain:function(){this.constrain();}};add$1.standard=[add$1.constrain];const modify$1={draw:function(){this.draw();}};modify$1.standard=[modify$1.draw];const draw$1={basic:function(state,prevState){const graphie=this.graphie;if(!this.state.visibleShape){const radii=[this.pointSize()/graphie.scale[0],this.pointSize()/graphie.scale[1]];const options={maxScale:Math.max(this.highlightStyle().scale,this.normalStyle().scale),padding:10,shadow:state.shadow};this.state.visibleShape=new WrappedEllipse(graphie,this.coord(),radii,options);this.state.visibleShape.attr(_.omit(this.normalStyle(),"scale"));this.state.visibleShape.toFront();if(this.mouseTarget()){this.mouseTarget().toFront();}}if(state.shadow!==prevState.shadow){this.state.visibleShape.setShadow(state.shadow);}if(state.normalStyle!==prevState.normalStyle&&!_.isEqual(state.normalStyle,prevState.normalStyle)){this.state.visibleShape.attr(this.normalStyle());}this.state.visibleShape.moveTo(this.coord());if(this.mouseTarget()){this.mouseTarget().moveTo(this.coord());}},highlight:function(state,prevState){if(state.isHovering&&!prevState.isHovering){state.visibleShape.animate(this.highlightStyle(),50);}else if(!state.isHovering&&prevState.isHovering){state.visibleShape.animate(this.normalStyle(),50);}}};draw$1.standard=[draw$1.basic,draw$1.highlight];const remove$1={basic:function(){if(this.state.visibleShape){this.state.visibleShape.remove();this.state.visibleShape=null;}}};remove$1.standard=remove$1.basic;const constraints$1={fixed:function(){return function(){return false}},snap:function(snap){return function(coord){if(snap===null){return true}return point.roundTo(coord,snap||this.graphie.snap)}},bound:function(range,snap,optionalPaddingPx){const paddingPx=(()=>{if(optionalPaddingPx===undefined){if(range===undefined){return 10}else {return 0}}else {return optionalPaddingPx}})();return function(coord,prev,options){const graphie=this.graphie;range=range||graphie.range;if(snap===undefined){snap=graphie.snap;}let lower=graphie.unscalePoint([paddingPx,graphie.ypixels-paddingPx]);let upper=graphie.unscalePoint([graphie.xpixels-paddingPx,paddingPx]);if(snap){lower=point.ceilTo(lower,snap);upper=point.floorTo(upper,snap);}if(!!options&&!!options.onOutOfBounds){if(coord[0]>upper[0]||coord[0]<lower[0]||coord[1]>upper[1]||coord[1]<lower[1]){options.onSkipRemaining();options.onOutOfBounds();}return coord}const coordX=Math.max(lower[0],Math.min(upper[0],coord[0]));const coordY=Math.max(lower[1],Math.min(upper[1],coord[1]));return [coordX,coordY]}}};constraints$1.standard=null;var MovablePointOptions = {add:add$1,modify:modify$1,draw:draw$1,remove:remove$1,onMoveStart:{standard:null},constraints:constraints$1,onMove:{standard:null},onMoveEnd:{standard:null},onClick:{standard:null}};
|
|
1588
1588
|
|
|
1589
|
-
const assert$4=InteractiveUtil.assert;const normalizeOptions$1=InteractiveUtil.normalizeOptions;const{processMath}=Tex$1;const DEFAULT_PROPS$1={coord:[0,0],pointSize:4,static:false,cursor:"move",normalStyle:null,highlightStyle:null,shadow:false,tooltip:false};const DEFAULT_STATE$1={added:false,hasMoved:false,visibleShape:null,outOfBounds:false,mouseTarget:null,touchOffset:null};const tooltipResetFunctions=[];let MovablePoint$5 = class MovablePoint{modify(options){this.update(_.extend(this._createDefaultState(),options));}_createDefaultState(){return {id:this.state.id,...normalizeOptions$1(pluck(MovablePointOptions,"standard")),...DEFAULT_PROPS$1}}cloneState(){return {...this.movable.cloneState(),...this.state}}update(options){const self=this;const graphie=self.graphie;const state=_.extend(self.state,normalizeOptions$1(options));assert$4(point.is(state.coord));const movableColor=tokenValue(state.static?semanticColor.core.foreground.disabled.strong:semanticColor.core.foreground.instructive.default);state.normalStyle=_.extend({fill:movableColor,stroke:movableColor,scale:1},state.normalStyle);state.highlightStyle=_.extend({fill:movableColor,stroke:movableColor,scale:2},state.highlightStyle);if(!state.static){if(!state.mouseTarget){const center=self.state.coord;const radii=graphie.unscaleVector(24);const options={mouselayer:true,padding:0,interactiveKindForTesting:"movable-point"};state.mouseTarget=new WrappedEllipse(graphie,center,radii,options);state.mouseTarget.attr({fill:"#000",opacity:0});}}const showTrashTooltip=()=>{this._showTooltip(container=>{render(jsxRuntimeExports.jsx("span",{style:{fontSize:"2em"},children:jsxRuntimeExports.jsx(InlineIcon,{...iconTrash,style:{position:"static",color:movableColor,marginInlineStart:9,marginInlineEnd:9}})}),container);});};let startCoord=state.coord;self.movable.modify(_.extend({},state,{add:null,modify:null,draw:self.draw.bind(self),remove:null,onMoveStart:startMouseCoord=>{state.hasMoved=false;startCoord=state.coord;if(state.touchOffset==null){const isMouse=!("ontouchstart"in window);state.touchOffset=isMouse?[0,0]:vector$3.subtract(startCoord,startMouseCoord);}const svgElem=state.visibleShape.wrapper;if(state.shadow){const filter="none";svgElem.style.filter=filter;}if(state.showHairlines){state.showHairlines(state.coord);}tooltipResetFunctions.forEach(f=>f());if(state.tooltip){if(state.xOnlyTooltip){this._showTooltip(`${state.coord[0]}`);}else {this._showTooltip(`(${state.coord[0]}, ${state.coord[1]})`);}if(state.shadow){const content=svgElem.getElementsByClassName("tooltip-content")[0];const filter="drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.5))";content.style.filter=filter;}}self._fireEvent(state.onMoveStart,startCoord,startCoord);self.draw();},onMove:(mouseCoord,prevMouseCoord)=>{const transformedCoord=vector$3.add(mouseCoord,state.touchOffset);self.moveTo(transformedCoord);if(state.showHairlines){if(!this.state.outOfBounds){state.showHairlines(state.coord);}else {state.hideHairlines();}}if(state.tooltip){if(!this.state.outOfBounds){if(state.xOnlyTooltip){this._showTooltip(`${state.coord[0]}`);}else {this._showTooltip(`(${state.coord[0]}, ${state.coord[1]})`);}}}if(state.onRemove&&this.state.outOfBounds){showTrashTooltip();}},onMoveEnd:()=>{if(self.isHovering()&&!state.hasMoved){self._fireEvent(state.onClick,state.coord,startCoord);}const svgElem=state.visibleShape.wrapper;if(state.shadow){const filter=
|
|
1589
|
+
const assert$4=InteractiveUtil.assert;const normalizeOptions$1=InteractiveUtil.normalizeOptions;const{processMath}=Tex$1;const DEFAULT_PROPS$1={coord:[0,0],pointSize:4,static:false,cursor:"move",normalStyle:null,highlightStyle:null,shadow:false,tooltip:false};const DEFAULT_STATE$1={added:false,hasMoved:false,visibleShape:null,outOfBounds:false,mouseTarget:null,touchOffset:null};const tooltipResetFunctions=[];let MovablePoint$5 = class MovablePoint{modify(options){this.update(_.extend(this._createDefaultState(),options));}_createDefaultState(){return {id:this.state.id,...normalizeOptions$1(pluck(MovablePointOptions,"standard")),...DEFAULT_PROPS$1}}cloneState(){return {...this.movable.cloneState(),...this.state}}update(options){const self=this;const graphie=self.graphie;const state=_.extend(self.state,normalizeOptions$1(options));assert$4(point.is(state.coord));const movableColor=tokenValue(state.static?semanticColor.core.foreground.disabled.strong:semanticColor.core.foreground.instructive.default);state.normalStyle=_.extend({fill:movableColor,stroke:movableColor,scale:1},state.normalStyle);state.highlightStyle=_.extend({fill:movableColor,stroke:movableColor,scale:2},state.highlightStyle);if(!state.static){if(!state.mouseTarget){const center=self.state.coord;const radii=graphie.unscaleVector(24);const options={mouselayer:true,padding:0,interactiveKindForTesting:"movable-point"};state.mouseTarget=new WrappedEllipse(graphie,center,radii,options);state.mouseTarget.attr({fill:"#000",opacity:0});}}const showTrashTooltip=()=>{this._showTooltip(container=>{render(jsxRuntimeExports.jsx("span",{style:{fontSize:"2em"},children:jsxRuntimeExports.jsx(InlineIcon,{...iconTrash,style:{position:"static",color:movableColor,marginInlineStart:9,marginInlineEnd:9}})}),container);});};let startCoord=state.coord;self.movable.modify(_.extend({},state,{add:null,modify:null,draw:self.draw.bind(self),remove:null,onMoveStart:startMouseCoord=>{state.hasMoved=false;startCoord=state.coord;if(state.touchOffset==null){const isMouse=!("ontouchstart"in window);state.touchOffset=isMouse?[0,0]:vector$3.subtract(startCoord,startMouseCoord);}const svgElem=state.visibleShape.wrapper;if(state.shadow){const filter="none";svgElem.style.filter=filter;}if(state.showHairlines){state.showHairlines(state.coord);}tooltipResetFunctions.forEach(f=>f());if(state.tooltip){if(state.xOnlyTooltip){this._showTooltip(`${state.coord[0]}`);}else {this._showTooltip(`(${state.coord[0]}, ${state.coord[1]})`);}if(state.shadow){const content=svgElem.getElementsByClassName("tooltip-content")[0];const filter="drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.5))";content.style.filter=filter;}}self._fireEvent(state.onMoveStart,startCoord,startCoord);self.draw();},onMove:(mouseCoord,prevMouseCoord)=>{const transformedCoord=vector$3.add(mouseCoord,state.touchOffset);self.moveTo(transformedCoord);if(state.showHairlines){if(!this.state.outOfBounds){state.showHairlines(state.coord);}else {state.hideHairlines();}}if(state.tooltip){if(!this.state.outOfBounds){if(state.xOnlyTooltip){this._showTooltip(`${state.coord[0]}`);}else {this._showTooltip(`(${state.coord[0]}, ${state.coord[1]})`);}}}if(state.onRemove&&this.state.outOfBounds){showTrashTooltip();}},onMoveEnd:()=>{if(self.isHovering()&&!state.hasMoved){self._fireEvent(state.onClick,state.coord,startCoord);}const svgElem=state.visibleShape.wrapper;if(state.shadow){const filter=wrappedEllipseShadow;svgElem.style.filter=filter;}if(state.hideHairlines){state.hideHairlines();}if(state.hasMoved){this._hideTooltip();}else if(state.onRemove){showTrashTooltip();const content=svgElem.getElementsByClassName("tooltip-content")[0];content.style.filter="none";this._tooltip.firstChild.addEventListener("touchstart",e=>{e.stopPropagation();},true);this._tooltip.firstChild.addEventListener("touchend",e=>{state.onRemove();e.stopPropagation();},true);}else if(state.tooltip){this._hideTooltip();}if(state.outOfBounds){state.onRemove();}self._fireEvent(state.onMoveEnd,state.coord,startCoord);state.hasMoved=false;state.touchOffset=null;self.draw();}}));if(!state.added){self.prevState={};self._fireEvent(state.add,self.cloneState(),self.prevState);state.added=true;self.prevState=self.cloneState();}self._fireEvent(state.modify,self.cloneState(),self.prevState);}draw(){const currState=this.cloneState();this._fireEvent(this.state.draw,currState,this.prevState);this.prevState=currState;}constrain(){const result=this._applyConstraints(this.coord(),this.coord());if(point.is(result)){this.setCoord(result);}return result!==false}_fireEvent(listeners,...args){for(const listener of listeners){listener.call(this,...args);}}_applyConstraints(current,previous,extraOptions){let skipRemaining=false;return this.state.constraints.reduce((memo,constraint)=>{if(memo===false){return false}if(skipRemaining){return memo}const result=constraint.call(this,memo,previous,{onSkipRemaining:()=>{skipRemaining=true;},...extraOptions});if(result===false){return false}if(point.is(result,2)){return result}if(result===true||result==null){return memo}throw new PerseusError("Constraint returned invalid result: "+result,Errors.Internal)},current)}_showTooltip(contents){if(!this._tooltip){this._tooltip=document.createElement("div");this._tooltip.className="tooltip-content";this.state.visibleShape.wrapper.className="tooltip";this.state.visibleShape.wrapper.appendChild(this._tooltip);tooltipResetFunctions.push(()=>{if(this.state.added){this._hideTooltip();}});}if(this._tooltip.firstChild){this._tooltip.removeChild(this._tooltip.firstChild);}this.state.visibleShape.wrapper.className="tooltip visible";this._tooltip.appendChild(document.createElement("span"));if(typeof contents==="string"){processMath(this._tooltip.firstChild,contents,false);}else if(typeof contents==="function"){contents(this._tooltip.firstChild);}else {this._tooltip.firstChild.appendChild(contents);}}_hideTooltip(){if(this._tooltip){this.state.visibleShape.wrapper.className="tooltip";}}coord(){return this.state.coord}setCoord(coord){assert$4(point.is(coord,2));this.state.coord=_.clone(coord);this.draw();}setCoordConstrained(coord){assert$4(point.is(coord,2));const result=this._applyConstraints(coord,this.coord());if(result!==false){this.state.coord=_.clone(result);this.draw();}}listen(eventName,id,func){this._listenerMap=this._listenerMap||{};const key=getKey(eventName,id);const index=this._listenerMap[key]=this._listenerMap[key]||this.state[eventName].length;this.state[eventName][index]=func;}unlisten(eventName,id){this._listenerMap=this._listenerMap||{};const key=getKey(eventName,id);const index=this._listenerMap[key];if(index!==undefined){this.state[eventName].splice(index,1);delete this._listenerMap[key];const keys=Object.keys(this._listenerMap);_.each(keys,key=>{if(getEventName(key)===eventName&&this._listenerMap[key]>index){this._listenerMap[key]--;}},this);}}grab(coord){this.state.touchOffset=[0,0];this.movable.grab(coord);this.moveTo(coord);}moveTo(coord){const state=this.state;this.state.outOfBounds=false;const result=this._applyConstraints(coord,state.coord,state.onRemove?{onOutOfBounds:()=>{this.state.outOfBounds=true;},onSkipRemaining:()=>{}}:{onSkipRemaining:()=>{}});if(result===false){return}if(point.is(result)){coord=result;}if(!point.equal(coord,state.coord)){const prevCoord=state.coord;state.coord=coord;state.hasMoved=true;this._fireEvent(state.onMove,state.coord,prevCoord);this.draw();}}remove(){this.state.added=false;this._fireEvent(this.state.remove);if(this.movable){this.movable.remove();}this.state.mouseTarget=null;}pointSize(){return this.state.pointSize}static(){return this.state.static}cursor(){return this.state.cursor}normalStyle(){return this.state.normalStyle}highlightStyle(){return this.state.highlightStyle}shadow(){return this.state.shadow}tooltip(){return this.state.tooltip}added(){return this.state.added}hasMoved(){return this.state.hasMoved}visibleShape(){return this.state.visibleShape}outOfBounds(){return this.state.outOfBounds}mouseTarget(){return this.state.mouseTarget}touchOffset(){return this.state.touchOffset}isHovering(){return this.movable.isHovering()}isDragging(){return this.movable.isDragging()}toBack(){this.movable.toBack();if(this.state.visibleShape){this.state.visibleShape.toBack();}}toFront(){if(this.state.visibleShape){this.state.visibleShape.toFront();}this.movable.toFront();}constructor(graphie,movable,options){this._listenerMap={};this.graphie=graphie;this.movable=movable;this.state={id:_.uniqueId("movablePoint")};this.modify({...DEFAULT_STATE$1,...options});}};MovablePoint$5.add=MovablePointOptions.add;MovablePoint$5.modify=MovablePointOptions.modify;MovablePoint$5.draw=MovablePointOptions.draw;MovablePoint$5.remove=MovablePointOptions.remove;MovablePoint$5.onMoveStart=MovablePointOptions.onMoveStart;MovablePoint$5.constraints=MovablePointOptions.constraints;MovablePoint$5.onMove=MovablePointOptions.onMove;MovablePoint$5.onMoveEnd=MovablePointOptions.onMoveEnd;MovablePoint$5.onClick=MovablePointOptions.onClick;function getKey(eventName,id){return eventName+":"+id}function getEventName(key){return key.split(":")[0]}
|
|
1590
1590
|
|
|
1591
1591
|
function sum(array){return _.reduce(array,function(memo,arg){return memo+arg},0)}function clockwise$2(points){const segments=_.zip(points,points.slice(1).concat(points.slice(0,1)));const areas=segments.map(function(segment){const p1=segment[0];const p2=segment[1];return (p2[0]-p1[0])*(p2[1]+p1[1])});return sum(areas)>0}const add={constrain:function(){this.constrain();},pointsToFront:function(state){_.invoke(state.points,"toFront");}};add.standard=[add.constrain,add.pointsToFront];const modify={draw:function(){this.draw();}};modify.standard=[modify.draw];const draw={basic:function(state,prevState){const graphie=this.graphie;const path=this.path(state);if(!this.state.visibleShape){this.state.visibleShape=graphie.raphael.path(path);this.state.visibleShape.attr(this.normalStyle());}if(state.normalStyle!==prevState.normalStyle&&!_.isEqual(state.normalStyle,prevState.normalStyle)){this.state.visibleShape.attr(this.normalStyle());}this.state.visibleShape.attr({path:path});if(this.mouseTarget()){this.mouseTarget().attr({path:path});}},labels:function(state,prevState){const graphie=this.graphie;const self=this;const coords=_.invoke(state.points,"coord");const isClockwise=clockwise$2(coords);const n=coords.length;if(self.state._labelCache!=null){_.invoke(self.state._labelCache,"remove");}self.state._labelCache=[];if(state.angleLabels.length||state.showRightAngleMarkers.length){if(self.state._labeledAngles==null){self.state._labeledAngles=_.times(Math.max(state.angleLabels.length,state.showRightAngleMarkers.length),function(){return graphie.label([0,0],"","center",state.labelStyle)});}_.each(self.state._labeledAngles,function(label,i){self.state._labelCache.push(graphie.labelAngle({point1:coords[(i-1+n)%n],vertex:coords[i],point3:coords[(i+1)%n],label:label,text:state.angleLabels[i],showRightAngleMarker:state.showRightAngleMarkers[i],numArcs:state.numArcs[i],clockwise:isClockwise,style:state.labelStyle}));});}if(state.sideLabels.length){if(self.state._labeledSides==null){self.state._labeledSides=state.sideLabels.map(function(label){return graphie.label([0,0],"","center",state.labelStyle)});}_.each(self.state._labeledSides,function(label,i){self.state._labelCache.push(graphie.labelSide({point1:coords[i],point2:coords[(i+1)%n],label:label,text:state.sideLabels[i],numArrows:state.numArrows[i],numTicks:state.numTicks[i],clockwise:isClockwise,style:state.labelStyle}));});}if(state.vertexLabels.length){if(self.state._labeledVertices==null){self.state._labeledVertices=state.vertexLabels.map(function(label){return graphie.label([0,0],"","center",state.labelStyle)});}_.each(self.state._labeledVertices,function(label,i){self.state._labelCache.push(graphie.labelVertex({point1:coords[(i-1+n)%n],vertex:coords[i],point3:coords[(i+1)%n],label:label,text:state.vertexLabels[i],clockwise:isClockwise,style:state.labelStyle}));});}self.state._labelCache=_.flatten(self.state._labelCache);},highlight:function(state,prevState){if(state.isHovering&&!prevState.isHovering){state.visibleShape.animate(this.highlightStyle(),50);}else if(!state.isHovering&&prevState.isHovering){state.visibleShape.animate(this.normalStyle(),50);}}};draw.standard=[draw.basic,draw.labels,draw.highlight];const remove={basic:function(){if(this.state.visibleShape){this.state.visibleShape.remove();}},labels:function(){const labels=[this.state._labeledSides,this.state._labeledVertices,this.state._labeledAngles,this.state._labelCache];_.each(labels,function(labelType){if(labelType!=null&&labelType.length){_.invoke(labelType,"remove");}});}};remove.standard=[remove.basic,remove.labels];const constraints={fixed:function(){return function(){return false}},snap:function(snap){return function(coord){if(snap===null){return true}snap=snap||this.graphie.snap;return point.roundTo(coord,snap)}},bound:function(range,snap,paddingPx){if(paddingPx===undefined){if(range===undefined){paddingPx=10;}else {paddingPx=0;}}return function(coord,prevCoord){const graphie=this.graphie;const delta=vector$3.subtract(coord,prevCoord);range=range||graphie.range;if(snap===undefined){snap=graphie.snap;}let absoluteLower=graphie.unscalePoint([paddingPx,graphie.ypixels-paddingPx]);let absoluteUpper=graphie.unscalePoint([graphie.xpixels-paddingPx,paddingPx]);if(snap){absoluteLower=point.ceilTo(absoluteLower,snap);absoluteUpper=point.floorTo(absoluteUpper,snap);}const deltaBounds=this.coords().map(function(coord,i){const max=vector$3.subtract(absoluteUpper,coord);const min=vector$3.subtract(absoluteLower,coord);return [min,max]});const boundedDelta=_.reduce(deltaBounds,function(delta,bound){const lower=bound[0];const upper=bound[1];const deltaX=Math.max(lower[0],Math.min(upper[0],delta[0]));const deltaY=Math.max(lower[1],Math.min(upper[1],delta[1]));return [deltaX,deltaY]},delta);return vector$3.add(prevCoord,boundedDelta)}}};constraints.standard=null;const onMove={updatePoints:function(coord,prevCoord){const actualDelta=vector$3.subtract(coord,prevCoord);_.each(this.state.points,function(point){point.setCoord(vector$3.add(point.coord(),actualDelta));});}};onMove.standard=null;var MovablePolygonOptions = {add:add,modify:modify,draw:draw,remove:remove,onMoveStart:{standard:null},constraints:constraints,onMove:onMove,onMoveEnd:{standard:null},onClick:{standard:null}};
|
|
1592
1592
|
|
|
@@ -1594,7 +1594,7 @@ const assert$3=InteractiveUtil.assert;const normalizeOptions=InteractiveUtil.nor
|
|
|
1594
1594
|
|
|
1595
1595
|
const Interactive2={MovablePoint:MovablePoint$5,addMovablePoint:function(graphie,options){const movable=new Movable(graphie,{});return new MovablePoint$5(graphie,movable,options)},MovableLine:MovableLine$4,addMovableLine:function(graphie,options){const movable=new Movable(graphie,{});return new MovableLine$4(graphie,movable,options)},MovablePolygon:MovablePolygon,addMovablePolygon:function(graphie,options){const movable=new Movable(graphie,{});return new MovablePolygon(graphie,movable,options)},addMovablePointV2:function(widget,extraProps){const commonStyle={stroke:tokenValue(semanticColor.core.border.knockout.default),"stroke-width":3,fill:tokenValue(semanticColor.core.foreground.instructive.default)};const normalStyle=Object.assign(commonStyle,extraProps.normalStyle);const highlightStyle=Object.assign({...commonStyle,"stroke-width":2,scale:.75},extraProps.highlightStyle);const props=Object.assign({normalStyle:normalStyle,highlightStyle:highlightStyle,shadow:true,tooltip:widget.props.showTooltips,showHairlines:widget.showHairlines,hideHairlines:widget.hideHairlines},{pointSize:7});return Interactive2.addMovablePoint(widget.graphie,Object.assign(extraProps,props))}};
|
|
1596
1596
|
|
|
1597
|
-
const MovablePoint$4=GraphieClasses.createClass({displayName:"MovablePoint",movableProps:["children"],_getProps:function(){if(!this.props.isMobile||this.props.static){return this.props}const interactiveColor=tokenValue(semanticColor.core.foreground.instructive.default);const commonStyle={stroke:tokenValue(semanticColor.core.foreground.knockout.default),"stroke-width":3,fill:interactiveColor};return Object.assign(this.props,{normalStyle:{...commonStyle,...this.props.mobileStyleOverride||{}},highlightStyle:{...commonStyle,"stroke-width":0,scale:.75,...this.props.mobileStyleOverride||{}},shadow:true,tooltip:this.props.showTooltips,pointSize:7})},add:function(graphie){this.point=Interactive2.addMovablePoint(graphie,this._getProps());},modify:function(){this.point.modify(this._getProps());},remove:function(){this.point.remove();},toFront:function(){this.point.toFront();},grab:function(coord){this.point.grab(coord);}});_.extend(MovablePoint$4,Interactive2.MovablePoint);const MovableLine$3=GraphieClasses.createClass({displayName:"MovableLine",movableProps:["children"],add:function(graphie){const points=_.pluck(this.props.children,"point");const props=_.extend({},this.props,{points:points});this.line=Interactive2.addMovableLine(graphie,props);},modify:function(){const points=_.pluck(this.props.children,"point");const props=_.extend({},this.props,{points:points});this.line.modify(props);},remove:function(){this.line.remove();},toFront:function(){this.line.toFront();}});_.extend(MovableLine$3,Interactive2.MovableLine);const Label$1=GraphieClasses.createSimpleClass((graphie,props)=>{let coord=props.coord;if(props.unscaled){coord=graphie.unscalePoint(coord);}let elem;if(getDependencies().JIPT.useJIPT){elem=graphie.label(coord,props.text,props.direction,false,props.style);getDependencies().graphieMovablesJiptLabels.addLabel(elem,props.tex);}else {elem=graphie.label(coord,props.text,props.direction,props.tex,props.style);}return elem});const Line$3=GraphieClasses.createClass({displayName:"Line",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.line=this.graphie.line(props.start,props.end,props.style);},modify:function(){const props=this.props;this.line.remove();this.line=this.graphie.line(props.start,props.end,props.style);},remove:function(){this.line.remove();},toFront:function(){this.line.toFront();}});const Parabola=GraphieClasses.createClass({displayName:"Parabola",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.parabola=this.graphie.parabola(props.a,props.b,props.c,props.style);},modify:function(){const props=this.props;const path=this.graphie.svgParabolaPath(props.a,props.b,props.c);this.parabola.attr(_.extend({},props.style,{path:path}));},remove:function(){this.parabola.remove();},toFront:function(){this.parabola.toFront();}});const Sinusoid=GraphieClasses.createClass({displayName:"Sinusoid",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.sinusoid=this.graphie.sinusoid(props.a,props.b,props.c,props.d,props.style);},modify:function(){const props=this.props;const path=this.graphie.svgSinusoidPath(props.a,props.b,props.c,props.d);this.sinusoid.attr(_.extend({},props.style,{path:path}));},remove:function(){this.sinusoid.remove();},toFront:function(){this.sinusoid.toFront();}});const Plot$1=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.plot(props.fn,props.range,props.style)});const PlotParametric$1=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.plotParametric(props.fn,props.range,props.style)});const Point$1=GraphieClasses.createSimpleClass((graphie,props)=>{const neutralColor=tokenValue(semanticColor.core.foreground.neutral.strong);return graphie.ellipse(props.coord,graphie.unscaleVector([4,4]),{fill:props.color||neutralColor,stroke:props.color||neutralColor})});const Path=GraphieClasses.createClass({displayName:"Path",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.path=this.graphie.path(props.coords,props.style);},modify:function(){const props=this.props;const path=this.graphie.svgPath(props.coords);this.path.attr({path:path});},remove:function(){this.path.remove();},toFront:function(){this.path.toFront();}});const Arc$1=GraphieClasses.createSimpleClass((graphie,props)=>{let center=props.center;let radius=props.radius;if(props.unscaled){center=graphie.unscalePoint(center);radius=graphie.unscaleVector(radius);}return graphie.arc(center,radius,props.startAngle,props.endAngle,props.sector,props.style)});const Circle=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.circle(props.center,props.radius,props.style)});const Rect$1=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.rect(props.x,props.y,props.width,props.height,props.style)});var Movables = {Arc:Arc$1,Circle:Circle,Label:Label$1,Line:Line$3,MovableLine:MovableLine$3,MovablePoint:MovablePoint$4,Parabola:Parabola,Path:Path,Plot:Plot$1,PlotParametric:PlotParametric$1,Point:Point$1,Sinusoid:Sinusoid,Rect:Rect$1};
|
|
1597
|
+
const MovablePoint$4=GraphieClasses.createClass({displayName:"MovablePoint",movableProps:["children"],_getProps:function(){if(!this.props.isMobile||this.props.static){return this.props}const interactiveColor=tokenValue(semanticColor.core.foreground.instructive.default);const commonStyle={stroke:tokenValue(semanticColor.core.foreground.knockout.default),"stroke-width":3,fill:interactiveColor};return Object.assign(this.props,{normalStyle:{...commonStyle,...this.props.mobileStyleOverride||{}},highlightStyle:{...commonStyle,"stroke-width":0,scale:.75,...this.props.mobileStyleOverride||{}},shadow:this.props.shadow??true,tooltip:this.props.showTooltips,pointSize:7})},add:function(graphie){this.point=Interactive2.addMovablePoint(graphie,this._getProps());},modify:function(){this.point.modify(this._getProps());},remove:function(){this.point.remove();},toFront:function(){this.point.toFront();},grab:function(coord){this.point.grab(coord);}});_.extend(MovablePoint$4,Interactive2.MovablePoint);const MovableLine$3=GraphieClasses.createClass({displayName:"MovableLine",movableProps:["children"],add:function(graphie){const points=_.pluck(this.props.children,"point");const props=_.extend({},this.props,{points:points});this.line=Interactive2.addMovableLine(graphie,props);},modify:function(){const points=_.pluck(this.props.children,"point");const props=_.extend({},this.props,{points:points});this.line.modify(props);},remove:function(){this.line.remove();},toFront:function(){this.line.toFront();}});_.extend(MovableLine$3,Interactive2.MovableLine);const Label$1=GraphieClasses.createSimpleClass((graphie,props)=>{let coord=props.coord;if(props.unscaled){coord=graphie.unscalePoint(coord);}let elem;if(getDependencies().JIPT.useJIPT){elem=graphie.label(coord,props.text,props.direction,false,props.style);getDependencies().graphieMovablesJiptLabels.addLabel(elem,props.tex);}else {elem=graphie.label(coord,props.text,props.direction,props.tex,props.style);}return elem});const Line$3=GraphieClasses.createClass({displayName:"Line",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.line=this.graphie.line(props.start,props.end,props.style);},modify:function(){const props=this.props;this.line.remove();this.line=this.graphie.line(props.start,props.end,props.style);},remove:function(){this.line.remove();},toFront:function(){this.line.toFront();}});const Parabola=GraphieClasses.createClass({displayName:"Parabola",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.parabola=this.graphie.parabola(props.a,props.b,props.c,props.style);},modify:function(){const props=this.props;const path=this.graphie.svgParabolaPath(props.a,props.b,props.c);this.parabola.attr(_.extend({},props.style,{path:path}));},remove:function(){this.parabola.remove();},toFront:function(){this.parabola.toFront();}});const Sinusoid=GraphieClasses.createClass({displayName:"Sinusoid",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.sinusoid=this.graphie.sinusoid(props.a,props.b,props.c,props.d,props.style);},modify:function(){const props=this.props;const path=this.graphie.svgSinusoidPath(props.a,props.b,props.c,props.d);this.sinusoid.attr(_.extend({},props.style,{path:path}));},remove:function(){this.sinusoid.remove();},toFront:function(){this.sinusoid.toFront();}});const Plot$1=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.plot(props.fn,props.range,props.style)});const PlotParametric$1=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.plotParametric(props.fn,props.range,props.style)});const Point$1=GraphieClasses.createSimpleClass((graphie,props)=>{const neutralColor=tokenValue(semanticColor.core.foreground.neutral.strong);return graphie.ellipse(props.coord,graphie.unscaleVector([4,4]),{fill:props.color||neutralColor,stroke:props.color||neutralColor})});const Path=GraphieClasses.createClass({displayName:"Path",movableProps:["children"],add:function(graphie){const props=this.props;this.graphie=graphie;this.path=this.graphie.path(props.coords,props.style);},modify:function(){const props=this.props;const path=this.graphie.svgPath(props.coords);this.path.attr({path:path});},remove:function(){this.path.remove();},toFront:function(){this.path.toFront();}});const Arc$1=GraphieClasses.createSimpleClass((graphie,props)=>{let center=props.center;let radius=props.radius;if(props.unscaled){center=graphie.unscalePoint(center);radius=graphie.unscaleVector(radius);}return graphie.arc(center,radius,props.startAngle,props.endAngle,props.sector,props.style)});const Circle=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.circle(props.center,props.radius,props.style)});const Rect$1=GraphieClasses.createSimpleClass((graphie,props)=>{return graphie.rect(props.x,props.y,props.width,props.height,props.style)});var Movables = {Arc:Arc$1,Circle:Circle,Label:Label$1,Line:Line$3,MovableLine:MovableLine$3,MovablePoint:MovablePoint$4,Parabola:Parabola,Path:Path,Plot:Plot$1,PlotParametric:PlotParametric$1,Point:Point$1,Sinusoid:Sinusoid,Rect:Rect$1};
|
|
1598
1598
|
|
|
1599
1599
|
const GraphieMovable=GraphieClasses.GraphieMovable;const createGraphie=GraphUtils.createGraphie;const{nestedMap}=Util;const{assert: assert$2}=InteractiveUtil;class Graphie extends React.Component{componentDidMount(){this._setupGraphie();this._updateMovables();}shouldComponentUpdate(nextProps){return !_.isEqual(this.props,nextProps)}componentDidUpdate(prevProps){if(this.props.setup!==prevProps.setup){Log.error("<Graphie> was given a new setup function. "+"This is a bad idea; please refactor your code to give "+"the same setup function reference to <Graphie> on "+"every render.",Errors.Internal);}if(!approximateDeepEqual(this.props.options,prevProps.options)||!approximateDeepEqual(this.props.box,prevProps.box)||!approximateDeepEqual(this.props.range,prevProps.range)){this._setupGraphie();}this._updateMovables();}componentWillUnmount(){this._removeMovables();this._graphie.cleanup();}render(){return jsxRuntimeExports.jsx("div",{className:"graphie-container",children:jsxRuntimeExports.jsx("div",{className:"graphie",ref:this.graphieDivRef})})}constructor(...args){super(...args),this.graphieDivRef=React.createRef(),this._graphie=new Graphie$1(document.createElement("div")),this._movables={},this.movables={},this.getGraphie=()=>{return this._graphie},this._range=()=>{const boundsCheckRange=range=>{if(range[0]>=range[1]){return [-10,10]}return range};return [boundsCheckRange(this.props.range[0]),boundsCheckRange(this.props.range[1])]},this._box=()=>{const ensureMinSize=pixelDim=>{return pixelDim>0?pixelDim:340};return [ensureMinSize(this.props.box[0]),ensureMinSize(this.props.box[1])]},this._scale=()=>{const box=this._box();const range=this._range();return box.map((pixelDim,i)=>{const unitDim=range[i][1]-range[i][0];return pixelDim/unitDim})},this._setupGraphie=()=>{this._graphie.cleanup();this._removeMovables();const graphieDiv=this.graphieDivRef.current;if(graphieDiv==null||graphieDiv instanceof Text){throw new Error("No graphie container div found")}graphieDiv.innerHTML="";const graphie=this._graphie=createGraphie(graphieDiv);graphie.init({range:this._range(),scale:this._scale(),isMobile:this.props.isMobile});if(this.props.addMouseLayer){graphie.addMouseLayer({onClick:this.props.onClick,onMouseDown:this.props.onMouseDown,onMouseMove:this.props.onMouseMove});}graphie.snap=this.props.options.snapStep||[1,1];if(this.props.responsive){graphieDiv.style.width="100%";graphieDiv.style.height="100%";graphie.raphael.setSize("100%","100%");}this.props.setup(graphie,_.extend({range:this._range(),scale:this._scale()},this.props.options));},this._removeMovables=()=>{_.invoke(this._movables,"remove");this._movables={};},this._renderMovables=(children,options)=>{const graphie=options.graphie;const oldMovables=options.oldMovables;const newMovables=options.newMovables;const renderChildren=elem=>{_.each(elem.movableProps,prop=>{elem.props[prop]=this._renderMovables(elem.props[prop],options);});};let areMovablesOutOfOrder=false;return nestedMap(children,childDescriptor=>{if(!childDescriptor){options.nextKey++;return childDescriptor}const child=new childDescriptor.type(childDescriptor.props);assert$2(child instanceof GraphieMovable,"All children of a Graphie component must be Graphie "+"movables");const keyProp=childDescriptor.key;const key=keyProp==null?"_no_id_"+options.nextKey:keyProp;options.nextKey++;const ref=childDescriptor.ref;renderChildren(child);const prevMovable=oldMovables[key];if(!prevMovable){child.add(graphie);areMovablesOutOfOrder=true;newMovables[key]=child;}else if(child.constructor===prevMovable.constructor){prevMovable.props=child.props;const modifyResult=prevMovable.modify(graphie);if(modifyResult==="reordered"){areMovablesOutOfOrder=true;}newMovables[key]=prevMovable;}else {if(keyProp==null){Log.error("Replacing a <Graphie> child with a "+"child of a different type. Please add keys "+"to your <Graphie> children",Errors.Internal);}prevMovable.remove();child.add(graphie);areMovablesOutOfOrder=true;newMovables[key]=child;}if(areMovablesOutOfOrder){newMovables[key].toFront();}if(ref){this.movables[ref]=newMovables[key];}return newMovables[key]})},this._updateMovables=()=>{const graphie=this._graphie;const oldMovables=this._movables;const newMovables={};this._movables=newMovables;this.movables={};this._renderMovables(this.props.children,{nextKey:1,graphie:graphie,oldMovables:oldMovables,newMovables:newMovables});_.each(oldMovables,(oldMovable,key)=>{if(!newMovables[key]){oldMovable.remove();}});};}}Graphie.defaultProps={range:[[-10,10],[-10,10]],options:{},responsive:false,addMouseLayer:true};_.extend(Graphie,GraphieClasses);_.extend(Graphie,Movables);
|
|
1600
1600
|
|
|
@@ -1768,7 +1768,7 @@ var styles$m = {"content":"perseus_HDIlPzEz","contentCollapsed":"perseus_NkFQFgc
|
|
|
1768
1768
|
|
|
1769
1769
|
const styles$l={buttonStyleOverrides:{height:"auto",lineHeight:"inherit",marginLeft:"-0.2rem",marginRight:"0.2rem",paddingLeft:"0.2rem"},content:{borderLeft:"0px solid var(--wb-semanticColor-core-border-neutral-subtle)",display:"inline-grid",position:"relative"},contentCollapsed:{gridTemplateColumns:"0fr",gridTemplateRows:"0fr",marginBottom:"0",marginTop:"0",minWidth:"0",paddingBottom:"0",visibility:"hidden"},contentExpanded:{borderLeftWidth:"5px",gridTemplateColumns:"1fr",gridTemplateRows:"1fr",marginBottom:"1.4rem",marginLeft:"-2.3rem",marginTop:"1.4rem",minWidth:"100%",paddingBottom:"1rem",paddingLeft:"2.3rem",visibility:"visible"},contentWrapper:{overflow:"hidden"},labelStyle:{fontSize:"var(--wb-font-heading-size-medium)",lineHeight:"inherit",marginRight:"-0.6rem",textAlign:"left",whiteSpace:"normal"},transitionCollapsed:{transition:"all 0.25s step-end, grid-template-rows 0.25s, margin-top 0.25s, margin-bottom 0.25s, padding-bottom 0.25s"},transitionExpanded:{transition:"grid-template-rows 0.5s, margin-top 0.5s, margin-bottom 0.5s, padding-bottom 0.5s"}};
|
|
1770
1770
|
|
|
1771
|
-
function mediaQueryIsMatched(mediaQuery){if(typeof window.matchMedia!=="function"){return false}return window.matchMedia(mediaQuery).matches}
|
|
1771
|
+
function mediaQueryIsMatched(mediaQuery){if(typeof window.matchMedia!=="function"){return false}return window.matchMedia(mediaQuery).matches}const Explanation=forwardRef(function Explanation(props,ref){const{strings}=usePerseusI18n();const dependencies=useDependencies();const[expanded,setExpanded]=useState(false);const contentId=useId();const{hidePrompt,showPrompt,explanation,widgets}=props.options;useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"explanation",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON(){return getPromptJSON$j(props)}}));function onClick(){setExpanded(!expanded);props.trackInteraction();}const legacyContentStyling=[styles$l.content,expanded?styles$l.contentExpanded:styles$l.contentCollapsed,mediaQueryIsMatched("(prefers-reduced-motion: no-preference)")&&(expanded?styles$l.transitionExpanded:styles$l.transitionCollapsed)];const contentClasses=[styles$m.content,expanded?styles$m.contentExpanded:styles$m.contentCollapsed,expanded?styles$m.transitionExpanded:styles$m.transitionCollapsed];return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Button,{"aria-expanded":expanded,"aria-controls":contentId,endIcon:expanded?caretUp:caretDown,kind:"tertiary",labelStyle:styles$l.labelStyle,onClick:onClick,size:"small",style:styles$l.buttonStyleOverrides,children:expanded?hidePrompt:showPrompt}),jsxRuntimeExports.jsx(View,{id:contentId,style:legacyContentStyling,className:contentClasses.join(" "),"aria-hidden":!expanded,testId:"content-container",children:jsxRuntimeExports.jsx(View,{className:styles$m.contentWrapper,style:styles$l.contentWrapper,children:jsxRuntimeExports.jsx(UserInputManager,{widgets:widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>{return jsxRuntimeExports.jsx(Renderer,{apiOptions:props.apiOptions,content:explanation,widgets:widgets,linterContext:props.linterContext,strings:strings,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput})}})})})]})});var Explanation$1 = {name:"explanation",displayName:"Explanation",widget:Explanation,isLintable:true};
|
|
1772
1772
|
|
|
1773
1773
|
class FreeResponse extends React.Component{isOverLimit(){return !this.props.options.allowUnlimitedCharacters&&this.characterCount()>this.props.options.characterLimit}render(){const{allowUnlimitedCharacters,characterLimit,question,placeholder}=this.props.options;const isOverLimit=this.isOverLimit();const characterCountText=allowUnlimitedCharacters?undefined:this.context.strings.characterCount({used:this.characterCount(),num:characterLimit});if(characterCountText){this.announceCharacterCount(characterCountText,isOverLimit);}return jsxRuntimeExports.jsx(View,{style:styles$k.container,className:"free-response",children:jsxRuntimeExports.jsx(LabeledField,{label:jsxRuntimeExports.jsx(View,{className:"free-response-question",children:jsxRuntimeExports.jsx(Renderer,{content:question,strings:this.context.strings})}),field:jsxRuntimeExports.jsx(TextArea,{error:isOverLimit,onChange:this._handleUserInput,placeholder:placeholder,style:styles$k.textarea,value:this.props.userInput.currentValue}),additionalHelperMessage:jsxRuntimeExports.jsxs("p",{className:css(styles$k.characterCountText,isOverLimit?styles$k.overCharacterLimit:undefined),children:[isOverLimit&&jsxRuntimeExports.jsx(PhosphorIcon,{"aria-label":"Error:",icon:warningCircleIcon,size:"small",style:styles$k.warningCircleIcon}),characterCountText]})})})}constructor(...args){super(...args),this.isWidget=true,this.announceCharacterCount=(message,isOverLimit)=>{const level=isOverLimit?"assertive":"polite";announceMessage({message,level,debounceThreshold:750});},this.characterCount=()=>{return this.props.userInput.currentValue.replace(/\n/g,"").length},this._handleUserInput=newValue=>{this.props.handleUserInput({currentValue:newValue});};}}FreeResponse.contextType=PerseusI18nContext;function getStartUserInput$c(){return {currentValue:""}}var FreeResponse$1 = {name:"free-response",accessible:true,displayName:"Free Response (Assessments only)",widget:FreeResponse,hidden:false,getUserInputFromSerializedState:getStartUserInput$c,getStartUserInput: getStartUserInput$c};const styles$k=StyleSheet.create({container:{gap:spacing.xSmall_8},characterCountText:{color:semanticColor.core.foreground.neutral.default,fontSize:font.body.size.small,margin:0},overCharacterLimit:{color:semanticColor.core.foreground.critical.default},textarea:{padding:spacing.medium_16},warningCircleIcon:{marginInlineEnd:spacing.xSmall_8}});
|
|
1774
1774
|
|
|
@@ -1780,9 +1780,9 @@ const GRADING_STATUSES={ungraded:"ungraded",correct:"correct",incorrect:"incorre
|
|
|
1780
1780
|
|
|
1781
1781
|
const getPromptJSON$h=(widgetData,activeGroupJSON)=>{return {type:"graded-group-set",options:{groupCount:widgetData.options.gradedGroups.length,currentGroup:activeGroupJSON}}};
|
|
1782
1782
|
|
|
1783
|
-
class Indicators extends React.Component{render(){return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames$2(css(styles$h.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>{const isCurrent=i===this.props.currentGroup;return jsxRuntimeExports.jsx("li",{className:css(styles$h.indicator),children:jsxRuntimeExports.jsx(Clickable,{role:"button","aria-label":title,"aria-current":isCurrent,style:styles$h.indicatorButton,onClick:()=>this.props.onChangeCurrentGroup(i),onKeyDown:e=>this.handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(View,{style:[styles$h.indicatorDot,isCurrent&&styles$h.indicatorDotActive,(hovered||focused||pressed)&&styles$h.indicatorDotFocused]})})},i)})})}constructor(...args){super(...args),this.handleKeyDown=(e,i)=>{if(e.key==="Enter"||e.key===" "){this.props.onChangeCurrentGroup(i);}};}}Indicators.contextType=PerseusI18nContext;class GradedGroupSet extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group-set",widgetSubType:"null",widgetId:this.props.widgetId}});}shouldComponentUpdate(nextProps,nextState){return nextProps!==this.props||nextState!==this.state}getPromptJSON(){const activeGroupPromptJSON=this._childGroup.getPromptJSON();return getPromptJSON$h(this.props,activeGroupPromptJSON)}render(){const{gradedGroups}=this.props.options;const{JIPT}=getDependencies();if(JIPT.useJIPT&&gradedGroups.length>1){return jsxRuntimeExports.jsx("div",{className:css(styles$h.container),children:gradedGroups.map((gradedGroup,i)=>{return jsxRuntimeExports.jsx(GradedGroup,{...this.props,options:gradedGroup,inGradedGroupSet:false,linterContext:this.props.linterContext},i)})})}const currentGroup=gradedGroups[this.state.currentGroup];if(!currentGroup){return jsxRuntimeExports.jsx("span",{children:"No current group..."})}const numGroups=gradedGroups.length;const handleNextQuestion=this.state.currentGroup<numGroups-1?this.handleNextQuestion:undefined;return jsxRuntimeExports.jsxs("div",{className:css(styles$h.container),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$h.top),children:[jsxRuntimeExports.jsx("div",{className:css(styles$h.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:css(styles$h.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroup:this.state.currentGroup,gradedGroups:gradedGroups,onChangeCurrentGroup:currentGroup=>this.setState({currentGroup})})]}),jsxRuntimeExports.jsx(GradedGroup,{ref:comp=>this._childGroup=comp,...this.props,options:{...currentGroup,title:""},inGradedGroupSet:true,onNextQuestion:handleNextQuestion,linterContext:this.props.linterContext},this.state.currentGroup)]})}constructor(...args){super(...args),this.state={currentGroup:0},this.getInputPaths=()=>{return this._childGroup.getInputPaths()},this.focus=()=>{return this._childGroup.focus()},this.focusInputPath=path=>{this._childGroup.focusInputPath(path);},this.blurInputPath=path=>{this._childGroup.blurInputPath(path);},this.handleNextQuestion=()=>{const{currentGroup}=this.state;const numGroups=this.props.options.gradedGroups.length;if(currentGroup<numGroups-1){this.setState({currentGroup:currentGroup+1});}};}}const WrappedGradedGroupSet=withDependencies(GradedGroupSet);var GradedGroupSet$1 = {name:"graded-group-set",displayName:"Graded group set (articles only)",widget:WrappedGradedGroupSet,hidden:false,tracking:"all",isLintable:true};const styles$h=StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:font.heading.size.small,color:semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyleType:"none",margin:"unset",paddingInlineStart:"unset",flexWrap:"wrap"},indicator:{width:24,height:24},indicatorButton:{width:"100%",height:"100%",display:"flex",flexWrap:"wrap",placeContent:"center",cursor:"pointer",":focus":{outline:"none"}},indicatorDot:{boxSizing:"content-box",width:10,height:10,borderRadius:border$1.radius.radius_full,borderWidth:border$1.width.medium,borderColor:semanticColor.core.border.instructive.default,borderStyle:"solid"},indicatorDotFocused:{outlineColor:semanticColor.focus.outer,outlineStyle:"solid",outlineWidth:border$1.width.medium,outlineOffset:border$1.width.medium,boxShadow:`0 0 0 ${border$1.width.medium} ${semanticColor.focus.inner}`},indicatorDotActive:{backgroundColor:semanticColor.core.foreground.instructive.default,borderColor:semanticColor.core.
|
|
1783
|
+
class Indicators extends React.Component{render(){return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames$2(css(styles$h.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>{const isCurrent=i===this.props.currentGroup;return jsxRuntimeExports.jsx("li",{className:css(styles$h.indicator),children:jsxRuntimeExports.jsx(Clickable,{role:"button","aria-label":title,"aria-current":isCurrent,style:styles$h.indicatorButton,onClick:()=>this.props.onChangeCurrentGroup(i),onKeyDown:e=>this.handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(View,{style:[styles$h.indicatorDot,isCurrent&&styles$h.indicatorDotActive,(hovered||focused||pressed)&&styles$h.indicatorDotFocused]})})},i)})})}constructor(...args){super(...args),this.handleKeyDown=(e,i)=>{if(e.key==="Enter"||e.key===" "){this.props.onChangeCurrentGroup(i);}};}}Indicators.contextType=PerseusI18nContext;class GradedGroupSet extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group-set",widgetSubType:"null",widgetId:this.props.widgetId}});}shouldComponentUpdate(nextProps,nextState){return nextProps!==this.props||nextState!==this.state}getPromptJSON(){const activeGroupPromptJSON=this._childGroup.getPromptJSON();return getPromptJSON$h(this.props,activeGroupPromptJSON)}render(){const{gradedGroups}=this.props.options;const{JIPT}=getDependencies();if(JIPT.useJIPT&&gradedGroups.length>1){return jsxRuntimeExports.jsx("div",{className:css(styles$h.container),children:gradedGroups.map((gradedGroup,i)=>{return jsxRuntimeExports.jsx(GradedGroup,{...this.props,options:gradedGroup,inGradedGroupSet:false,linterContext:this.props.linterContext},i)})})}const currentGroup=gradedGroups[this.state.currentGroup];if(!currentGroup){return jsxRuntimeExports.jsx("span",{children:"No current group..."})}const numGroups=gradedGroups.length;const handleNextQuestion=this.state.currentGroup<numGroups-1?this.handleNextQuestion:undefined;return jsxRuntimeExports.jsxs("div",{className:css(styles$h.container),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$h.top),children:[jsxRuntimeExports.jsx("div",{className:css(styles$h.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:css(styles$h.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroup:this.state.currentGroup,gradedGroups:gradedGroups,onChangeCurrentGroup:currentGroup=>this.setState({currentGroup})})]}),jsxRuntimeExports.jsx(GradedGroup,{ref:comp=>this._childGroup=comp,...this.props,options:{...currentGroup,title:""},inGradedGroupSet:true,onNextQuestion:handleNextQuestion,linterContext:this.props.linterContext},this.state.currentGroup)]})}constructor(...args){super(...args),this.state={currentGroup:0},this.getInputPaths=()=>{return this._childGroup.getInputPaths()},this.focus=()=>{return this._childGroup.focus()},this.focusInputPath=path=>{this._childGroup.focusInputPath(path);},this.blurInputPath=path=>{this._childGroup.blurInputPath(path);},this.handleNextQuestion=()=>{const{currentGroup}=this.state;const numGroups=this.props.options.gradedGroups.length;if(currentGroup<numGroups-1){this.setState({currentGroup:currentGroup+1});}};}}const WrappedGradedGroupSet=withDependencies(GradedGroupSet);var GradedGroupSet$1 = {name:"graded-group-set",displayName:"Graded group set (articles only)",widget:WrappedGradedGroupSet,hidden:false,tracking:"all",isLintable:true};const styles$h=StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:font.heading.size.small,color:semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyleType:"none",margin:"unset",paddingInlineStart:"unset",flexWrap:"wrap"},indicator:{width:24,height:24},indicatorButton:{width:"100%",height:"100%",display:"flex",flexWrap:"wrap",placeContent:"center",cursor:"pointer",":focus":{outline:"none"}},indicatorDot:{boxSizing:"content-box",width:10,height:10,borderRadius:border$1.radius.radius_full,borderWidth:border$1.width.medium,borderColor:semanticColor.core.border.instructive.default,borderStyle:"solid"},indicatorDotFocused:{outlineColor:semanticColor.focus.outer,outlineStyle:"solid",outlineWidth:border$1.width.medium,outlineOffset:border$1.width.medium,boxShadow:`0 0 0 ${border$1.width.medium} ${semanticColor.focus.inner}`},indicatorDotActive:{backgroundColor:semanticColor.core.foreground.instructive.default,borderColor:semanticColor.core.transparent},container:{borderBlockStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,backgroundColor:semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"}});
|
|
1784
1784
|
|
|
1785
|
-
class ButtonGroup extends React.Component{componentWillUnmount(){this.container=null;}focus(){if(this.container){this.container.focus();return true}}toggleSelect(newValue){const value=this.props.value;if(this.props.allowEmpty){this.props.onChange(value!==newValue?newValue:null);}else {this.props.onChange(newValue);}}render(){const value=this.props.value;const buttons=this.props.buttons.map((button,i)=>{return jsxRuntimeExports.jsx("button",{title:button.title,type:"button",disabled:this.props.disabled,className:css(styles$g.buttonStyle,button.value===value&&styles$g.selectedStyle,button.value===value&&this.props.selectedButtonStyle,this.props.disabled&&styles$g.disabledStyle),onClick:()=>this.toggleSelect(button.value),children:button.content||""+button.value},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:node=>this.container=node,children:buttons})}}ButtonGroup.defaultProps={value:null,allowEmpty:true};const styles$g=StyleSheet.create({buttonStyle:{backgroundColor:
|
|
1785
|
+
class ButtonGroup extends React.Component{componentWillUnmount(){this.container=null;}focus(){if(this.container){this.container.focus();return true}}toggleSelect(newValue){const value=this.props.value;if(this.props.allowEmpty){this.props.onChange(value!==newValue?newValue:null);}else {this.props.onChange(newValue);}}render(){const value=this.props.value;const buttons=this.props.buttons.map((button,i)=>{return jsxRuntimeExports.jsx("button",{title:button.title,type:"button",disabled:this.props.disabled,className:css(styles$g.buttonStyle,button.value===value&&styles$g.selectedStyle,button.value===value&&this.props.selectedButtonStyle,this.props.disabled&&styles$g.disabledStyle),onClick:()=>this.toggleSelect(button.value),children:button.content||""+button.value},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:node=>this.container=node,children:buttons})}}ButtonGroup.defaultProps={value:null,allowEmpty:true};const styles$g=StyleSheet.create({buttonStyle:{backgroundColor:semanticColor.core.background.base.default,border:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderInlineStart:"0",color:semanticColor.core.foreground.neutral.strong,cursor:"pointer",margin:"0",paddingBlock:"5px",paddingInline:"10px",position:"relative",":first-child":{borderInlineStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderStartStartRadius:border$1.radius.radius_040,borderEndStartRadius:border$1.radius.radius_040},":last-child":{borderInlineEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderStartEndRadius:border$1.radius.radius_040,borderEndEndRadius:border$1.radius.radius_040},":hover":{backgroundColor:semanticColor.core.background.instructive.subtle},":focus":{zIndex:2}},selectedStyle:{backgroundColor:semanticColor.core.background.instructive.subtle,boxShadow:`inset 0 calc(-1 * ${border$1.width.thick}) 0 ${semanticColor.core.border.instructive.default}`},disabledStyle:{cursor:"not-allowed",backgroundColor:semanticColor.core.background.disabled.default,color:semanticColor.core.foreground.disabled.strong,":hover":{backgroundColor:semanticColor.core.background.disabled.default}}});
|
|
1786
1786
|
|
|
1787
1787
|
const getPromptJSON$g=widgetData=>{const{userInput}=widgetData;const{type,coords}=userInput;const input={type,coords};if(userInput.type==="logarithm"||userInput.type==="exponential"){input["asymptote"]=userInput.asymptote;}return {type:"grapher",options:{availableTypes:widgetData.options.availableTypes,range:widgetData.options.graph.range,labels:widgetData.options.graph.labels,tickStep:widgetData.options.graph.step,gridStep:widgetData.options.graph.gridStep,snapStep:widgetData.options.graph.snapStep,backgroundImageUrl:widgetData.options.graph.backgroundImage.url},userInput:input}};
|
|
1788
1788
|
|
|
@@ -2017,7 +2017,9 @@ const StatefulMafsGraph=React.forwardRef(function StatefulMafsGraphWithRef(props
|
|
|
2017
2017
|
|
|
2018
2018
|
class InteractiveGraph extends React.Component{static getEquationString(props){return getEquationString$1(props)}getUserInput(){if(this.mafsRef.current?.getUserInput){return this.mafsRef.current.getUserInput()}throw new PerseusError("Cannot getUserInput from a graph that has never rendered",Errors.NotAllowed)}getPromptJSON(){return getPromptJSON$f(this.props,this.getUserInput())}getSerializedState(){const{userInput,options,...rest}=this.props;return {...options,...rest,graph:userInput}}render(){const options=this.props.options;const box=getInteractiveBoxFromSizeClass(this.props.containerSizeClass);const gridStep=options.gridStep||Util.getGridStep(options.range,options.step,box[0]);const snapStep=options.snapStep||Util.snapStepFromGridStep(gridStep);const mafsProps={...options,static:this.props.static,containerSizeClass:this.props.containerSizeClass,graph:this.props.userInput,onChange:()=>this.props.handleUserInput(this.mafsRef.current?.getUserInput())};const showUngradedText=this.props.graded===false&&options.graph.type!=="none";const ungradedDescriptionId=`interactive-graph-ungraded-description-${this.props.widgetId?.replace(/\s+/g,"-")}`;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[showUngradedText&&jsxRuntimeExports.jsx("p",{id:ungradedDescriptionId,children:this.context.strings.ungradedInteractiveGraph}),jsxRuntimeExports.jsx(StatefulMafsGraph,{...mafsProps,ref:this.mafsRef,gridStep:gridStep,snapStep:snapStep,box:box,showTooltips:!!options.showTooltips,readOnly:this.props.apiOptions?.readOnly,widgetId:this.props.widgetId,graded:this.props.graded,ungradedDescriptionId:showUngradedText?ungradedDescriptionId:undefined})]})}constructor(...args){super(...args),this.mafsRef=React.createRef();}}InteractiveGraph.contextType=PerseusI18nContext;function getUserInputFromSerializedState$b(serializedState){return serializedState.graph}function getStartUserInput$b(options){return options.graph}function getCorrectUserInput$5(options){return options.correct}var InteractiveGraph$1 = {name:"interactive-graph",displayName:"Interactive graph",widget:InteractiveGraph,getStartUserInput: getStartUserInput$b,getCorrectUserInput: getCorrectUserInput$5,getUserInputFromSerializedState: getUserInputFromSerializedState$b,supportsUngraded:true};
|
|
2019
2019
|
|
|
2020
|
-
const
|
|
2020
|
+
const paths={linear:"M8 42L42 8",quadratic:"M8 8Q25 72 42 8",sinusoid:"M8 25C11.1 13 13.4 13 16.5 25C19.6 37 21.9 37 25 25C28.1 13 30.4 13 33.5 25C36.6 37 38.9 37 42 25",tangent:"M8 42L8.2 38.6L8.5 35.2L9.1 31.8L10.4 28.4L13.7 25L16.9 21.6L18.3 18.2L18.8 14.8L19.1 11.4L19.3 8M19.3 42L19.5 38.6L19.8 35.2L20.4 31.8L21.7 28.4L25 25L28.3 21.6L29.6 18.2L30.2 14.8L30.5 11.4L30.7 8M30.7 42L30.9 38.6L31.2 35.2L31.7 31.8L33.1 28.4L36.3 25L39.6 21.6L40.9 18.2L41.5 14.8L41.8 11.4L42 8",exponential:"M8 42L10.6 41.8L13.2 41.5L15.8 41.1L18.5 40.5L21.1 39.8L23.7 38.7L26.3 37.3L28.9 35.4L31.5 32.7L34.2 29.1L36.8 24.1L39.4 17.3L42 8",logarithm:"M8 42L10.6 29.7L13.2 24.5L15.8 21.2L18.5 18.7L21.1 16.7L23.7 15.1L26.3 13.7L28.9 12.5L31.5 11.4L34.2 10.4L36.8 9.5L39.4 8.7L42 8",absolute_value:"M10 8L25 42L40 8"};function FunctionTypeIcon({type,label}){return jsxRuntimeExports.jsx("svg",{width:50,height:50,viewBox:"0 0 50 50",role:"img","aria-label":label,focusable:"false",children:jsxRuntimeExports.jsx("path",{d:paths[type],fill:"none",stroke:semanticColor.core.foreground.instructive.default,strokeWidth:3,strokeLinecap:"round",strokeLinejoin:"round"})})}
|
|
2021
|
+
|
|
2022
|
+
const movableTypeToComponent={PLOT:Graphie.Plot,PARABOLA:Graphie.Parabola,SINUSOID:Graphie.Sinusoid};const DEFAULT_BACKGROUND_IMAGE={url:null};const getEquationString=plot=>{if(plot.type&&plot.coords){const handler=GrapherUtil$1.functionForType(plot.type);const result=handler.getEquationString(plot.coords,plot.asymptote);return result||""}return ""};const pointsFromNormalized=(coordsList,range,step,snapStep)=>{const numSteps=function(range,step){return Math.floor((range[1]-range[0])/step)};return coordsList.map(coords=>{const unsnappedPoint=coords.map((coord,i)=>{const currRange=range[i];const currStep=step[i];const nSteps=numSteps(currRange,currStep);const tick=Math.round(coord*nSteps);return currRange[0]+currStep*tick});return point.roundTo(unsnappedPoint,snapStep)})};const maybePointsFromNormalized=(coordsList,range,step,snapStep)=>{if(coordsList){return pointsFromNormalized(coordsList,range,step,snapStep)}return coordsList};const defaultPlotProps=(type,graph)=>{const model=GrapherUtil$1.functionForType(type);const defaultAsymptote="defaultAsymptote"in model?model.defaultAsymptote:null;const gridStep=[1,1];const snapStep=Util.snapStepFromGridStep(gridStep);return {type,asymptote:maybePointsFromNormalized(defaultAsymptote,graph.range,graph.step,snapStep),coords:null}};const chooseType=_.first;const getGridAndSnapSteps=(options,boxSize)=>{const gridStep=options.gridStep||Util.getGridStep(options.range,options.step,boxSize);const snapStep=options.snapStep||Util.snapStepFromGridStep(gridStep);return {gridStep:gridStep,snapStep:snapStep}};const defaultGraph={labels:["x","y"],range:[[-10,10],[-10,10]],step:[1,1],backgroundImage:DEFAULT_BACKGROUND_IMAGE,markings:"graph",rulerLabel:"",rulerTicks:10,valid:true,showTooltips:false};const defaultPlot=defaultPlotProps("linear",defaultGraph);const DEFAULT_GRAPHER_PROPS={graph:defaultGraph,plot:defaultPlot,availableTypes:[defaultPlot.type]};const typeToButton=type=>{const capitalized=type.charAt(0).toUpperCase()+type.substring(1);return {value:type,title:capitalized,content:jsxRuntimeExports.jsx(FunctionTypeIcon,{type:type,label:capitalized})}};
|
|
2021
2023
|
|
|
2022
2024
|
const MovablePoint$2=Graphie.MovablePoint;const MovableLine$1=Graphie.MovableLine;function isFlipped(newCoord,oldCoord,line){const CCW=(a,b,c)=>{return (b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1])};return CCW(line[0],line[1],oldCoord)>0!==CCW(line[0],line[1],newCoord)>0}const typeSelectorStyle={padding:"5px 5px"};class FunctionGrapher extends React.Component{render(){const pointForCoord=(coord,i)=>{return jsxRuntimeExports.jsx(MovablePoint$2,{coord:coord,static:this.props.static,constraints:[Interactive2.MovablePoint.constraints.bound(),Interactive2.MovablePoint.constraints.snap(),coord=>{const isFunction=this._coords().every((otherCoord,j)=>{return i===j||!otherCoord||!number.equal(coord[0],otherCoord[0])});if(!isFunction){return false}if(this.props.model&&this.props.model.extraCoordConstraint){const extraConstraint=this.props.model.extraCoordConstraint;const proposedCoords=deepClone(this._coords());const oldCoord=deepClone(proposedCoords[i]);proposedCoords[i]=coord;return extraConstraint(coord,oldCoord,proposedCoords,this._asymptote(),this.props.graph)}return isFunction}],onMove:(newCoord,oldCoord)=>{let coords;const asymptote=this._asymptote();if(asymptote&&this.props.model.allowReflectOverAsymptote&&isFlipped(newCoord,oldCoord,asymptote)){coords=this._coords().map(coord=>{return point.reflectOverLine(coord,asymptote)});}else {coords=deepClone(this._coords());}coords[i]=newCoord;this.props.onChange({coords:coords});},showHairlines:this.props.showHairlines,hideHairlines:this.props.hideHairlines,showTooltips:this.props.showTooltips,isMobile:this.props.isMobile},i)};const points=this._coords().map(pointForCoord);const box=this.props.graph.box;const imageDescription=this.props.graph.backgroundImage;let image=null;if(imageDescription.url){const scale=box[0]/interactiveSizes$1.defaultBoxSize;image=jsxRuntimeExports.jsx(SvgImage,{src:imageDescription.url,allowZoom:false,width:imageDescription.width,height:imageDescription.height,scale:scale});}return jsxRuntimeExports.jsx("div",{className:"perseus-widget "+"perseus-widget-grapher",style:{width:box[0],height:box[1],boxSizing:"initial"},children:jsxRuntimeExports.jsxs("div",{className:"graphie-container blank-background",style:{width:box[0],height:box[1]},children:[image,jsxRuntimeExports.jsxs(Graphie,{...this.props.graph,children:[this.props.model&&this.renderPlot(),this.props.model&&this.renderAsymptote(),this.props.model&&points]})]})})}constructor(...args){super(...args),this._coords=()=>{const props=this.props;const graph=props.graph;const defaultModelCoords=props.model&&maybePointsFromNormalized(props.model.defaultCoords,graph.range,graph.step,graph.snapStep);return props.coords||defaultModelCoords||null},this._asymptote=()=>{return this.props.asymptote},this.renderPlot=()=>{const model=this.props.model;const xRange=this.props.graph.range[0];const style={stroke:tokenValue(this.props.static?semanticColor.core.foreground.disabled.strong:semanticColor.core.foreground.instructive.default),...this.props.isMobile?{"stroke-width":3}:{}};const coeffs=model.getCoefficients(this._coords(),this._asymptote());if(!coeffs){return}const functionProps=model.getPropsForCoeffs(coeffs,xRange);const Movable=movableTypeToComponent[model.movable];return createElement(Movable,{...functionProps,key:this.props.model.url,range:xRange,style:style})},this.renderAsymptote=()=>{const model=this.props.model;const graph=this.props.graph;const asymptote=this._asymptote();const showAsymptote=asymptote?.length>0;const dashed={"stroke-dasharray":"- "};return showAsymptote&&jsxRuntimeExports.jsx(MovableLine$1,{static:this.props.static,onMove:(newCoord,oldCoord)=>{const delta=vector$3.subtract(newCoord,oldCoord);const newAsymptote=this._asymptote().map(coord=>vector$3.add(coord,delta));this.props.onChange({asymptote:newAsymptote});},constraints:[Interactive2.MovableLine.constraints.bound(),Interactive2.MovableLine.constraints.snap(),(newCoord,oldCoord)=>{const delta=vector$3.subtract(newCoord,oldCoord);const proposedAsymptote=this._asymptote().map(coord=>vector$3.add(coord,delta));if(model.extraAsymptoteConstraint){return model.extraAsymptoteConstraint(newCoord,oldCoord,this._coords(),proposedAsymptote,graph)}return true}],normalStyle:dashed,highlightStyle:dashed,children:asymptote.map((coord,i)=>jsxRuntimeExports.jsx(MovablePoint$2,{coord:coord,static:true,draw:null,extendLine:true,showHairlines:this.props.showHairlines,hideHairlines:this.props.hideHairlines,showTooltips:this.props.showTooltips,isMobile:this.props.isMobile},`asymptoteCoord-${i}`))})};}}FunctionGrapher.defaultProps={graph:{range:[[-10,10],[-10,10]],step:[1,1]},coords:null,asymptote:null,isMobile:false};class Grapher extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"grapher",widgetSubType:"null",widgetId:this.props.widgetId}});}_getGridConfig(options){return options.step.map((step,i)=>{return Util.gridDimensionConfig(step,options.range[i],options.box[i],options.gridStep[i])})}_calculateMobileTickStep(gridStep,step,ranges){const tickStep=Util.constrainedTickStepsFromTickSteps(step,ranges);tickStep[0]=tickStep[0]/gridStep[0];tickStep[1]=tickStep[1]/gridStep[1];return tickStep}getPromptJSON(){return getPromptJSON$g(this.props)}getSerializedState(){const{userInput,options,...rest}=this.props;const{correct,...optionsRest}=options;return {...optionsRest,...rest,plot:this.props.userInput}}getAvailableTypes(){const{correct,availableTypes}=this.props.options;if(this.props.static){invariant(correct,"static widgets must have a correct answer");return [correct.type]}return availableTypes}renderLegacyGrapher(){const availableTypes=this.getAvailableTypes();const type=this.props.userInput.type;const coords=this.props.userInput.coords;const asymptote="asymptote"in this.props.userInput?this.props.userInput.asymptote:undefined;const typeSelector=jsxRuntimeExports.jsx("div",{style:typeSelectorStyle,children:jsxRuntimeExports.jsx(ButtonGroup,{value:type,allowEmpty:true,buttons:availableTypes.map(typeToButton),onChange:this.handleActiveTypeChange})});const box=getInteractiveBoxFromSizeClass(this.props.containerSizeClass);const{graph}=this.props.options;const options={...graph,...getGridAndSnapSteps(graph,box[0]),gridConfig:this._getGridConfig({...graph,box:box,...getGridAndSnapSteps(graph,box[0])})};const grapherProps={graph:{box:box,range:options.range,step:options.step,snapStep:options.snapStep,backgroundImage:options.backgroundImage,options:options,setup:this._setupGraphie},onChange:this.handlePlotChanges,model:type&&GrapherUtil$1.functionForType(type),coords:coords,asymptote:asymptote,static:this.props.static,isMobile:this.props.apiOptions.isMobile,showTooltips:graph.showTooltips,showHairlines:this.showHairlines,hideHairlines:this.hideHairlines};return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(FunctionGrapher,{...grapherProps}),availableTypes.length>1&&typeSelector]})}render(){const{options,...universalProps}=this.props;const interactiveGraphOptions=convertGrapherOptionsToInteractiveGraph(options);if(interactiveGraphOptions==null){return this.renderLegacyGrapher()}const interactiveGraphUserInput=convertGrapherUserInputToInteractiveGraph(this.props.userInput);return jsxRuntimeExports.jsx(InteractiveGraph$1.widget,{...universalProps,options:interactiveGraphOptions,userInput:interactiveGraphUserInput,handleUserInput:interactiveGraphUserInput=>this.props.handleUserInput(convertInteractiveGraphUserInputToGrapher(interactiveGraphUserInput))})}constructor(...args){super(...args),this.handlePlotChanges=newPlot=>{const plot={...this.props.userInput,...newPlot};this.props.handleUserInput(plot);this.props.trackInteraction();},this.handleActiveTypeChange=newType=>{const{graph}=this.props.options;const plot={...this.props.userInput,...defaultPlotProps(newType,graph)};this.props.handleUserInput(plot);},this._setupGraphie=(graphie,options)=>{const isMobile=this.props.apiOptions.isMobile;if(options.markings==="graph"){graphie.graphInit({range:options.range,scale:options.gridConfig.map(e=>e.scale),axisArrows:"<->",labelFormat:function(s){return "\\small{"+s+"}"},gridStep:options.gridStep,snapStep:options.snapStep,tickStep:isMobile?this._calculateMobileTickStep(options.gridStep,options.step,options.range):options.gridConfig.map(e=>e.tickStep),labelStep:1,unityLabels:options.gridConfig.map(e=>e.unityLabel),isMobile:isMobile});graphie.label([0,options.range[1][1]],options.labels[1],isMobile?"below right":"above");graphie.label([options.range[0][1],0],options.labels[0],isMobile?"above left":"right");}else if(options.markings==="grid"){graphie.graphInit({range:options.range,scale:options.gridConfig.map(e=>e.scale),gridStep:options.gridStep,axes:false,ticks:false,labels:false,isMobile:isMobile});}else if(options.markings==="none"){graphie.init({range:options.range,scale:options.gridConfig.map(e=>e.scale)});}const hairlineStyle={normalStyle:{strokeWidth:1}};this.horizHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.horizHairline.attr({stroke:tokenValue(semanticColor.core.border.instructive.default)});this.horizHairline.hide();this.vertHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.vertHairline.attr({stroke:tokenValue(semanticColor.core.border.instructive.default)});this.vertHairline.hide();},this.showHairlines=point=>{const{graph}=this.props.options;this.horizHairline.moveTo([graph.range[0][0],point[1]],[graph.range[0][1],point[1]]);this.horizHairline.show();this.vertHairline.moveTo([point[0],graph.range[1][0]],[point[0],graph.range[1][1]]);this.vertHairline.show();},this.hideHairlines=()=>{this.horizHairline.hide();this.vertHairline.hide();};}}function getUserInputFromSerializedState$a(serializedState){return serializedState.plot}function getStartUserInput$a(options){if(options.availableTypes.length===1){const graph=options.graph;const type=chooseType(options.availableTypes);if(type){return defaultPlotProps(type,graph)}}return DEFAULT_GRAPHER_PROPS.plot}function getCorrectUserInput$4(options){invariant(options.correct,"getCorrectUserInput should only be called for static widgets");return options.correct}const WrappedGrapher=withDependencies(Grapher);var Grapher$1 = {name:"grapher",displayName:"Grapher",hidden:true,widget:WrappedGrapher,getUserInputFromSerializedState: getUserInputFromSerializedState$a,getStartUserInput: getStartUserInput$a,getCorrectUserInput: getCorrectUserInput$4};
|
|
2023
2025
|
|
|
@@ -2039,7 +2041,7 @@ const GifControlsButton=({isPlaying,onToggle})=>{const strings=usePerseusI18n().
|
|
|
2039
2041
|
|
|
2040
2042
|
const MODAL_HEIGHT=568;function ExploreImageModalContent({options,linterContext,apiOptions,captionId,longDescId}){const{backgroundImage,scale:contentScale,caption,alt,longDescription,box,labels,range}=options;const[isGifPlaying,setIsGifPlaying]=React.useState(false);const[gifFrames,setGifFrames]=React.useState(null);const[imageIsGif,setImageIsGif]=React.useState(false);const context=React.useContext(PerseusI18nContext);React.useEffect(()=>{setIsGifPlaying(false);setGifFrames(null);const url=backgroundImage.url;if(!url||!isGif(url)){setImageIsGif(false);return}setImageIsGif(true);let mounted=true;decodeGifFrames(url).then(frames=>{if(mounted){setGifFrames(frames);}});return ()=>{mounted=false;}},[backgroundImage.url]);if(!backgroundImage.url){return null}const imageIsSvg=isSvg(backgroundImage.url);const isAnimatedGif=imageIsGif&&gifFrames!=null&&gifFrames.length>1;let scale=1;if(backgroundImage.width&&backgroundImage.height){scale=imageIsSvg?Math.max(contentScale,2):Math.max(contentScale,1);}let height=backgroundImage.height;let width=backgroundImage.width;if(backgroundImage.height&&backgroundImage.width){width=backgroundImage.width;height=backgroundImage.height;const maxScale=MODAL_HEIGHT/backgroundImage.height;scale=Math.min(scale,maxScale);}return jsxRuntimeExports.jsxs("div",{className:styles$d.modalPanelContainer,children:[jsxRuntimeExports.jsx("div",{className:styles$d.modalImageContainer,children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,allowZoom:false,alt:caption===alt?"":alt,width:width,height:height,scale:scale,extraGraphie:{box:box,range:range,labels:labels??[]},zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,setAssetStatus:setAssetStatus,isGifPlaying:imageIsGif?isGifPlaying:undefined,onGifLoop:imageIsGif?()=>setIsGifPlaying(false):undefined,gifFrames:imageIsGif?gifFrames??undefined:undefined})})}),jsxRuntimeExports.jsxs("div",{className:`perseus-image-modal-description ${styles$d.modalDescriptionContainer}`,children:[isAnimatedGif&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(GifControlsButton,{isPlaying:isGifPlaying,onToggle:()=>setIsGifPlaying(!isGifPlaying)}),jsxRuntimeExports.jsx("div",{className:styles$d.spacerVertical})]}),caption&&jsxRuntimeExports.jsx("div",{id:captionId,className:styles$d.modalCaptionContainer,children:jsxRuntimeExports.jsx(Renderer,{content:caption,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})}),jsxRuntimeExports.jsx(Heading,{size:"large",tag:"h2",style:wbStyles$1.descriptionHeading,children:context.strings.imageDescriptionLabel}),jsxRuntimeExports.jsx("div",{id:longDescId,children:jsxRuntimeExports.jsx(Renderer,{content:longDescription,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})})]})]})}const wbStyles$1={descriptionHeading:{marginBlockEnd:sizing.size_160}};
|
|
2041
2043
|
|
|
2042
|
-
const ExploreImageModal=props=>{const context=React__default.useContext(PerseusI18nContext);const uniqueId=React__default.useId();const captionId=`${uniqueId}-caption`;const longDescId=`${uniqueId}-long-desc`;const{analytics}=useDependencies();React__default.useEffect(()=>{const openedAt=Date.now();return ()=>{analytics.onAnalyticsEvent({type:"perseus:image:explore-modal-closed:ti",payload:{widgetSubType:"null",widgetId:props.widgetId,durationMs:Date.now()-openedAt}});}},[]);const titleText=props.options.title||context.strings.imageAlternativeTitle;const title=jsxRuntimeExports.jsx("h1",{className:`perseus-image-modal-title ${styles$d.modalTitleContainer}`,children:jsxRuntimeExports.jsx(Renderer,{content:titleText,apiOptions:props.apiOptions,linterContext:props.linterContext,strings:context.strings})});return jsxRuntimeExports.jsx("div",{className:`framework-perseus ${styles$d.modalContainer}`,children:jsxRuntimeExports.jsx(FlexibleDialog,{title:title,content:jsxRuntimeExports.jsx(ExploreImageModalContent,{...props,captionId:captionId,longDescId:longDescId}),"aria-describedby":props.options.caption?`${captionId} ${longDescId}`:longDescId,styles:{root:wbStyles.root}})})};const wbStyles={root:{borderRadius:sizing.size_120,maxWidth:"100%"}};
|
|
2044
|
+
const ExploreImageModal=props=>{const context=React__default.useContext(PerseusI18nContext);const uniqueId=React__default.useId();const captionId=`${uniqueId}-caption`;const longDescId=`${uniqueId}-long-desc`;const{analytics}=useDependencies();React__default.useEffect(()=>{const openedAt=Date.now();return ()=>{analytics.onAnalyticsEvent({type:"perseus:image:explore-modal-closed:ti",payload:{widgetSubType:"null",widgetId:props.widgetId,durationMs:Date.now()-openedAt}});}},[]);const titleText=props.options.title||context.strings.imageAlternativeTitle;const title=jsxRuntimeExports.jsx("h1",{className:`perseus-image-modal-title ${styles$d.modalTitleContainer}`,children:jsxRuntimeExports.jsx(Renderer,{content:titleText,apiOptions:props.apiOptions,linterContext:props.linterContext,strings:context.strings})});return jsxRuntimeExports.jsx("div",{className:`framework-perseus wb-themed-math ${styles$d.modalContainer}`,children:jsxRuntimeExports.jsx(FlexibleDialog,{title:title,content:jsxRuntimeExports.jsx(ExploreImageModalContent,{...props,captionId:captionId,longDescId:longDescId}),"aria-describedby":props.options.caption?`${captionId} ${longDescId}`:longDescId,styles:{root:wbStyles.root}})})};const wbStyles={root:{borderRadius:sizing.size_120,maxWidth:"100%"}};
|
|
2043
2045
|
|
|
2044
2046
|
const GifControlsIcon=({isPlaying,onToggle})=>{const strings=usePerseusI18n().strings;return jsxRuntimeExports.jsx(IconButton,{icon:isPlaying?pauseIcon:playIcon,kind:"secondary","aria-label":isPlaying?strings.gifPauseButtonLabel:strings.gifPlayButtonLabel,onClick:onToggle,style:{flexShrink:0}})};
|
|
2045
2047
|
|
|
@@ -2081,7 +2083,7 @@ class Measurer extends React.Component{componentDidMount(){this.setupGraphie();}
|
|
|
2081
2083
|
|
|
2082
2084
|
const getPromptJSON$6=widgetData=>{const{userInput}=widgetData;return {type:"number-line",options:{range:widgetData.options.range,snapDivisions:widgetData.options.snapDivisions},userInput:{numLinePosition:userInput.numLinePosition,numDivisions:userInput.numDivisions,rel:userInput.rel}}};
|
|
2083
2085
|
|
|
2084
|
-
const MovablePoint=Graphie.MovablePoint;const Line=Graphie.Line;const{assert}=InteractiveUtil;const bound=(x,gt,lt)=>Math.min(Math.max(x,gt),lt);const EN_DASH="–";const horizontalPadding=30;const MOBILE_BOX_WIDTH=288;const DESKTOP_BOX_WIDTH=460;function getNumberLineWidthPx(isMobile){return (isMobile?MOBILE_BOX_WIDTH:DESKTOP_BOX_WIDTH)-horizontalPadding*2}const reverseRel={eq:"eq",ge:"le",gt:"lt",le:"ge",lt:"gt"};const toggleStrictRel={eq:"eq",ge:"gt",gt:"ge",le:"lt",lt:"le"};function formatImproper(n,d){if(d===1){return ""+n}return `\\dfrac{${n}}{${d}}`}function formatMixed(n,d){if(n<0){return "-"+formatMixed(-n,d)}const w=Math.floor(n/d);if(w===0){return formatImproper(n,d)}if(n-w*d===0){return ""+w}return w+formatImproper(n-w*d,d)}function formatNonReduced(n,d,base){const factor=Math.floor(base/d);return formatImproper(n*factor,base)}const _label=(graphie,labelStyle,pos,value,base)=>{value=value||pos;if(labelStyle==="decimal"){return graphie.label([pos,-0.53],Math.round(value*100)/100,"center")}if(labelStyle==="improper"){const frac=KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatImproper(frac[0],frac[1]),"below")}if(labelStyle==="mixed"){const frac=KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatMixed(frac[0],frac[1]),"below")}if(labelStyle==="non-reduced"){const frac=KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatNonReduced(frac[0],frac[1],base),"below")}};const TickMarks=Graphie.createSimpleClass((graphie,props)=>{if(!Number.isFinite(props.tickStep)||props.tickStep<=0){return []}const results=[];const{range,labelRange,labelStyle,labelTicks,tickStep,numDivisions}=props;const leftLabel=labelRange[0]==null?range[0]:labelRange[0];const rightLabel=labelRange[1]==null?range[1]:labelRange[1];let base;if(labelStyle==="non-reduced"){const fractions=[leftLabel,rightLabel];for(let i=0;i<=numDivisions;i++){const x=range[0]+i*tickStep;fractions.push(x);}const getDenom=x=>number.toFraction(x)[1];const denoms=fractions.map(getDenom);base=denoms.reduce((x,y)=>KhanMath.getLCM(x,y));}else {base=undefined;}const highlightedLineStyle={stroke:tokenValue(semanticColor.core.foreground.instructive.default),strokeWidth:3.5};const highlightedTextStyle={color:tokenValue(semanticColor.core.foreground.instructive.default)};const initialTicks=[...Array(Math.round(numDivisions)).keys()].map(index=>range[0]+index*tickStep);const byNumericAscending=(a,b)=>a-b;const allTicks=[...new Set([...initialTicks,leftLabel,rightLabel,...range])].sort(byNumericAscending);allTicks.forEach(tick=>{const tickIsHighlighted=tick===leftLabel||tick===rightLabel;const lineStyle=tickIsHighlighted?highlightedLineStyle:null;const textStyle=tickIsHighlighted?highlightedTextStyle:null;graphie.style(lineStyle,()=>{results.push(graphie.line([tick,-0.2],[tick,.2]));});if(labelTicks||tickIsHighlighted){graphie.style(textStyle,()=>{results.push(_label(graphie,labelStyle,tick,tick,base));});}});return results});function isValid(props){const{range,divisionRange,snapDivisions}=props.options;let initialX=props.userInput?.numLinePosition;initialX=initialX==null?range[0]:initialX;return range[0]<range[1]&&number.sign(initialX-range[0])>=0&&number.sign(initialX-range[1])<=0&&divisionRange[0]<divisionRange[1]&&0<props.userInput?.numDivisions&&0<snapDivisions}const NumberLine=forwardRef(function NumberLine(props,ref){const{strings}=usePerseusI18n();const propsRef=useLatestRef(props);const[numDivisionsEmpty,setNumDivisionsEmpty]=useState(false);const tickStep=getTickStep(props.options.range,props.userInput.numDivisions);const graphieRef=useRef(null);const tickCtrlRef=useRef(null);useOnMountEffect(()=>{props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"number-line",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({focus:()=>{if(props.options.isTickCtrl){tickCtrlRef.current?.focus();return true}return false},focusInputPath:path=>{if(path?.length===1){tickCtrlRef.current?.focus();}},blurInputPath:path=>{if(path?.length===1){tickCtrlRef.current?.blur();}},getInputPaths:()=>{if(props.options.isTickCtrl){return [["tick-ctrl"]]}return []},getDOMNodeForPath:inputPath=>{if(inputPath?.length===1){return ReactDOM__default.findDOMNode(tickCtrlRef.current)}return null},getSerializedState:()=>({alignment:props.alignment,static:props.static,range:props.options.range,labelRange:props.options.labelRange,labelStyle:props.options.labelStyle,labelTicks:props.options.labelTicks,divisionRange:props.options.divisionRange,snapDivisions:props.options.snapDivisions,isInequality:props.options.isInequality,showTooltips:props.options.showTooltips,isTickCtrl:props.options.isTickCtrl,numDivisions:props.userInput.numDivisions,numLinePosition:props.userInput.numLinePosition,rel:"ge"}),getPromptJSON(){return getPromptJSON$6(props)},movePosition}));const setupGraphie=useCallback((graphie,options)=>{const latestProps=propsRef.current;if(!isValid(latestProps)){return}const widthInPixels=getNumberLineWidthPx(latestProps.apiOptions.isMobile);const range=options.range;const scale=(range[1]-range[0])/widthInPixels;const buffer=horizontalPadding*scale;const left=range[0]-buffer;const right=range[1]+buffer;const{labelStyle}=latestProps.options;const hasFractionalLabels=labelStyle==="improper"||labelStyle==="mixed"||labelStyle==="non-reduced";const bottom=hasFractionalLabels?-1.5:-1;const top=1;graphie.init({range:[[left,right],[bottom,top]],scale:[1/scale,40],isMobile:latestProps.apiOptions.isMobile});const center=(range[0]+range[1])/2;graphie.line([center,0],[right,0],{arrows:"->"});graphie.line([center,0],[left,0],{arrows:"->"});},[propsRef]);function snapNumLinePosition(tickStep,numLinePosition){const{range,snapDivisions}=props.options;const left=range[0];const right=range[1];const snapX=tickStep/snapDivisions;let x=bound(numLinePosition,left,right);x=left+number.roundTo(x-left,snapX);assert(Number.isFinite(x));return x}function onNumDivisionsChange(numDivisions,cb){numDivisions=Math.round(numDivisions);numDivisions=numDivisions<0?numDivisions*-1:numDivisions;if(numDivisions){const newTickStep=getTickStep(props.options.range,numDivisions);const newNumLinePosition=snapNumLinePosition(newTickStep,props.userInput.numLinePosition);setNumDivisionsEmpty(false);props.handleUserInput({...props.userInput,numDivisions:numDivisions,numLinePosition:newNumLinePosition},cb);}else {setNumDivisionsEmpty(true);cb?.();}}function handleTickCtrlFocus(){props.onFocus(["tick-ctrl"]);}function handleTickCtrlBlur(){props.onBlur(["tick-ctrl"]);}function movePosition(targetPosition){props.handleUserInput({...props.userInput,numLinePosition:targetPosition});props.trackInteraction();}function handleReverse(){const newRel=reverseRel[props.userInput.rel];props.handleUserInput({...props.userInput,rel:newRel});}function handleToggleStrict(){const newRel=toggleStrictRel[props.userInput.rel];props.handleUserInput({...props.userInput,rel:newRel});}function renderNumberLinePoint(){const isOpen=["lt","gt"].includes(props.userInput.rel);const interactiveColor=tokenValue(semanticColor.core.foreground.instructive.default);const staticColor=tokenValue(semanticColor.core.foreground.disabled.strong);const knockoutColor=tokenValue(semanticColor.core.border.knockout.default);const hollowFill=tokenValue(semanticColor.core.foreground.knockout.default);const pointColor=props.static?staticColor:interactiveColor;const normalStyle={fill:isOpen?hollowFill:pointColor,stroke:isOpen?pointColor:knockoutColor,"stroke-width":isOpen?3:1};const highlightStyle={fill:isOpen?hollowFill:interactiveColor,"stroke-width":isOpen?3:1};const mobileDotStyle=props.options.isInequality&&isOpen?{fill:hollowFill,stroke:pointColor,"stroke-width":3}:{};return jsxRuntimeExports.jsx(MovablePoint,{ref:"numberLinePoint",pointSize:6,coord:[props.userInput.numLinePosition,0],constraints:[(coord,prevCoord)=>{return [coord[0],prevCoord[1]]},(coord,prevCoord)=>{const x=snapNumLinePosition(tickStep,coord[0]);return [x,coord[1]]}],normalStyle:normalStyle,highlightStyle:highlightStyle,onMove:coord=>{movePosition(coord[0]);},isMobile:props.apiOptions.isMobile,mobileStyleOverride:mobileDotStyle,showTooltips:props.options.showTooltips??false,xOnlyTooltip:true})}function getInequalityEndpoint(){const isGreater=["ge","gt"].includes(props.userInput.rel);const widthInPixels=getNumberLineWidthPx(props.apiOptions.isMobile);const range=props.options.range;const scale=(range[1]-range[0])/widthInPixels;const buffer=horizontalPadding*scale;const left=range[0]-buffer;const right=range[1]+buffer;const end=isGreater?[right,0]:[left,0];return end}function renderInequality(){if(props.options.isInequality){const end=getInequalityEndpoint();const style={arrows:"->",stroke:tokenValue(semanticColor.core.foreground.instructive.default),strokeWidth:3.5};return jsxRuntimeExports.jsx(Line,{start:[props.userInput.numLinePosition,0],end:end,style:style})}return null}function renderGraphie(){const range=props.options.range;return jsxRuntimeExports.jsxs(Graphie,{ref:graphieRef,box:[props.apiOptions.isMobile?MOBILE_BOX_WIDTH:DESKTOP_BOX_WIDTH,80],options:{range,isTickCtrl:props.options.isTickCtrl},onMouseDown:coord=>{const point=graphieRef.current?.movables.numberLinePoint;point?.grab(coord);},setup:setupGraphie,isMobile:props.apiOptions.isMobile,children:[jsxRuntimeExports.jsx(TickMarks,{range:props.options.range,labelTicks:props.options.labelTicks,labelStyle:props.options.labelStyle,labelRange:props.options.labelRange,tickStep:tickStep,numDivisions:props.userInput.numDivisions,isMobile:props.apiOptions.isMobile}),renderInequality(),renderNumberLinePoint()]},props.options.labelStyle)}const{divisionRange,isTickCtrl,isInequality}=props.options;const divRangeString=divisionRange[0]+EN_DASH+divisionRange[1];const invalidNumDivisions=props.userInput?.numDivisions<divisionRange[0]||props.userInput?.numDivisions>divisionRange[1];const inequalityControls=jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("input",{type:"button",className:"simple-button",value:strings.switchDirection,onClick:handleReverse}),jsxRuntimeExports.jsx("input",{type:"button",className:"simple-button",value:["le","ge"].includes(props.userInput?.rel)?strings.circleOpen:strings.circleFilled,onClick:handleToggleStrict})]});let tickCtrl;if(isTickCtrl){const Input=props.apiOptions.customKeypad?SimpleKeypadInput:NumberInput;tickCtrl=jsxRuntimeExports.jsxs("label",{children:[strings.numDivisions," ",jsxRuntimeExports.jsx(Input,{ref:tickCtrlRef,value:numDivisionsEmpty?null:props.userInput?.numDivisions||divisionRange[0],checkValidity:val=>val>=divisionRange[0]&&val<=divisionRange[1],onChange:onNumDivisionsChange,onFocus:handleTickCtrlFocus,onBlur:handleTickCtrlBlur,useArrowKeys:true,keypadElement:props.keypadElement})]});}return jsxRuntimeExports.jsxs("div",{className:"perseus-widget "+"perseus-widget-interactive-number-line",children:[tickCtrl,!isValid(props)?jsxRuntimeExports.jsx("div",{className:"perseus-error",children:"Invalid number line configuration."}):isTickCtrl&&invalidNumDivisions?jsxRuntimeExports.jsx("div",{className:"perseus-error",children:strings.divisions({divRangeString:divRangeString})}):renderGraphie(),!props.static&&isInequality&&inequalityControls]})});function getUserInputFromSerializedState$4(serializedState){return {numDivisions:serializedState.numDivisions,numLinePosition:serializedState.numLinePosition,rel:"eq"}}function getStartNumDivisions(options){const width=options.range[1]-options.range[0];let numDivisions;if(options.numDivisions!=null){numDivisions=options.numDivisions;}else if(options.tickStep!=null){numDivisions=width/options.tickStep;}else {numDivisions=undefined;}return numDivisions}function getTickStep(range,numDivisions){const[min,max]=range;const width=max-min;return width/numDivisions}function getCorrectUserInput$1(options){const numLinePosition=options.correctX!=null?options.correctX:options.range[0];return {numDivisions:getStartNumDivisions(options),numLinePosition,rel:options.isInequality&&options.correctRel||"eq"}}function getStartUserInput$4(options){const numLinePosition=options.initialX!=null?options.initialX:options.range[0];return {numDivisions:getStartNumDivisions(options),numLinePosition,rel:options.isInequality?"ge":"eq"}}const WrappedNumberLine=withDependencies(NumberLine);var NumberLine$1 = {name:"number-line",displayName:"Number line",widget:WrappedNumberLine,getCorrectUserInput: getCorrectUserInput$1,getStartUserInput: getStartUserInput$4,getUserInputFromSerializedState: getUserInputFromSerializedState$4};
|
|
2086
|
+
const MovablePoint=Graphie.MovablePoint;const Line=Graphie.Line;const{assert}=InteractiveUtil;const bound=(x,gt,lt)=>Math.min(Math.max(x,gt),lt);const EN_DASH="–";const horizontalPadding=30;const MOBILE_BOX_WIDTH=288;const DESKTOP_BOX_WIDTH=460;function getNumberLineWidthPx(isMobile){return (isMobile?MOBILE_BOX_WIDTH:DESKTOP_BOX_WIDTH)-horizontalPadding*2}const reverseRel={eq:"eq",ge:"le",gt:"lt",le:"ge",lt:"gt"};const toggleStrictRel={eq:"eq",ge:"gt",gt:"ge",le:"lt",lt:"le"};function formatImproper(n,d){if(d===1){return ""+n}return `\\dfrac{${n}}{${d}}`}function formatMixed(n,d){if(n<0){return "-"+formatMixed(-n,d)}const w=Math.floor(n/d);if(w===0){return formatImproper(n,d)}if(n-w*d===0){return ""+w}return w+formatImproper(n-w*d,d)}function formatNonReduced(n,d,base){const factor=Math.floor(base/d);return formatImproper(n*factor,base)}const _label=(graphie,labelStyle,pos,value,base)=>{value=value||pos;if(labelStyle==="decimal"){return graphie.label([pos,-0.53],Math.round(value*100)/100,"center")}if(labelStyle==="improper"){const frac=KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatImproper(frac[0],frac[1]),"below")}if(labelStyle==="mixed"){const frac=KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatMixed(frac[0],frac[1]),"below")}if(labelStyle==="non-reduced"){const frac=KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatNonReduced(frac[0],frac[1],base),"below")}};const TickMarks=Graphie.createSimpleClass((graphie,props)=>{if(!Number.isFinite(props.tickStep)||props.tickStep<=0){return []}const results=[];const{range,labelRange,labelStyle,labelTicks,tickStep,numDivisions}=props;const leftLabel=labelRange[0]==null?range[0]:labelRange[0];const rightLabel=labelRange[1]==null?range[1]:labelRange[1];let base;if(labelStyle==="non-reduced"){const fractions=[leftLabel,rightLabel];for(let i=0;i<=numDivisions;i++){const x=range[0]+i*tickStep;fractions.push(x);}const getDenom=x=>number.toFraction(x)[1];const denoms=fractions.map(getDenom);base=denoms.reduce((x,y)=>KhanMath.getLCM(x,y));}else {base=undefined;}const highlightedLineStyle={stroke:tokenValue(semanticColor.core.foreground.instructive.default),strokeWidth:3.5};const highlightedTextStyle={color:tokenValue(semanticColor.core.foreground.instructive.default)};const initialTicks=[...Array(Math.round(numDivisions)).keys()].map(index=>range[0]+index*tickStep);const byNumericAscending=(a,b)=>a-b;const allTicks=[...new Set([...initialTicks,leftLabel,rightLabel,...range])].sort(byNumericAscending);allTicks.forEach(tick=>{const tickIsHighlighted=tick===leftLabel||tick===rightLabel;const lineStyle=tickIsHighlighted?highlightedLineStyle:null;const textStyle=tickIsHighlighted?highlightedTextStyle:null;graphie.style(lineStyle,()=>{results.push(graphie.line([tick,-0.2],[tick,.2]));});if(labelTicks||tickIsHighlighted){graphie.style(textStyle,()=>{results.push(_label(graphie,labelStyle,tick,tick,base));});}});return results});function isValid(props){const{range,divisionRange,snapDivisions}=props.options;let initialX=props.userInput?.numLinePosition;initialX=initialX==null?range[0]:initialX;return range[0]<range[1]&&number.sign(initialX-range[0])>=0&&number.sign(initialX-range[1])<=0&&divisionRange[0]<divisionRange[1]&&0<props.userInput?.numDivisions&&0<snapDivisions}const NumberLine=forwardRef(function NumberLine(props,ref){const{strings}=usePerseusI18n();const propsRef=useLatestRef(props);const[numDivisionsEmpty,setNumDivisionsEmpty]=useState(false);const tickStep=getTickStep(props.options.range,props.userInput.numDivisions);const graphieRef=useRef(null);const tickCtrlRef=useRef(null);useOnMountEffect(()=>{props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"number-line",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({focus:()=>{if(props.options.isTickCtrl){tickCtrlRef.current?.focus();return true}return false},focusInputPath:path=>{if(path?.length===1){tickCtrlRef.current?.focus();}},blurInputPath:path=>{if(path?.length===1){tickCtrlRef.current?.blur();}},getInputPaths:()=>{if(props.options.isTickCtrl){return [["tick-ctrl"]]}return []},getDOMNodeForPath:inputPath=>{if(inputPath?.length===1){return ReactDOM__default.findDOMNode(tickCtrlRef.current)}return null},getSerializedState:()=>({alignment:props.alignment,static:props.static,range:props.options.range,labelRange:props.options.labelRange,labelStyle:props.options.labelStyle,labelTicks:props.options.labelTicks,divisionRange:props.options.divisionRange,snapDivisions:props.options.snapDivisions,isInequality:props.options.isInequality,showTooltips:props.options.showTooltips,isTickCtrl:props.options.isTickCtrl,numDivisions:props.userInput.numDivisions,numLinePosition:props.userInput.numLinePosition,rel:"ge"}),getPromptJSON(){return getPromptJSON$6(props)},movePosition}));const setupGraphie=useCallback((graphie,options)=>{const latestProps=propsRef.current;if(!isValid(latestProps)){return}const widthInPixels=getNumberLineWidthPx(latestProps.apiOptions.isMobile);const range=options.range;const scale=(range[1]-range[0])/widthInPixels;const buffer=horizontalPadding*scale;const left=range[0]-buffer;const right=range[1]+buffer;const{labelStyle}=latestProps.options;const hasFractionalLabels=labelStyle==="improper"||labelStyle==="mixed"||labelStyle==="non-reduced";const bottom=hasFractionalLabels?-1.5:-1;const top=1;graphie.init({range:[[left,right],[bottom,top]],scale:[1/scale,40],isMobile:latestProps.apiOptions.isMobile});const center=(range[0]+range[1])/2;graphie.line([center,0],[right,0],{arrows:"->"});graphie.line([center,0],[left,0],{arrows:"->"});},[propsRef]);function snapNumLinePosition(tickStep,numLinePosition){const{range,snapDivisions}=props.options;const left=range[0];const right=range[1];const snapX=tickStep/snapDivisions;let x=bound(numLinePosition,left,right);x=left+number.roundTo(x-left,snapX);assert(Number.isFinite(x));return x}function onNumDivisionsChange(numDivisions,cb){numDivisions=Math.round(numDivisions);numDivisions=numDivisions<0?numDivisions*-1:numDivisions;if(numDivisions){const newTickStep=getTickStep(props.options.range,numDivisions);const newNumLinePosition=snapNumLinePosition(newTickStep,props.userInput.numLinePosition);setNumDivisionsEmpty(false);props.handleUserInput({...props.userInput,numDivisions:numDivisions,numLinePosition:newNumLinePosition},cb);}else {setNumDivisionsEmpty(true);cb?.();}}function handleTickCtrlFocus(){props.onFocus(["tick-ctrl"]);}function handleTickCtrlBlur(){props.onBlur(["tick-ctrl"]);}function movePosition(targetPosition){props.handleUserInput({...props.userInput,numLinePosition:targetPosition});props.trackInteraction();}function handleReverse(){const newRel=reverseRel[props.userInput.rel];props.handleUserInput({...props.userInput,rel:newRel});}function handleToggleStrict(){const newRel=toggleStrictRel[props.userInput.rel];props.handleUserInput({...props.userInput,rel:newRel});}function renderNumberLinePoint(){const isOpen=["lt","gt"].includes(props.userInput.rel);const interactiveColor=tokenValue(semanticColor.core.foreground.instructive.default);const staticColor=tokenValue(semanticColor.core.foreground.disabled.strong);const knockoutColor=tokenValue(semanticColor.core.border.knockout.default);const hollowFill=tokenValue(semanticColor.core.foreground.knockout.default);const pointColor=props.static?staticColor:interactiveColor;const normalStyle={fill:isOpen?hollowFill:pointColor,stroke:isOpen?pointColor:knockoutColor,"stroke-width":isOpen?3:1};const highlightStyle={fill:isOpen?hollowFill:interactiveColor,"stroke-width":isOpen?3:1};const mobileDotStyle=props.options.isInequality&&isOpen?{fill:hollowFill,stroke:pointColor,"stroke-width":3}:{};return jsxRuntimeExports.jsx(MovablePoint,{ref:"numberLinePoint",pointSize:6,coord:[props.userInput.numLinePosition,0],constraints:[(coord,prevCoord)=>{return [coord[0],prevCoord[1]]},(coord,prevCoord)=>{const x=snapNumLinePosition(tickStep,coord[0]);return [x,coord[1]]}],shadow:!!props.apiOptions.isMobile&&!isOpen,normalStyle:normalStyle,highlightStyle:highlightStyle,onMove:coord=>{movePosition(coord[0]);},isMobile:props.apiOptions.isMobile,mobileStyleOverride:mobileDotStyle,showTooltips:props.options.showTooltips??false,xOnlyTooltip:true})}function getInequalityEndpoint(){const isGreater=["ge","gt"].includes(props.userInput.rel);const widthInPixels=getNumberLineWidthPx(props.apiOptions.isMobile);const range=props.options.range;const scale=(range[1]-range[0])/widthInPixels;const buffer=horizontalPadding*scale;const left=range[0]-buffer;const right=range[1]+buffer;const end=isGreater?[right,0]:[left,0];return end}function renderInequality(){if(props.options.isInequality){const end=getInequalityEndpoint();const style={arrows:"->",stroke:tokenValue(semanticColor.core.foreground.instructive.default),strokeWidth:3.5};return jsxRuntimeExports.jsx(Line,{start:[props.userInput.numLinePosition,0],end:end,style:style})}return null}function renderGraphie(){const range=props.options.range;return jsxRuntimeExports.jsxs(Graphie,{ref:graphieRef,box:[props.apiOptions.isMobile?MOBILE_BOX_WIDTH:DESKTOP_BOX_WIDTH,80],options:{range,isTickCtrl:props.options.isTickCtrl},onMouseDown:coord=>{const point=graphieRef.current?.movables.numberLinePoint;point?.grab(coord);},setup:setupGraphie,isMobile:props.apiOptions.isMobile,children:[jsxRuntimeExports.jsx(TickMarks,{range:props.options.range,labelTicks:props.options.labelTicks,labelStyle:props.options.labelStyle,labelRange:props.options.labelRange,tickStep:tickStep,numDivisions:props.userInput.numDivisions,isMobile:props.apiOptions.isMobile}),renderInequality(),renderNumberLinePoint()]},props.options.labelStyle)}const{divisionRange,isTickCtrl,isInequality}=props.options;const divRangeString=divisionRange[0]+EN_DASH+divisionRange[1];const invalidNumDivisions=props.userInput?.numDivisions<divisionRange[0]||props.userInput?.numDivisions>divisionRange[1];const inequalityControls=jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("input",{type:"button",className:"simple-button",value:strings.switchDirection,onClick:handleReverse}),jsxRuntimeExports.jsx("input",{type:"button",className:"simple-button",value:["le","ge"].includes(props.userInput?.rel)?strings.circleOpen:strings.circleFilled,onClick:handleToggleStrict})]});let tickCtrl;if(isTickCtrl){const Input=props.apiOptions.customKeypad?SimpleKeypadInput:NumberInput;tickCtrl=jsxRuntimeExports.jsxs("label",{children:[strings.numDivisions," ",jsxRuntimeExports.jsx(Input,{ref:tickCtrlRef,value:numDivisionsEmpty?null:props.userInput?.numDivisions||divisionRange[0],checkValidity:val=>val>=divisionRange[0]&&val<=divisionRange[1],onChange:onNumDivisionsChange,onFocus:handleTickCtrlFocus,onBlur:handleTickCtrlBlur,useArrowKeys:true,keypadElement:props.keypadElement})]});}return jsxRuntimeExports.jsxs("div",{className:"perseus-widget "+"perseus-widget-interactive-number-line",children:[tickCtrl,!isValid(props)?jsxRuntimeExports.jsx("div",{className:"perseus-error",children:"Invalid number line configuration."}):isTickCtrl&&invalidNumDivisions?jsxRuntimeExports.jsx("div",{className:"perseus-error",children:strings.divisions({divRangeString:divRangeString})}):renderGraphie(),!props.static&&isInequality&&inequalityControls]})});function getUserInputFromSerializedState$4(serializedState){return {numDivisions:serializedState.numDivisions,numLinePosition:serializedState.numLinePosition,rel:"eq"}}function getStartNumDivisions(options){const width=options.range[1]-options.range[0];let numDivisions;if(options.numDivisions!=null){numDivisions=options.numDivisions;}else if(options.tickStep!=null){numDivisions=width/options.tickStep;}else {numDivisions=undefined;}return numDivisions}function getTickStep(range,numDivisions){const[min,max]=range;const width=max-min;return width/numDivisions}function getCorrectUserInput$1(options){const numLinePosition=options.correctX!=null?options.correctX:options.range[0];return {numDivisions:getStartNumDivisions(options),numLinePosition,rel:options.isInequality&&options.correctRel||"eq"}}function getStartUserInput$4(options){const numLinePosition=options.initialX!=null?options.initialX:options.range[0];return {numDivisions:getStartNumDivisions(options),numLinePosition,rel:options.isInequality?"ge":"eq"}}const WrappedNumberLine=withDependencies(NumberLine);var NumberLine$1 = {name:"number-line",displayName:"Number line",widget:WrappedNumberLine,getCorrectUserInput: getCorrectUserInput$1,getStartUserInput: getStartUserInput$4,getUserInputFromSerializedState: getUserInputFromSerializedState$4};
|
|
2085
2087
|
|
|
2086
2088
|
const getPromptJSON$5=widgetData=>{return {type:"orderer",options:{options:widgetData.options.options.map(option=>option.content)},userInput:{values:widgetData.userInput.current}}};
|
|
2087
2089
|
|
|
@@ -2101,7 +2103,9 @@ function getUrlFromProgramID(programID){return `/python-program/${programID}/emb
|
|
|
2101
2103
|
|
|
2102
2104
|
const getPromptJSON$1=userInput=>{return {type:"sorter",userInput:{values:userInput.options,changed:userInput.changed}}};
|
|
2103
2105
|
|
|
2104
|
-
|
|
2106
|
+
const Sorter$1=forwardRef(function Sorter(props,ref){const dependencies=useDependencies();const sortable=useRef(null);const{options,userInput,widgetId,linterContext,apiOptions}=props;const{layout,padding}=options;useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"sorter",widgetId:widgetId}});});useImperativeHandle(ref,()=>({moveOptionToIndex:(option,index)=>{sortable.current?.moveOptionToIndex(option,index);},getPromptJSON:()=>getPromptJSON$1(props.userInput),getSerializedState:()=>{const{userInput,options,...rest}=props;return {...rest,...options,changed:userInput.changed,options:userInput.options}}}));function handleChange(){props.handleUserInput({options:sortable.current?.getOptions()??[],changed:true});props.trackInteraction();}return jsxRuntimeExports.jsx("div",{className:"perseus-clearfix",children:jsxRuntimeExports.jsx(Sortable,{options:userInput.options,layout:layout,margin:apiOptions.isMobile?8:5,padding:padding,onChange:handleChange,linterContext:linterContext,ref:sortable})})});
|
|
2107
|
+
|
|
2108
|
+
function getStartUserInput$1(options,problemNum){const shuffled=shuffleSorter(options,problemNum);return {options:shuffled,changed:false}}function getUserInputFromSerializedState$1(serializedState){return {changed:serializedState.changed,options:serializedState.options}}var Sorter = {name:"sorter",displayName:"Sorter",widget:Sorter$1,isLintable:true,getStartUserInput: getStartUserInput$1,getUserInputFromSerializedState: getUserInputFromSerializedState$1};
|
|
2105
2109
|
|
|
2106
2110
|
function getInputPath(row,column){return [""+row,""+column]}function getDefaultPath(){return getInputPath(0,0)}function getRowFromPath(path){invariant(Array.isArray(path)&&path.length===2,"path should be a (row, colum) pair");return +path[0]}function getColumnFromPath(path){invariant(Array.isArray(path)&&path.length===2,"path should be a (row, colum) pair");return +path[1]}function getRefForPath(path){const row=getRowFromPath(path);const column=getColumnFromPath(path);return "answer"+row+","+column}const Table=forwardRef(function Table(props,ref){const{strings}=usePerseusI18n();const cellRefs=useRef({});useImperativeHandle(ref,()=>({focus(){getCellForPath(getDefaultPath())?.focus();return true},focusInputPath(path){getCellForPath(path)?.focus();},blurInputPath(path){getCellForPath(path)?.blur();},getDOMNodeForPath(path){const cell=getCellForPath(path);if(cell instanceof HTMLInputElement){return cell}return ReactDOM__default.findDOMNode(cell??null)},getInputPaths:()=>props.userInput.flatMap((rowArr,r)=>rowArr.map((_,c)=>getInputPath(r,c))),getSerializedState(){const{userInput,editableHeaders,options,...rest}=props;return {...options,...rest,answers:userInput}}}));function getCellForPath(path){return cellRefs.current[getRefForPath(path)]}function handleValueChange(row,column,eventOrValue){const answers=deepClone(props.userInput);answers[row][column]=eventOrValue.target?eventOrValue.target.value:eventOrValue;props.handleUserInput(answers);props.trackInteraction();}function handleHeaderChange(index,e){const headers=[...props.options.headers];headers[index]=e.content;props.onChange({headers});}let InputComponent;let inputStyle;const extraInputProps={};if(props.apiOptions.customKeypad){InputComponent=SimpleKeypadInput;inputStyle={width:80};extraInputProps.keypadElement=props.keypadElement;}else {InputComponent="input";inputStyle={};}const headerRow=jsxRuntimeExports.jsx("tr",{children:props.options.headers.map((header,i)=>{if(props.editableHeaders){return jsxRuntimeExports.jsx("th",{children:jsxRuntimeExports.jsx(props.Editor,{apiOptions:props.apiOptions,content:header,widgetEnabled:false,onChange:e=>handleHeaderChange(i,e)})},i)}return jsxRuntimeExports.jsx("th",{children:jsxRuntimeExports.jsx(Renderer,{content:header,linterContext:props.linterContext,strings:strings})},i)})});const tableRows=props.userInput.map((rowCells,r)=>jsxRuntimeExports.jsx("tr",{children:rowCells.map((answer,c)=>jsxRuntimeExports.jsx("td",{children:jsxRuntimeExports.jsx(InputComponent,{ref:cell=>{const refId=getRefForPath(getInputPath(r,c));cellRefs.current[refId]=cell??undefined;},type:"text",value:answer,disabled:props.apiOptions.readOnly,onFocus:()=>props.onFocus(getInputPath(r,c)),onBlur:()=>props.onBlur(getInputPath(r,c)),onChange:e=>handleValueChange(r,c,e),style:inputStyle,...extraInputProps})},c))},r));return jsxRuntimeExports.jsxs("table",{className:"perseus-widget-table-of-values non-markdown",children:[jsxRuntimeExports.jsx("thead",{children:headerRow}),jsxRuntimeExports.jsx("tbody",{children:tableRows})]})});function getStartUserInput(options){const rows=options.rows;const columns=options.columns;return Util.stringArrayOfSize2D({rows,columns})}function getUserInputFromSerializedState(serializedState){return serializedState.answers}var Table$1 = {name:"table",displayName:"Table (deprecated - use markdown table instead)",widget:Table,hidden:true,isLintable:true,getStartUserInput,getUserInputFromSerializedState};
|
|
2107
2111
|
|
|
@@ -2113,15 +2117,15 @@ var styles$3 = {"perseusVideoWidget":"perseus_gxXDcWBe","perseusVideoFixedToResp
|
|
|
2113
2117
|
|
|
2114
2118
|
const DEFAULT_WIDTH=1280;const DEFAULT_HEIGHT=720;const KA_EMBED="{host}/embed_video?slug={slug}"+"&internal_video_only=1";const IS_URL=/^https?:\/\//;const IS_KA_SITE=/(khanacademy\.org|localhost)/;const IS_VIMEO=/(vimeo\.com)/;class Video extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"video",widgetId:this.props.widgetId}});}getPromptJSON(){return getPromptJSON()}render(){const{InitialRequestUrl}=getDependencies();const{location}=this.props.options;if(!location){return jsxRuntimeExports.jsx("div",{})}let url;if(IS_URL.test(location)){url=location;if(IS_VIMEO.test(url)){if(url.indexOf("?")===-1){url+="?dnt=1";}else {url+="&dnt=1";}}}else {url=KA_EMBED.replace("{slug}",location);let embedHostname="https://www.khanacademy.org";if(IS_KA_SITE.test(InitialRequestUrl.host)){embedHostname=InitialRequestUrl.origin;}url=url.replace("{host}",embedHostname);}url=this.props.dependencies.generateUrl({url,context:"video:video_url",kaLocale:this.context.locale});return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(FixedToResponsive,{className:styles$3.perseusVideoFixedToResponsive,width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,children:jsxRuntimeExports.jsx("iframe",{title:this.context.strings.videoWrapper,className:styles$3.perseusVideoWidget,sandbox:"allow-same-origin allow-scripts",width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,src:url,allowFullScreen:true,allow:"autoplay"})},location),jsxRuntimeExports.jsx(VideoTranscriptLink,{location:location})]})}constructor(...args){super(...args),this.isWidget=true;}}Video.contextType=PerseusI18nContext;const WrappedVideo=withDependencies(Video);var Video$1 = {name:"video",displayName:"Video",widget:WrappedVideo};
|
|
2115
2119
|
|
|
2116
|
-
var extraWidgets = [Blank,CSProgram$1,Categorizer$1,Definition$1,DeprecatedStandin$1,Dropdown$1,Explanation$1,FreeResponse$1,GradedGroup$1,GradedGroupSet$1,Grapher$1,Group$1,Iframe$1,Image$1,Interactive,InteractiveGraph$1,LabelImage$1,Matcher$1,Matrix$1,Measurer$1,NumberLine$1,Orderer$1,PhetSimulation$1,Plotter$1,PythonProgram$1,Sorter
|
|
2120
|
+
var extraWidgets = [Blank,CSProgram$1,Categorizer$1,Definition$1,DeprecatedStandin$1,Dropdown$1,Explanation$1,FreeResponse$1,GradedGroup$1,GradedGroupSet$1,Grapher$1,Group$1,Iframe$1,Image$1,Interactive,InteractiveGraph$1,LabelImage$1,Matcher$1,Matrix$1,Measurer$1,NumberLine$1,Orderer$1,PhetSimulation$1,Plotter$1,PythonProgram$1,Sorter,Table$1,Video$1];
|
|
2117
2121
|
|
|
2118
2122
|
const init=function(){registerWidgets(basicWidgets);registerWidgets(extraWidgets);replaceDeprecatedWidgets();};
|
|
2119
2123
|
|
|
2120
|
-
const libName="@khanacademy/perseus";const libVersion="85.
|
|
2124
|
+
const libName="@khanacademy/perseus";const libVersion="85.1.2";addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
2121
2125
|
|
|
2122
2126
|
const apiVersion={major:12,minor:0};
|
|
2123
2127
|
|
|
2124
|
-
class ArticleRenderer extends React.Component{componentDidMount(){this._currentFocus=null;}shouldComponentUpdate(nextProps){return nextProps!==this.props}render(){const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,isArticle:true};const classes=classNames$2({"framework-perseus":true,"perseus-article":true,[ClassNames.MOBILE]:apiOptions.isMobile});const sections=this._sections().map((section,sectionIndex)=>{return jsxRuntimeExports.jsx("div",{className:"clearfix",children:jsxRuntimeExports.jsx(UserInputManager,{widgets:section.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>createElement(Renderer,{...section,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,ref:elem=>{if(elem){this.sectionRenderers[sectionIndex]=elem;}},key:sectionIndex,keypadElement:this.props.keypadElement,apiOptions:{...apiOptions,onFocusChange:(newFocusPath,oldFocusPath)=>{this._handleFocusChange(newFocusPath&&[sectionIndex].concat(newFocusPath),oldFocusPath&&[sectionIndex].concat(oldFocusPath));}},linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"article"),legacyPerseusLint:this.props.legacyPerseusLint,strings:this.context.strings})})},sectionIndex)});return jsxRuntimeExports.jsx("div",{className:classes,children:jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:sections})})}constructor(props){super(props),this.sectionRenderers=[],this._handleFocusChange=(newFocusPath,oldFocusPath)=>{if(newFocusPath){this._setCurrentFocus(newFocusPath);}else {this._onRendererBlur(oldFocusPath);}},this._setCurrentFocus=newFocusPath=>{const{keypadElement,apiOptions}=this.props;const{isMobile}=apiOptions;const prevFocusPath=this._currentFocus;this._currentFocus=newFocusPath;let didFocusInput=false;let focusedInput;if(this._currentFocus){const[sectionIndex,...focusPath]=this._currentFocus;const inputPaths=this.sectionRenderers[sectionIndex].getInputPaths();didFocusInput=inputPaths.some(inputPath=>{return Util.inputPathsEqual(inputPath,focusPath)});focusedInput=this.sectionRenderers[sectionIndex].getDOMNodeForPath(focusPath);}const{onFocusChange}=this.props.apiOptions;if(onFocusChange){setTimeout(()=>{const keypadDomNode=keypadElement?.getDOMNode();const keypadHeight=keypadDomNode&&didFocusInput?keypadDomNode.getBoundingClientRect().height:0;onFocusChange(this._currentFocus,prevFocusPath,keypadHeight,didFocusInput?focusedInput:null);},0);}if(keypadElement&&isMobile){if(didFocusInput){keypadElement.activate();}else {keypadElement.dismiss();}}},this._onRendererBlur=blurPath=>{const blurringFocusPath=this._currentFocus;if(!Util.inputPathsEqual(blurPath,blurringFocusPath)){return}setTimeout(()=>{if(Util.inputPathsEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.blur=()=>{if(this._currentFocus){const[sectionIndex,...inputPath]=this._currentFocus;this.sectionRenderers[sectionIndex].blurPath(inputPath);}},this._sections=()=>{const sections=Array.isArray(this.props.json)?this.props.json:[this.props.json];if(getDependencies().JIPT.useJIPT){const paragraphs=[];for(const section of sections){JiptParagraphs.parseToArray(section.content).forEach(paragraph=>{paragraphs.push({...section,content:paragraph});});}return paragraphs}return sections};}}ArticleRenderer.contextType=PerseusI18nContext;ArticleRenderer.defaultProps={apiOptions:ApiOptions.defaults,linterContext:PerseusLinter.linterContextDefault};
|
|
2128
|
+
class ArticleRenderer extends React.Component{componentDidMount(){this._currentFocus=null;}shouldComponentUpdate(nextProps){return nextProps!==this.props}render(){const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,isArticle:true};const classes=classNames$2({"framework-perseus":true,"perseus-article":true,"wb-themed-math":true,[ClassNames.MOBILE]:apiOptions.isMobile});const sections=this._sections().map((section,sectionIndex)=>{return jsxRuntimeExports.jsx("div",{className:"clearfix",children:jsxRuntimeExports.jsx(UserInputManager,{widgets:section.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>createElement(Renderer,{...section,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,ref:elem=>{if(elem){this.sectionRenderers[sectionIndex]=elem;}},key:sectionIndex,keypadElement:this.props.keypadElement,apiOptions:{...apiOptions,onFocusChange:(newFocusPath,oldFocusPath)=>{this._handleFocusChange(newFocusPath&&[sectionIndex].concat(newFocusPath),oldFocusPath&&[sectionIndex].concat(oldFocusPath));}},linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"article"),legacyPerseusLint:this.props.legacyPerseusLint,strings:this.context.strings})})},sectionIndex)});return jsxRuntimeExports.jsx("div",{className:classes,children:jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:sections})})}constructor(props){super(props),this.sectionRenderers=[],this._handleFocusChange=(newFocusPath,oldFocusPath)=>{if(newFocusPath){this._setCurrentFocus(newFocusPath);}else {this._onRendererBlur(oldFocusPath);}},this._setCurrentFocus=newFocusPath=>{const{keypadElement,apiOptions}=this.props;const{isMobile}=apiOptions;const prevFocusPath=this._currentFocus;this._currentFocus=newFocusPath;let didFocusInput=false;let focusedInput;if(this._currentFocus){const[sectionIndex,...focusPath]=this._currentFocus;const inputPaths=this.sectionRenderers[sectionIndex].getInputPaths();didFocusInput=inputPaths.some(inputPath=>{return Util.inputPathsEqual(inputPath,focusPath)});focusedInput=this.sectionRenderers[sectionIndex].getDOMNodeForPath(focusPath);}const{onFocusChange}=this.props.apiOptions;if(onFocusChange){setTimeout(()=>{const keypadDomNode=keypadElement?.getDOMNode();const keypadHeight=keypadDomNode&&didFocusInput?keypadDomNode.getBoundingClientRect().height:0;onFocusChange(this._currentFocus,prevFocusPath,keypadHeight,didFocusInput?focusedInput:null);},0);}if(keypadElement&&isMobile){if(didFocusInput){keypadElement.activate();}else {keypadElement.dismiss();}}},this._onRendererBlur=blurPath=>{const blurringFocusPath=this._currentFocus;if(!Util.inputPathsEqual(blurPath,blurringFocusPath)){return}setTimeout(()=>{if(Util.inputPathsEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.blur=()=>{if(this._currentFocus){const[sectionIndex,...inputPath]=this._currentFocus;this.sectionRenderers[sectionIndex].blurPath(inputPath);}},this._sections=()=>{const sections=Array.isArray(this.props.json)?this.props.json:[this.props.json];if(getDependencies().JIPT.useJIPT){const paragraphs=[];for(const section of sections){JiptParagraphs.parseToArray(section.content).forEach(paragraph=>{paragraphs.push({...section,content:paragraph});});}return paragraphs}return sections};}}ArticleRenderer.contextType=PerseusI18nContext;ArticleRenderer.defaultProps={apiOptions:ApiOptions.defaults,linterContext:PerseusLinter.linterContextDefault};
|
|
2125
2129
|
|
|
2126
2130
|
class HintRenderer extends React.Component{render(){if(this.props.hint.placeholder){return jsxRuntimeExports.jsx("span",{})}const{apiOptions,className,hint,lastHint,lastRendered,pos,totalHints}=this.props;const{isMobile}=apiOptions;const classNames=classNames$2("hint",!isMobile&&"perseus-hint-renderer",isMobile&&css(styles$2.newHint),isMobile&&lastRendered&&css(styles$2.lastRenderedNewHint),lastHint&&"last-hint",lastRendered&&"last-rendered",className);const rendererApiOptions={...apiOptions,customKeypad:false};return jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{className:classNames,tabIndex:"-1",children:[!apiOptions.isMobile&&jsxRuntimeExports.jsx("span",{className:"perseus-sr-only",children:this.context.strings.hintPos({pos:pos+1})}),!apiOptions.isMobile&&totalHints!=null&&pos!=null&&jsxRuntimeExports.jsx("span",{className:"perseus-hint-label",style:{display:"block",color:apiOptions.hintProgressColor},children:`${pos+1} / ${totalHints}`}),jsxRuntimeExports.jsx(UserInputManager,{widgets:hint.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>jsxRuntimeExports.jsx(Renderer,{ref:this.rendererRef,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,widgets:hint.widgets,content:hint.content||"",images:hint.images,apiOptions:rendererApiOptions,findExternalWidgets:this.props.findExternalWidgets,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hint"),strings:this.context.strings})})]})})}constructor(...args){super(...args),this.rendererRef=React.createRef(),this.getSerializedState=()=>{return this.rendererRef.current?.getSerializedState()};}}HintRenderer.contextType=PerseusI18nContext;HintRenderer.defaultProps={linterContext:PerseusLinter.linterContextDefault};const styles$2=StyleSheet.create({newHint:{marginBlockEnd:sizing.size_240,borderInlineStartColor:semanticColor.core.border.neutral.subtle,borderInlineStartStyle:"solid",borderInlineStartWidth:hintBorderWidth,[mediaQueries.lgOrSmaller]:{paddingInlineStart:hintPaddingInlineStart},[mediaQueries.smOrSmaller]:{paddingInlineStart:0},":focus":{outline:"none"}},lastRenderedNewHint:{marginBlockEnd:0,borderInlineStartColor:semanticColor.core.border.instructive.default}});
|
|
2127
2131
|
|