@khanacademy/perseus 66.2.2 → 66.4.0

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.
Files changed (40) hide show
  1. package/dist/es/index.css +13 -1
  2. package/dist/es/index.css.map +1 -1
  3. package/dist/es/index.js +55 -55
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.css +13 -1
  6. package/dist/index.css.map +1 -1
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +57 -54
  9. package/dist/index.js.map +1 -1
  10. package/dist/widget-ai-utils/categorizer/categorizer-ai-utils.d.ts +1 -1
  11. package/dist/widget-ai-utils/matrix/matrix-ai-utils.d.ts +1 -1
  12. package/dist/widgets/categorizer/categorizer.d.ts +3 -7
  13. package/dist/widgets/dropdown/dropdown.d.ts +10 -10
  14. package/dist/widgets/expression/expression.d.ts +14 -21
  15. package/dist/widgets/graded-group/graded-group.d.ts +1 -2
  16. package/dist/widgets/graded-group-set/graded-group-set.d.ts +1 -2
  17. package/dist/widgets/grapher/grapher.d.ts +2 -34
  18. package/dist/widgets/group/group.d.ts +1 -2
  19. package/dist/widgets/image/image.d.ts +1 -2
  20. package/dist/widgets/input-number/input-number.d.ts +1 -4
  21. package/dist/widgets/interactive-graphs/interactive-graph-question-builder.d.ts +7 -0
  22. package/dist/widgets/interactive-graphs/interactive-graph.d.ts +16 -1
  23. package/dist/widgets/interactive-graphs/mafs-graph.d.ts +1 -0
  24. package/dist/widgets/interactive-graphs/reducer/use-graph-config.d.ts +2 -1
  25. package/dist/widgets/interactive-graphs/stateful-mafs-graph.d.ts +1 -0
  26. package/dist/widgets/matrix/matrix.d.ts +1 -11
  27. package/dist/widgets/passage/passage.d.ts +1 -8
  28. package/dist/widgets/passage-ref/passage-ref.d.ts +0 -5
  29. package/dist/widgets/passage-ref-target/passage-ref-target.d.ts +0 -1
  30. package/dist/widgets/plotter/plotter.d.ts +0 -1
  31. package/dist/widgets/radio/base-radio.d.ts +1 -0
  32. package/dist/widgets/radio/choice.new.d.ts +9 -26
  33. package/dist/widgets/radio/multiple-choice-component.new.d.ts +3 -25
  34. package/dist/widgets/radio/multiple-choice-widget.new.d.ts +17 -1
  35. package/dist/widgets/video/video.d.ts +1 -2
  36. package/package.json +42 -42
  37. package/dist/widgets/radio/choice-none-above.new.d.ts +0 -14
  38. package/dist/widgets/radio/focus-ring.new.d.ts +0 -19
  39. package/dist/widgets/radio/multiple-choice-option.new.d.ts +0 -11
  40. package/dist/widgets/radio/option-status.new.d.ts +0 -23
package/dist/index.js CHANGED
@@ -30,12 +30,14 @@ var pureMarkdown = require('@khanacademy/pure-markdown');
30
30
  var IconButton = require('@khanacademy/wonder-blocks-icon-button');
31
31
  var caretLeftIcon = require('@phosphor-icons/core/regular/caret-left.svg');
32
32
  var caretRightIcon = require('@phosphor-icons/core/regular/caret-right.svg');
33
+ var wonderBlocksIcon = require('@khanacademy/wonder-blocks-icon');
34
+ var checkIcon = require('@phosphor-icons/core/bold/check-bold.svg');
35
+ var minusIcon = require('@phosphor-icons/core/bold/minus-circle-bold.svg');
33
36
  var Banner = require('@khanacademy/wonder-blocks-banner');
34
37
  var wonderBlocksDropdown = require('@khanacademy/wonder-blocks-dropdown');
35
38
  var Button = require('@khanacademy/wonder-blocks-button');
36
39
  var caretDown = require('@phosphor-icons/core/regular/caret-down.svg');
37
40
  var caretUp = require('@phosphor-icons/core/regular/caret-up.svg');
38
- var wonderBlocksIcon = require('@khanacademy/wonder-blocks-icon');
39
41
  var wonderBlocksLabeledField = require('@khanacademy/wonder-blocks-labeled-field');
40
42
  var warningCircleIcon = require('@phosphor-icons/core/regular/warning-circle.svg');
41
43
  var KAS = require('@khanacademy/kas');
@@ -85,6 +87,8 @@ var SimpleMarkdown__default = /*#__PURE__*/_interopDefaultCompat(SimpleMarkdown)
85
87
  var IconButton__default = /*#__PURE__*/_interopDefaultCompat(IconButton);
86
88
  var caretLeftIcon__default = /*#__PURE__*/_interopDefaultCompat(caretLeftIcon);
87
89
  var caretRightIcon__default = /*#__PURE__*/_interopDefaultCompat(caretRightIcon);
90
+ var checkIcon__default = /*#__PURE__*/_interopDefaultCompat(checkIcon);
91
+ var minusIcon__default = /*#__PURE__*/_interopDefaultCompat(minusIcon);
88
92
  var Banner__default = /*#__PURE__*/_interopDefaultCompat(Banner);
89
93
  var Button__default = /*#__PURE__*/_interopDefaultCompat(Button);
90
94
  var caretDown__default = /*#__PURE__*/_interopDefaultCompat(caretDown);
@@ -1451,7 +1455,7 @@ var a11y = aphrodite.StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",he
1451
1455
 
1452
1456
  const debounce=(func,delay)=>{let timer=null;return (...args)=>{if(timer){clearTimeout(timer);}timer=window.setTimeout(()=>{func(...args);},delay);}};
1453
1457
 
1454
- class InnerMathInput extends React__namespace.Component{componentDidMount(){this.mathField()?.latex(this.props.value);}openKeypad(){if(this.props.buttonsVisible==="never"){return}this.setState({keypadOpen:true});}closeKeypad(){this.setState({keypadOpen:false});}render(){let className=classNames__default.default({"perseus-math-input":true,"mq-editable-field":true,"mq-math-mode":true});const popoverContentUniqueId=uuid.v4().slice(0,8);if(this.props.className){className=className+" "+this.props.className;}return jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:[styles$J.outerWrapper,this.state.focused&&styles$J.wrapperFocused],children:jsxRuntimeExports.jsxs("div",{style:{display:"flex",padding:1},onClick:e=>{e.stopPropagation();const mathField=this.mathField();if(!mathField){return}this.setState({cursorContext:mathInput.getCursorContext(mathField)});},children:[jsxRuntimeExports.jsx("span",{className:className,ref:ref=>this.__mathFieldWrapperRef=ref,onFocus:()=>this.focus(),onBlur:()=>this.blur()}),jsxRuntimeExports.jsx(wonderBlocksPopover.Popover,{opened:this.state.keypadOpen,dismissEnabled:true,rootBoundary:"document","aria-label":this.context.strings.mathInputTitle,"aria-describedby":`popover-content-${popoverContentUniqueId}`,content:()=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(wonderBlocksTypography.HeadingMedium,{id:`popover-content-${popoverContentUniqueId}`,style:a11y.srOnly,children:this.context.strings.mathInputDescription}),jsxRuntimeExports.jsx(wonderBlocksPopover.PopoverContentCore,{style:styles$J.popoverContent,children:jsxRuntimeExports.jsx(mathInput.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__default.default,{"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"?true:false,cursorContext:mathInput.CursorContext.NONE},this.insert=value=>{const input=this.mathField();const{locale}=this.context;const customKeyTranslator={...mathInput.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(___default.default(value).isFunction()){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=mathInput.createMathField(this.__mathFieldWrapperRef,locale,this.props.mathInputStrings,baseConfig=>({...baseConfig,handlers:{edit:debounce(mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(mathInput.convertDotToTimesByLocale(locale,this.props.convertDotToTimes)){value=value.replace(/\\cdot/g,"\\times");const left=mathField.cursor()[mathInput.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:mathInput.getCursorContext(mathField)});},100),enter:()=>{if(this.__mathFieldWrapperRef){$__default.default(this.__mathFieldWrapperRef).submit();}},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)=>{const{locale}=this.context;const translator=mathInput.getKeyTranslator(locale,this.context.strings)[key];const mathField=this.mathField();if(mathField){if(translator){translator(mathField,key);}this.setState({cursorContext:mathInput.getCursorContext(mathField)});}if(e?.type==="click"){this.focus();}if(key==="DISMISS"){this.closeKeypad();}};}}InnerMathInput.contextType=PerseusI18nContext;InnerMathInput.defaultProps={value:"",convertDotToTimes:false};class MathInput extends React__namespace.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__namespace.createRef();}}MathInput.contextType=mathInput.MathInputI18nContext;MathInput.defaultProps={ariaLabel:"Math input"};const MathInputIcon=({hovered,focused,active})=>{let fillColor;switch(true){case focused||active:fillColor=wonderBlocksTokens.color.white;break;case hovered:fillColor=wonderBlocksTokens.color.blue;break;default:fillColor=wonderBlocksTokens.color.offBlack;break}const dynamicClass=active||focused?styles$J.iconActive:styles$J.iconInactive;return jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:[styles$J.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={borderWidth:2,borderColor:wonderBlocksTokens.color.blue,margin:-1};const styles$J=aphrodite.StyleSheet.create({iconContainer:{display:"flex",justifyContent:"center",height:"100%",padding:wonderBlocksTokens.spacing.xxxSmall_4,borderRadius:1},iconInactive:{border:"2px solid transparent",backgroundColor:wonderBlocksTokens.color.offBlack8},iconActive:{border:`2px solid ${wonderBlocksTokens.color.white}`,backgroundColor:wonderBlocksTokens.color.offBlack64},outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:1,borderColor:wonderBlocksTokens.color.offBlack50,borderRadius:3,background:wonderBlocksTokens.color.white,":hover":inputFocused},wrapperFocused:inputFocused,popoverContent:{padding:0,paddingBottom:wonderBlocksTokens.spacing.xxSmall_6,maxWidth:"initial"}});
1458
+ class InnerMathInput extends React__namespace.Component{componentDidMount(){this.mathField()?.latex(this.props.value);}openKeypad(){if(this.props.buttonsVisible==="never"){return}this.setState({keypadOpen:true});}closeKeypad(){this.setState({keypadOpen:false});}render(){let className=classNames__default.default({"perseus-math-input":true,"mq-editable-field":true,"mq-math-mode":true});const popoverContentUniqueId=uuid.v4().slice(0,8);if(this.props.className){className=className+" "+this.props.className;}return jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:[styles$H.outerWrapper,this.state.focused&&styles$H.wrapperFocused],children:jsxRuntimeExports.jsxs("div",{style:{display:"flex",padding:1},onClick:e=>{e.stopPropagation();const mathField=this.mathField();if(!mathField){return}this.setState({cursorContext:mathInput.getCursorContext(mathField)});},children:[jsxRuntimeExports.jsx("span",{className:className,ref:ref=>this.__mathFieldWrapperRef=ref,onFocus:()=>this.focus(),onBlur:()=>this.blur()}),jsxRuntimeExports.jsx(wonderBlocksPopover.Popover,{opened:this.state.keypadOpen,dismissEnabled:true,rootBoundary:"document","aria-label":this.context.strings.mathInputTitle,"aria-describedby":`popover-content-${popoverContentUniqueId}`,content:()=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(wonderBlocksTypography.HeadingMedium,{id:`popover-content-${popoverContentUniqueId}`,style:a11y.srOnly,children:this.context.strings.mathInputDescription}),jsxRuntimeExports.jsx(wonderBlocksPopover.PopoverContentCore,{style:styles$H.popoverContent,children:jsxRuntimeExports.jsx(mathInput.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__default.default,{"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"?true:false,cursorContext:mathInput.CursorContext.NONE},this.insert=value=>{const input=this.mathField();const{locale}=this.context;const customKeyTranslator={...mathInput.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(___default.default(value).isFunction()){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=mathInput.createMathField(this.__mathFieldWrapperRef,locale,this.props.mathInputStrings,baseConfig=>({...baseConfig,handlers:{edit:debounce(mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(mathInput.convertDotToTimesByLocale(locale,this.props.convertDotToTimes)){value=value.replace(/\\cdot/g,"\\times");const left=mathField.cursor()[mathInput.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:mathInput.getCursorContext(mathField)});},100),enter:()=>{if(this.__mathFieldWrapperRef){$__default.default(this.__mathFieldWrapperRef).submit();}},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)=>{const{locale}=this.context;const translator=mathInput.getKeyTranslator(locale,this.context.strings)[key];const mathField=this.mathField();if(mathField){if(translator){translator(mathField,key);}this.setState({cursorContext:mathInput.getCursorContext(mathField)});}if(e?.type==="click"){this.focus();}if(key==="DISMISS"){this.closeKeypad();}};}}InnerMathInput.contextType=PerseusI18nContext;InnerMathInput.defaultProps={value:"",convertDotToTimes:false};class MathInput extends React__namespace.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__namespace.createRef();}}MathInput.contextType=mathInput.MathInputI18nContext;MathInput.defaultProps={ariaLabel:"Math input"};const MathInputIcon=({hovered,focused,active})=>{let fillColor;switch(true){case focused||active:fillColor=wonderBlocksTokens.color.white;break;case hovered:fillColor=wonderBlocksTokens.color.blue;break;default:fillColor=wonderBlocksTokens.color.offBlack;break}const dynamicClass=active||focused?styles$H.iconActive:styles$H.iconInactive;return jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:[styles$H.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={borderWidth:2,borderColor:wonderBlocksTokens.color.blue,margin:-1};const styles$H=aphrodite.StyleSheet.create({iconContainer:{display:"flex",justifyContent:"center",height:"100%",padding:wonderBlocksTokens.spacing.xxxSmall_4,borderRadius:1},iconInactive:{border:"2px solid transparent",backgroundColor:wonderBlocksTokens.color.offBlack8},iconActive:{border:`2px solid ${wonderBlocksTokens.color.white}`,backgroundColor:wonderBlocksTokens.color.offBlack64},outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:1,borderColor:wonderBlocksTokens.color.offBlack50,borderRadius:3,background:wonderBlocksTokens.color.white,":hover":inputFocused},wrapperFocused:inputFocused,popoverContent:{padding:0,paddingBottom:wonderBlocksTokens.spacing.xxSmall_6,maxWidth:"initial"}});
1455
1459
 
1456
1460
  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__namespace.createContext({analytics:{onAnalyticsEvent:async()=>{}},useVideo:()=>{throw new Error("useVideo dependency not provided in Perseus dependencies")}});const useDependencies=()=>{const deps=React__namespace.useContext(DependenciesContext);return deps};
1457
1461
 
@@ -1471,7 +1475,7 @@ const ApiOptions={propTypes:PropTypes__default.default.shape({isArticle:PropType
1471
1475
 
1472
1476
  const getPromptJSON$t=(renderProps,userInput)=>{return {type:"expression",label:renderProps.visibleLabel,userInput:{value:userInput}}};
1473
1477
 
1474
- const englishOperators={arctg:"arctan",cosec:"csc",cossec:"csc",cotg:"cot",ctg:"cot",sen:"sin",tg:"tan"};const anglicizeOperators=tex=>{return tex.replace(/\\operatorname{([a-z]+)}/g,(_,op)=>`\\${englishOperators[op]??op} `)};const normalizeTex=tex=>{return anglicizeOperators(tex)};class Expression extends React__namespace.Component{getUserInput(){return normalizeTex(this.props.userInput)}getPromptJSON(){return getPromptJSON$t(this.props,normalizeTex(this.props.userInput))}focusInputPath(inputPath){this.refs.input.focus();}blurInputPath(inputPath){if(typeof this.refs.input?.blur==="function"){this.refs.input?.blur();}}insert(keyPressed){this.refs.input.insert(keyPressed);}getSerializedState(){const{userInput:_,...rest}=this.props;return {...rest,value:this.props.userInput}}render(){if(this.props.apiOptions.customKeypad){return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{className:aphrodite.css(styles$I.mobileLabelInputWrapper),children:[!!this.props.visibleLabel&&jsxRuntimeExports.jsx(wonderBlocksTypography.LabelSmall,{htmlFor:this._textareaId,tag:"label",children:this.props.visibleLabel}),jsxRuntimeExports.jsx(mathInput.KeypadInput,{ref:"input",ariaLabel:this.props.ariaLabel||this.context.strings.mathInputBox,value:this.props.userInput,keypadElement:this.props.keypadElement,onChange:this.changeAndTrack,onFocus:()=>{this.props.keypadElement?.configure(this.props.keypadConfiguration,()=>{if(this._isMounted){this._handleFocus();}});},onBlur:this._handleBlur})]})}return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{className:aphrodite.css(styles$I.desktopLabelInputWrapper),children:[!!this.props.visibleLabel&&jsxRuntimeExports.jsx(wonderBlocksTypography.LabelSmall,{htmlFor:this._textareaId,tag:"label",children:this.props.visibleLabel}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-expression",children:jsxRuntimeExports.jsx(MathInput,{ref:"input",value:this.props.userInput,onChange:this.changeAndTrack,convertDotToTimes:this.props.times,buttonSets:this.props.buttonSets,onFocus:this._handleFocus,onBlur:this._handleBlur,ariaLabel:this.props.ariaLabel||this.context.strings.mathInputBox,extraKeys:this.props.keypadConfiguration?.extraKeys,onAnalyticsEvent:this.props.analytics?.onAnalyticsEvent??(async()=>{})})})]})}constructor(...args){super(...args),this._textareaId=`expression_textarea_${Date.now()}`,this._isMounted=false,this.displayName="Expression",this.componentDidMount=()=>{this._isMounted=true;if(this.refs.input){const isMobile=this.props.apiOptions.customKeypad;const container=ReactDOM__namespace.default.findDOMNode(this.refs.input);const selector=isMobile?".mq-textarea > span":"textarea";const inputElement=container.querySelector(selector);inputElement?.setAttribute("id",this._textareaId);}},this.componentWillUnmount=()=>{this._isMounted=false;},this.changeAndTrack=(userInput,cb)=>{this.props.handleUserInput(normalizeTex(userInput),cb);this.props.trackInteraction();},this._handleFocus=()=>{this.props.analytics?.onAnalyticsEvent({type:"perseus:expression-focused",payload:null});this.props.onFocus([]);},this._handleBlur=()=>{this.props.onBlur([]);},this.focus=()=>{if(this.props.apiOptions.customKeypad){this.refs.input.focus();}return true},this.getInputPaths=()=>{return [[]]};}}Expression.contextType=PerseusI18nContext;Expression.defaultProps={times:false,functions:[],buttonSets:["basic","trig","prealgebra","logarithms"],onFocus:()=>{},onBlur:()=>{},apiOptions:ApiOptions.defaults,linterContext:PerseusLinter.linterContextDefault,userInput:""};const styles$I=aphrodite.StyleSheet.create({mobileLabelInputWrapper:{padding:"15px 4px 0"},desktopLabelInputWrapper:{margin:"5px 5px 0"}});const ExpressionWithDependencies=React__namespace.forwardRef((props,ref)=>{const deps=useDependencies();return jsxRuntimeExports.jsx(Expression,{ref:ref,analytics:deps.analytics,...props})});function getUserInputFromSerializedState$i(serializedState){return normalizeTex(serializedState.value)}function getStartUserInput$j(){return ""}var Expression$1 = {name:"expression",displayName:"Expression / Equation",widget:ExpressionWithDependencies,transform:widgetOptions=>{const{times,functions,buttonSets,buttonsVisible,visibleLabel,ariaLabel,extraKeys}=widgetOptions;return {keypadConfiguration:{keypadType:"EXPRESSION",extraKeys,times},times,functions,buttonSets,buttonsVisible,visibleLabel,ariaLabel}},version:perseusCore.expressionLogic.version,isLintable:true,getOneCorrectAnswerFromRubric(rubric){const correctAnswers=(rubric.answerForms||[]).filter(answerForm=>answerForm.considered==="correct");if(correctAnswers.length===0){return}return correctAnswers[0].value},getStartUserInput: getStartUserInput$j,getUserInputFromSerializedState: getUserInputFromSerializedState$i};
1478
+ const englishOperators={arctg:"arctan",cosec:"csc",cossec:"csc",cotg:"cot",ctg:"cot",sen:"sin",tg:"tan"};const anglicizeOperators=tex=>{return tex.replace(/\\operatorname{([a-z]+)}/g,(_,op)=>`\\${englishOperators[op]??op} `)};const normalizeTex=tex=>{return anglicizeOperators(tex)};class Expression extends React__namespace.Component{getUserInput(){return normalizeTex(this.props.userInput)}getPromptJSON(){return getPromptJSON$t(this.props,normalizeTex(this.props.userInput))}focusInputPath(inputPath){this.refs.input.focus();}blurInputPath(inputPath){if(typeof this.refs.input?.blur==="function"){this.refs.input?.blur();}}insert(keyPressed){this.refs.input.insert(keyPressed);}getKeypadConfiguration(){return {keypadType:"EXPRESSION",extraKeys:this.props.extraKeys,times:this.props.times}}getSerializedState(){const{userInput:_,answerForms:__,...rest}=this.props;return {...rest,value:this.props.userInput,keypadConfiguration:this.getKeypadConfiguration()}}render(){const keypadConfiguration=this.getKeypadConfiguration();if(this.props.apiOptions.customKeypad){return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{className:aphrodite.css(styles$G.mobileLabelInputWrapper),children:[!!this.props.visibleLabel&&jsxRuntimeExports.jsx(wonderBlocksTypography.LabelSmall,{htmlFor:this._textareaId,tag:"label",children:this.props.visibleLabel}),jsxRuntimeExports.jsx(mathInput.KeypadInput,{ref:"input",ariaLabel:this.props.ariaLabel||this.context.strings.mathInputBox,value:this.props.userInput,keypadElement:this.props.keypadElement,onChange:this.changeAndTrack,onFocus:()=>{this.props.keypadElement?.configure(keypadConfiguration,()=>{if(this._isMounted){this._handleFocus();}});},onBlur:this._handleBlur})]})}return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{className:aphrodite.css(styles$G.desktopLabelInputWrapper),children:[!!this.props.visibleLabel&&jsxRuntimeExports.jsx(wonderBlocksTypography.LabelSmall,{htmlFor:this._textareaId,tag:"label",children:this.props.visibleLabel}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-expression",children:jsxRuntimeExports.jsx(MathInput,{ref:"input",value:this.props.userInput,onChange:this.changeAndTrack,convertDotToTimes:this.props.times,buttonSets:this.props.buttonSets,onFocus:this._handleFocus,onBlur:this._handleBlur,ariaLabel:this.props.ariaLabel||this.context.strings.mathInputBox,extraKeys:keypadConfiguration.extraKeys,onAnalyticsEvent:this.props.analytics?.onAnalyticsEvent??(async()=>{})})})]})}constructor(...args){super(...args),this._textareaId=`expression_textarea_${Date.now()}`,this._isMounted=false,this.displayName="Expression",this.componentDidMount=()=>{this._isMounted=true;if(this.refs.input){const isMobile=this.props.apiOptions.customKeypad;const container=ReactDOM__namespace.default.findDOMNode(this.refs.input);const selector=isMobile?".mq-textarea > span":"textarea";const inputElement=container.querySelector(selector);inputElement?.setAttribute("id",this._textareaId);}},this.componentWillUnmount=()=>{this._isMounted=false;},this.changeAndTrack=(userInput,cb)=>{this.props.handleUserInput(normalizeTex(userInput),cb);this.props.trackInteraction();},this._handleFocus=()=>{this.props.analytics?.onAnalyticsEvent({type:"perseus:expression-focused",payload:null});this.props.onFocus([]);},this._handleBlur=()=>{this.props.onBlur([]);},this.focus=()=>{if(this.props.apiOptions.customKeypad){this.refs.input.focus();}return true},this.getInputPaths=()=>{return [[]]};}}Expression.contextType=PerseusI18nContext;Expression.defaultProps={times:false,functions:[],buttonSets:["basic","trig","prealgebra","logarithms"],onFocus:()=>{},onBlur:()=>{},apiOptions:ApiOptions.defaults,linterContext:PerseusLinter.linterContextDefault,userInput:""};const styles$G=aphrodite.StyleSheet.create({mobileLabelInputWrapper:{padding:"15px 4px 0"},desktopLabelInputWrapper:{margin:"5px 5px 0"}});const ExpressionWithDependencies=React__namespace.forwardRef((props,ref)=>{const deps=useDependencies();return jsxRuntimeExports.jsx(Expression,{ref:ref,analytics:deps.analytics,...props})});function getUserInputFromSerializedState$i(serializedState){return normalizeTex(serializedState.value)}function getStartUserInput$j(){return ""}function getOneCorrectAnswerFromRubric$1(rubric){const correctAnswers=(rubric.answerForms||[]).filter(answerForm=>answerForm.considered==="correct");if(correctAnswers.length===0){return}return correctAnswers[0].value}var Expression$1 = {name:"expression",displayName:"Expression / Equation",widget:ExpressionWithDependencies,version:perseusCore.expressionLogic.version,isLintable:true,getOneCorrectAnswerFromRubric: getOneCorrectAnswerFromRubric$1,getStartUserInput: getStartUserInput$j,getUserInputFromSerializedState: getUserInputFromSerializedState$i};
1475
1479
 
1476
1480
  class SimpleKeypadInput extends React__namespace.Component{componentDidMount(){this._isMounted=true;}componentWillUnmount(){this._isMounted=false;}focus(){this.inputRef.current?.focus(this.context.setKeypadActive);}blur(){this.inputRef.current?.blur();}getValue(){return this.props.value}render(){const _this=this;const{keypadElement,onFocus,value,...rest}=_this.props;return jsxRuntimeExports.jsx(mathInput.KeypadInput,{ref:this.inputRef,keypadElement:keypadElement,onFocus:()=>{if(keypadElement){keypadElement.configure({keypadType:"FRACTION"},()=>{if(_this._isMounted){onFocus?.();}});}else {onFocus?.();}},value:value==null?"":""+value,...rest})}constructor(...args){super(...args),this._isMounted=false,this.inputRef=React__namespace.createRef();}}SimpleKeypadInput.contextType=keypadContext.KeypadContext;SimpleKeypadInput.propTypes={keypadElement:mathInput.keypadElementPropType,onFocus:PropTypes__default.default.func,value:PropTypes__default.default.oneOfType([PropTypes__default.default.string,PropTypes__default.default.number])};
1477
1481
 
@@ -1481,7 +1485,7 @@ let lastId=0;function uniqueIdForInput(prefix="input-"){lastId++;return `${prefi
1481
1485
 
1482
1486
  const defaultContext$2={assetStatuses:{},setAssetStatus:(assetKey,loaded)=>{}};const context$1=React__namespace.createContext(defaultContext$2);
1483
1487
 
1484
- let supportsPassive=false;const nestedMap$2=function(children,func,context){if(Array.isArray(children)){return ___default.default.map(children,function(child){return nestedMap$2(child,func)})}return func.call(context,children)};function inputPathsEqual(a,b){if(a==null||b==null){return a==null===(b==null)}return a.length===b.length&&a.every((item,index)=>{return b[index]===item})}const rWidgetRule=/^\[\[\u2603 (([a-z-]+) ([0-9]+))\]\]/;const rTypeFromWidgetId=/^([a-z-]+) ([0-9]+)$/;const rWidgetParts=new RegExp(rWidgetRule.source+"$");const snowman="☃";const split="x".split(/(.)/g).length?function(str,r){return str.split(r)}:function(str,r){const output=[];let lastIndex=r.lastIndex=0;let match;while(match=r.exec(str)){const m=match;output.push(str.slice(lastIndex,m.index));output.push(...m.slice(1));lastIndex=m.index+m[0].length;}output.push(str.slice(lastIndex));return output};function firstNumericalParse$1(text){let first;const val=perseusScore.KhanAnswerTypes.predicate.createValidatorFunctional(function(ans){first=ans;return true},{simplify:"optional",inexact:true,forms:"integer, proper, improper, pi, log, mixed, decimal"});val(text);return first}function stringArrayOfSize(size){return Array(size).fill("")}function stringArrayOfSize2D(opt){const{rows,columns}=opt;const rowArr=stringArrayOfSize(rows);return rowArr.map(()=>stringArrayOfSize(columns))}function gridDimensionConfig(absTickStep,extent,dimensionConstraint,gridStep){const scale=scaleFromExtent(extent,dimensionConstraint);const stepPx=absTickStep*scale;const unityLabel=stepPx>30;return {scale:scale,tickStep:absTickStep/gridStep,unityLabel:unityLabel}}function getGridStep(range,step,boxSize){return ___default.default(2).times(function(i){const scale=scaleFromExtent(range[i],boxSize);const gridStep=gridStepFromTickStep(step[i],scale);return gridStep})}function snapStepFromGridStep(gridStep){return [gridStep[0]/2,gridStep[1]/2]}function gridStepFromTickStep(tickStep,scale){const tickWidth=tickStep*scale;const x=tickStep;const y=Math.pow(10,Math.floor(Math.log(x)/Math.LN10));const leadingDigit=Math.floor(x/y);if(tickWidth<25){return tickStep}if(tickWidth<50){if(leadingDigit===5){return tickStep}return tickStep/2}if(leadingDigit===1){return tickStep/2}if(leadingDigit===2){return tickStep/4}if(leadingDigit===5){return tickStep/5}}function scaleFromExtent(extent,dimensionConstraint){const span=extent[1]-extent[0];const scale=dimensionConstraint/span;return scale}function tickStepFromExtent(extent,dimensionConstraint){const span=extent[1]-extent[0];let tickFactor;if(15<span&&span<=20){tickFactor=23;}else if(span>100||span<5){tickFactor=10;}else {tickFactor=16;}const constraintFactor=dimensionConstraint/500;const desiredNumTicks=tickFactor*constraintFactor;return tickStepFromNumTicks(span,desiredNumTicks)}function tickStepFromNumTicks(span,numTicks){let step=Math.pow(10,Math.floor(Math.log(span/numTicks)/Math.LN10));const err=numTicks/span*step;if(err<=.15){step*=10;}else if(err<=.35){step*=5;}else if(err<=.75){step*=2;}return step}const constrainTickStep=(step,range)=>{const span=range[1]-range[0];const numTicks=span/step;if(numTicks<=10){return step}if(numTicks<=20){return step*2}return tickStepFromNumTicks(span,10)};function constrainedTickStepsFromTickSteps(tickSteps,ranges){return [constrainTickStep(tickSteps[0],ranges[0]),constrainTickStep(tickSteps[1],ranges[1])]}function parseQueryString(query){query=query||window.location.search.substring(1);const urlParams={};const a=/\+/g;const r=/([^&=]+)=?([^&]*)/g;const d=function(s){return decodeURIComponent(s.replace(a," "))};let e;while(e=r.exec(query)){const m=e;urlParams[d(m[1])]=d(m[2]);}return urlParams}function updateQueryString$2(uri,key,value){value=encodeURIComponent(value);const re=new RegExp("([?&])"+key+"=.*?(&|$)","i");const separator=uri.indexOf("?")!==-1?"&":"?";if(uri.match(re)){return uri.replace(re,"$1"+key+"="+value+"$2")}return uri+separator+key+"="+value}function strongEncodeURIComponent(str){return encodeURIComponent(str).replace(/['()!]/g,window.escape).replace(/\*/g,"%2A")}const touchHandlers={pointerDown:false,currentTouchIdentifier:null};function resetTouchHandlers(){Object.assign(touchHandlers,{pointerDown:false,currentTouchIdentifier:null});}function extractPointerLocation(event){let touchOrEvent;if(touchHandlers.pointerDown){if(touchHandlers.currentTouchIdentifier!=null){const len=event.changedTouches?event.changedTouches.length:0;for(let i=0;i<len;i++){if(event.changedTouches[i].identifier===touchHandlers.currentTouchIdentifier){touchOrEvent=event.changedTouches[i];}}}else {touchOrEvent=event;}const isEndish=event.type==="touchend"||event.type==="touchcancel";if(touchOrEvent&&isEndish){touchHandlers.pointerDown=false;touchHandlers.currentTouchIdentifier=null;}}else {touchHandlers.pointerDown=true;if(event.changedTouches){touchOrEvent=event.changedTouches[0];touchHandlers.currentTouchIdentifier=touchOrEvent.identifier;}else {touchOrEvent=event;}}if(touchOrEvent){return {left:touchOrEvent.pageX,top:touchOrEvent.pageY}}}const supportsPassiveEvents=()=>{try{const opts=Object.defineProperty({},"passive",{get:function(){supportsPassive=true;}});window.addEventListener("testPassive",null,opts);window.removeEventListener("testPassive",null,opts);}catch{}return supportsPassive};function captureScratchpadTouchStart$4(e){e.stopPropagation();}function getImageSize(url,callback){const img=new Image;img.onload=function(){if(img.width===0&&img.height===0){document.body?.appendChild(img);___default.default.defer(function(){callback(img.clientWidth,img.clientHeight);document.body?.removeChild(img);});}else {callback(img.width,img.height);}};img.src=perseusCore.getRealImageUrl(url);}function getWordBeforeCursor(textarea){const text=textarea.value;const endPos=textarea.selectionStart-1;const startPos=Math.max(text.lastIndexOf("\n",endPos),text.lastIndexOf(" ",endPos))+1;return {string:text.substring(startPos,endPos+1),pos:{start:startPos,end:endPos}}}function moveCursor(textarea,pos){textarea.selectionStart=pos;textarea.selectionEnd=pos;}const textarea={getWordBeforeCursor,moveCursor};const unescapeMathMode$1=label=>label.startsWith("$")&&label.endsWith("$")?label.slice(1,-1):label;const Util={inputPathsEqual,nestedMap: nestedMap$2,rWidgetRule,rTypeFromWidgetId,rWidgetParts,snowman,split,firstNumericalParse: firstNumericalParse$1,stringArrayOfSize,stringArrayOfSize2D,gridDimensionConfig,getGridStep,snapStepFromGridStep,scaleFromExtent,tickStepFromExtent,gridStepFromTickStep,tickStepFromNumTicks,constrainedTickStepsFromTickSteps,parseQueryString,updateQueryString: updateQueryString$2,strongEncodeURIComponent,touchHandlers,resetTouchHandlers,extractPointerLocation,supportsPassiveEvents,captureScratchpadTouchStart: captureScratchpadTouchStart$4,getImageSize,getImageSizeModern:perseusCore.getImageSizeModern,getRealImageUrl:perseusCore.getRealImageUrl,isLabeledSVG:perseusCore.isLabeledSVG,getBaseUrl:perseusCore.getBaseUrl,getSvgUrl:perseusCore.getSvgUrl,getDataUrl:perseusCore.getDataUrl,textarea,unescapeMathMode: unescapeMathMode$1};
1488
+ let supportsPassive=false;const nestedMap$2=function(children,func,context){if(Array.isArray(children)){return ___default.default.map(children,function(child){return nestedMap$2(child,func)})}return func.call(context,children)};function inputPathsEqual(a,b){if(a==null||b==null){return a==null===(b==null)}return a.length===b.length&&a.every((item,index)=>{return b[index]===item})}const rWidgetRule=/^\[\[\u2603 (([a-z-]+) ([0-9]+))\]\]/;const rTypeFromWidgetId=/^([a-z-]+) ([0-9]+)$/;const rWidgetParts=new RegExp(rWidgetRule.source+"$");const snowman="☃";const split="x".split(/(.)/g).length?function(str,r){return str.split(r)}:function(str,r){const output=[];let lastIndex=r.lastIndex=0;let match;while(match=r.exec(str)){const m=match;output.push(str.slice(lastIndex,m.index));output.push(...m.slice(1));lastIndex=m.index+m[0].length;}output.push(str.slice(lastIndex));return output};function firstNumericalParse$1(text){let first;const val=perseusScore.KhanAnswerTypes.predicate.createValidatorFunctional(function(ans){first=ans;return true},{simplify:"optional",inexact:true,forms:"integer, proper, improper, pi, log, mixed, decimal"});val(text);return first}function stringArrayOfSize(size){return Array(size).fill("")}function stringArrayOfSize2D(opt){const{rows,columns}=opt;const rowArr=stringArrayOfSize(rows);return rowArr.map(()=>stringArrayOfSize(columns))}function gridDimensionConfig(absTickStep,extent,dimensionConstraint,gridStep){const scale=scaleFromExtent(extent,dimensionConstraint);const stepPx=absTickStep*scale;const unityLabel=stepPx>30;return {scale:scale,tickStep:absTickStep/gridStep,unityLabel:unityLabel}}function getGridStep(range,step,boxSize){return ___default.default(2).times(function(i){const scale=scaleFromExtent(range[i],boxSize);const gridStep=gridStepFromTickStep(step[i],scale);return gridStep})}function snapStepFromGridStep(gridStep){return [gridStep[0]/2,gridStep[1]/2]}function gridStepFromTickStep(tickStep,scale){const tickWidth=tickStep*scale;const x=tickStep;const y=Math.pow(10,Math.floor(Math.log(x)/Math.LN10));const leadingDigit=Math.floor(x/y);if(tickWidth<25){return tickStep}if(tickWidth<50){if(leadingDigit===5){return tickStep}return tickStep/2}if(leadingDigit===1){return tickStep/2}if(leadingDigit===2){return tickStep/4}if(leadingDigit===5){return tickStep/5}}function scaleFromExtent(extent,dimensionConstraint){const span=extent[1]-extent[0];const scale=dimensionConstraint/span;return scale}function tickStepFromExtent(extent,dimensionConstraint){const span=extent[1]-extent[0];let tickFactor;if(15<span&&span<=20){tickFactor=23;}else if(span>100||span<5){tickFactor=10;}else {tickFactor=16;}const constraintFactor=dimensionConstraint/500;const desiredNumTicks=tickFactor*constraintFactor;return tickStepFromNumTicks(span,desiredNumTicks)}function tickStepFromNumTicks(span,numTicks){let step=Math.pow(10,Math.floor(Math.log(span/numTicks)/Math.LN10));const err=numTicks/span*step;if(err<=.15){step*=10;}else if(err<=.35){step*=5;}else if(err<=.75){step*=2;}return step}const constrainTickStep=(step,range)=>{const span=range[1]-range[0];const numTicks=span/step;if(numTicks<=10){return step}if(numTicks<=20){return step*2}return tickStepFromNumTicks(span,10)};function constrainedTickStepsFromTickSteps(tickSteps,ranges){return [constrainTickStep(tickSteps[0],ranges[0]),constrainTickStep(tickSteps[1],ranges[1])]}function parseQueryString(query){query=query||window.location.search.substring(1);const urlParams={};const a=/\+/g;const r=/([^&=]+)=?([^&]*)/g;const d=function(s){return decodeURIComponent(s.replace(a," "))};let e;while(e=r.exec(query)){const m=e;urlParams[d(m[1])]=d(m[2]);}return urlParams}function updateQueryString$2(uri,key,value){value=encodeURIComponent(value);const re=new RegExp("([?&])"+key+"=.*?(&|$)","i");const separator=uri.indexOf("?")!==-1?"&":"?";if(uri.match(re)){return uri.replace(re,"$1"+key+"="+value+"$2")}return uri+separator+key+"="+value}function strongEncodeURIComponent(str){return encodeURIComponent(str).replace(/['()!]/g,window.escape).replace(/\*/g,"%2A")}const touchHandlers={pointerDown:false,currentTouchIdentifier:null};function resetTouchHandlers(){Object.assign(touchHandlers,{pointerDown:false,currentTouchIdentifier:null});}function extractPointerLocation(event){let touchOrEvent;if(touchHandlers.pointerDown){if(touchHandlers.currentTouchIdentifier!=null){const len=event.changedTouches?event.changedTouches.length:0;for(let i=0;i<len;i++){if(event.changedTouches[i].identifier===touchHandlers.currentTouchIdentifier){touchOrEvent=event.changedTouches[i];}}}else {touchOrEvent=event;}const isEndish=event.type==="touchend"||event.type==="touchcancel";if(touchOrEvent&&isEndish){touchHandlers.pointerDown=false;touchHandlers.currentTouchIdentifier=null;}}else {touchHandlers.pointerDown=true;if(event.changedTouches){touchOrEvent=event.changedTouches[0];touchHandlers.currentTouchIdentifier=touchOrEvent.identifier;}else {touchOrEvent=event;}}if(touchOrEvent){return {left:touchOrEvent.pageX,top:touchOrEvent.pageY}}}const supportsPassiveEvents=()=>{try{const opts=Object.defineProperty({},"passive",{get:function(){supportsPassive=true;}});window.addEventListener("testPassive",null,opts);window.removeEventListener("testPassive",null,opts);}catch{}return supportsPassive};function captureScratchpadTouchStart$3(e){e.stopPropagation();}function getImageSize(url,callback){const img=new Image;img.onload=function(){if(img.width===0&&img.height===0){document.body?.appendChild(img);___default.default.defer(function(){callback(img.clientWidth,img.clientHeight);document.body?.removeChild(img);});}else {callback(img.width,img.height);}};img.src=perseusCore.getRealImageUrl(url);}function getWordBeforeCursor(textarea){const text=textarea.value;const endPos=textarea.selectionStart-1;const startPos=Math.max(text.lastIndexOf("\n",endPos),text.lastIndexOf(" ",endPos))+1;return {string:text.substring(startPos,endPos+1),pos:{start:startPos,end:endPos}}}function moveCursor(textarea,pos){textarea.selectionStart=pos;textarea.selectionEnd=pos;}const textarea={getWordBeforeCursor,moveCursor};const unescapeMathMode$1=label=>label.startsWith("$")&&label.endsWith("$")?label.slice(1,-1):label;const Util={inputPathsEqual,nestedMap: nestedMap$2,rWidgetRule,rTypeFromWidgetId,rWidgetParts,snowman,split,firstNumericalParse: firstNumericalParse$1,stringArrayOfSize,stringArrayOfSize2D,gridDimensionConfig,getGridStep,snapStepFromGridStep,scaleFromExtent,tickStepFromExtent,gridStepFromTickStep,tickStepFromNumTicks,constrainedTickStepsFromTickSteps,parseQueryString,updateQueryString: updateQueryString$2,strongEncodeURIComponent,touchHandlers,resetTouchHandlers,extractPointerLocation,supportsPassiveEvents,captureScratchpadTouchStart: captureScratchpadTouchStart$3,getImageSize,getImageSizeModern:perseusCore.getImageSizeModern,getRealImageUrl:perseusCore.getRealImageUrl,isLabeledSVG:perseusCore.isLabeledSVG,getBaseUrl:perseusCore.getBaseUrl,getSvgUrl:perseusCore.getSvgUrl,getDataUrl:perseusCore.getDataUrl,textarea,unescapeMathMode: unescapeMathMode$1};
1485
1489
 
1486
1490
  const Log={log:(message,extra)=>{getDependencies().Log.log(message,extra);},error:(message,kind,extra)=>{getDependencies().Log.error(message,kind,extra);}};
1487
1491
 
@@ -1669,7 +1673,7 @@ const arrayRules={fence:{match:SimpleMarkdown__default.default.defaultRules.fenc
1669
1673
 
1670
1674
  const denylist=["key","ref","containerSizeClass","widgetId","onChange","problemNum","apiOptions","widgetIsOpen","questionCompleted","findWidgets","onRemove","id","onBlur","onFocus","trackInteraction","keypadElement","linterContext","isLastUsedWidget","handleUserInput","analytics","showSolutions","reviewMode","reviewModeRubric"];function excludeDenylistKeys(obj){if(obj==null){return obj}const rv={};for(const k of Object.keys(obj)){if(!denylist.includes(k)){rv[k]=obj[k];}}return rv}
1671
1675
 
1672
- const exclamationIcon={path:"M6 11a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm0-9a1 1 0 0 1 1 1v4a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1z",height:12,width:12};class Lint extends React__namespace.Component{componentDidMount(){this._positionTimeout=window.setTimeout(this.getPosition);}componentWillUnmount(){window.clearTimeout(this._positionTimeout);}render(){const{children,inline,blockHighlight,insideTable}=this.props;if(insideTable){if(inline){return jsxRuntimeExports.jsx("span",{"data-lint-inside-table":"true",children:children})}return jsxRuntimeExports.jsx("div",{"data-lint-inside-table":"true",children:children})}if(blockHighlight){return jsxRuntimeExports.jsxs("span",{className:aphrodite.css(styles$H.lintContainer,styles$H.lintContainerBlock),children:[this.renderLink(styles$H.radioWidgetHoverTarget),jsxRuntimeExports.jsx("span",{children:children})]})}if(inline){return jsxRuntimeExports.jsxs("span",{className:aphrodite.css(styles$H.lintContainer),children:[this.renderLink(styles$H.inlineHoverTarget),jsxRuntimeExports.jsx("span",{children:children})]})}return jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$H.lintContainer),children:[this.renderLink(styles$H.hoverTarget),jsxRuntimeExports.jsx("div",{children:children})]})}constructor(...args){super(...args),this.state={tooltipAbove:true},this.getPosition=()=>{const rect=ReactDOM__namespace.default.findDOMNode(this).getBoundingClientRect();this.setState({tooltipAbove:rect.top>100});},this.renderLink=style=>{const tooltipAbove=this.state.tooltipAbove;let severityStyle;let warningText;let warningTextStyle;if(this.props.severity===1){severityStyle=styles$H.indicatorError;warningText="Error";warningTextStyle=styles$H.publishBlockingError;}else if(this.props.severity===2){severityStyle=styles$H.indicatorWarning;warningText="Warning";warningTextStyle=styles$H.warning;}else {severityStyle=styles$H.indicatorGuideline;warningText="Recommendation";warningTextStyle=styles$H.warning;}return jsxRuntimeExports.jsxs("a",{href:`https://khanacademy.org/r/linter-rules#${this.props.ruleName}`,target:"lint-help-window",className:aphrodite.css(style),children:[jsxRuntimeExports.jsx("span",{className:aphrodite.css(styles$H.indicator,severityStyle),children:this.props.severity===1&&jsxRuntimeExports.jsx(InlineIcon,{...exclamationIcon})}),jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$H.tooltip,tooltipAbove&&styles$H.tooltipAbove),children:[this.props.message.split("\n\n").map((m,i)=>jsxRuntimeExports.jsxs("p",{className:aphrodite.css(styles$H.tooltipParagraph),children:[jsxRuntimeExports.jsxs("span",{className:aphrodite.css(warningTextStyle),children:[warningText,":"," "]}),m]},i)),jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$H.tail,tooltipAbove&&styles$H.tailAbove)})]})]})};}}const styles$H=aphrodite.StyleSheet.create({lintContainer:{position:"relative"},lintContainerBlock:{display:"block"},hoverTarget:{position:"absolute",top:0,right:-40,display:"block",width:24,height:24,":hover > span":{backgroundColor:warningColorHover},":hover div":{display:"block"},":hover ~ div":{outline:"1px solid "+warningColor},":hover ~ div div[data-lint-inside-table]":{outline:"1px solid "+warningColor},":hover ~ div span[data-lint-inside-table]":{backgroundColor:warningColor,color:white}},inlineHoverTarget:{float:"right",position:"relative",marginRight:-40,display:"block",width:24,height:24,":hover > span":{backgroundColor:warningColorHover},":hover div":{display:"block"},":hover ~ span":{backgroundColor:warningColor,color:white}},radioWidgetHoverTarget:{position:"absolute",left:-40,display:"block",width:24,height:24,minWidth:264,":hover > span":{backgroundColor:warningColorHover},":hover > div":{display:"block",padding:8,width:280},":hover > div > div":{left:8},":hover ~ span":{backgroundColor:warningColor,color:white}},indicator:{alignItems:"center",borderRadius:4,color:"white",display:"flex",fontSize:12,height:8,justifyContent:"center",margin:8,width:8},indicatorError:{backgroundColor:"#be2612",borderRadius:8,height:16,width:16},indicatorWarning:{backgroundColor:"#f86700"},indicatorGuideline:{backgroundColor:"#ffbe26"},tooltip:{position:"absolute",right:-12,display:"none",zIndex:1e3,color:white,backgroundColor:gray17,opacity:.9,fontFamily:baseFontFamily,fontSize:"12px",lineHeight:"15px",width:"320px",borderRadius:"4px"},tooltipAbove:{bottom:32},tail:{position:"absolute",top:-12,right:16,width:0,height:0,borderLeft:"8px solid transparent",borderRight:"8px solid transparent",borderBottom:"12px solid "+gray17},tailAbove:{bottom:-12,borderBottom:"none",borderTop:"12px solid "+gray17,top:"auto"},tooltipParagraph:{margin:12},warning:{color:warningColor,fontFamily:boldFontFamily},publishBlockingError:{color:publishBlockingErrorColor}});
1676
+ const exclamationIcon={path:"M6 11a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm0-9a1 1 0 0 1 1 1v4a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1z",height:12,width:12};class Lint extends React__namespace.Component{componentDidMount(){this._positionTimeout=window.setTimeout(this.getPosition);}componentWillUnmount(){window.clearTimeout(this._positionTimeout);}render(){const{children,inline,blockHighlight,insideTable}=this.props;if(insideTable){if(inline){return jsxRuntimeExports.jsx("span",{"data-lint-inside-table":"true",children:children})}return jsxRuntimeExports.jsx("div",{"data-lint-inside-table":"true",children:children})}if(blockHighlight){return jsxRuntimeExports.jsxs("span",{className:aphrodite.css(styles$F.lintContainer,styles$F.lintContainerBlock),children:[this.renderLink(styles$F.radioWidgetHoverTarget),jsxRuntimeExports.jsx("span",{children:children})]})}if(inline){return jsxRuntimeExports.jsxs("span",{className:aphrodite.css(styles$F.lintContainer),children:[this.renderLink(styles$F.inlineHoverTarget),jsxRuntimeExports.jsx("span",{children:children})]})}return jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$F.lintContainer),children:[this.renderLink(styles$F.hoverTarget),jsxRuntimeExports.jsx("div",{children:children})]})}constructor(...args){super(...args),this.state={tooltipAbove:true},this.getPosition=()=>{const rect=ReactDOM__namespace.default.findDOMNode(this).getBoundingClientRect();this.setState({tooltipAbove:rect.top>100});},this.renderLink=style=>{const tooltipAbove=this.state.tooltipAbove;let severityStyle;let warningText;let warningTextStyle;if(this.props.severity===1){severityStyle=styles$F.indicatorError;warningText="Error";warningTextStyle=styles$F.publishBlockingError;}else if(this.props.severity===2){severityStyle=styles$F.indicatorWarning;warningText="Warning";warningTextStyle=styles$F.warning;}else {severityStyle=styles$F.indicatorGuideline;warningText="Recommendation";warningTextStyle=styles$F.warning;}return jsxRuntimeExports.jsxs("a",{href:`https://khanacademy.org/r/linter-rules#${this.props.ruleName}`,target:"lint-help-window",className:aphrodite.css(style),children:[jsxRuntimeExports.jsx("span",{className:aphrodite.css(styles$F.indicator,severityStyle),children:this.props.severity===1&&jsxRuntimeExports.jsx(InlineIcon,{...exclamationIcon})}),jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$F.tooltip,tooltipAbove&&styles$F.tooltipAbove),children:[this.props.message.split("\n\n").map((m,i)=>jsxRuntimeExports.jsxs("p",{className:aphrodite.css(styles$F.tooltipParagraph),children:[jsxRuntimeExports.jsxs("span",{className:aphrodite.css(warningTextStyle),children:[warningText,":"," "]}),m]},i)),jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$F.tail,tooltipAbove&&styles$F.tailAbove)})]})]})};}}const styles$F=aphrodite.StyleSheet.create({lintContainer:{position:"relative"},lintContainerBlock:{display:"block"},hoverTarget:{position:"absolute",top:0,right:-40,display:"block",width:24,height:24,":hover > span":{backgroundColor:warningColorHover},":hover div":{display:"block"},":hover ~ div":{outline:"1px solid "+warningColor},":hover ~ div div[data-lint-inside-table]":{outline:"1px solid "+warningColor},":hover ~ div span[data-lint-inside-table]":{backgroundColor:warningColor,color:white}},inlineHoverTarget:{float:"right",position:"relative",marginRight:-40,display:"block",width:24,height:24,":hover > span":{backgroundColor:warningColorHover},":hover div":{display:"block"},":hover ~ span":{backgroundColor:warningColor,color:white}},radioWidgetHoverTarget:{position:"absolute",left:-40,display:"block",width:24,height:24,minWidth:264,":hover > span":{backgroundColor:warningColorHover},":hover > div":{display:"block",padding:8,width:280},":hover > div > div":{left:8},":hover ~ span":{backgroundColor:warningColor,color:white}},indicator:{alignItems:"center",borderRadius:4,color:"white",display:"flex",fontSize:12,height:8,justifyContent:"center",margin:8,width:8},indicatorError:{backgroundColor:"#be2612",borderRadius:8,height:16,width:16},indicatorWarning:{backgroundColor:"#f86700"},indicatorGuideline:{backgroundColor:"#ffbe26"},tooltip:{position:"absolute",right:-12,display:"none",zIndex:1e3,color:white,backgroundColor:gray17,opacity:.9,fontFamily:baseFontFamily,fontSize:"12px",lineHeight:"15px",width:"320px",borderRadius:"4px"},tooltipAbove:{bottom:32},tail:{position:"absolute",top:-12,right:16,width:0,height:0,borderLeft:"8px solid transparent",borderRight:"8px solid transparent",borderBottom:"12px solid "+gray17},tailAbove:{bottom:-12,borderBottom:"none",borderTop:"12px solid "+gray17,top:"auto"},tooltipParagraph:{margin:12},warning:{color:warningColor,fontFamily:boldFontFamily},publishBlockingError:{color:publishBlockingErrorColor}});
1673
1677
 
1674
1678
  const rules$1={...pureMarkdown.pureMarkdownRules,columns:{...pureMarkdown.pureMarkdownRules.columns,react:(node,output,state)=>{return jsxRuntimeExports.jsxs("div",{className:"perseus-two-columns",children:[jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col1,state)})}),jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col2,state)})})]},state.key)}},crowdinId:{...pureMarkdown.pureMarkdownRules.crowdinId,react:(node,output,state)=>node.id},table:{...pureMarkdown.pureMarkdownRules.table,react:function(node,output,state){const table=SimpleMarkdown__default.default.defaultRules.table.react(node,output,state);if(!state.isMobile){return table}return React__namespace.cloneElement(table,{tabIndex:0})}},titledTable:{...pureMarkdown.pureMarkdownRules.titledTable,react:(node,output,state)=>{let contents;if(!node.table){contents="//invalid table//";}else if(node.table.type==="lint"){if(node.table.content?.type==="table"){contents=rules$1.lint.react({...node.table,content:{...node,table:node.table.content}},output,{...state,unwrapTitledTableContents:true});}else {contents=rules$1.lint.react(node.table,output,state);}}else {const tableOutput=SimpleMarkdown__default.default.defaultRules.table.react(node.table,output,state);const caption=jsxRuntimeExports.jsx("caption",{className:"perseus-table-title",children:output(node.title,state)},"caption");contents=React__namespace.cloneElement(tableOutput,null,[caption,...tableOutput.props.children]);}if(state.unwrapTitledTableContents){return contents}return jsxRuntimeExports.jsx("div",{className:"perseus-titled-table",children:contents},state.key)}},widget:{...pureMarkdown.pureMarkdownRules.widget,react:(node,output,state)=>{return jsxRuntimeExports.jsx("em",{children:`[Widget: ${node.id}]`},state.key)}},blockMath:{...pureMarkdown.pureMarkdownRules.blockMath,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},math:{...pureMarkdown.pureMarkdownRules.math,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},unescapedDollar:{...pureMarkdown.pureMarkdownRules.unescapedDollar,react:(node,output,state)=>{return "$"}},link:{...pureMarkdown.pureMarkdownRules.link,react:function(node,output,state){const link=SimpleMarkdown__default.default.defaultRules.link.react(node,output,state);const href=link.props.href;let rel=null;const isKAUrl=href?href.match(/https?:\/\/[^/]*khanacademy.org|^\//):false;if(!isKAUrl){rel="noopener noreferrer";}const newProps={...link.props,target:"_blank",href,rel};if(state.baseElements&&state.baseElements.Link){return state.baseElements.Link(newProps)}return React__namespace.cloneElement(link,newProps)}},codeBlock:{...pureMarkdown.pureMarkdownRules.codeBlock,react:(node,output,state)=>{if(node.lang==="alt"){return jsxRuntimeExports.jsx("div",{className:"perseus-markdown-alt perseus-sr-only",children:output(node.content,state)},state.key)}return SimpleMarkdown__default.default.defaultRules.codeBlock.react(node,output,state)}},lint:{...pureMarkdown.pureMarkdownRules.lint,react:(node,output,state)=>{return jsxRuntimeExports.jsx(Lint,{message:node.message,ruleName:node.ruleName,inline:isInline(node.content),blockHighlight:node.blockHighlight,insideTable:node.insideTable,severity:node.severity,children:output(node.content,state)})}}};function isInline(node){return !!(node&&node.type&&inlineNodeTypes.hasOwnProperty(node.type))}const inlineNodeTypes={text:true,math:true,unescapedDollar:true,link:true,img:true,strong:true,u:true,em:true,del:true,code:true};const builtParser$1=SimpleMarkdown__default.default.parserFor(rules$1);const parse$3=(source,state)=>{const paragraphedSource=source+"\n\n";return builtParser$1(paragraphedSource,{...state,inline:false})};const inlineParser=(source,state)=>{return builtParser$1(source,{...state,inline:true})};const getContent=ast=>{if(___default.default.isArray(ast)){return ___default.default.flatten(___default.default.map(ast,getContent))}if(ast.content&&___default.default.isString(ast.content)){if(ast.type.toLowerCase().indexOf("code")!==-1){return ["",ast.content,""]}return [ast.content.replace(/\s+/g," ")]}const children=___default.default.chain(ast).values().flatten().filter(object=>object!=null&&___default.default.has(object,"type")).value();if(!children.length){return []}const nestedContent=getContent(children);if(ast.type==="paragraph"&&nestedContent.length){nestedContent[0]=nestedContent[0].replace(/^\s+/,"");const last=nestedContent.length-1;nestedContent[last]=nestedContent[last].replace(/\s+$/,"");}return nestedContent};const characterCount=source=>{const ast=parse$3(source);const content=getContent(ast).join("");return content.length};var PerseusMarkdown = {characterCount:characterCount,traverseContent:pureMarkdown.traverseContent,parse:parse$3,parseInline:inlineParser,reactFor:SimpleMarkdown__default.default.reactFor,ruleOutput:SimpleMarkdown__default.default.ruleOutput(rules$1,"react"),basicOutput:SimpleMarkdown__default.default.reactFor(SimpleMarkdown__default.default.ruleOutput(rules$1,"react")),sanitizeUrl:SimpleMarkdown__default.default.sanitizeUrl};
1675
1679
 
@@ -1709,13 +1713,13 @@ var widgets$1 = /*#__PURE__*/Object.freeze({
1709
1713
 
1710
1714
  class WidgetContainer extends React__namespace.Component{componentDidMount(){if(this.state.widgetProps.apiOptions.isMobile){const containerWidth=ReactDOM__namespace.default.findDOMNode(this).offsetWidth;this.setState({sizeClass:getClassFromWidth(containerWidth)});}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.type!==nextProps.type){throw new Error("WidgetContainer can't change widget type; set a different "+"key instead to recreate the container.")}}shouldComponentUpdate(nextProps,nextState){return this.props.shouldHighlight!==nextProps.shouldHighlight||this.props.type!==nextProps.type||this.state.widgetProps!==nextState.widgetProps||this.state.sizeClass!==nextState.sizeClass}render(){let className=classNames__default.default({"perseus-widget-container":true,"widget-highlight":this.props.shouldHighlight,"widget-nohighlight":!this.props.shouldHighlight,"perseus-widget__definition":this.props.type==="definition"});const type=this.props.type;const userAgent=navigator.userAgent;const WidgetType=getWidget(type);if(WidgetType==null){console.warn(`Widget type '${type}' not found!`);return jsxRuntimeExports.jsx("div",{className:className})}let subType="null";if(type==="interactive-graph"){const props=this.state.widgetProps;subType=props.graph?.type??"null";}let alignment=this.state.widgetProps.alignment;if(alignment==="default"){alignment=perseusCore.CoreWidgetRegistry.getDefaultAlignment(type);}className+=" widget-"+alignment;const apiOptions=this.state.widgetProps.apiOptions;const isStatic=this.state.widgetProps.static||apiOptions.readOnly;const staticContainerStyles={position:"relative",overflow:"visible"};const staticOverlayStyles={width:"100%",height:"100%",position:"absolute",top:0,left:0,zIndex:3};const linterContext=isLintable(type)?this.props.linterContext:{...this.props.linterContext,highlightLint:false};return jsxRuntimeExports.jsx("div",{className:className,style:isStatic?staticContainerStyles:{},children:jsxRuntimeExports.jsx(DependenciesContext.Consumer,{children:({analytics})=>jsxRuntimeExports.jsxs(ErrorBoundary,{metadata:{widget_type:type,widget_id:this.props.id},onError:error=>{analytics.onAnalyticsEvent({type:"perseus:widget-rendering-error:ti",payload:{widgetSubType:subType,widgetType:type,widgetId:this.props.id,message:error.message,userAgent:userAgent}});},children:[jsxRuntimeExports.jsx(WidgetType,{...this.state.widgetProps,linterContext:linterContext,containerSizeClass:this.state.sizeClass,ref:this.widgetRef}),isStatic&&jsxRuntimeExports.jsx("div",{style:staticOverlayStyles})]})})})}constructor(...args){super(...args),this.widgetRef=React__namespace.createRef(),this.state={sizeClass:containerSizeClass.MEDIUM,widgetProps:this.props.initialProps},this.getWidget=()=>{return this.widgetRef.current},this.replaceWidgetProps=newWidgetProps=>{this.setState({widgetProps:newWidgetProps});};}}WidgetContainer.defaultProps={linterContext:PerseusLinter.linterContextDefault};
1711
1715
 
1712
- const rContainsNonWhitespace=/\S/;const rImageURL=/(web\+graphie|https):\/\/[^\s]*/;const noopOnRender=()=>{};const makeContainerId=id=>"container:"+id;const isIdPathPrefix=function(prefixArray,wholeArray){if(prefixArray===null||wholeArray===null){return prefixArray===wholeArray}return ___default.default.every(prefixArray,(elem,i)=>{if(wholeArray!=null){return ___default.default.isEqual(elem,wholeArray[i])}})};function isDifferentQuestion(propsA,propsB){function makeItem(props){return perseusCore.splitPerseusItem({question:{content:props.content,widgets:props.widgets,images:{}},hints:[],answerArea:perseusCore.getDefaultAnswerArea()})}return propsA.problemNum!==propsB.problemNum||!___default.default.isEqual(makeItem(propsA),makeItem(propsB))}class Renderer extends React__namespace.Component{componentDidMount(){this._isMounted=true;this.handleRender({});this._currentFocus=null;this.props.initializeUserInput?.(this.props.widgets,this.props.problemNum??0);if(this.props.serializedState){this.restoreSerializedState(this.props.serializedState);}if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}}UNSAFE_componentWillReceiveProps(nextProps){if(isDifferentQuestion(this.props,nextProps)){this.props.initializeUserInput?.(nextProps.widgets,nextProps.problemNum??0);this.setState(this._getInitialWidgetState(nextProps));}}shouldComponentUpdate(nextProps,nextState){if(this.props.alwaysUpdate){return true}const stateChanged=!___default.default.isEqual(this.state,nextState);const propsChanged=!___default.default.isEqual(this.props,nextProps);return propsChanged||stateChanged}UNSAFE_componentWillUpdate(nextProps,nextState){const oldJipt=this.shouldRenderJiptPlaceholder(this.props,this.state);const newJipt=this.shouldRenderJiptPlaceholder(nextProps,nextState);const oldContent=this.getContent(this.props,this.state);const newContent=this.getContent(nextProps,nextState);const oldHighlightedWidgets=this.props.highlightedWidgets;const newHighlightedWidgets=nextProps.highlightedWidgets;this.reuseMarkdown=!oldJipt&&!newJipt&&oldContent===newContent&&___default.default.isEqual(this.state.translationLintErrors,nextState.translationLintErrors)&&(!this.props.linterContext.highlightLint||___default.default.isEqual(this.props.widgets,nextProps.widgets))&&this.props.linterContext.highlightLint===nextProps.linterContext.highlightLint&&oldHighlightedWidgets===newHighlightedWidgets;}componentDidUpdate(prevProps,prevState){this.handleRender(prevProps);this.widgetIds.forEach(id=>{const container=this._widgetContainers.get(makeContainerId(id));container?.replaceWidgetProps(this.getWidgetProps(id));});if(this.props.serializedState&&!___default.default.isEqual(this.props.serializedState,prevProps.serializedState)){this.restoreSerializedState(this.props.serializedState);}if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}}componentWillUnmount(){this.widgetIds=[];if(this.translationIndex!=null){getDependencies().rendererTranslationComponents.removeComponentAtIndex(this.translationIndex);}this._isMounted=false;}getWidgetProps(widgetId){const apiOptions=this.getApiOptions();const widgetProps=this.state.widgetProps[widgetId]||{};const widgetInfo=this.state.widgetInfo[widgetId];const reviewModeRubric=this.props.reviewMode&&widgetInfo?widgetInfo.options:null;if(!this._interactionTrackers){this._interactionTrackers={};}let interactionTracker=this._interactionTrackers[widgetId];if(!interactionTracker){interactionTracker=this._interactionTrackers[widgetId]=new InteractionTracker(apiOptions.trackInteraction,widgetInfo&&widgetInfo.type,widgetId,getTracking(widgetInfo&&widgetInfo.type));}return {...widgetProps,userInput:this.props.userInput?.[widgetId],widgetId:widgetId,alignment:widgetInfo&&widgetInfo.alignment,static:widgetInfo?.static,problemNum:this.props.problemNum,apiOptions:this.getApiOptions(),keypadElement:this.props.keypadElement,questionCompleted:this.props.questionCompleted,showSolutions:this.props.showSolutions,onFocus:___default.default.partial(this._onWidgetFocus,widgetId),onBlur:___default.default.partial(this._onWidgetBlur,widgetId),findWidgets:this.findWidgets,reviewModeRubric:reviewModeRubric,reviewMode:this.props.reviewMode,onChange:(newProps,cb,silent=false)=>{this._setWidgetProps(widgetId,newProps,cb,silent);},handleUserInput:newUserInput=>{const updatedUserInput={...this.props.userInput,[widgetId]:newUserInput};const emptyWidgetIds=perseusScore.emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,updatedUserInput,this.context.locale);const widgetsEmpty=emptyWidgetIds.length>0;this.props.handleUserInput?.(widgetId,newUserInput,widgetsEmpty);this.props.onInteractWithWidget(widgetId);},trackInteraction:interactionTracker.track,isLastUsedWidget:widgetId===this.state.lastUsedWidgetId}}emptyWidgets(){if(!this.props.userInput){throw new Error(`emptyWidgets called without providing userInput to Renderer`)}return perseusScore.emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale)}handleStateUpdate(id,cb,silent){this.setState(prevState=>{const lastUsedWidgetId=silent?prevState.lastUsedWidgetId:id;return {lastUsedWidgetId}},()=>{setTimeout(()=>{const cbResult=cb&&cb();if(!silent){this.props.onInteractWithWidget(id);}if(cbResult!==false){this._setCurrentFocus([id]);}},0);});}_setWidgetProps(id,nextWidgetProps,cb,silent){this.setState(prevState=>{const widgetProps=nextWidgetProps?{...prevState.widgetProps,[id]:{...prevState.widgetProps[id],...nextWidgetProps}}:prevState.widgetProps;return {widgetProps}},()=>{this.handleStateUpdate(id,cb,silent);});}getUserInput(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInput called without providing userInput to Renderer`)}return this.widgetIds.map(id=>{return userInput[id]})}getUserInputMap(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInputMap called without providing userInput to Renderer`)}return userInput}getPromptJSON(){const{content}=this.props;const widgetJSON={};this.widgetIds.forEach(id=>{const widget=this.getWidgetInstance(id);widgetJSON[id]=widget?.getPromptJSON?.()||{};});return {content,widgets:widgetJSON}}score(){if(!this.props.userInput){throw new Error(`score called without providing userInput to Renderer`)}const scores=perseusScore.scoreWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale);const combinedScore=perseusScore.flattenScores(scores);return combinedScore}render(){const apiOptions=this.getApiOptions();if(this.reuseMarkdown){return this.lastRenderedMarkdown}const content=this.getContent(this.props,this.state);this.widgetIds=[];if(this.shouldRenderJiptPlaceholder(this.props,this.state)){if(!this.translationIndex){this.translationIndex=getDependencies().rendererTranslationComponents.addComponent(this);}if(!apiOptions.isArticle){return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{"data-perseus-component-index":this.translationIndex,children:content})})}}this._isTwoColumn=false;const parsedMarkdown=this.props.inline?PerseusMarkdown.parseInline(content,{isJipt:this.translationIndex!=null}):PerseusMarkdown.parse(content,{isJipt:this.translationIndex!=null});if(this.props.linterContext.highlightLint){const fullLinterContext={content:this.props.content,widgets:this.props.widgets,...this.props.linterContext};PerseusLinter__namespace.runLinter(parsedMarkdown,fullLinterContext,true);this._translationLinter.applyLintErrors(parsedMarkdown,[...this.state.translationLintErrors,...this.props.legacyPerseusLint||[]]);}const markdownContents=this.outputMarkdown(parsedMarkdown,{baseElements:apiOptions.baseElements});const className=classNames__default.default({[ClassNames.RENDERER]:true,[ClassNames.RESPONSIVE_RENDERER]:true,[ClassNames.TWO_COLUMN_RENDERER]:this._isTwoColumn});this.lastRenderedMarkdown=jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{className:className,children:markdownContents})});return this.lastRenderedMarkdown}constructor(props){super(props),this._widgetContainers=new Map,this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions}},this._getInitialWidgetState=props=>{const allWidgetInfo=perseusCore.applyDefaultsToWidgets(props.widgets);return {widgetInfo:allWidgetInfo,widgetProps:this._getAllWidgetsStartProps(allWidgetInfo,props)}},this._getAllWidgetsStartProps=(allWidgetInfo,props)=>{const{apiOptions,problemNum}=props;const widgetsStartProps={};const{strings}=this.props;wonderStuffCore.entries(allWidgetInfo).forEach(([key,widgetInfo])=>{widgetsStartProps[key]=getRendererPropsForWidgetInfo(widgetInfo,strings,problemNum);});apiOptions?.onWidgetStartProps?.(widgetsStartProps);return widgetsStartProps},this._getDefaultWidgetInfo=widgetId=>{const widgetIdParts=Util.rTypeFromWidgetId.exec(widgetId);if(widgetIdParts==null){return {}}return {type:widgetIdParts[1],graded:true,options:{}}},this._getWidgetInfo=widgetId=>{return this.state.widgetInfo[widgetId]||this._getDefaultWidgetInfo(widgetId)},this.renderWidget=(impliedType,id,state)=>{const widgetInfo=this.state.widgetInfo[id];if(widgetInfo&&widgetInfo.alignment==="full-width"){state.foundFullWidth=true;}if(widgetInfo){const type=widgetInfo&&widgetInfo.type||impliedType;const shouldHighlight=___default.default.contains(this.props.highlightedWidgets,id);return jsxRuntimeExports.jsx(WidgetContainer,{id:id,ref:node=>{const containerId=makeContainerId(id);if(node!=null){this._widgetContainers.set(containerId,node);}else {this._widgetContainers.delete(containerId);}},type:type,initialProps:this.getWidgetProps(id),shouldHighlight:shouldHighlight,linterContext:PerseusLinter__namespace.pushContextStack(this.props.linterContext,"widget")},makeContainerId(id))}return null},this.getSerializedState=widgetProps=>{return perseusCore.mapObject(widgetProps||this.state.widgetProps,(props,widgetId)=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getSerializedState){return excludeDenylistKeys(widget.getSerializedState())}return props})},this.restoreSerializedState=(serializedState,callback)=>{const serializedWidgetIds=___default.default.keys(serializedState);const widgetPropIds=___default.default.keys(this.state.widgetProps);if(serializedWidgetIds.length!==widgetPropIds.length||___default.default.intersection(serializedWidgetIds,widgetPropIds).length!==serializedWidgetIds.length){Log.error("Refusing to restore bad serialized state:",perseusCore.Errors.Internal,{loggedMetadata:{serializedState:JSON.stringify(serializedState),currentProps:JSON.stringify(this.state.widgetProps)}});return}let numCallbacks=1;const fireCallback=()=>{--numCallbacks;if(callback&&numCallbacks===0){callback();}};const restoredWidgetProps={};Object.entries(serializedState).forEach(([widgetId,props])=>{const widget=this.getWidgetInstance(widgetId);if(widget?.restoreSerializedState){++numCallbacks;const restoreResult=widget.restoreSerializedState(props,fireCallback);restoredWidgetProps[widgetId]={...this.state.widgetProps[widgetId],...restoreResult};}else {restoredWidgetProps[widgetId]=props;}});this.props.restoreUserInputFromSerializedState?.(serializedState,this.props.widgets);this.setState({widgetProps:restoredWidgetProps},()=>{setTimeout(fireCallback,0);});},this.findInternalWidgets=filterCriterion=>{let filterFunc;if(typeof filterCriterion==="string"){if(filterCriterion.indexOf(" ")!==-1){const widgetId=filterCriterion;filterFunc=(id,widgetInfo,widget)=>id===widgetId;}else {const widgetType=filterCriterion;filterFunc=(id,widgetInfo,widget)=>{return widgetInfo.type===widgetType};}}else {filterFunc=filterCriterion;}const results=this.widgetIds.filter(id=>{const widgetInfo=this._getWidgetInfo(id);const widget=this.getWidgetInstance(id);return filterFunc(id,widgetInfo,widget)}).map(this.getWidgetInstance);return results},this.findWidgets=filterCriterion=>{return [...this.findInternalWidgets(filterCriterion),...this.props.findExternalWidgets(filterCriterion)]},this.getWidgetInstance=id=>{const ref=this._widgetContainers.get(makeContainerId(id));if(!ref){return null}return ref.getWidget()},this._onWidgetFocus=(id,focusPath=[])=>{if(!___default.default.isArray(focusPath)){throw new perseusCore.PerseusError("widget props.onFocus focusPath must be an Array, "+"but was"+JSON.stringify(focusPath),perseusCore.Errors.Internal)}this._setCurrentFocus([id].concat(focusPath));},this._onWidgetBlur=(id,blurPath)=>{const blurringFocusPath=this._currentFocus;const fullPath=[id].concat(blurPath);if(!___default.default.isEqual(fullPath,blurringFocusPath)){return}___default.default.defer(()=>{if(___default.default.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.getContent=(props,state)=>{return state.jiptContent||props.content},this.shouldRenderJiptPlaceholder=(props,state)=>{return getDependencies().JIPT.useJIPT&&state.jiptContent==null&&props.content.indexOf("crwdns")!==-1},this.replaceJiptContent=(content,paragraphIndex)=>{if(paragraphIndex==null){this.setState({jiptContent:content});}else {const codeFenceRegex=/^\s*(`{3,}|~{3,})\s*(\S+)?\s*\n([\s\S]+?)\s*\1\s*$/;if(codeFenceRegex.test(content));else if(/\S\n\s*\n\S/.test(content)){content="$\\large{\\red{\\text{Please translate each "+"paragraph to a single paragraph.}}}$";}else if(/^\s*$/.test(content)){content="$\\large{\\red{\\text{Translated paragraph is "+"currently empty}}}$";}const allContent=this.getContent(this.props,this.state);const paragraphs=JiptParagraphs.parseToArray(allContent);paragraphs[paragraphIndex]=content;this.setState({jiptContent:JiptParagraphs.joinFromArray(paragraphs)});}},this.outputMarkdown=(ast,state)=>{if(___default.default.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;state.paragraphIndex=i;const nodeOut=this.outputMarkdown(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}this._foundTextNodes=false;state.foundFullWidth=false;const output=this.outputNested(ast,state);let className;if(this.translationIndex!=null){className=null;}else {className=classNames__default.default({"perseus-paragraph-centered":!this._foundTextNodes,"perseus-paragraph-full-width":state.foundFullWidth&&ast.content.length===1});}return jsxRuntimeExports.jsx(QuestionParagraph,{className:className,translationIndex:this.translationIndex,paragraphIndex:state.paragraphIndex,inline:this.props.inline,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:output})},state.key)},this.outputNested=(ast,state)=>{if(___default.default.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;const nodeOut=this.outputNested(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}return this.outputNode(ast,this.outputNested,state)},this.outputNode=(node,nestedOutput,state)=>{const apiOptions=this.getApiOptions();const imagePlaceholder=apiOptions.imagePlaceholder;if(node.type==="widget"){const widgetPlaceholder=apiOptions.widgetPlaceholder;if(widgetPlaceholder){return widgetPlaceholder}this._foundTextNodes=true;if(this.widgetIds.includes(node.id)){return jsxRuntimeExports.jsx("span",{className:"renderer-widget-error",children:["Widget [[","☃"," ",node.id,"]] already exists."].join("")},state.key)}this.widgetIds.push(node.id);return this.renderWidget(node.widgetType,node.id,state)}if(node.type==="blockMath"){const content=preprocessTex(node.content);const innerStyle={overflowX:"auto",overflowY:"hidden",paddingTop:10,paddingBottom:10,marginTop:-10,marginBottom:-10};if(apiOptions.isMobile){const margin=16;const outerStyle={marginLeft:-16,marginRight:-16};const horizontalPadding={paddingLeft:margin,paddingRight:margin};const mobileInnerStyle={...innerStyle,...styles$G.mobileZoomableParentFix};return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",style:outerStyle,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:{...mobileInnerStyle,...horizontalPadding},children:jsxRuntimeExports.jsx(ZoomableTeX,{children:content})})})},state.key)}return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:innerStyle,children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{setAssetStatus:setAssetStatus,children:content})})})})},state.key)}if(node.type==="math"){const tex=node.content;return jsxRuntimeExports.jsx("span",{style:{whiteSpace:"nowrap"},children:jsxRuntimeExports.jsxs(ErrorBoundary,{children:[jsxRuntimeExports.jsx("span",{}),jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.props.onRender,setAssetStatus:setAssetStatus,children:tex})}),jsxRuntimeExports.jsx("span",{})]})},state.key)}if(node.type==="image"){if(imagePlaceholder){return imagePlaceholder}const extraAttrs=___default.default.has(this.props.images,node.target)?this.props.images[node.target]:null;const responsive=!state.inTable;return jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{setAssetStatus:setAssetStatus,src:PerseusMarkdown.sanitizeUrl(node.target),alt:node.alt,title:node.title,responsive:responsive,onUpdate:this.props.onRender,zoomToFullSizeOnMobile:apiOptions.isMobile&&apiOptions.isArticle,...extraAttrs})})},state.key)}if(node.type==="columns"){this._isTwoColumn=true;return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)}if(node.type==="text"){if(rContainsNonWhitespace.test(node.content)){this._foundTextNodes=true;}if(imagePlaceholder&&rImageURL.test(node.content)){return imagePlaceholder}return node.content}if(node.type==="table"||node.type==="titledTable"){const output=PerseusMarkdown.ruleOutput(node,nestedOutput,{...state,isMobile:apiOptions.isMobile,inTable:true});if(!apiOptions.isMobile){return output}const outerStyle={marginLeft:-16,marginRight:-16};const innerStyle={paddingLeft:0,paddingRight:0};const mobileInnerStyle={...innerStyle,...styles$G.mobileZoomableParentFix};const wrappedOutput=jsxRuntimeExports.jsx("div",{style:{...mobileInnerStyle,overflowX:"auto"},children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(Zoomable,{animateHeight:true,children:output})})});return jsxRuntimeExports.jsx("div",{style:outerStyle,children:wrappedOutput})}return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)},this.handleRender=prevProps=>{const onRender=this.props.onRender;const oldOnRender=prevProps.onRender;if(onRender!==noopOnRender||oldOnRender!==noopOnRender){const $images=$__default.default(ReactDOM__namespace.default.findDOMNode(this)).find("img");if(oldOnRender!==noopOnRender){$images.off("load",oldOnRender);}if(onRender!==noopOnRender){$images.on("load",onRender);}}onRender();},this._setCurrentFocus=path=>{const apiOptions=this.getApiOptions();if(!isIdPathPrefix(path,this._currentFocus)){const prevFocus=this._currentFocus;if(prevFocus){this.blurPath(prevFocus);}this._currentFocus=path;apiOptions.onFocusChange(this._currentFocus,prevFocus);}},this.focus=()=>{let id;let focusResult;for(let i=0;i<this.widgetIds.length;i++){const widgetId=this.widgetIds[i];const widget=this.getWidgetInstance(widgetId);const widgetFocusResult=widget?.focus?.();if(widgetFocusResult){id=widgetId;focusResult=widgetFocusResult;break}}if(id){let path;if(typeof focusResult==="object"){path=[id].concat(focusResult.path||[]);Log.error("Renderer received a focus result of type 'object' "+"instead of the expected type 'boolean'",perseusCore.Errors.Internal,{loggedMetadata:{focusResult:JSON.stringify(focusResult),currentProps:JSON.stringify(this.state.widgetProps)}});}else {path=[id];}this._setCurrentFocus(path);return true}},this.getDOMNodeForPath=path=>{const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget?.getDOMNodeForPath){return widget.getDOMNodeForPath(interWidgetPath)}if(interWidgetPath.length===0){return ReactDOM__namespace.default.findDOMNode(widget)}},this.getInputPaths=()=>{const inputPaths=[];this.widgetIds.forEach(widgetId=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getInputPaths){const widgetInputPaths=widget.getInputPaths();widgetInputPaths.forEach(inputPath=>{const relativeInputPath=[widgetId].concat(inputPath);inputPaths.push(relativeInputPath);});}});return inputPaths},this.focusPath=path=>{if(___default.default.isEqual(this._currentFocus,path)){return}if(this._currentFocus){this.blurPath(this._currentFocus);}const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const focusWidget=this.getWidgetInstance(widgetId);focusWidget?.focusInputPath?.(interWidgetPath);},this.blurPath=path=>{if(!___default.default.isEqual(this._currentFocus,path)){return}const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget){const blurWidget=this.getWidgetInstance(widgetId);blurWidget?.blurInputPath?.(interWidgetPath);}},this.blur=()=>{if(this._currentFocus){this.blurPath(this._currentFocus);}},this.serialize=()=>{const state={};___default.default.each(this.state.widgetInfo,function(info,id){const widget=this.getWidgetInstance(id);const s=widget.serialize();if(!___default.default.isEmpty(s)){state[id]=s;}},this);return state},this.getWidgetIds=()=>{return this.widgetIds},this.handletranslationLintErrors=lintErrors=>{if(!this._isMounted){return}this.setState({translationLintErrors:lintErrors});};this._translationLinter=new TranslationLinter;this.state={jiptContent:null,translationLintErrors:[],lastUsedWidgetId:null,...this._getInitialWidgetState(props)};}}Renderer.contextType=PerseusI18nContext;Renderer.defaultProps={content:"",widgets:{},images:{},highlightedWidgets:[],questionCompleted:false,showSolutions:"none",onRender:noopOnRender,onInteractWithWidget:function(){},findExternalWidgets:()=>[],alwaysUpdate:false,reviewMode:false,serializedState:null,linterContext:PerseusLinter__namespace.linterContextDefault};const styles$G={mobileZoomableParentFix:{transform:"translate3d(0,0,0)"}};
1716
+ const rContainsNonWhitespace=/\S/;const rImageURL=/(web\+graphie|https):\/\/[^\s]*/;const noopOnRender=()=>{};const makeContainerId=id=>"container:"+id;const isIdPathPrefix=function(prefixArray,wholeArray){if(prefixArray===null||wholeArray===null){return prefixArray===wholeArray}return ___default.default.every(prefixArray,(elem,i)=>{if(wholeArray!=null){return ___default.default.isEqual(elem,wholeArray[i])}})};function isDifferentQuestion(propsA,propsB){function makeItem(props){return perseusCore.splitPerseusItem({question:{content:props.content,widgets:props.widgets,images:{}},hints:[],answerArea:perseusCore.getDefaultAnswerArea()})}return propsA.problemNum!==propsB.problemNum||!___default.default.isEqual(makeItem(propsA),makeItem(propsB))}class Renderer extends React__namespace.Component{componentDidMount(){this._isMounted=true;this.handleRender({});this._currentFocus=null;this.props.initializeUserInput?.(this.props.widgets,this.props.problemNum??0);if(this.props.serializedState){this.restoreSerializedState(this.props.serializedState);}if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}}UNSAFE_componentWillReceiveProps(nextProps){if(isDifferentQuestion(this.props,nextProps)){this.props.initializeUserInput?.(nextProps.widgets,nextProps.problemNum??0);this.setState(this._getInitialWidgetState(nextProps));}}shouldComponentUpdate(nextProps,nextState){if(this.props.alwaysUpdate){return true}const stateChanged=!___default.default.isEqual(this.state,nextState);const propsChanged=!___default.default.isEqual(this.props,nextProps);return propsChanged||stateChanged}UNSAFE_componentWillUpdate(nextProps,nextState){const oldJipt=this.shouldRenderJiptPlaceholder(this.props,this.state);const newJipt=this.shouldRenderJiptPlaceholder(nextProps,nextState);const oldContent=this.getContent(this.props,this.state);const newContent=this.getContent(nextProps,nextState);const oldHighlightedWidgets=this.props.highlightedWidgets;const newHighlightedWidgets=nextProps.highlightedWidgets;this.reuseMarkdown=!oldJipt&&!newJipt&&oldContent===newContent&&___default.default.isEqual(this.state.translationLintErrors,nextState.translationLintErrors)&&(!this.props.linterContext.highlightLint||___default.default.isEqual(this.props.widgets,nextProps.widgets))&&this.props.linterContext.highlightLint===nextProps.linterContext.highlightLint&&oldHighlightedWidgets===newHighlightedWidgets;}componentDidUpdate(prevProps,prevState){this.handleRender(prevProps);this.widgetIds.forEach(id=>{const container=this._widgetContainers.get(makeContainerId(id));container?.replaceWidgetProps(this.getWidgetProps(id));});if(this.props.serializedState&&!___default.default.isEqual(this.props.serializedState,prevProps.serializedState)){this.restoreSerializedState(this.props.serializedState);}if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}}componentWillUnmount(){this.widgetIds=[];if(this.translationIndex!=null){getDependencies().rendererTranslationComponents.removeComponentAtIndex(this.translationIndex);}this._isMounted=false;}getWidgetProps(widgetId){const apiOptions=this.getApiOptions();const widgetProps=this.state.widgetProps[widgetId]||{};const widgetInfo=this.state.widgetInfo[widgetId];const reviewModeRubric=this.props.reviewMode&&widgetInfo?widgetInfo.options:null;if(!this._interactionTrackers){this._interactionTrackers={};}let interactionTracker=this._interactionTrackers[widgetId];if(!interactionTracker){interactionTracker=this._interactionTrackers[widgetId]=new InteractionTracker(apiOptions.trackInteraction,widgetInfo&&widgetInfo.type,widgetId,getTracking(widgetInfo&&widgetInfo.type));}return {...widgetProps,userInput:this.props.userInput?.[widgetId],widgetId:widgetId,alignment:widgetInfo&&widgetInfo.alignment,static:widgetInfo?.static,problemNum:this.props.problemNum,apiOptions:this.getApiOptions(),keypadElement:this.props.keypadElement,questionCompleted:this.props.questionCompleted,showSolutions:this.props.showSolutions,onFocus:___default.default.partial(this._onWidgetFocus,widgetId),onBlur:___default.default.partial(this._onWidgetBlur,widgetId),findWidgets:this.findWidgets,reviewModeRubric:reviewModeRubric,reviewMode:this.props.reviewMode,onChange:(newProps,cb,silent=false)=>{this._setWidgetProps(widgetId,newProps,cb,silent);},handleUserInput:newUserInput=>{const updatedUserInput={...this.props.userInput,[widgetId]:newUserInput};const emptyWidgetIds=perseusScore.emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,updatedUserInput,this.context.locale);const widgetsEmpty=emptyWidgetIds.length>0;this.props.handleUserInput?.(widgetId,newUserInput,widgetsEmpty);this.props.onInteractWithWidget(widgetId);},trackInteraction:interactionTracker.track,isLastUsedWidget:widgetId===this.state.lastUsedWidgetId}}emptyWidgets(){if(!this.props.userInput){throw new Error(`emptyWidgets called without providing userInput to Renderer`)}return perseusScore.emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale)}handleStateUpdate(id,cb,silent){this.setState(prevState=>{const lastUsedWidgetId=silent?prevState.lastUsedWidgetId:id;return {lastUsedWidgetId}},()=>{setTimeout(()=>{const cbResult=cb&&cb();if(!silent){this.props.onInteractWithWidget(id);}if(cbResult!==false){this._setCurrentFocus([id]);}},0);});}_setWidgetProps(id,nextWidgetProps,cb,silent){this.setState(prevState=>{const widgetProps=nextWidgetProps?{...prevState.widgetProps,[id]:{...prevState.widgetProps[id],...nextWidgetProps}}:prevState.widgetProps;return {widgetProps}},()=>{this.handleStateUpdate(id,cb,silent);});}getUserInput(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInput called without providing userInput to Renderer`)}return this.widgetIds.map(id=>{return userInput[id]})}getUserInputMap(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInputMap called without providing userInput to Renderer`)}return userInput}getPromptJSON(){const{content}=this.props;const widgetJSON={};this.widgetIds.forEach(id=>{const widget=this.getWidgetInstance(id);widgetJSON[id]=widget?.getPromptJSON?.()||{};});return {content,widgets:widgetJSON}}score(){if(!this.props.userInput){throw new Error(`score called without providing userInput to Renderer`)}const scores=perseusScore.scoreWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale);const combinedScore=perseusScore.flattenScores(scores);return combinedScore}render(){const apiOptions=this.getApiOptions();if(this.reuseMarkdown){return this.lastRenderedMarkdown}const content=this.getContent(this.props,this.state);this.widgetIds=[];if(this.shouldRenderJiptPlaceholder(this.props,this.state)){if(!this.translationIndex){this.translationIndex=getDependencies().rendererTranslationComponents.addComponent(this);}if(!apiOptions.isArticle){return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{"data-perseus-component-index":this.translationIndex,children:content})})}}this._isTwoColumn=false;const parsedMarkdown=this.props.inline?PerseusMarkdown.parseInline(content,{isJipt:this.translationIndex!=null}):PerseusMarkdown.parse(content,{isJipt:this.translationIndex!=null});if(this.props.linterContext.highlightLint){const fullLinterContext={content:this.props.content,widgets:this.props.widgets,...this.props.linterContext};PerseusLinter__namespace.runLinter(parsedMarkdown,fullLinterContext,true);this._translationLinter.applyLintErrors(parsedMarkdown,[...this.state.translationLintErrors,...this.props.legacyPerseusLint||[]]);}const markdownContents=this.outputMarkdown(parsedMarkdown,{baseElements:apiOptions.baseElements});const className=classNames__default.default({[ClassNames.RENDERER]:true,[ClassNames.RESPONSIVE_RENDERER]:true,[ClassNames.TWO_COLUMN_RENDERER]:this._isTwoColumn});this.lastRenderedMarkdown=jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{className:className,children:markdownContents})});return this.lastRenderedMarkdown}constructor(props){super(props),this._widgetContainers=new Map,this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions}},this._getInitialWidgetState=props=>{const allWidgetInfo=perseusCore.applyDefaultsToWidgets(props.widgets);return {widgetInfo:allWidgetInfo,widgetProps:this._getAllWidgetsStartProps(allWidgetInfo,props)}},this._getAllWidgetsStartProps=(allWidgetInfo,props)=>{const{apiOptions,problemNum}=props;const widgetsStartProps={};const{strings}=this.props;wonderStuffCore.entries(allWidgetInfo).forEach(([key,widgetInfo])=>{widgetsStartProps[key]=getRendererPropsForWidgetInfo(widgetInfo,strings,problemNum);});apiOptions?.onWidgetStartProps?.(widgetsStartProps);return widgetsStartProps},this._getDefaultWidgetInfo=widgetId=>{const widgetIdParts=Util.rTypeFromWidgetId.exec(widgetId);if(widgetIdParts==null){return {}}return {type:widgetIdParts[1],graded:true,options:{}}},this._getWidgetInfo=widgetId=>{return this.state.widgetInfo[widgetId]||this._getDefaultWidgetInfo(widgetId)},this.renderWidget=(impliedType,id,state)=>{const widgetInfo=this.state.widgetInfo[id];if(widgetInfo&&widgetInfo.alignment==="full-width"){state.foundFullWidth=true;}if(widgetInfo){const type=widgetInfo&&widgetInfo.type||impliedType;const shouldHighlight=___default.default.contains(this.props.highlightedWidgets,id);return jsxRuntimeExports.jsx(WidgetContainer,{id:id,ref:node=>{const containerId=makeContainerId(id);if(node!=null){this._widgetContainers.set(containerId,node);}else {this._widgetContainers.delete(containerId);}},type:type,initialProps:this.getWidgetProps(id),shouldHighlight:shouldHighlight,linterContext:PerseusLinter__namespace.pushContextStack(this.props.linterContext,"widget")},makeContainerId(id))}return null},this.getSerializedState=widgetProps=>{return perseusCore.mapObject(widgetProps||this.state.widgetProps,(props,widgetId)=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getSerializedState){return excludeDenylistKeys(widget.getSerializedState())}return props})},this.restoreSerializedState=(serializedState,callback)=>{const serializedWidgetIds=___default.default.keys(serializedState);const widgetPropIds=___default.default.keys(this.state.widgetProps);if(serializedWidgetIds.length!==widgetPropIds.length||___default.default.intersection(serializedWidgetIds,widgetPropIds).length!==serializedWidgetIds.length){Log.error("Refusing to restore bad serialized state:",perseusCore.Errors.Internal,{loggedMetadata:{serializedState:JSON.stringify(serializedState),currentProps:JSON.stringify(this.state.widgetProps)}});return}let numCallbacks=1;const fireCallback=()=>{--numCallbacks;if(callback&&numCallbacks===0){callback();}};const restoredWidgetProps={};Object.entries(serializedState).forEach(([widgetId,props])=>{const widget=this.getWidgetInstance(widgetId);if(widget?.restoreSerializedState){++numCallbacks;const restoreResult=widget.restoreSerializedState(props,fireCallback);restoredWidgetProps[widgetId]={...this.state.widgetProps[widgetId],...restoreResult};}else {restoredWidgetProps[widgetId]=props;}});this.props.restoreUserInputFromSerializedState?.(serializedState,this.props.widgets);this.setState({widgetProps:restoredWidgetProps},()=>{setTimeout(fireCallback,0);});},this.findInternalWidgets=filterCriterion=>{let filterFunc;if(typeof filterCriterion==="string"){if(filterCriterion.indexOf(" ")!==-1){const widgetId=filterCriterion;filterFunc=(id,widgetInfo,widget)=>id===widgetId;}else {const widgetType=filterCriterion;filterFunc=(id,widgetInfo,widget)=>{return widgetInfo.type===widgetType};}}else {filterFunc=filterCriterion;}const results=this.widgetIds.filter(id=>{const widgetInfo=this._getWidgetInfo(id);const widget=this.getWidgetInstance(id);return filterFunc(id,widgetInfo,widget)}).map(this.getWidgetInstance);return results},this.findWidgets=filterCriterion=>{return [...this.findInternalWidgets(filterCriterion),...this.props.findExternalWidgets(filterCriterion)]},this.getWidgetInstance=id=>{const ref=this._widgetContainers.get(makeContainerId(id));if(!ref){return null}return ref.getWidget()},this._onWidgetFocus=(id,focusPath=[])=>{if(!___default.default.isArray(focusPath)){throw new perseusCore.PerseusError("widget props.onFocus focusPath must be an Array, "+"but was"+JSON.stringify(focusPath),perseusCore.Errors.Internal)}this._setCurrentFocus([id].concat(focusPath));},this._onWidgetBlur=(id,blurPath)=>{const blurringFocusPath=this._currentFocus;const fullPath=[id].concat(blurPath);if(!___default.default.isEqual(fullPath,blurringFocusPath)){return}___default.default.defer(()=>{if(___default.default.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.getContent=(props,state)=>{return state.jiptContent||props.content},this.shouldRenderJiptPlaceholder=(props,state)=>{return getDependencies().JIPT.useJIPT&&state.jiptContent==null&&props.content.indexOf("crwdns")!==-1},this.replaceJiptContent=(content,paragraphIndex)=>{if(paragraphIndex==null){this.setState({jiptContent:content});}else {const codeFenceRegex=/^\s*(`{3,}|~{3,})\s*(\S+)?\s*\n([\s\S]+?)\s*\1\s*$/;if(codeFenceRegex.test(content));else if(/\S\n\s*\n\S/.test(content)){content="$\\large{\\red{\\text{Please translate each "+"paragraph to a single paragraph.}}}$";}else if(/^\s*$/.test(content)){content="$\\large{\\red{\\text{Translated paragraph is "+"currently empty}}}$";}const allContent=this.getContent(this.props,this.state);const paragraphs=JiptParagraphs.parseToArray(allContent);paragraphs[paragraphIndex]=content;this.setState({jiptContent:JiptParagraphs.joinFromArray(paragraphs)});}},this.outputMarkdown=(ast,state)=>{if(___default.default.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;state.paragraphIndex=i;const nodeOut=this.outputMarkdown(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}this._foundTextNodes=false;state.foundFullWidth=false;const output=this.outputNested(ast,state);let className;if(this.translationIndex!=null){className=null;}else {className=classNames__default.default({"perseus-paragraph-centered":!this._foundTextNodes,"perseus-paragraph-full-width":state.foundFullWidth&&ast.content.length===1});}return jsxRuntimeExports.jsx(QuestionParagraph,{className:className,translationIndex:this.translationIndex,paragraphIndex:state.paragraphIndex,inline:this.props.inline,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:output})},state.key)},this.outputNested=(ast,state)=>{if(___default.default.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;const nodeOut=this.outputNested(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}return this.outputNode(ast,this.outputNested,state)},this.outputNode=(node,nestedOutput,state)=>{const apiOptions=this.getApiOptions();const imagePlaceholder=apiOptions.imagePlaceholder;if(node.type==="widget"){const widgetPlaceholder=apiOptions.widgetPlaceholder;if(widgetPlaceholder){return widgetPlaceholder}this._foundTextNodes=true;if(this.widgetIds.includes(node.id)){return jsxRuntimeExports.jsx("span",{className:"renderer-widget-error",children:["Widget [[","☃"," ",node.id,"]] already exists."].join("")},state.key)}this.widgetIds.push(node.id);return this.renderWidget(node.widgetType,node.id,state)}if(node.type==="blockMath"){const content=preprocessTex(node.content);const innerStyle={overflowX:"auto",overflowY:"hidden",paddingTop:10,paddingBottom:10,marginTop:-10,marginBottom:-10};if(apiOptions.isMobile){const margin=16;const outerStyle={marginLeft:-16,marginRight:-16};const horizontalPadding={paddingLeft:margin,paddingRight:margin};const mobileInnerStyle={...innerStyle,...styles$E.mobileZoomableParentFix};return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",style:outerStyle,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:{...mobileInnerStyle,...horizontalPadding},children:jsxRuntimeExports.jsx(ZoomableTeX,{children:content})})})},state.key)}return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:innerStyle,children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{setAssetStatus:setAssetStatus,children:content})})})})},state.key)}if(node.type==="math"){const tex=node.content;return jsxRuntimeExports.jsx("span",{style:{whiteSpace:"nowrap"},children:jsxRuntimeExports.jsxs(ErrorBoundary,{children:[jsxRuntimeExports.jsx("span",{}),jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.props.onRender,setAssetStatus:setAssetStatus,children:tex})}),jsxRuntimeExports.jsx("span",{})]})},state.key)}if(node.type==="image"){if(imagePlaceholder){return imagePlaceholder}const extraAttrs=___default.default.has(this.props.images,node.target)?this.props.images[node.target]:null;const responsive=!state.inTable;return jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{setAssetStatus:setAssetStatus,src:PerseusMarkdown.sanitizeUrl(node.target),alt:node.alt,title:node.title,responsive:responsive,onUpdate:this.props.onRender,zoomToFullSizeOnMobile:apiOptions.isMobile&&apiOptions.isArticle,...extraAttrs})})},state.key)}if(node.type==="columns"){this._isTwoColumn=true;return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)}if(node.type==="text"){if(rContainsNonWhitespace.test(node.content)){this._foundTextNodes=true;}if(imagePlaceholder&&rImageURL.test(node.content)){return imagePlaceholder}return node.content}if(node.type==="table"||node.type==="titledTable"){const output=PerseusMarkdown.ruleOutput(node,nestedOutput,{...state,isMobile:apiOptions.isMobile,inTable:true});if(!apiOptions.isMobile){return output}const outerStyle={marginLeft:-16,marginRight:-16};const innerStyle={paddingLeft:0,paddingRight:0};const mobileInnerStyle={...innerStyle,...styles$E.mobileZoomableParentFix};const wrappedOutput=jsxRuntimeExports.jsx("div",{style:{...mobileInnerStyle,overflowX:"auto"},children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(Zoomable,{animateHeight:true,children:output})})});return jsxRuntimeExports.jsx("div",{style:outerStyle,children:wrappedOutput})}return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)},this.handleRender=prevProps=>{const onRender=this.props.onRender;const oldOnRender=prevProps.onRender;if(onRender!==noopOnRender||oldOnRender!==noopOnRender){const $images=$__default.default(ReactDOM__namespace.default.findDOMNode(this)).find("img");if(oldOnRender!==noopOnRender){$images.off("load",oldOnRender);}if(onRender!==noopOnRender){$images.on("load",onRender);}}onRender();},this._setCurrentFocus=path=>{const apiOptions=this.getApiOptions();if(!isIdPathPrefix(path,this._currentFocus)){const prevFocus=this._currentFocus;if(prevFocus){this.blurPath(prevFocus);}this._currentFocus=path;apiOptions.onFocusChange(this._currentFocus,prevFocus);}},this.focus=()=>{let id;let focusResult;for(let i=0;i<this.widgetIds.length;i++){const widgetId=this.widgetIds[i];const widget=this.getWidgetInstance(widgetId);const widgetFocusResult=widget?.focus?.();if(widgetFocusResult){id=widgetId;focusResult=widgetFocusResult;break}}if(id){let path;if(typeof focusResult==="object"){path=[id].concat(focusResult.path||[]);Log.error("Renderer received a focus result of type 'object' "+"instead of the expected type 'boolean'",perseusCore.Errors.Internal,{loggedMetadata:{focusResult:JSON.stringify(focusResult),currentProps:JSON.stringify(this.state.widgetProps)}});}else {path=[id];}this._setCurrentFocus(path);return true}},this.getDOMNodeForPath=path=>{const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget?.getDOMNodeForPath){return widget.getDOMNodeForPath(interWidgetPath)}if(interWidgetPath.length===0){return ReactDOM__namespace.default.findDOMNode(widget)}},this.getInputPaths=()=>{const inputPaths=[];this.widgetIds.forEach(widgetId=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getInputPaths){const widgetInputPaths=widget.getInputPaths();widgetInputPaths.forEach(inputPath=>{const relativeInputPath=[widgetId].concat(inputPath);inputPaths.push(relativeInputPath);});}});return inputPaths},this.focusPath=path=>{if(___default.default.isEqual(this._currentFocus,path)){return}if(this._currentFocus){this.blurPath(this._currentFocus);}const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const focusWidget=this.getWidgetInstance(widgetId);focusWidget?.focusInputPath?.(interWidgetPath);},this.blurPath=path=>{if(!___default.default.isEqual(this._currentFocus,path)){return}const widgetId=___default.default.first(path);const interWidgetPath=___default.default.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget){const blurWidget=this.getWidgetInstance(widgetId);blurWidget?.blurInputPath?.(interWidgetPath);}},this.blur=()=>{if(this._currentFocus){this.blurPath(this._currentFocus);}},this.serialize=()=>{const state={};___default.default.each(this.state.widgetInfo,function(info,id){const widget=this.getWidgetInstance(id);const s=widget.serialize();if(!___default.default.isEmpty(s)){state[id]=s;}},this);return state},this.getWidgetIds=()=>{return this.widgetIds},this.handletranslationLintErrors=lintErrors=>{if(!this._isMounted){return}this.setState({translationLintErrors:lintErrors});};this._translationLinter=new TranslationLinter;this.state={jiptContent:null,translationLintErrors:[],lastUsedWidgetId:null,...this._getInitialWidgetState(props)};}}Renderer.contextType=PerseusI18nContext;Renderer.defaultProps={content:"",widgets:{},images:{},highlightedWidgets:[],questionCompleted:false,showSolutions:"none",onRender:noopOnRender,onInteractWithWidget:function(){},findExternalWidgets:()=>[],alwaysUpdate:false,reviewMode:false,serializedState:null,linterContext:PerseusLinter__namespace.linterContextDefault};const styles$E={mobileZoomableParentFix:{transform:"translate3d(0,0,0)"}};
1713
1717
 
1714
- const{captureScratchpadTouchStart: captureScratchpadTouchStart$3}=Util;const InputWithExamples=React.forwardRef(function InputWithExamples({shouldShowExamples=true,onFocus=()=>{},onBlur=()=>{},disabled=false,linterContext=PerseusLinter__namespace.linterContextDefault,className="",...props},ref){const context=React__namespace.useContext(PerseusI18nContext);const inputRef=React__namespace.useRef(null);const[inputFocused,setInputFocused]=React__namespace.useState(false);const id=React.useId();const ariaId=`aria-for-${id}`;React.useImperativeHandle(ref,()=>({current:inputRef.current,focus:()=>{if(inputRef.current){inputRef.current.focus();}},blur:()=>{if(inputRef.current){inputRef.current.blur();}}}));const getInputClassName=()=>{let inputClassName=ClassNames.INPUT;if(inputFocused){inputClassName+=" "+ClassNames.FOCUSED;}if(className){inputClassName+=" "+className;}return inputClassName};const handleFocus=()=>{onFocus();setInputFocused(true);};const handleBlur=()=>{onBlur();setInputFocused(false);};const renderInput=()=>{const examplesAria=shouldShowExamples?`${props.examples[0]}
1715
- ${props.examples.slice(1).join(", or\n")}`.replaceAll("*","").replaceAll("$","").replaceAll("\\ \\text{pi}"," pi").replaceAll("\\ "," and "):"";const inputProps={id:id,"aria-describedby":shouldShowExamples?ariaId:undefined,ref:inputRef,className:getInputClassName(),labelText:props.labelText,value:props.value,onFocus:handleFocus,onBlur:handleBlur,disabled:disabled,style:props.style,onChange:props.onChange,onTouchStart:captureScratchpadTouchStart$3,autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:"false"};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(TextInput,{...inputProps}),jsxRuntimeExports.jsx("span",{id:ariaId,style:{display:"none"},children:examplesAria})]})};const renderTooltipContent=()=>{return jsxRuntimeExports.jsx(Tooltip.TooltipContent,{children:jsxRuntimeExports.jsx("div",{id:id,className:"input-with-examples-tooltip",children:jsxRuntimeExports.jsx(Renderer,{content:examplesContent,linterContext:PerseusLinter__namespace.pushContextStack(linterContext,"input-with-examples"),strings:context.strings})})})};const examplesContent=props.examples.length<=2?props.examples.join(" "):props.examples.map((example,index)=>{return index===0&&example.startsWith("**")?`${example}
1718
+ const{captureScratchpadTouchStart: captureScratchpadTouchStart$2}=Util;const InputWithExamples=React.forwardRef(function InputWithExamples({shouldShowExamples=true,onFocus=()=>{},onBlur=()=>{},disabled=false,linterContext=PerseusLinter__namespace.linterContextDefault,className="",...props},ref){const context=React__namespace.useContext(PerseusI18nContext);const inputRef=React__namespace.useRef(null);const[inputFocused,setInputFocused]=React__namespace.useState(false);const id=React.useId();const ariaId=`aria-for-${id}`;React.useImperativeHandle(ref,()=>({current:inputRef.current,focus:()=>{if(inputRef.current){inputRef.current.focus();}},blur:()=>{if(inputRef.current){inputRef.current.blur();}}}));const getInputClassName=()=>{let inputClassName=ClassNames.INPUT;if(inputFocused){inputClassName+=" "+ClassNames.FOCUSED;}if(className){inputClassName+=" "+className;}return inputClassName};const handleFocus=()=>{onFocus();setInputFocused(true);};const handleBlur=()=>{onBlur();setInputFocused(false);};const renderInput=()=>{const examplesAria=shouldShowExamples?`${props.examples[0]}
1719
+ ${props.examples.slice(1).join(", or\n")}`.replaceAll("*","").replaceAll("$","").replaceAll("\\ \\text{pi}"," pi").replaceAll("\\ "," and "):"";const inputProps={id:id,"aria-describedby":shouldShowExamples?ariaId:undefined,ref:inputRef,className:getInputClassName(),labelText:props.labelText,value:props.value,onFocus:handleFocus,onBlur:handleBlur,disabled:disabled,style:props.style,onChange:props.onChange,onTouchStart:captureScratchpadTouchStart$2,autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:"false"};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(TextInput,{...inputProps}),jsxRuntimeExports.jsx("span",{id:ariaId,style:{display:"none"},children:examplesAria})]})};const renderTooltipContent=()=>{return jsxRuntimeExports.jsx(Tooltip.TooltipContent,{children:jsxRuntimeExports.jsx("div",{id:id,className:"input-with-examples-tooltip",children:jsxRuntimeExports.jsx(Renderer,{content:examplesContent,linterContext:PerseusLinter__namespace.pushContextStack(linterContext,"input-with-examples"),strings:context.strings})})})};const examplesContent=props.examples.length<=2?props.examples.join(" "):props.examples.map((example,index)=>{return index===0&&example.startsWith("**")?`${example}
1716
1720
  `:`- ${example}`}).join("\n");const showExamplesTooltip=shouldShowExamples&&inputFocused;return jsxRuntimeExports.jsx(Tooltip__default.default,{content:renderTooltipContent(),opened:showExamplesTooltip,placement:"bottom",children:renderInput()})});
1717
1721
 
1718
- const formExamples={integer:function(_,strings){return strings.integerExample},proper:function(options,strings){if(options.simplify==="optional"){return strings.properExample}return strings.simplifiedProperExample},improper:function(options,strings){if(options.simplify==="optional"){return strings.improperExample}return strings.simplifiedImproperExample},mixed:function(_,strings){return strings.mixedExample},decimal:function(_,strings){return strings.decimalExample},percent:function(_,strings){return strings.percentExample},pi:function(_,strings){return strings.piExample}};class InputNumber extends React__namespace.Component{getPromptJSON(){return getPromptJSON$s(this.props)}examples(){const{strings}=this.context;const type=this.props.answerType;const forms=perseusScore.inputNumberAnswerTypes[type].forms.split(/\s*,\s*/);const examples=forms.map(form=>formExamples[form](this.props,strings));return [strings.yourAnswer].concat(examples)}getSerializedState(){const{userInput,...rest}=this.props;return {...rest,currentValue:userInput.currentValue}}render(){if(this.props.apiOptions.customKeypad){const input=jsxRuntimeExports.jsx(SimpleKeypadInput,{ref:"input",value:this.props.userInput.currentValue,keypadElement:this.props.keypadElement,onChange:this.handleChange,onFocus:this._handleFocus,onBlur:this._handleBlur});if(this.props.rightAlign){return jsxRuntimeExports.jsx("div",{className:"perseus-input-right-align",children:input})}return input}const inputStyles=[styles$F.default,this.props.size==="small"?styles$F.small:null,this.props.rightAlign?styles$F.rightAlign:styles$F.leftAlign];if(this.props.reviewMode&&!this.props.userInput.currentValue){inputStyles.push(styles$F.answerStateUnanswered);}return jsxRuntimeExports.jsx(InputWithExamples,{ref:"input",value:this.props.userInput.currentValue,onChange:this.handleChange,style:inputStyles,examples:this.examples(),shouldShowExamples:this.shouldShowExamples(),onFocus:this._handleFocus,onBlur:this._handleBlur,id:this.props.widgetId,disabled:this.props.apiOptions.readOnly,linterContext:this.props.linterContext})}constructor(...args){super(...args),this.shouldShowExamples=()=>{return this.props.answerType!=="number"},this.handleChange=(newValue,cb)=>{this.props.handleUserInput({currentValue:newValue},cb);},this._handleFocus=()=>{this.props.onFocus([]);},this._handleBlur=()=>{this.props.onBlur([]);},this.focus=()=>{this.refs.input.focus();return true},this.focusInputPath=inputPath=>{this.refs.input.focus();},this.blurInputPath=inputPath=>{if(typeof this.refs.input?.blur==="function"){this.refs.input?.blur();}},this.getInputPaths=()=>{return [[]]};}}InputNumber.contextType=PerseusI18nContext;InputNumber.defaultProps={size:"normal",answerType:"number",rightAlign:false,apiOptions:ApiOptions.defaults,linterContext:PerseusLinter.linterContextDefault,userInput:{currentValue:""}};const styles$F=aphrodite.StyleSheet.create({default:{width:80,height:"auto",direction:"ltr"},small:{width:40},leftAlign:{paddingLeft:wonderBlocksTokens.spacing.xxxSmall_4,paddingRight:0},rightAlign:{textAlign:"right",paddingLeft:0,paddingRight:wonderBlocksTokens.spacing.xxxSmall_4},answerStateUnanswered:{backgroundColor:"#eee",border:"solid 1px #999"}});function transform$6(widgetOptions){const{simplify,size,answerType,rightAlign}=widgetOptions;return {simplify,size,answerType,rightAlign}}function getOneCorrectAnswerFromRubric(rubric){if(rubric.value==null){return}let answerString=String(rubric.value);if(rubric.inexact&&rubric.maxError){answerString+=" ± "+rubric.maxError;}return answerString}function getUserInputFromSerializedState$h(serializedState){return {currentValue:serializedState.currentValue}}function getStartUserInput$i(){return {currentValue:""}}var InputNumber$1 = {name:"input-number",displayName:"Input number (deprecated - use numeric input instead)",hidden:true,widget:InputNumber,isLintable:true,transform: transform$6,getOneCorrectAnswerFromRubric,getStartUserInput: getStartUserInput$i,getUserInputFromSerializedState: getUserInputFromSerializedState$h};
1722
+ const formExamples={integer:function(_,strings){return strings.integerExample},proper:function(options,strings){if(options.simplify==="optional"){return strings.properExample}return strings.simplifiedProperExample},improper:function(options,strings){if(options.simplify==="optional"){return strings.improperExample}return strings.simplifiedImproperExample},mixed:function(_,strings){return strings.mixedExample},decimal:function(_,strings){return strings.decimalExample},percent:function(_,strings){return strings.percentExample},pi:function(_,strings){return strings.piExample}};class InputNumber extends React__namespace.Component{getPromptJSON(){return getPromptJSON$s(this.props)}examples(){const{strings}=this.context;const type=this.props.answerType;const forms=perseusScore.inputNumberAnswerTypes[type].forms.split(/\s*,\s*/);const examples=forms.map(form=>formExamples[form](this.props,strings));return [strings.yourAnswer].concat(examples)}getSerializedState(){return {alignment:this.props.alignment,static:this.props.static,simplify:this.props.simplify,size:this.props.size,answerType:this.props.answerType,rightAlign:this.props.rightAlign,currentValue:this.props.userInput.currentValue}}render(){if(this.props.apiOptions.customKeypad){const input=jsxRuntimeExports.jsx(SimpleKeypadInput,{ref:"input",value:this.props.userInput.currentValue,keypadElement:this.props.keypadElement,onChange:this.handleChange,onFocus:this._handleFocus,onBlur:this._handleBlur});if(this.props.rightAlign){return jsxRuntimeExports.jsx("div",{className:"perseus-input-right-align",children:input})}return input}const inputStyles=[styles$D.default,this.props.size==="small"?styles$D.small:null,this.props.rightAlign?styles$D.rightAlign:styles$D.leftAlign];if(this.props.reviewMode&&!this.props.userInput.currentValue){inputStyles.push(styles$D.answerStateUnanswered);}return jsxRuntimeExports.jsx(InputWithExamples,{ref:"input",value:this.props.userInput.currentValue,onChange:this.handleChange,style:inputStyles,examples:this.examples(),shouldShowExamples:this.shouldShowExamples(),onFocus:this._handleFocus,onBlur:this._handleBlur,id:this.props.widgetId,disabled:this.props.apiOptions.readOnly,linterContext:this.props.linterContext})}constructor(...args){super(...args),this.shouldShowExamples=()=>{return this.props.answerType!=="number"},this.handleChange=(newValue,cb)=>{this.props.handleUserInput({currentValue:newValue},cb);},this._handleFocus=()=>{this.props.onFocus([]);},this._handleBlur=()=>{this.props.onBlur([]);},this.focus=()=>{this.refs.input.focus();return true},this.focusInputPath=inputPath=>{this.refs.input.focus();},this.blurInputPath=inputPath=>{if(typeof this.refs.input?.blur==="function"){this.refs.input?.blur();}},this.getInputPaths=()=>{return [[]]};}}InputNumber.contextType=PerseusI18nContext;InputNumber.defaultProps={size:"normal",answerType:"number",rightAlign:false,apiOptions:ApiOptions.defaults,linterContext:PerseusLinter.linterContextDefault,userInput:{currentValue:""}};const styles$D=aphrodite.StyleSheet.create({default:{width:80,height:"auto",direction:"ltr"},small:{width:40},leftAlign:{paddingLeft:wonderBlocksTokens.spacing.xxxSmall_4,paddingRight:0},rightAlign:{textAlign:"right",paddingLeft:0,paddingRight:wonderBlocksTokens.spacing.xxxSmall_4},answerStateUnanswered:{backgroundColor:"#eee",border:"solid 1px #999"}});function getOneCorrectAnswerFromRubric(rubric){if(rubric.value==null){return}let answerString=String(rubric.value);if(rubric.inexact&&rubric.maxError){answerString+=" ± "+rubric.maxError;}return answerString}function getUserInputFromSerializedState$h(serializedState){return {currentValue:serializedState.currentValue}}function getStartUserInput$i(){return {currentValue:""}}var InputNumber$1 = {name:"input-number",displayName:"Input number (deprecated - use numeric input instead)",hidden:true,widget:InputNumber,isLintable:true,getOneCorrectAnswerFromRubric,getStartUserInput: getStartUserInput$i,getUserInputFromSerializedState: getUserInputFromSerializedState$h};
1719
1723
 
1720
1724
  const getPromptJSON$r=renderProps=>{return {type:"numeric-input",label:renderProps.labelText,userInput:{value:renderProps.userInput.currentValue}}};
1721
1725
 
@@ -1727,33 +1731,25 @@ class NumericInput extends React__namespace.Component{getPromptJSON(){return get
1727
1731
 
1728
1732
  const getPromptJSON$q=(renderProps,userInput)=>{const choices=renderProps.choices||[];const options=choices.map(choice=>{const option={value:choice.content};if(choice.rationale){option.rationale=choice.rationale;}return option});return {type:"radio",hasNoneOfTheAbove:!!renderProps.hasNoneOfTheAbove,options,userInput:{selectedOptions:userInput?.choicesSelected?.slice()??[]}}};
1729
1733
 
1730
- var styles$E = {"scrollButtonsContainer":"perseus_kjDHiWdD","scrollFade":"perseus_KB5rz4XY","scrollFadeLeft":"perseus_tP0ytdCp","scrollFadeRight":"perseus_t5yijnoR"};
1731
-
1732
- const SCROLL_DISTANCE=100;function ScrollableView({overflowX,overflowY,children,className,scrollDescription,style,role="group",...additionalProps}){const{strings}=usePerseusI18n();const containerRef=React.useRef(null);const[isScrollable,setIsScrollable]=React.useState(false);const[canScrollStart,setCanScrollStart]=React.useState(false);const[canScrollEnd,setCanScrollEnd]=React.useState(false);const[isRtl,setIsRtl]=React.useState(false);const updateScrollState=React__namespace.useCallback(()=>{if(!containerRef.current){return}const{scrollLeft,scrollWidth,clientWidth}=containerRef.current;setIsRtl(getComputedStyle(containerRef.current).direction==="rtl");const scrollableThreshold=5;setIsScrollable(scrollWidth>clientWidth+scrollableThreshold);if(isRtl){setCanScrollStart(Math.abs(scrollLeft)<scrollWidth-clientWidth-scrollableThreshold);setCanScrollEnd(scrollLeft<-5);}else {setCanScrollStart(scrollLeft>scrollableThreshold);setCanScrollEnd(scrollLeft+clientWidth<scrollWidth-scrollableThreshold);}},[isRtl]);const scroll=direction=>{if(!containerRef.current){return}const scrollNegative=isRtl&&direction!=="start"||!isRtl&&direction==="start";const scrollAmount=scrollNegative?-100:SCROLL_DISTANCE;containerRef.current.scrollBy({left:scrollAmount,behavior:"smooth"});};React.useEffect(()=>{const container=containerRef.current;if(!container){return}updateScrollState();container.addEventListener("scroll",updateScrollState);window.addEventListener("resize",updateScrollState);return ()=>{container.removeEventListener("scroll",updateScrollState);window.removeEventListener("resize",updateScrollState);}},[children,updateScrollState]);const mergeStyle={overflowX:isScrollable&&overflowX==="auto"?"scroll":overflowX,overflowY:isScrollable&&overflowY==="auto"?"scroll":overflowY,scrollbarWidth:"thin",...style};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[canScrollEnd&&jsxRuntimeExports.jsx("div",{className:`${styles$E.scrollFade} ${isRtl?styles$E.scrollFadeRight:styles$E.scrollFadeLeft}`}),canScrollStart&&jsxRuntimeExports.jsx("div",{className:`${styles$E.scrollFade} ${isRtl?styles$E.scrollFadeLeft:styles$E.scrollFadeRight}`}),jsxRuntimeExports.jsx("div",{...additionalProps,role:role,className:className,style:mergeStyle,ref:containerRef,children:children}),isScrollable&&jsxRuntimeExports.jsx(ScrollButtons,{onScrollStart:()=>isRtl?scroll("end"):scroll("start"),onScrollEnd:()=>isRtl?scroll("start"):scroll("end"),canScrollStart:canScrollStart,canScrollEnd:canScrollEnd,scrollDescription:scrollDescription?scrollDescription:strings.scrollAnswers,isRTL:isRtl})]})}function ScrollButtons({onScrollStart,onScrollEnd,canScrollStart,canScrollEnd,scrollDescription,isRTL}){const{strings}=usePerseusI18n();return jsxRuntimeExports.jsxs("div",{className:styles$E.scrollButtonsContainer,children:[jsxRuntimeExports.jsx(IconButton__default.default,{icon:isRTL?caretRightIcon__default.default:caretLeftIcon__default.default,actionType:"neutral",kind:"secondary",size:"small",onClick:isRTL?onScrollEnd:onScrollStart,"aria-label":strings.scrollStart,disabled:isRTL?!canScrollEnd:!canScrollStart}),jsxRuntimeExports.jsx(IconButton__default.default,{icon:isRTL?caretLeftIcon__default.default:caretRightIcon__default.default,actionType:"neutral",kind:"secondary",size:"small",onClick:isRTL?onScrollStart:onScrollEnd,"aria-label":strings.scrollEnd,disabled:isRTL?!canScrollStart:!canScrollEnd}),jsxRuntimeExports.jsx(wonderBlocksTypography.LabelSmall,{children:scrollDescription})]})}
1733
-
1734
- if(typeof HTMLElement!=="undefined"&&!HTMLElement.prototype.scrollTo){HTMLElement.prototype.scrollTo=function(left,top){this.scrollLeft=left;this.scrollTop=top;};}const applyUniversalScrollOffset=(elementOrWindow,amount)=>{if(typeof elementOrWindow.scrollTo==="function"){elementOrWindow.scrollTo(0,amount);}else if("scrollTop"in elementOrWindow){elementOrWindow.scrollTop=amount;}};const scrollElementToOffset=(elementOrWindow,offset,duration=0,callback)=>{const startPosition=elementOrWindow===window?window.pageYOffset:elementOrWindow.scrollTop;const endPosition=offset;const scrollDistance=endPosition-startPosition;const tickLength=17;const numberOfSteps=duration/tickLength;let step=0;const scrollInterval=setInterval(function(){if(step<numberOfSteps){const x=step/numberOfSteps;const y=(-Math.cos(Math.PI*x)+1)/2;const newPosition=startPosition+scrollDistance*y;applyUniversalScrollOffset(elementOrWindow,newPosition);step+=1;}else {applyUniversalScrollOffset(elementOrWindow,endPosition);clearInterval(scrollInterval);}},tickLength);};const getScrollContainer=element=>{if(element===document.body){return window}if(element==null){return window}if(element.scrollHeight>element.clientHeight){return element}return getScrollContainer(element.parentElement)};const SCROLL_ANIMATION_DURATION=750;const scrollElementIntoView=(element,callback)=>{setTimeout(()=>{const scrollContainer=getScrollContainer(element);const childBounds=element.getBoundingClientRect();const containerBounds=scrollContainer===window?{top:0,bottom:window.innerHeight}:scrollContainer.getBoundingClientRect();let offset=0;const currentScrollTop=scrollContainer===window?window.scrollY:scrollContainer.scrollTop;if(childBounds.bottom>containerBounds.bottom){let distanceToScroll=childBounds.bottom-containerBounds.bottom;if(childBounds.top+distanceToScroll<containerBounds.top){distanceToScroll=childBounds.top-containerBounds.top;}offset=currentScrollTop+distanceToScroll;}else if(childBounds.top<containerBounds.top){const distanceToScroll=childBounds.top-containerBounds.top;offset=currentScrollTop+distanceToScroll;}scrollElementToOffset(scrollContainer,offset,SCROLL_ANIMATION_DURATION);},0);};
1735
-
1736
- const{pureXsMax,pureSmMax,pureMdMin,pureMdMax,pureLgMin,pureLgMax,pureXlMin}=constants;var mediaQueries = {md:`@media screen and (min-width: ${pureMdMin}) and `+`(max-width: ${pureMdMax})`,xl:`@media screen and (min-width: ${pureXlMin})`,xsOrSmaller:`@media screen and (max-width: ${pureXsMax})`,smOrSmaller:`@media screen and (max-width: ${pureSmMax})`,mdOrSmaller:`@media screen and (max-width: ${pureMdMax})`,lgOrSmaller:`@media screen and (max-width: ${pureLgMax})`,lgOrLarger:`@media screen and (min-width: ${pureLgMin})`};
1734
+ var styles$C = {"scrollButtonsContainer":"perseus_kjDHiWdD"};
1737
1735
 
1738
- const FocusRing=function({visible=true,color=kaGreen,multipleSelect=false,children}){const borderColor=visible?color:"transparent";const borderRadius=multipleSelect?5:"50%";const style={borderColor,borderRadius};return jsxRuntimeExports.jsx("span",{"data-testid":"focus-ring",className:aphrodite.css(styles$D.ring),style:style,children:children})};const styles$D=aphrodite.StyleSheet.create({ring:{margin:"auto",display:"inline-block",borderWidth:2,padding:2,borderStyle:"solid"}});
1736
+ const SCROLL_DISTANCE=100;function ScrollableView({overflowX,overflowY,children,className,scrollDescription,style,role="group",...additionalProps}){const{strings}=usePerseusI18n();const containerRef=React.useRef(null);const[isScrollable,setIsScrollable]=React.useState(false);const[canScrollStart,setCanScrollStart]=React.useState(false);const[canScrollEnd,setCanScrollEnd]=React.useState(false);const[isRtl,setIsRtl]=React.useState(false);const updateScrollState=React__namespace.useCallback(()=>{if(!containerRef.current){return}const{scrollLeft,scrollWidth,clientWidth}=containerRef.current;setIsRtl(getComputedStyle(containerRef.current).direction==="rtl");const scrollableThreshold=5;setIsScrollable(scrollWidth>clientWidth+scrollableThreshold);if(isRtl){setCanScrollStart(Math.abs(scrollLeft)<scrollWidth-clientWidth-scrollableThreshold);setCanScrollEnd(scrollLeft<-5);}else {setCanScrollStart(scrollLeft>scrollableThreshold);setCanScrollEnd(scrollLeft+clientWidth<scrollWidth-scrollableThreshold);}},[isRtl]);const scroll=direction=>{if(!containerRef.current){return}const scrollNegative=isRtl&&direction!=="start"||!isRtl&&direction==="start";const scrollAmount=scrollNegative?-100:SCROLL_DISTANCE;containerRef.current.scrollBy({left:scrollAmount,behavior:"smooth"});};React.useEffect(()=>{const container=containerRef.current;if(!container){return}updateScrollState();container.addEventListener("scroll",updateScrollState);window.addEventListener("resize",updateScrollState);return ()=>{container.removeEventListener("scroll",updateScrollState);window.removeEventListener("resize",updateScrollState);}},[children,updateScrollState]);const mergeStyle={overflowX:isScrollable&&overflowX==="auto"?"scroll":overflowX,overflowY:isScrollable&&overflowY==="auto"?"scroll":overflowY,scrollbarWidth:"thin",...style};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("div",{...additionalProps,role:role,className:className,style:mergeStyle,ref:containerRef,children:children}),isScrollable&&jsxRuntimeExports.jsx(ScrollButtons,{onScrollStart:()=>isRtl?scroll("end"):scroll("start"),onScrollEnd:()=>isRtl?scroll("start"):scroll("end"),canScrollStart:canScrollStart,canScrollEnd:canScrollEnd,scrollDescription:scrollDescription?scrollDescription:strings.scrollAnswers,isRTL:isRtl})]})}function ScrollButtons({onScrollStart,onScrollEnd,canScrollStart,canScrollEnd,scrollDescription,isRTL}){const{strings}=usePerseusI18n();return jsxRuntimeExports.jsxs("div",{className:styles$C.scrollButtonsContainer,children:[jsxRuntimeExports.jsx(IconButton__default.default,{icon:isRTL?caretRightIcon__default.default:caretLeftIcon__default.default,actionType:"neutral",kind:"secondary",size:"small",onClick:isRTL?onScrollEnd:onScrollStart,"aria-label":strings.scrollStart,disabled:isRTL?!canScrollEnd:!canScrollStart}),jsxRuntimeExports.jsx(IconButton__default.default,{icon:isRTL?caretLeftIcon__default.default:caretRightIcon__default.default,actionType:"neutral",kind:"secondary",size:"small",onClick:isRTL?onScrollStart:onScrollEnd,"aria-label":strings.scrollEnd,disabled:isRTL?!canScrollStart:!canScrollEnd}),jsxRuntimeExports.jsx(wonderBlocksTypography.LabelSmall,{children:scrollDescription})]})}
1739
1737
 
1740
- function getChoiceLetter$1(pos,strings){const lettersString=strings.letters;const letters=lettersString.split(" ");if(pos<letters.length){return letters[pos]}return " "}function getUserInputFromSerializedState$f(props,unshuffle=true){if(props.choiceStates){const choiceStates=props.choiceStates;const choicesSelected=choiceStates.map(()=>false);for(let i=0;i<choicesSelected.length;i++){const index=unshuffle?props.choices[i].originalIndex:i;choicesSelected[index]=choiceStates[i].selected;}return {choicesSelected}}const{values}=props;if(values){const choicesSelected=[...values];const valuesLength=values.length;for(let i=0;i<valuesLength;i++){const index=unshuffle?props.choices[i].originalIndex:i;choicesSelected[index]=values[i];}return {choicesSelected}}return {choicesSelected:props.choices.map(()=>false)}}
1738
+ var styles$B = {"base":"perseus_C4cWo-dY","is-correct":"perseus_vWc7XkhJ","isCorrect":"perseus_vWc7XkhJ","is-wrong":"perseus_yVmsF9sA","isWrong":"perseus_yVmsF9sA","icon":"perseus_brEUCVvd","circle-shape":"perseus_irgRpkgB","circleShape":"perseus_irgRpkgB","square-shape":"perseus_JsUZt48D","squareShape":"perseus_JsUZt48D"};
1741
1739
 
1742
- const CHOICE_ICON_SIZE$1=24;const styles$C={iconWrapper:{display:"inline-block",position:"relative",background:"linear-gradient(to right, white 10%, transparent)"}};
1740
+ const Indicator=props=>{const{checked,showCorrectness}=props;const iconImage=checked&&showCorrectness==="correct"?checkIcon__default.default:checked&&showCorrectness==="wrong"?minusIcon__default.default:undefined;const icon=iconImage?jsxRuntimeExports.jsx(wonderBlocksIcon.PhosphorIcon,{"aria-hidden":true,className:styles$B.icon,icon:iconImage,role:"img"}):undefined;const classes=[styles$B.base,styles$B[props.shape+"-shape"]];if(showCorrectness){classes.push(styles$B["is-"+showCorrectness]);}const handleClick=showCorrectness?undefined:event=>{event.stopPropagation();props.updateChecked(!checked);};return jsxRuntimeExports.jsxs("button",{"aria-pressed":checked,className:classes.join(" "),type:"button",ref:props.buttonRef,onClick:handleClick,children:[icon,props.content]})};
1743
1741
 
1744
- function ChoiceInner$1(props){const{pos,showCorrectness,correct}=props;const{strings}=usePerseusI18n();const letter=getChoiceLetter$1(pos,strings);if(!showCorrectness){return jsxRuntimeExports.jsx("span",{children:letter})}if(correct){return jsxRuntimeExports.jsx(InlineIcon,{...iconCheck,style:{position:"relative",top:-1}})}return jsxRuntimeExports.jsx(InlineIcon,{...iconMinus})}const ChoiceIcon$1=function(props){const{checked,showCorrectness,correct,focused,hovered,multipleSelect,pos,previouslyAnswered,pressed}=props;const choiceIsChecked=checked||showCorrectness&&!correct&&previouslyAnswered;const choiceStyling=[styles$B.choiceBase,multipleSelect?styles$B.multiSelectShape:styles$B.singleSelectShape,showCorrectness?styles$B.choiceHasIcon:styles$B.choiceHasLetter,choiceIsChecked?styles$B.choiceIsChecked:styles$B.choiceIsUnchecked];if(showCorrectness&&correct&&checked){choiceStyling.push(styles$B.choiceCorrect);}else if(showCorrectness&&!correct&&(checked||previouslyAnswered)){choiceStyling.push(styles$B.choiceIncorrect);}else if(checked){choiceStyling.push(styles$B.choiceNeutral);}else if(pressed){choiceStyling.push(styles$B.activeNeutral);}else {choiceStyling.push(styles$B.uncheckedColors);}return jsxRuntimeExports.jsx("div",{style:styles$C.iconWrapper,children:jsxRuntimeExports.jsx(FocusRing,{color:wonderBlocksTokens.color.blue,visible:focused||hovered,multipleSelect:multipleSelect,children:jsxRuntimeExports.jsx("div",{"data-testid":"choice-icon__library-choice-icon",className:aphrodite.css(...choiceStyling),"data-is-radio-icon":true,children:jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$B.innerWrapper),children:jsxRuntimeExports.jsx(ChoiceInner$1,{pos:pos,showCorrectness:showCorrectness,correct:correct})})})})})};const styles$B=aphrodite.StyleSheet.create({innerWrapper:{width:CHOICE_ICON_SIZE$1,height:CHOICE_ICON_SIZE$1,display:"flex",alignItems:"center",justifyContent:"center"},choiceBase:{width:CHOICE_ICON_SIZE$1,height:CHOICE_ICON_SIZE$1,boxSizing:"border-box",borderStyle:"solid",borderWidth:2,fontFamily:baseFontFamily,fontWeight:"bold",display:"flex",alignItems:"center",justifyContent:"center",background:wonderBlocksTokens.color.white},choiceHasLetter:{fontSize:12},choiceHasIcon:{fontSize:CHOICE_ICON_SIZE$1},choiceIsChecked:{color:wonderBlocksTokens.color.white},choiceIsUnchecked:{color:wonderBlocksTokens.color.offBlack64},choiceCorrect:{backgroundColor:wonderBlocksTokens.color.green,borderColor:wonderBlocksTokens.color.green},choiceIncorrect:{backgroundColor:wonderBlocksTokens.color.red,borderColor:wonderBlocksTokens.color.red},choiceNeutral:{backgroundColor:wonderBlocksTokens.color.blue,borderColor:wonderBlocksTokens.color.blue},activeNeutral:{color:wonderBlocksTokens.color.blue,borderColor:wonderBlocksTokens.color.blue,backgroundColor:"transparent"},multiSelectShape:{borderRadius:3},singleSelectShape:{borderRadius:CHOICE_ICON_SIZE$1},uncheckedColors:{borderColor:wonderBlocksTokens.color.offBlack64}});
1742
+ var styles$A = {"choice":"perseus_hm3uu-sq","is-correct":"perseus_qpU2z5U7","isCorrect":"perseus_qpU2z5U7","is-wrong":"perseus_dUXUrBDI","isWrong":"perseus_dUXUrBDI"};
1745
1743
 
1746
- const getChoiceLetter=(pos,strings)=>{const lettersString=strings.letters;const letters=lettersString.split(" ");if(pos<letters.length){return letters[pos]}return " "};const getOptionStatusText=({checked,correct,strings})=>{if(correct){if(checked){return strings.correctSelected}return strings.correct}if(checked){return strings.incorrectSelected}return strings.incorrect};const getInstructionsText$1=({multipleSelect,countChoices,numCorrect,strings})=>{if(multipleSelect){if(perseusCore.usesNumCorrect(multipleSelect,!!countChoices,numCorrect)){return strings.chooseNumAnswers({numCorrect:String(numCorrect)})}return strings.chooseAllAnswers}return strings.chooseOneAnswer};const getA11yText$1=({letter,checked,correct,showCorrectness,strings})=>{if(showCorrectness&&correct){if(checked){return strings.choiceCheckedCorrect({letter})}return strings.choiceCorrect({letter})}if(showCorrectness&&!correct){if(checked){return strings.choiceCheckedIncorrect({letter})}return strings.choiceIncorrect({letter})}if(checked){return strings.choiceChecked({letter})}return strings.choice({letter})};
1744
+ const Choice$2=props=>{const showCorrectness=props.showCorrectness;const buttonRef=React.useRef(null);const indicatorShape=props.isMultiSelect?"square":"circle";const clickHandler=showCorrectness?undefined:()=>{buttonRef.current?.click();};const classes=[styles$A.choice].concat(showCorrectness?[styles$A["is-"+showCorrectness]]:[]).join(" ");return jsxRuntimeExports.jsxs("li",{className:classes,onClick:clickHandler,children:[jsxRuntimeExports.jsx(Indicator,{buttonRef:buttonRef,checked:props.checked,content:props.indicatorContent,shape:indicatorShape,showCorrectness:showCorrectness,updateChecked:props.updateChecked}),props.children]})};
1747
1745
 
1748
- const OptionStatus$1=({checked,correct,previouslyAnswered,reviewMode})=>{const{strings}=usePerseusI18n();if(!reviewMode&&!previouslyAnswered){return null}let textStyle;if(correct){textStyle=styles$A.correct;}else {if(checked||previouslyAnswered){textStyle=styles$A.incorrectAnswered;}else {textStyle=styles$A.incorrect;}}return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$A.text,textStyle),children:getOptionStatusText({checked,correct,strings})})};const styles$A=aphrodite.StyleSheet.create({text:{alignItems:"center",display:"flex",fontSize:12,height:32,textTransform:"uppercase",textAlign:"start"},correct:{color:wonderBlocksTokens.color.green},incorrectAnswered:{color:wonderBlocksTokens.color.red},incorrect:{color:wonderBlocksTokens.color.offBlack64}});
1746
+ var styles$z = {"container":"perseus_dzsult1u","choiceList":"perseus_HSvzOAAR","content":"perseus_A5d7KcQj","instructions":"perseus_skOlpdjN","rationale":"perseus_y4m8wyRd","isCorrect":"perseus_IfCbxIVP","reviewAnswers":"perseus_QYlQJ6BF"};
1749
1747
 
1750
- const intermediateCheckboxPadding$1=`16px 16px`;const intermediateCheckboxPaddingPhone$1=`12px 16px`;const Choice$2=React__namespace.forwardRef(function ChoiceWithRef({disabled=false,checked=false,content,showCorrectness,multipleSelect,onChange=newValues=>{},reviewMode,correct=false,apiOptions=ApiOptions.defaults,previouslyAnswered=false,pos=0,showRationale=false,rationale},ref){const[isInputFocused,setIsInputFocused]=React.useState(false);const{strings}=usePerseusI18n();React.useEffect(()=>{if(isInputFocused&&disabled){setIsInputFocused(false);}},[disabled,isInputFocused,setIsInputFocused]);function sendChange(newValues){const updatedChecked=newValues.checked??checked;onChange({checked:updatedChecked});}const descriptionClassName=classNames__default.default("description");const rationaleClassName=classNames__default.default("perseus-radio-rationale-content");const showDimmed=!reviewMode&&apiOptions.readOnly;const letter=getChoiceLetter(pos,strings);const a11yText=getA11yText$1({letter,checked,correct,showCorrectness,strings});return jsxRuntimeExports.jsxs("div",{className:descriptionClassName,style:styles$z.description,children:[jsxRuntimeExports.jsxs("div",{style:{...styles$z.choicesContainer,opacity:showDimmed?.5:1},children:[jsxRuntimeExports.jsx("div",{className:"perseus-sr-only",children:jsxRuntimeExports.jsxs("label",{children:[a11yText,"   ",content,jsxRuntimeExports.jsx("input",{type:multipleSelect?"checkbox":"radio",checked:checked,onClick:()=>{sendChange({checked:!checked});},onChange:()=>{},disabled:disabled||apiOptions.readOnly,tabIndex:-1,className:ClassNames.RADIO.OPTION_CONTENT})]})}),jsxRuntimeExports.jsx(Clickable__default.default,{onClick:()=>{sendChange({checked:!checked});},disabled:disabled||apiOptions.readOnly,style:styles$z.optionContainer,ref:ref,"aria-hidden":"true",hideDefaultFocusRing:true,children:({hovered,focused,pressed})=>jsxRuntimeExports.jsxs("div",{style:styles$z.choiceRow,children:[jsxRuntimeExports.jsx("div",{style:styles$z.choiceIcon,children:jsxRuntimeExports.jsx(ChoiceIcon$1,{pos:pos,correct:correct,pressed:pressed,focused:focused,checked:checked,hovered:hovered,showCorrectness:showCorrectness,multipleSelect:multipleSelect,reviewMode:reviewMode,previouslyAnswered:previouslyAnswered})}),jsxRuntimeExports.jsxs("span",{style:styles$z.choiceContent,children:[jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsx(OptionStatus$1,{checked:checked,correct:correct,previouslyAnswered:previouslyAnswered,reviewMode:reviewMode})}),jsxRuntimeExports.jsx("div",{children:content})]})]})})]}),showRationale&&jsxRuntimeExports.jsx("div",{className:rationaleClassName,style:styles$z.rationale,"data-testid":`perseus-radio-rationale-content-${pos}`,children:rationale})]})});const styles$z={description:{display:"inline-block",width:"100%",flexDirection:"column",color:wonderBlocksTokens.color.offBlack},choicesContainer:{display:"flex"},optionContainer:{flex:1,color:wonderBlocksTokens.color.offBlack,userSelect:"text"},choiceRow:{display:"flex",flexDirection:"row",justifyContent:"flex-start",alignItems:"center",paddingBlock:wonderBlocksTokens.spacing.xSmall_8,paddingInlineStart:wonderBlocksTokens.spacing.xSmall_8,position:"relative",minWidth:"100%",insetInlineStart:0,height:"100%",background:wonderBlocksTokens.color.white64},choiceIcon:{flexGrow:0,flexShrink:0,flexBasis:"30px",position:"sticky",insetInlineStart:0,background:"linear-gradient(to right, white 70%, transparent)",":dir(rtl)":{background:"linear-gradient(to left, white 70%, transparent)"},paddingInlineStart:wonderBlocksTokens.spacing.xSmall_8,paddingInlineEnd:wonderBlocksTokens.spacing.xSmall_8,paddingTop:wonderBlocksTokens.spacing.xxxSmall_4,zIndex:1,alignItems:"center",justifyContent:"center",height:"100%"},choiceContent:{paddingInlineStart:wonderBlocksTokens.spacing.small_12,textAlign:"start",flex:1,paddingTop:wonderBlocksTokens.spacing.xxxSmall_4,minWidth:0},rationale:{display:"block",padding:intermediateCheckboxPadding$1,paddingTop:0,marginInlineStart:54,color:wonderBlocksTokens.color.offBlack64,[mediaQueries.smOrSmaller]:{padding:intermediateCheckboxPaddingPhone$1,paddingTop:0}}};
1748
+ function getChoiceLetter(pos,strings){const lettersString=strings.letters;const letters=lettersString.split(" ");if(pos<letters.length){return letters[pos]}return " "}function getUserInputFromSerializedState$f(props,unshuffle=true){if(props.choiceStates){const choiceStates=props.choiceStates;const choicesSelected=choiceStates.map(()=>false);for(let i=0;i<choicesSelected.length;i++){const index=unshuffle?props.choices[i].originalIndex:i;choicesSelected[index]=choiceStates[i].selected;}return {choicesSelected}}const{values}=props;if(values){const choicesSelected=[...values];const valuesLength=values.length;for(let i=0;i<valuesLength;i++){const index=unshuffle?props.choices[i].originalIndex:i;choicesSelected[index]=values[i];}return {choicesSelected}}return {choicesSelected:props.choices.map(()=>false)}}
1751
1749
 
1752
- const ChoiceNoneAbove$2=React__namespace.forwardRef(function ChoiceNoneAboveWithRef({content,showContent=true,...otherChoiceProps},forwardedRef){const{strings}=usePerseusI18n();const choiceProps={...otherChoiceProps,content:showContent?content:jsxRuntimeExports.jsx(Renderer,{content:strings.noneOfTheAbove,strings:strings},"noneOfTheAboveRenderer")};return jsxRuntimeExports.jsx(Choice$2,{...choiceProps,ref:forwardedRef})});
1750
+ const getInstructionsText$1=({multipleSelect,countChoices,numCorrect,strings})=>{if(multipleSelect){if(perseusCore.usesNumCorrect(multipleSelect,!!countChoices,numCorrect)){return strings.chooseNumAnswers({numCorrect:String(numCorrect)})}return strings.chooseAllAnswers}return strings.chooseOneAnswer};
1753
1751
 
1754
- var styles$y = {"instructions":"perseus_skOlpdjN","choiceList":"perseus_z99pdFDb","item":"perseus_LIclTOkz","responsiveItem":"perseus_3CbdqYKp","selectedItem":"perseus_5aX6Caaw","responsiveContainer":"perseus_sGfTgWhS","responsiveFieldset":"perseus_JupKA3Xd"};
1755
-
1756
- const{captureScratchpadTouchStart: captureScratchpadTouchStart$2}=Util;const MultipleChoiceComponent=({apiOptions,reviewModeRubric,reviewMode,editMode=false,multipleSelect=false,labelWrap,countChoices,numCorrect,isLastUsedWidget,choices,onChoiceChange})=>{const{strings}=usePerseusI18n();const choiceRefs=React.useRef([]);const prevReviewModeRubric=React.useRef();React.useEffect(()=>{if(apiOptions.canScrollPage&&isLastUsedWidget&&reviewModeRubric&&!prevReviewModeRubric.current){const checkedIndex=choices.findIndex(c=>c.checked);if(checkedIndex>=0){const ref=choiceRefs.current[checkedIndex];if(ref.current){scrollElementIntoView(ref.current);}}}prevReviewModeRubric.current=reviewModeRubric;},[apiOptions,isLastUsedWidget,reviewModeRubric,choices]);const choiceListClassName=classNames__default.default("perseus-widget-radio",!editMode&&"perseus-rendered-radio",styles$y.choiceList);const instructionsClassName=classNames__default.default(styles$y.instructions);const instructions=getInstructionsText$1({multipleSelect,countChoices,numCorrect,strings});const fieldset=jsxRuntimeExports.jsxs("fieldset",{className:`perseus-widget-radio-fieldset ${styles$y.responsiveFieldset}`,"data-feature-flag":"feature flag is ON",children:[jsxRuntimeExports.jsx("legend",{className:"perseus-sr-only",children:instructions}),jsxRuntimeExports.jsx("div",{className:instructionsClassName,"aria-hidden":"true",children:instructions}),jsxRuntimeExports.jsx(ScrollableView,{overflowX:"auto",children:jsxRuntimeExports.jsx("ul",{className:choiceListClassName,children:choices.map((choice,i)=>{let Element=Choice$2;const ref=React__namespace.createRef();choiceRefs.current[i]=ref;const elementProps={apiOptions:apiOptions,multipleSelect:multipleSelect,checked:choice.checked,previouslyAnswered:choice.previouslyAnswered,reviewMode,correct:choice.correct,rationale:choice.rationale,content:choice.content,disabled:apiOptions.readOnly||choice.disabled,showCorrectness:reviewMode||!!choice.showCorrectness,showRationale:choice.hasRationale&&(reviewMode||choice.showRationale),pos:i,onChange:newValues=>{if(editMode){return}onChoiceChange(i,newValues.checked);}};if(choice.isNoneOfTheAbove){Element=ChoiceNoneAbove$2;___default.default.extend(elementProps,{showContent:choice.revealNoneOfTheAbove});}const itemClassName=classNames__default.default(styles$y.item,styles$y.responsiveItem,choice.checked&&styles$y.selectedItem);let correctnessClass;if(reviewMode&&reviewModeRubric){correctnessClass=reviewModeRubric.choices[i].correct?ClassNames.CORRECT:ClassNames.INCORRECT;}const className=classNames__default.default(itemClassName,ClassNames.RADIO.OPTION,choice.checked&&ClassNames.RADIO.SELECTED,correctnessClass);let listElem=null;let clickHandler;if(editMode){clickHandler=e=>{let elem=e.target;while(elem&&elem!==listElem){if(elem.getAttribute("data-is-radio-icon")){onChoiceChange(i,!choice.checked);return}elem=elem.parentNode;}};}return jsxRuntimeExports.jsx("li",{ref:e=>listElem=e,className:className,onClick:clickHandler,onTouchStart:labelWrap?undefined:captureScratchpadTouchStart$2,children:jsxRuntimeExports.jsx(Element,{...elementProps,ref:ref})},i)})})})]});return jsxRuntimeExports.jsx("div",{className:styles$y.responsiveContainer,children:fieldset})};
1752
+ const MultipleChoiceComponent=({choices,countChoices,multipleSelect=false,numCorrect,onChoiceChange,reviewMode})=>{const{strings}=usePerseusI18n();const instructions=getInstructionsText$1({multipleSelect,countChoices,numCorrect,strings});const choiceListClasses=reviewMode?`${styles$z.choiceList} ${styles$z.reviewAnswers}`:styles$z.choiceList;return jsxRuntimeExports.jsxs("fieldset",{className:styles$z.container,"data-feature-flag":"feature flag is ON",children:[jsxRuntimeExports.jsx("legend",{className:styles$z.instructions,children:instructions}),jsxRuntimeExports.jsx(ScrollableView,{overflowX:"auto",children:jsxRuntimeExports.jsx("ul",{className:choiceListClasses,children:jsxRuntimeExports.jsx(ChoiceListItems,{choices:choices,i18nStrings:strings,onChoiceChange:onChoiceChange,reviewMode:reviewMode,multipleSelect:multipleSelect})})})]})};const ChoiceListItems=props=>{const{choices,i18nStrings,multipleSelect,onChoiceChange,reviewMode}=props;const items=choices.map((choice,i)=>{const updateChecked=isChecked=>{onChoiceChange(i,isChecked);};const choiceLetter=getChoiceLetter(i,i18nStrings);const showCorrectness=reviewMode===true?choice.correct?"correct":"wrong":undefined;const content=choice.isNoneOfTheAbove?i18nStrings.noneOfTheAbove:choice.content;const rationaleClasses=[styles$z.rationale].concat(showCorrectness==="correct"?[styles$z.isCorrect]:[]).join(" ");const rationale=reviewMode&&choice.hasRationale?jsxRuntimeExports.jsx("div",{className:rationaleClasses,children:choice.rationale}):undefined;return jsxRuntimeExports.jsx(Choice$2,{checked:choice.checked,indicatorContent:choiceLetter,isMultiSelect:multipleSelect,showCorrectness:showCorrectness,updateChecked:updateChecked,children:jsxRuntimeExports.jsxs("div",{className:styles$z.content,children:[content,rationale]})},choice.id)});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:items})};
1757
1753
 
1758
1754
  const getPromptJSON$p=renderProps=>{return {type:"passage-ref",options:{passageNumber:renderProps.passageNumber,referenceNumber:renderProps.referenceNumber,summaryText:renderProps.summaryText}}};
1759
1755
 
@@ -1763,9 +1759,9 @@ function addHighlight(existingHighlights,newHighlight){const newHighlights={};le
1763
1759
 
1764
1760
  function getRelativePosition(child,parent){return {left:child.left-parent.left,top:child.top-parent.top}}function getRelativeRect({left,top,width,height},parent){return {...getRelativePosition({left,top},parent),width,height}}function getClientRectsForTextInRange(range){const mutableRects=[];addClientRectsForTextInNodeAndRange(range.commonAncestorContainer,range,mutableRects);return mutableRects}function addClientRectsForTextInNodeAndRange(node,range,mutableRects){const nodeContentsRange=new Range;nodeContentsRange.selectNodeContents(node);if(node.nodeType===Node.TEXT_NODE){const intersectedRange=intersectRanges(range,nodeContentsRange);if(intersectedRange){addClientRectsForText(node,intersectedRange,mutableRects);}}else if(node.nodeType===Node.ELEMENT_NODE){if(!rangesOverlap(range,nodeContentsRange)){return}for(const child of Array.from(node.childNodes)){addClientRectsForTextInNodeAndRange(child,range,mutableRects);}}}function addClientRectsForText(textNode,textRange,mutableRects){const parentElement=textNode.parentElement;const computedStyle=window.getComputedStyle(parentElement);let lineHeight=null;if(typeof computedStyle.lineHeight==="string"&&computedStyle.lineHeight.endsWith("px")){const parsedLineHeight=parseFloat(computedStyle.lineHeight);if(!isNaN(parsedLineHeight)){lineHeight=parsedLineHeight;}}const boundingRects=Array.from(textRange.getClientRects());for(const boundingRect of boundingRects){const rect={left:boundingRect.left,top:boundingRect.top,height:boundingRect.height,width:boundingRect.width};if(lineHeight!==null){const heightIncrease=lineHeight-rect.height;rect.top-=heightIncrease;rect.height=lineHeight;}mutableRects.push(rect);}}
1765
1761
 
1766
- class HighlightRenderer extends React__namespace.PureComponent{UNSAFE_componentWillReceiveProps(nextProps){if(this.props.highlight!==nextProps.highlight||this.props.offsetParent!==nextProps.offsetParent){this.setState({cachedHighlightRects:this._computeRects(nextProps)});}}_computeRects(props){const{highlight,offsetParent}=props;const clientRects=getClientRectsForTextInRange(highlight.domRange);const{left,top}=offsetParent.getBoundingClientRect();const relativeRects=clientRects.map(rect=>getRelativeRect(rect,{left,top}));return relativeRects}_rectIsHovered(rect,mouseOffsetPosition){const positionWithinRect=getRelativePosition(mouseOffsetPosition,{left:rect.left,top:rect.top});return 0<=positionWithinRect.left&&positionWithinRect.left<rect.width&&0<=positionWithinRect.top&&positionWithinRect.top<rect.height}isHovered(mouseClientPosition){if(!mouseClientPosition){return false}const{offsetParent}=this.props;const{cachedHighlightRects}=this.state;const{left,top}=offsetParent.getBoundingClientRect();const mouseOffsetPosition=getRelativePosition(mouseClientPosition,{left,top});return cachedHighlightRects.some(rect=>this._rectIsHovered(rect,mouseOffsetPosition))}render(){const rects=this.state.cachedHighlightRects;return jsxRuntimeExports.jsx("div",{children:rects.map((rect,index)=>jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$x.highlightRect),style:{position:"absolute",width:rect.width,height:rect.height,top:rect.top,left:rect.left,zIndex:this.props.zIndexes.belowContent}},index))})}constructor(...args){super(...args),this.state={cachedHighlightRects:this._computeRects(this.props),tooltipIsHovered:false};}}const styles$x=aphrodite.StyleSheet.create({highlightRect:{background:"#fffabe"}});
1762
+ class HighlightRenderer extends React__namespace.PureComponent{UNSAFE_componentWillReceiveProps(nextProps){if(this.props.highlight!==nextProps.highlight||this.props.offsetParent!==nextProps.offsetParent){this.setState({cachedHighlightRects:this._computeRects(nextProps)});}}_computeRects(props){const{highlight,offsetParent}=props;const clientRects=getClientRectsForTextInRange(highlight.domRange);const{left,top}=offsetParent.getBoundingClientRect();const relativeRects=clientRects.map(rect=>getRelativeRect(rect,{left,top}));return relativeRects}_rectIsHovered(rect,mouseOffsetPosition){const positionWithinRect=getRelativePosition(mouseOffsetPosition,{left:rect.left,top:rect.top});return 0<=positionWithinRect.left&&positionWithinRect.left<rect.width&&0<=positionWithinRect.top&&positionWithinRect.top<rect.height}isHovered(mouseClientPosition){if(!mouseClientPosition){return false}const{offsetParent}=this.props;const{cachedHighlightRects}=this.state;const{left,top}=offsetParent.getBoundingClientRect();const mouseOffsetPosition=getRelativePosition(mouseClientPosition,{left,top});return cachedHighlightRects.some(rect=>this._rectIsHovered(rect,mouseOffsetPosition))}render(){const rects=this.state.cachedHighlightRects;return jsxRuntimeExports.jsx("div",{children:rects.map((rect,index)=>jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$y.highlightRect),style:{position:"absolute",width:rect.width,height:rect.height,top:rect.top,left:rect.left,zIndex:this.props.zIndexes.belowContent}},index))})}constructor(...args){super(...args),this.state={cachedHighlightRects:this._computeRects(this.props),tooltipIsHovered:false};}}const styles$y=aphrodite.StyleSheet.create({highlightRect:{background:"#fffabe"}});
1767
1763
 
1768
- class HighlightTooltip extends React__namespace.PureComponent{_getFocusRect(){const{focusNode,focusOffset,offsetParent}=this.props;const focusRange=document.createRange();focusRange.setStart(focusNode,focusOffset);focusRange.setEnd(focusNode,focusOffset);const focusRect=focusRange.getClientRects()[0];if(!focusRect){Log.log("[Highlighting] Known bug: Could not determine the focus "+'position, so did not show an "Add Highlight" tooltip. '+"https://app.asana.com/0/329800276300868/413878480039713 "+"(see also /r/asana-links)");return null}const{left,top}=offsetParent.getBoundingClientRect();const relativeFocusRect=getRelativeRect({left:focusRect.left,top:focusRect.top,width:focusRect.width,height:focusRect.height},{left,top});return relativeFocusRect}render(){const focusRect=this._getFocusRect();if(!focusRect){return null}const content=jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$w.tooltipLabel),onClick:this.props.onClick,children:this.props.label});const style={position:"absolute",left:focusRect.left,top:`calc(${Math.round(focusRect.top)}px + 0.95em)`,height:0};return jsxRuntimeExports.jsx("div",{style:style,onMouseEnter:this.props.onMouseEnter,onMouseLeave:this.props.onMouseLeave,children:jsxRuntimeExports.jsx(Tooltip__default.default,{content:content,opened:true,children:jsxRuntimeExports.jsx("div",{})})})}}const styles$w=aphrodite.StyleSheet.create({tooltipLabel:{userSelect:"none",fontFamily:`"Lato", sans-serif`,padding:`10px ${wonderBlocksTokens.spacing.medium_16}px`,cursor:"pointer"}});
1764
+ class HighlightTooltip extends React__namespace.PureComponent{_getFocusRect(){const{focusNode,focusOffset,offsetParent}=this.props;const focusRange=document.createRange();focusRange.setStart(focusNode,focusOffset);focusRange.setEnd(focusNode,focusOffset);const focusRect=focusRange.getClientRects()[0];if(!focusRect){Log.log("[Highlighting] Known bug: Could not determine the focus "+'position, so did not show an "Add Highlight" tooltip. '+"https://app.asana.com/0/329800276300868/413878480039713 "+"(see also /r/asana-links)");return null}const{left,top}=offsetParent.getBoundingClientRect();const relativeFocusRect=getRelativeRect({left:focusRect.left,top:focusRect.top,width:focusRect.width,height:focusRect.height},{left,top});return relativeFocusRect}render(){const focusRect=this._getFocusRect();if(!focusRect){return null}const content=jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$x.tooltipLabel),onClick:this.props.onClick,children:this.props.label});const style={position:"absolute",left:focusRect.left,top:`calc(${Math.round(focusRect.top)}px + 0.95em)`,height:0};return jsxRuntimeExports.jsx("div",{style:style,onMouseEnter:this.props.onMouseEnter,onMouseLeave:this.props.onMouseLeave,children:jsxRuntimeExports.jsx(Tooltip__default.default,{content:content,opened:true,children:jsxRuntimeExports.jsx("div",{})})})}}const styles$x=aphrodite.StyleSheet.create({tooltipLabel:{userSelect:"none",fontFamily:`"Lato", sans-serif`,padding:`10px ${wonderBlocksTokens.spacing.medium_16}px`,cursor:"pointer"}});
1769
1765
 
1770
1766
  class HighlightSetRenderer extends React__namespace.PureComponent{componentDidMount(){this._updateEditListeners(false,this.props.editable);}UNSAFE_componentWillReceiveProps(nextProps){this._updateEditListeners(this.props.editable,nextProps.editable);if(this.state.hoveredHighlightKey!=null&&!(this.state.hoveredHighlightKey in nextProps.highlights)){this.setState({hoveredHighlightKey:null});}if(this.state.hoveringTooltipFor!=null&&!(this.state.hoveringTooltipFor in nextProps.highlights)){this.setState({hoveringTooltipFor:null});}}componentWillUnmount(){this._updateEditListeners(this.props.editable,false);}_updateEditListeners(wasListening,willListen){if(!wasListening&&willListen){window.addEventListener("mousemove",this._handleMouseMove);}else if(wasListening&&!willListen){window.removeEventListener("mousemove",this._handleMouseMove);this.setState({hoveredHighlightKey:null,hoveringTooltipFor:null});}}_getHoveredHighlightKey(mouseClientPosition){const{hoveringTooltipFor}=this.state;if(typeof hoveringTooltipFor==="string"){return hoveringTooltipFor}const highlightKeys=Object.keys(this.props.highlights);return highlightKeys.find(key=>{const highlightRenderer=this._highlightRenderers[key];return highlightRenderer&&highlightRenderer.isHovered(mouseClientPosition)})}_renderTooltip(){const{hoveredHighlightKey}=this.state;if(hoveredHighlightKey==null){return null}const hoveredHighlight=this.props.highlights[hoveredHighlightKey];return jsxRuntimeExports.jsx(HighlightTooltip,{label:this.context.strings.removeHighlight,focusNode:hoveredHighlight.domRange.endContainer,focusOffset:hoveredHighlight.domRange.endOffset,offsetParent:this.props.offsetParent,onClick:()=>this.props.onRemoveHighlight(hoveredHighlightKey),onMouseEnter:()=>this.setState({hoveringTooltipFor:hoveredHighlightKey}),onMouseLeave:()=>this.setState({hoveringTooltipFor:null})})}render(){return jsxRuntimeExports.jsxs("div",{children:[Object.keys(this.props.highlights).map(key=>jsxRuntimeExports.jsx(HighlightRenderer,{ref:r=>{if(r){this._highlightRenderers[key]=r;}else {delete this._highlightRenderers[key];}},highlight:this.props.highlights[key],highlightKey:key,offsetParent:this.props.offsetParent,zIndexes:this.props.zIndexes},key)),this.props.editable&&this._renderTooltip()]})}constructor(...args){super(...args),this.state={hoveredHighlightKey:null,hoveringTooltipFor:null},this._highlightRenderers={},this._handleMouseMove=e=>{const mouseClientPosition={left:e.clientX,top:e.clientY};const hoveredHighlightKey=this._getHoveredHighlightKey(mouseClientPosition);this.setState({hoveredHighlightKey});};}}HighlightSetRenderer.contextType=PerseusI18nContext;
1771
1767
 
@@ -1775,41 +1771,47 @@ class HighlightingUI extends React__namespace.PureComponent{_handleAddHighlight(
1775
1771
 
1776
1772
  class WordIndexer extends React__namespace.PureComponent{componentDidMount(){this._sendWordsUpdate();}componentDidUpdate(){this._sendWordsUpdate();}_sendWordsUpdate(){this.props.onWordsUpdate(this._getWordRanges());}_getWordRanges(){const container=this._container;if(!container){throw new perseusCore.PerseusError("invariant violation: `this._container` is not defined, but "+"this method is only called after mount/update",perseusCore.Errors.NotAllowed)}const treeWalker=container.ownerDocument.createTreeWalker(container,NodeFilter.SHOW_TEXT|NodeFilter.SHOW_ELEMENT,()=>NodeFilter.FILTER_ACCEPT,false);const index=[];let trailingWordRange=null;while(treeWalker.nextNode()){const node=treeWalker.currentNode;if(node.nodeType===Node.ELEMENT_NODE){const element=node;if(getComputedStyle(element).display!=="inline"){trailingWordRange=null;}}else if(node.nodeType===Node.TEXT_NODE){const text=node.nodeValue;const wordPattern=/\S+/g;let wordMatch;let newTrailingWordRange=null;while((wordMatch=wordPattern.exec(text))!==null){const startOffset=wordMatch.index;const endOffset=wordMatch.index+wordMatch[0].length;let range;if(startOffset===0&&trailingWordRange){range=trailingWordRange;range.setEnd(node,endOffset);}else {range=node.ownerDocument.createRange();range.setStart(node,startOffset);range.setEnd(node,endOffset);index.push(range);}if(endOffset===text.length){newTrailingWordRange=range;}}trailingWordRange=newTrailingWordRange;}}return index}render(){return jsxRuntimeExports.jsx("div",{ref:container=>this._container=container,children:this.props.children})}}
1777
1773
 
1778
- class HighlightableContent extends React__namespace.PureComponent{_buildHighlight(highlightRange){return buildHighlight(this._getDOMHighlights(),this.state.wordRanges,highlightRange)}_getDOMHighlights(){const{serializedHighlights}=this.props;const{wordRanges}=this.state;const domHighlights={};for(const key of Object.keys(serializedHighlights)){domHighlights[key]=deserializeHighlight(serializedHighlights[key],wordRanges);}return domHighlights}render(){const highlights=this._getDOMHighlights();const buildHighlight=r=>this._buildHighlight(r);return jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$v.container),ref:container=>this._container=container,children:[jsxRuntimeExports.jsx("div",{children:this.props.enabled&&this._container&&this._content&&jsxRuntimeExports.jsx(HighlightingUI,{buildHighlight:buildHighlight,contentNode:this._content,editable:this.props.editable,highlights:highlights,offsetParent:this._container,zIndexes:{belowContent:0},onAddHighlight:this._handleAddHighlight,onRemoveHighlight:this._handleRemoveHighlight})}),jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$v.content),ref:content=>this._content=content,children:jsxRuntimeExports.jsx(WordIndexer,{onWordsUpdate:this._handleWordsUpdate,children:this.props.children})})]})}constructor(...args){super(...args),this.state={wordRanges:[]},this._handleAddHighlight=highlight=>{const newDomHighlights=addHighlight(this._getDOMHighlights(),highlight);const newSerializedHighlights={};for(const key of Object.keys(newDomHighlights)){newSerializedHighlights[key]=serializeHighlight(newDomHighlights[key]);}this.props.onSerializedHighlightsUpdate(newSerializedHighlights);},this._handleRemoveHighlight=keyToRemove=>{const{serializedHighlights}=this.props;const newSerializedHighlights={...serializedHighlights};delete newSerializedHighlights[keyToRemove];this.props.onSerializedHighlightsUpdate(newSerializedHighlights);},this._handleWordsUpdate=wordRanges=>{this.setState({wordRanges});};}}const styles$v=aphrodite.StyleSheet.create({container:{position:"relative",zIndex:0},content:{position:"relative",zIndex:1}});
1774
+ class HighlightableContent extends React__namespace.PureComponent{_buildHighlight(highlightRange){return buildHighlight(this._getDOMHighlights(),this.state.wordRanges,highlightRange)}_getDOMHighlights(){const{serializedHighlights}=this.props;const{wordRanges}=this.state;const domHighlights={};for(const key of Object.keys(serializedHighlights)){domHighlights[key]=deserializeHighlight(serializedHighlights[key],wordRanges);}return domHighlights}render(){const highlights=this._getDOMHighlights();const buildHighlight=r=>this._buildHighlight(r);return jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$w.container),ref:container=>this._container=container,children:[jsxRuntimeExports.jsx("div",{children:this.props.enabled&&this._container&&this._content&&jsxRuntimeExports.jsx(HighlightingUI,{buildHighlight:buildHighlight,contentNode:this._content,editable:this.props.editable,highlights:highlights,offsetParent:this._container,zIndexes:{belowContent:0},onAddHighlight:this._handleAddHighlight,onRemoveHighlight:this._handleRemoveHighlight})}),jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$w.content),ref:content=>this._content=content,children:jsxRuntimeExports.jsx(WordIndexer,{onWordsUpdate:this._handleWordsUpdate,children:this.props.children})})]})}constructor(...args){super(...args),this.state={wordRanges:[]},this._handleAddHighlight=highlight=>{const newDomHighlights=addHighlight(this._getDOMHighlights(),highlight);const newSerializedHighlights={};for(const key of Object.keys(newDomHighlights)){newSerializedHighlights[key]=serializeHighlight(newDomHighlights[key]);}this.props.onSerializedHighlightsUpdate(newSerializedHighlights);},this._handleRemoveHighlight=keyToRemove=>{const{serializedHighlights}=this.props;const newSerializedHighlights={...serializedHighlights};delete newSerializedHighlights[keyToRemove];this.props.onSerializedHighlightsUpdate(newSerializedHighlights);},this._handleWordsUpdate=wordRanges=>{this.setState({wordRanges});};}}const styles$w=aphrodite.StyleSheet.create({container:{position:"relative",zIndex:0},content:{position:"relative",zIndex:1}});
1779
1775
 
1780
1776
  const getPromptJSON$o=renderProps=>{return {type:"passage",options:{passageTitle:renderProps.passageTitle,passageText:renderProps.passageText,footnotes:renderProps.footnotes}}};
1781
1777
 
1782
1778
  function getInitialParseState(){return {currentRef:[],useRefs:true,lastRef:0,firstSentenceRef:null,firstQuestionRef:null,lastFootnote:{id:0,text:""}}}class RefStart extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("span",{style:REF_STYLE,children:"_"})}constructor(...args){super(...args),this.getRefContent=()=>{return this.props.refContent};}}class RefEnd extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("span",{style:REF_STYLE,children:"_"})}}const AltText=({id,number})=>{const{strings}=usePerseusI18n();return jsxRuntimeExports.jsx("span",{className:"perseus-sr-only",children:strings[id]({number})},"alt-text")};const rules={newline:SimpleMarkdown__default.default.defaultRules.newline,paragraph:SimpleMarkdown__default.default.defaultRules.paragraph,escape:SimpleMarkdown__default.default.defaultRules.escape,passageFootnote:{order:SimpleMarkdown__default.default.defaultRules.escape.order+.1,match:SimpleMarkdown__default.default.inlineRegex(/^\^/),parse:(capture,parse,state)=>{const id=state.lastFootnote.id+1;const footnote={id:id,text:id===1?"*":""+id};if(state.lastFootnote.text==="*"){state.lastFootnote.text=""+state.lastFootnote.id;}state.lastFootnote=footnote;return footnote},react:(node,output,state)=>{return jsxRuntimeExports.jsx("sup",{children:node.text},state.key)}},refStart:{order:SimpleMarkdown__default.default.defaultRules.escape.order+.2,match:function(source){const capture=/^\{\{/.exec(source);if(capture){let closeIndex=2;let refNestingLevel=0;while(closeIndex<source.length){const token=source.slice(closeIndex,closeIndex+2);if(token==="{{"){refNestingLevel++;closeIndex++;}else if(token==="}}"){if(refNestingLevel>0){refNestingLevel--;closeIndex++;}else {break}}closeIndex++;}capture[1]=source.slice(2,closeIndex);return capture}return null},parse:(capture,parse,state)=>{if(!state.useRefs){return {ref:null,refContent:null}}const ref=state.lastRef+1;state.lastRef=ref;state.currentRef.push(ref);const refContent=parse("(“"+capture[1]+"”)\n\n",___default.default.defaults({useRefs:false},getInitialParseState()));return {ref:ref,refContent:refContent}},react:(node,output,state)=>{const ref=node.ref;if(ref==null){return null}const refContent=output(node.refContent,{});return jsxRuntimeExports.jsx(RefStart,{ref:START_REF_PREFIX+ref,refContent:refContent},START_REF_PREFIX+ref)}},refEnd:{order:SimpleMarkdown__default.default.defaultRules.escape.order+.3,match:SimpleMarkdown__default.default.inlineRegex(/^\}\}/),parse:(capture,parse,state)=>{if(!state.useRefs){return {ref:null}}const ref=state.currentRef.pop()||null;return {ref:ref}},react:(node,output,state)=>{if(node.ref!=null){return jsxRuntimeExports.jsx(RefEnd,{ref:END_REF_PREFIX+node.ref},END_REF_PREFIX+node.ref)}return null}},squareLabel:{order:SimpleMarkdown__default.default.defaultRules.escape.order+.4,match:SimpleMarkdown__default.default.inlineRegex(/^\[\[(\w+)\]\]( *)/),parse:(capture,parse,state)=>{if(!state.firstQuestionRef){state.firstQuestionRef=capture[1];}return {content:capture[1],space:capture[2].length>0}},react:(node,output,state)=>{return [jsxRuntimeExports.jsx("span",{className:"perseus-passage-square-label",style:LABEL_OUTER_STYLE,"aria-hidden":"true",children:jsxRuntimeExports.jsx("span",{style:SQUARE_LABEL_STYLE,children:node.content})},"visual-square"),jsxRuntimeExports.jsx(AltText,{id:"questionMarker",number:node.content},"alt-text"),node.space?" ":null]}},circleLabel:{order:SimpleMarkdown__default.default.defaultRules.escape.order+.5,match:SimpleMarkdown__default.default.inlineRegex(/^\(\((\w+)\)\)( *)/),parse:(capture,parse,state)=>{return {content:capture[1],space:capture[2].length>0}},react:(node,output,state)=>{return [jsxRuntimeExports.jsx("span",{className:"perseus-passage-circle-label",style:LABEL_OUTER_STYLE,"aria-hidden":true,children:jsxRuntimeExports.jsx("span",{style:CIRCLE_LABEL_STYLE,children:node.content})},"visual-circle"),jsxRuntimeExports.jsx(AltText,{id:"circleMarker",number:node.content},"alt-text"),node.space?" ":null]}},squareBracketRef:{order:SimpleMarkdown__default.default.defaultRules.escape.order+.6,match:SimpleMarkdown__default.default.inlineRegex(/^\[(\d+)\]( *)/),parse:(capture,parse,state)=>{if(!state.firstSentenceRef){state.firstSentenceRef=capture[1];}return {content:capture[1],space:capture[2].length>0}},react:(node,output,state)=>{return [jsxRuntimeExports.jsxs("span",{className:"perseus-passage-bracket-label","aria-hidden":"true",children:["[",node.content,"]"]},"visual-brackets"),jsxRuntimeExports.jsx(AltText,{id:"sentenceMarker",number:node.content},"alt-text"),node.space?" ":null]}},highlight:{order:SimpleMarkdown__default.default.defaultRules.escape.order+.7,match:SimpleMarkdown__default.default.inlineRegex(/^{highlighting.start}(.+?){highlighting.end}/),parse:(capture,parse,state)=>{return {content:capture[1]}},react:(node,output,state)=>{return [jsxRuntimeExports.jsx("span",{className:"perseus-highlight",children:node.content},0)]}},reviewHighlight:{order:SimpleMarkdown__default.default.defaultRules.escape.order+.7,match:SimpleMarkdown__default.default.inlineRegex(/^{review-highlighting.start}(.+?){review-highlighting.end}/),parse:(capture,parse,state)=>{return {content:capture[1]}},react:(node,output,state)=>{return [jsxRuntimeExports.jsx("span",{className:"perseus-review-highlight",children:node.content},0)]}},strong:SimpleMarkdown__default.default.defaultRules.strong,u:SimpleMarkdown__default.default.defaultRules.u,em:SimpleMarkdown__default.default.defaultRules.em,del:SimpleMarkdown__default.default.defaultRules.del,text:{...SimpleMarkdown__default.default.defaultRules.text,react(node,output,state){return jsxRuntimeExports.jsx("span",{children:node.content},state.key)}}};const START_REF_PREFIX="start-ref-";const END_REF_PREFIX="end-ref-";const REF_STYLE={display:"inline-block",width:0,visibility:"hidden"};const LABEL_OUTER_STYLE={display:"inline",whiteSpace:"nowrap"};const SQUARE_LABEL_STYLE={display:"inline-block",color:"rgb(255, 255, 255)",backgroundColor:"rgb(90, 90, 90)",paddingLeft:10,paddingRight:10,userSelect:"none",WebkitUserSelect:"none"};const CIRCLE_LABEL_STYLE={display:"inline-block",color:"rgb(255, 255, 255)",backgroundColor:"rgb(90, 90, 90)",userSelect:"none",WebkitUserSelect:"none",width:22,height:22,borderRadius:"50%",textAlign:"center"};const builtParser=SimpleMarkdown__default.default.parserFor(rules);const parse$2=(source,state)=>{state=state||{};const paragraphedSource=source+"\n\n";return builtParser(paragraphedSource,___default.default.extend(state,getInitialParseState()))};const output=SimpleMarkdown__default.default.reactFor(SimpleMarkdown__default.default.ruleOutput(rules,"react"));var PassageMarkdown = {parse: parse$2,output,START_REF_PREFIX,END_REF_PREFIX,getInitialParseState};
1783
1779
 
1784
- class LineHeightMeasurer extends React__namespace.Component{measureLineHeight(){if(!this._line){return 0}return this._line.clientHeight}render(){return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$u.measurer),"aria-hidden":"true",children:jsxRuntimeExports.jsx("div",{ref:ref=>this._line=ref,className:"paragraph",children:"Line Height Measurement"})})}}const styles$u=aphrodite.StyleSheet.create({measurer:{position:"absolute",top:0,left:0,visibility:"hidden",zIndex:-1}});class Passage extends React__namespace.Component{componentDidMount(){this._updateState();this._onResize=___default.default.throttle(()=>{if(this.shouldRenderJipt()){return}this._lineHeightMeasurerRef?.measureLineHeight();this._updateState();},500);window.addEventListener("resize",this._onResize);this._stylesAppiedTimer=window.setTimeout(()=>{this.setState({stylesAreApplied:true});},0);}shouldComponentUpdate(nextProps,nextState){return !___default.default.isEqual(this.props,nextProps)||!___default.default.isEqual(this.state,nextState)}componentDidUpdate(){this._updateState();}componentWillUnmount(){window.removeEventListener("resize",this._onResize);clearTimeout(this._stylesAppiedTimer);}_updateState(){if(this.shouldRenderJipt()){return}this.setState({nLines:this._measureLines(),startLineNumbersAfter:this._getInitialLineNumber()});}_measureLines(){const renderer=ReactDOM__namespace.findDOMNode(this._contentRef);const contentsHeight=$__default.default(renderer).height();const lineHeight=this._getLineHeight();const nLines=Math.round(contentsHeight/lineHeight);return nLines}_getInitialLineNumber(){let isPassageBeforeThisPassage=true;const passagesBeforeUs=this.props.findWidgets((id,widgetInfo)=>{if(widgetInfo.type!=="passage"){return false}if(id===this.props.widgetId){isPassageBeforeThisPassage=false;}return isPassageBeforeThisPassage}).filter(isPassageWidget);return passagesBeforeUs.map(passageWidget=>{return passageWidget.getLineCount()}).reduce((a,b)=>a+b,0)}_getLineHeight(){return this._lineHeightMeasurerRef?.measureLineHeight()||0}getLineCount(){if(this.state.nLines!=null){return this.state.nLines}return this._measureLines()}_getStartRefLineNumber(referenceNumber){const refRef=PassageMarkdown.START_REF_PREFIX+referenceNumber;const ref=this.refs[refRef];if(!ref){return null}const $ref=$__default.default(ReactDOM__namespace.findDOMNode(ref));let $refText=$ref.next();if($refText.length===0){$refText=$ref;}const vPos=$refText.offset().top;return this.state.startLineNumbersAfter+1+this._convertPosToLineNumber(vPos)}_getEndRefLineNumber(referenceNumber){const refRef=PassageMarkdown.END_REF_PREFIX+referenceNumber;const ref=this.refs[refRef];if(!ref){return null}const $ref=$__default.default(ReactDOM__namespace.findDOMNode(ref));let $refText=$ref.prev();if($refText.length===0){$refText=$ref;}const height=$refText.height();const vPos=$refText.offset().top;let line=this._convertPosToLineNumber(vPos+height);if(height===0){line+=1;}return this.state.startLineNumbersAfter+line}_convertPosToLineNumber(absoluteVPos){const content=ReactDOM__namespace.findDOMNode(this._contentRef);const relativeVPos=absoluteVPos-$__default.default(content).offset().top;const lineHeight=this._getLineHeight();const line=Math.round(relativeVPos/lineHeight);return line}_getRefContent(referenceNumber){const refRef=PassageMarkdown.START_REF_PREFIX+referenceNumber;const ref=this.refs[refRef];if(!ref){return null}return ref.getRefContent()}getReference(referenceNumber){const refStartLine=this._getStartRefLineNumber(referenceNumber);const refEndLine=this._getEndRefLineNumber(referenceNumber);if(refStartLine==null||refEndLine==null){return null}const refContent=this._getRefContent(referenceNumber);return {startLine:refStartLine,endLine:refEndLine,content:refContent}}getPromptJSON(){return getPromptJSON$o(this.props)}_renderInstructions(parseState){const firstQuestionNumber=parseState.firstQuestionRef;const firstSentenceRef=parseState.firstSentenceRef;const{strings}=this.context;let instructions="";if(firstQuestionNumber){instructions+=strings.symbolPassage({questionSymbol:"[["+firstQuestionNumber+"]]",questionNumber:firstQuestionNumber});}if(firstSentenceRef){instructions+=strings.symbolQuestion({sentenceSymbol:"["+firstSentenceRef+"]"});}const parsedInstructions=PassageMarkdown.parse(instructions);return jsxRuntimeExports.jsx("div",{className:"perseus-widget-passage-instructions",children:PassageMarkdown.output(parsedInstructions)})}shouldRenderJipt(){const{JIPT}=getDependencies();return JIPT.useJIPT&&this.props.passageText.indexOf("crwdns")!==-1}_renderContent(parsed){const enabled=this.state.stylesAreApplied;const editable=!this.props.reviewMode;return jsxRuntimeExports.jsx(HighlightableContent,{editable:editable,enabled:enabled,onSerializedHighlightsUpdate:this._handleSerializedHighlightsUpdate,serializedHighlights:this.props.highlights,children:jsxRuntimeExports.jsxs("div",{ref:ref=>this._contentRef=ref,children:[jsxRuntimeExports.jsx(LineHeightMeasurer,{ref:ref=>this._lineHeightMeasurerRef=ref}),PassageMarkdown.output(parsed)]})})}_hasFootnotes(){const rawContent=this.props.footnotes;const isEmpty=/^\s*$/.test(rawContent);return !isEmpty}_renderFootnotes(){const rawContent=this.props.footnotes;const parsed=PassageMarkdown.parse(rawContent);return PassageMarkdown.output(parsed)}render(){const{strings}=this.context;let lineNumbers;const nLines=this.state.nLines;if(this.props.showLineNumbers&&nLines){lineNumbers=___default.default.range(1,nLines+1).map(lineN=>{const lineAt=lineN+this.state.startLineNumbersAfter;if(lineAt===4){const translatedLine=strings.lineLabel;return jsxRuntimeExports.jsx("span",{className:"line-marker",children:translatedLine},"line-marker")}return jsxRuntimeExports.jsx("span",{children:lineAt},lineN)});}const parseState=PassageMarkdown.getInitialParseState();const re=/("{1})([^"]*)("{1})/g;const doubleQuoteParsedContent=this.props.passageText.replace(re,"“$2”");const parsedContent=PassageMarkdown.parse(doubleQuoteParsedContent,parseState);const hasTitle=/\S/.test(this.props.passageTitle);return jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-passage-container",children:[this._renderInstructions(parseState),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-passage",children:[hasTitle&&jsxRuntimeExports.jsx("h3",{className:"passage-title",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.passageTitle,linterContext:this.props.linterContext,strings:strings})}),lineNumbers&&jsxRuntimeExports.jsx("div",{className:"line-numbers","aria-hidden":true,children:lineNumbers}),!hasTitle&&jsxRuntimeExports.jsx("h3",{className:"perseus-sr-only",children:strings.beginningPassage}),jsxRuntimeExports.jsx("div",{className:"passage-text",children:this.shouldRenderJipt()?jsxRuntimeExports.jsx(Renderer,{content:this.props.passageText,strings:strings}):this._renderContent(parsedContent)}),this._hasFootnotes()&&[jsxRuntimeExports.jsx("h4",{className:"perseus-sr-only",children:strings.beginningFootnotes},"footnote-start"),jsxRuntimeExports.jsx("div",{className:"footnotes",children:this._renderFootnotes()},"footnotes")],jsxRuntimeExports.jsx("div",{className:"perseus-sr-only",children:strings.endPassage})]})]})})}constructor(...args){super(...args),this.isWidget=true,this.state={nLines:null,startLineNumbersAfter:0,stylesAreApplied:false},this._handleSerializedHighlightsUpdate=serializedHighlights=>{this.props.onChange({highlights:serializedHighlights});};}}Passage.contextType=PerseusI18nContext;Passage.defaultProps={passageTitle:"",passageText:"",footnotes:"",showLineNumbers:true,highlights:{},linterContext:PerseusLinter.linterContextDefault};var Passage$1 = {name:"passage",displayName:"Passage (SAT only)",hidden:true,widget:Passage,transform:editorProps=>{return ___default.default.pick(editorProps,"passageTitle","passageText","footnotes","showLineNumbers")},isLintable:true};
1780
+ class LineHeightMeasurer extends React__namespace.Component{measureLineHeight(){if(!this._line){return 0}return this._line.clientHeight}render(){return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$v.measurer),"aria-hidden":"true",children:jsxRuntimeExports.jsx("div",{ref:ref=>this._line=ref,className:"paragraph",children:"Line Height Measurement"})})}}const styles$v=aphrodite.StyleSheet.create({measurer:{position:"absolute",top:0,left:0,visibility:"hidden",zIndex:-1}});class Passage extends React__namespace.Component{componentDidMount(){this._updateState();this._onResize=___default.default.throttle(()=>{if(this.shouldRenderJipt()){return}this._lineHeightMeasurerRef?.measureLineHeight();this._updateState();},500);window.addEventListener("resize",this._onResize);this._stylesAppiedTimer=window.setTimeout(()=>{this.setState({stylesAreApplied:true});},0);}shouldComponentUpdate(nextProps,nextState){return !___default.default.isEqual(this.props,nextProps)||!___default.default.isEqual(this.state,nextState)}componentDidUpdate(){this._updateState();}componentWillUnmount(){window.removeEventListener("resize",this._onResize);clearTimeout(this._stylesAppiedTimer);}_updateState(){if(this.shouldRenderJipt()){return}this.setState({nLines:this._measureLines(),startLineNumbersAfter:this._getInitialLineNumber()});}_measureLines(){const renderer=ReactDOM__namespace.findDOMNode(this._contentRef);const contentsHeight=$__default.default(renderer).height();const lineHeight=this._getLineHeight();const nLines=Math.round(contentsHeight/lineHeight);return nLines}_getInitialLineNumber(){let isPassageBeforeThisPassage=true;const passagesBeforeUs=this.props.findWidgets((id,widgetInfo)=>{if(widgetInfo.type!=="passage"){return false}if(id===this.props.widgetId){isPassageBeforeThisPassage=false;}return isPassageBeforeThisPassage}).filter(isPassageWidget);return passagesBeforeUs.map(passageWidget=>{return passageWidget.getLineCount()}).reduce((a,b)=>a+b,0)}_getLineHeight(){return this._lineHeightMeasurerRef?.measureLineHeight()||0}getLineCount(){if(this.state.nLines!=null){return this.state.nLines}return this._measureLines()}_getStartRefLineNumber(referenceNumber){const refRef=PassageMarkdown.START_REF_PREFIX+referenceNumber;const ref=this.refs[refRef];if(!ref){return null}const $ref=$__default.default(ReactDOM__namespace.findDOMNode(ref));let $refText=$ref.next();if($refText.length===0){$refText=$ref;}const vPos=$refText.offset().top;return this.state.startLineNumbersAfter+1+this._convertPosToLineNumber(vPos)}_getEndRefLineNumber(referenceNumber){const refRef=PassageMarkdown.END_REF_PREFIX+referenceNumber;const ref=this.refs[refRef];if(!ref){return null}const $ref=$__default.default(ReactDOM__namespace.findDOMNode(ref));let $refText=$ref.prev();if($refText.length===0){$refText=$ref;}const height=$refText.height();const vPos=$refText.offset().top;let line=this._convertPosToLineNumber(vPos+height);if(height===0){line+=1;}return this.state.startLineNumbersAfter+line}_convertPosToLineNumber(absoluteVPos){const content=ReactDOM__namespace.findDOMNode(this._contentRef);const relativeVPos=absoluteVPos-$__default.default(content).offset().top;const lineHeight=this._getLineHeight();const line=Math.round(relativeVPos/lineHeight);return line}_getRefContent(referenceNumber){const refRef=PassageMarkdown.START_REF_PREFIX+referenceNumber;const ref=this.refs[refRef];if(!ref){return null}return ref.getRefContent()}getReference(referenceNumber){const refStartLine=this._getStartRefLineNumber(referenceNumber);const refEndLine=this._getEndRefLineNumber(referenceNumber);if(refStartLine==null||refEndLine==null){return null}const refContent=this._getRefContent(referenceNumber);return {startLine:refStartLine,endLine:refEndLine,content:refContent}}getPromptJSON(){return getPromptJSON$o(this.props)}_renderInstructions(parseState){const firstQuestionNumber=parseState.firstQuestionRef;const firstSentenceRef=parseState.firstSentenceRef;const{strings}=this.context;let instructions="";if(firstQuestionNumber){instructions+=strings.symbolPassage({questionSymbol:"[["+firstQuestionNumber+"]]",questionNumber:firstQuestionNumber});}if(firstSentenceRef){instructions+=strings.symbolQuestion({sentenceSymbol:"["+firstSentenceRef+"]"});}const parsedInstructions=PassageMarkdown.parse(instructions);return jsxRuntimeExports.jsx("div",{className:"perseus-widget-passage-instructions",children:PassageMarkdown.output(parsedInstructions)})}shouldRenderJipt(){const{JIPT}=getDependencies();return JIPT.useJIPT&&this.props.passageText.indexOf("crwdns")!==-1}_renderContent(parsed){const enabled=this.state.stylesAreApplied;const editable=!this.props.reviewMode;return jsxRuntimeExports.jsx(HighlightableContent,{editable:editable,enabled:enabled,onSerializedHighlightsUpdate:this._handleSerializedHighlightsUpdate,serializedHighlights:this.props.highlights,children:jsxRuntimeExports.jsxs("div",{ref:ref=>this._contentRef=ref,children:[jsxRuntimeExports.jsx(LineHeightMeasurer,{ref:ref=>this._lineHeightMeasurerRef=ref}),PassageMarkdown.output(parsed)]})})}_hasFootnotes(){const rawContent=this.props.footnotes;const isEmpty=/^\s*$/.test(rawContent);return !isEmpty}_renderFootnotes(){const rawContent=this.props.footnotes;const parsed=PassageMarkdown.parse(rawContent);return PassageMarkdown.output(parsed)}render(){const{strings}=this.context;let lineNumbers;const nLines=this.state.nLines;if(this.props.showLineNumbers&&nLines){lineNumbers=___default.default.range(1,nLines+1).map(lineN=>{const lineAt=lineN+this.state.startLineNumbersAfter;if(lineAt===4){const translatedLine=strings.lineLabel;return jsxRuntimeExports.jsx("span",{className:"line-marker",children:translatedLine},"line-marker")}return jsxRuntimeExports.jsx("span",{children:lineAt},lineN)});}const parseState=PassageMarkdown.getInitialParseState();const re=/("{1})([^"]*)("{1})/g;const doubleQuoteParsedContent=this.props.passageText.replace(re,"“$2”");const parsedContent=PassageMarkdown.parse(doubleQuoteParsedContent,parseState);const hasTitle=/\S/.test(this.props.passageTitle);return jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-passage-container",children:[this._renderInstructions(parseState),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-passage",children:[hasTitle&&jsxRuntimeExports.jsx("h3",{className:"passage-title",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.passageTitle,linterContext:this.props.linterContext,strings:strings})}),lineNumbers&&jsxRuntimeExports.jsx("div",{className:"line-numbers","aria-hidden":true,children:lineNumbers}),!hasTitle&&jsxRuntimeExports.jsx("h3",{className:"perseus-sr-only",children:strings.beginningPassage}),jsxRuntimeExports.jsx("div",{className:"passage-text",children:this.shouldRenderJipt()?jsxRuntimeExports.jsx(Renderer,{content:this.props.passageText,strings:strings}):this._renderContent(parsedContent)}),this._hasFootnotes()&&[jsxRuntimeExports.jsx("h4",{className:"perseus-sr-only",children:strings.beginningFootnotes},"footnote-start"),jsxRuntimeExports.jsx("div",{className:"footnotes",children:this._renderFootnotes()},"footnotes")],jsxRuntimeExports.jsx("div",{className:"perseus-sr-only",children:strings.endPassage})]})]})})}constructor(...args){super(...args),this.isWidget=true,this.state={nLines:null,startLineNumbersAfter:0,stylesAreApplied:false},this._handleSerializedHighlightsUpdate=serializedHighlights=>{this.props.onChange({highlights:serializedHighlights});};}}Passage.contextType=PerseusI18nContext;Passage.defaultProps={passageTitle:"",passageText:"",footnotes:"",showLineNumbers:true,highlights:{},linterContext:PerseusLinter.linterContextDefault};var Passage$1 = {name:"passage",displayName:"Passage (SAT only)",hidden:true,widget:Passage,isLintable:true};
1785
1781
 
1786
1782
  function isPassageWidget(widget){return widget instanceof Passage}
1787
1783
 
1788
- const EN_DASH$1="–";class PassageRef extends React__namespace.Component{componentDidMount(){this._isMounted=true;this._deferredUpdateRange();this._throttledUpdateRange=___default.default.throttle(this._deferredUpdateRange,500);window.addEventListener("resize",this._throttledUpdateRange);}shouldComponentUpdate(nextProps,nextState){return !___default.default.isEqual(this.props,nextProps)||!___default.default.isEqual(this.state,nextState)}componentDidUpdate(){this._deferredUpdateRange();}componentWillUnmount(){window.removeEventListener("resize",this._throttledUpdateRange);this._isMounted=false;}getPromptJSON(){return getPromptJSON$p(this.props)}render(){const{strings}=this.context;const lineRange=this.state.lineRange;let lineRangeOutput;if(!lineRange){lineRangeOutput=strings.lineRange({lineRange:`?${EN_DASH$1}?`});}else if(lineRange[0]===lineRange[1]){lineRangeOutput=strings.lineNumber({lineNumber:String(lineRange[0])});}else {lineRangeOutput=strings.lineRange({lineRange:lineRange[0]+EN_DASH$1+lineRange[1]});}let summaryOutput;if(this.props.summaryText){const summaryTree=PerseusMarkdown.parseInline(this.props.summaryText);summaryOutput=jsxRuntimeExports.jsxs("span",{"aria-hidden":true,children:[" ","(“",PerseusMarkdown.basicOutput(summaryTree),"”)"]});}else {summaryOutput=null;}return jsxRuntimeExports.jsxs("span",{children:[lineRangeOutput,summaryOutput,lineRange&&jsxRuntimeExports.jsx("div",{className:"perseus-sr-only",children:this.state.content})]})}constructor(...args){super(...args),this.displayName="PassageRef",this.isWidget=true,this.state={lineRange:null,content:null},this._deferredUpdateRange=()=>{___default.default.defer(this._updateRange);},this._updateRange=()=>{const passage=this.props.findWidgets("passage "+this.props.passageNumber).filter(isPassageWidget)[0];const refInfo=passage?.getReference(this.props.referenceNumber);if(this._isMounted){if(refInfo){this.setState({lineRange:[refInfo.startLine,refInfo.endLine],content:refInfo.content});}else {this.setState({lineRange:null,content:null});}}};}}PassageRef.contextType=PerseusI18nContext;PassageRef.defaultProps={passageNumber:1,referenceNumber:1,summaryText:""};var PassageRef$1 = {name:"passage-ref",displayName:"PassageRef (SAT only)",hidden:true,widget:PassageRef,transform:widgetOptions=>({passageNumber:widgetOptions.passageNumber,referenceNumber:widgetOptions.referenceNumber,summaryText:widgetOptions.summaryText}),version:perseusCore.passageRefLogic.version};
1784
+ const EN_DASH$1="–";class PassageRef extends React__namespace.Component{componentDidMount(){this._isMounted=true;this._deferredUpdateRange();this._throttledUpdateRange=___default.default.throttle(this._deferredUpdateRange,500);window.addEventListener("resize",this._throttledUpdateRange);}shouldComponentUpdate(nextProps,nextState){return !___default.default.isEqual(this.props,nextProps)||!___default.default.isEqual(this.state,nextState)}componentDidUpdate(){this._deferredUpdateRange();}componentWillUnmount(){window.removeEventListener("resize",this._throttledUpdateRange);this._isMounted=false;}getPromptJSON(){return getPromptJSON$p(this.props)}render(){const{strings}=this.context;const lineRange=this.state.lineRange;let lineRangeOutput;if(!lineRange){lineRangeOutput=strings.lineRange({lineRange:`?${EN_DASH$1}?`});}else if(lineRange[0]===lineRange[1]){lineRangeOutput=strings.lineNumber({lineNumber:String(lineRange[0])});}else {lineRangeOutput=strings.lineRange({lineRange:lineRange[0]+EN_DASH$1+lineRange[1]});}let summaryOutput;if(this.props.summaryText){const summaryTree=PerseusMarkdown.parseInline(this.props.summaryText);summaryOutput=jsxRuntimeExports.jsxs("span",{"aria-hidden":true,children:[" ","(“",PerseusMarkdown.basicOutput(summaryTree),"”)"]});}else {summaryOutput=null;}return jsxRuntimeExports.jsxs("span",{children:[lineRangeOutput,summaryOutput,lineRange&&jsxRuntimeExports.jsx("div",{className:"perseus-sr-only",children:this.state.content})]})}constructor(...args){super(...args),this.displayName="PassageRef",this.isWidget=true,this.state={lineRange:null,content:null},this._deferredUpdateRange=()=>{___default.default.defer(this._updateRange);},this._updateRange=()=>{const passage=this.props.findWidgets("passage "+this.props.passageNumber).filter(isPassageWidget)[0];const refInfo=passage?.getReference(this.props.referenceNumber);if(this._isMounted){if(refInfo){this.setState({lineRange:[refInfo.startLine,refInfo.endLine],content:refInfo.content});}else {this.setState({lineRange:null,content:null});}}};}}PassageRef.contextType=PerseusI18nContext;PassageRef.defaultProps={passageNumber:1,referenceNumber:1,summaryText:""};var PassageRef$1 = {name:"passage-ref",displayName:"PassageRef (SAT only)",hidden:true,widget:PassageRef,version:perseusCore.passageRefLogic.version};
1789
1785
 
1790
1786
  const getChoiceStates=({choices,isStatic,showSolutions,choiceStates,values})=>{const defaultState={selected:false,readOnly:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false};if(isStatic||showSolutions==="all"){return choices.map(choice=>({...defaultState,selected:!!choice.correct,readOnly:true,rationaleShown:true,correctnessShown:true}))}if(choiceStates){return choiceStates}if(values){return values.map(val=>({...defaultState,selected:val}))}return choices.map(()=>({...defaultState}))};const parseNestedWidgets=content=>{let nextPassageRefId=1;const extractedWidgets={};const parsedContent=content.replace(/\{\{passage-ref (\d+) (\d+)(?: "([^"]*)")?\}\}/g,(_,passageNum,refNum,summaryText)=>{const widgetId="passage-ref "+nextPassageRefId;nextPassageRefId++;extractedWidgets[widgetId]={type:"passage-ref",graded:false,options:{passageNumber:parseInt(passageNum),referenceNumber:parseInt(refNum),summaryText:summaryText},version:PassageRef$1.version};return "[["+Util.snowman+" "+widgetId+"]]"});return {parsedContent,extractedWidgets}};
1791
1787
 
1792
- class MultipleChoiceWidget extends React__namespace.Component{getPromptJSON(){return getPromptJSON$q(this.props,this.props.userInput)}render(){const choicesProps=this.prepareChoicesProps();const{apiOptions,reviewModeRubric,reviewMode,editMode=false,multipleSelect,labelWrap=true,countChoices,numCorrect,isLastUsedWidget}=this.props;return jsxRuntimeExports.jsx(MultipleChoiceComponent,{apiOptions:apiOptions,reviewModeRubric:reviewModeRubric,reviewMode:reviewMode,editMode:editMode,multipleSelect:multipleSelect,labelWrap:labelWrap,countChoices:countChoices,numCorrect:numCorrect,isLastUsedWidget:isLastUsedWidget,choices:choicesProps,onChoiceChange:this.handleChoiceChange})}constructor(...args){super(...args),this.renderContent=(content="")=>{const{parsedContent,extractedWidgets}=parseNestedWidgets(content);const{strings=mockStrings,findWidgets}=this.props;const linterContext={contentType:"radio",highlightLint:false,paths:[],stack:[]};return jsxRuntimeExports.jsx(Renderer,{content:parsedContent,widgets:extractedWidgets,findExternalWidgets:findWidgets,alwaysUpdate:true,linterContext:linterContext,strings:strings},"choiceContentRenderer")},this.handleChoiceChange=(choiceIndex,newCheckedState)=>{const{choices,choiceStates,multipleSelect=false,onChange,trackInteraction}=this.props;let newCheckedList;if(newCheckedState&&!multipleSelect){newCheckedList=choices.map(()=>false);}else {newCheckedList=choiceStates?choiceStates.map(state=>state.selected):choices.map(()=>false);}newCheckedList[choiceIndex]=newCheckedState;const newChoiceStates=choiceStates?choiceStates.map(state=>({...state})):choices.map(()=>({selected:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false,readOnly:false}));newChoiceStates.forEach((choiceState,i)=>{choiceState.selected=newCheckedList[i];});onChange({choiceStates:newChoiceStates});trackInteraction();},this.buildChoiceProps=choiceStates=>{const{choices,reviewModeRubric,questionCompleted,strings=mockStrings}=this.props;return choices.map((choice,i)=>{const content=choice.isNoneOfTheAbove&&!choice.content?strings.noneOfTheAbove:choice.content;const{selected,rationaleShown,correctnessShown,readOnly,previouslyAnswered}=choiceStates[i];const reviewChoice=reviewModeRubric?.choices[i];return {content:this.renderContent(content),checked:selected,correct:choice.correct===undefined?!!reviewChoice&&!!reviewChoice.correct:choice.correct,disabled:readOnly,hasRationale:!!choice.rationale,rationale:this.renderContent(choice.rationale),showRationale:rationaleShown,showCorrectness:correctnessShown,isNoneOfTheAbove:!!choice.isNoneOfTheAbove,revealNoneOfTheAbove:!!(questionCompleted&&selected),previouslyAnswered}})},this.prepareChoicesProps=()=>{const{choices,showSolutions,choiceStates,values}=this.props;const processedChoiceStates=getChoiceStates({choices,isStatic:this.props.static,showSolutions,choiceStates,values});const choicesProps=this.buildChoiceProps(processedChoiceStates);return choicesProps};}}MultipleChoiceWidget.defaultProps={choices:[],multipleSelect:false,countChoices:false,deselectEnabled:false,linterContext:PerseusLinter.linterContextDefault,showSolutions:"none"};const Radio$3=MultipleChoiceWidget;
1788
+ class MultipleChoiceWidget extends React__namespace.Component{getPromptJSON(){return getPromptJSON$q(this.props,this.props.userInput)}render(){const choicesProps=this.prepareChoicesProps();const{apiOptions,reviewMode,multipleSelect,countChoices,numCorrect}=this.props;const onChoiceChange=apiOptions.readOnly||reviewMode?()=>{}:this.handleChoiceChange;return jsxRuntimeExports.jsx(MultipleChoiceComponent,{reviewMode:reviewMode,multipleSelect:multipleSelect,countChoices:countChoices,numCorrect:numCorrect,choices:choicesProps,onChoiceChange:onChoiceChange})}constructor(...args){super(...args),this.renderContent=(content="")=>{const{parsedContent,extractedWidgets}=parseNestedWidgets(content);const{strings=mockStrings,findWidgets}=this.props;const linterContext={contentType:"radio",highlightLint:false,paths:[],stack:[]};return jsxRuntimeExports.jsx(Renderer,{content:parsedContent,widgets:extractedWidgets,findExternalWidgets:findWidgets,alwaysUpdate:true,linterContext:linterContext,strings:strings},"choiceContentRenderer")},this.handleChoiceChange=(choiceIndex,newCheckedState)=>{const{choices,choiceStates,multipleSelect=false,onChange,trackInteraction}=this.props;let newCheckedList;if(newCheckedState&&!multipleSelect){newCheckedList=choices.map(()=>false);}else {newCheckedList=choiceStates?choiceStates.map(state=>state.selected):choices.map(()=>false);}newCheckedList[choiceIndex]=newCheckedState;const newChoiceStates=choiceStates?choiceStates.map(state=>({...state})):choices.map(()=>({selected:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false,readOnly:false}));newChoiceStates.forEach((choiceState,i)=>{choiceState.selected=newCheckedList[i];});onChange({choiceStates:newChoiceStates});trackInteraction();},this.buildChoiceProps=choiceStates=>{const{choices,reviewModeRubric,questionCompleted,strings=mockStrings}=this.props;return choices.map((choice,i)=>{const content=choice.isNoneOfTheAbove&&!choice.content?strings.noneOfTheAbove:choice.content;const{selected,rationaleShown,correctnessShown,readOnly,previouslyAnswered}=choiceStates[i];const reviewChoice=reviewModeRubric?.choices[i];return {id:choice.id,content:this.renderContent(content),checked:selected,correct:choice.correct===undefined?!!reviewChoice&&!!reviewChoice.correct:choice.correct,disabled:readOnly,hasRationale:!!choice.rationale,rationale:this.renderContent(choice.rationale),showRationale:rationaleShown,showCorrectness:correctnessShown,isNoneOfTheAbove:!!choice.isNoneOfTheAbove,revealNoneOfTheAbove:!!(questionCompleted&&selected),previouslyAnswered}})},this.prepareChoicesProps=()=>{const{choices,showSolutions,choiceStates,values}=this.props;const processedChoiceStates=getChoiceStates({choices,isStatic:this.props.static,showSolutions,choiceStates,values});const choicesProps=this.buildChoiceProps(processedChoiceStates);return choicesProps};}}MultipleChoiceWidget.defaultProps={choices:[],multipleSelect:false,countChoices:false,deselectEnabled:false,linterContext:PerseusLinter.linterContextDefault,showSolutions:"none"};const Radio$3=MultipleChoiceWidget;
1789
+
1790
+ const{pureXsMax,pureSmMax,pureMdMin,pureMdMax,pureLgMin,pureLgMax,pureXlMin}=constants;var mediaQueries = {md:`@media screen and (min-width: ${pureMdMin}) and `+`(max-width: ${pureMdMax})`,xl:`@media screen and (min-width: ${pureXlMin})`,xsOrSmaller:`@media screen and (max-width: ${pureXsMax})`,smOrSmaller:`@media screen and (max-width: ${pureSmMax})`,mdOrSmaller:`@media screen and (max-width: ${pureMdMax})`,lgOrSmaller:`@media screen and (max-width: ${pureLgMax})`,lgOrLarger:`@media screen and (min-width: ${pureLgMin})`};
1791
+
1792
+ if(typeof HTMLElement!=="undefined"&&!HTMLElement.prototype.scrollTo){HTMLElement.prototype.scrollTo=function(left,top){this.scrollLeft=left;this.scrollTop=top;};}const applyUniversalScrollOffset=(elementOrWindow,amount)=>{if(typeof elementOrWindow.scrollTo==="function"){elementOrWindow.scrollTo(0,amount);}else if("scrollTop"in elementOrWindow){elementOrWindow.scrollTop=amount;}};const scrollElementToOffset=(elementOrWindow,offset,duration=0,callback)=>{const startPosition=elementOrWindow===window?window.pageYOffset:elementOrWindow.scrollTop;const endPosition=offset;const scrollDistance=endPosition-startPosition;const tickLength=17;const numberOfSteps=duration/tickLength;let step=0;const scrollInterval=setInterval(function(){if(step<numberOfSteps){const x=step/numberOfSteps;const y=(-Math.cos(Math.PI*x)+1)/2;const newPosition=startPosition+scrollDistance*y;applyUniversalScrollOffset(elementOrWindow,newPosition);step+=1;}else {applyUniversalScrollOffset(elementOrWindow,endPosition);clearInterval(scrollInterval);}},tickLength);};const getScrollContainer=element=>{if(element===document.body){return window}if(element==null){return window}if(element.scrollHeight>element.clientHeight){return element}return getScrollContainer(element.parentElement)};const SCROLL_ANIMATION_DURATION=750;const scrollElementIntoView=(element,callback)=>{setTimeout(()=>{const scrollContainer=getScrollContainer(element);const childBounds=element.getBoundingClientRect();const containerBounds=scrollContainer===window?{top:0,bottom:window.innerHeight}:scrollContainer.getBoundingClientRect();let offset=0;const currentScrollTop=scrollContainer===window?window.scrollY:scrollContainer.scrollTop;if(childBounds.bottom>containerBounds.bottom){let distanceToScroll=childBounds.bottom-containerBounds.bottom;if(childBounds.top+distanceToScroll<containerBounds.top){distanceToScroll=childBounds.top-containerBounds.top;}offset=currentScrollTop+distanceToScroll;}else if(childBounds.top<containerBounds.top){const distanceToScroll=childBounds.top-containerBounds.top;offset=currentScrollTop+distanceToScroll;}scrollElementToOffset(scrollContainer,offset,SCROLL_ANIMATION_DURATION);},0);};
1793
1793
 
1794
1794
  function getA11yText(letter,checked,correct,showCorrectness,strings){if(showCorrectness&&correct){if(checked){return strings.choiceCheckedCorrect({letter})}return strings.choiceCorrect({letter})}if(showCorrectness&&!correct){if(checked){return strings.choiceCheckedIncorrect({letter})}return strings.choiceIncorrect({letter})}if(checked){return strings.choiceChecked({letter})}return strings.choice({letter})}
1795
1795
 
1796
+ const FocusRing=function({visible=true,color=kaGreen,multipleSelect=false,children}){const borderColor=visible?color:"transparent";const borderRadius=multipleSelect?5:"50%";const style={borderColor,borderRadius};return jsxRuntimeExports.jsx("span",{"data-testid":"focus-ring",className:aphrodite.css(styles$u.ring),style:style,children:children})};const styles$u=aphrodite.StyleSheet.create({ring:{margin:"auto",display:"inline-block",borderWidth:2,padding:2,borderStyle:"solid"}});
1797
+
1796
1798
  const CHOICE_ICON_SIZE=24;const styles$t=aphrodite.StyleSheet.create({iconWrapper:{display:"inline-block",position:"relative"}});
1797
1799
 
1798
- function ChoiceInner(props){const{pos,showCorrectness,correct}=props;const{strings}=usePerseusI18n();const letter=getChoiceLetter$1(pos,strings);if(!showCorrectness){return jsxRuntimeExports.jsx("span",{children:letter})}if(correct){return jsxRuntimeExports.jsx(InlineIcon,{...iconCheck,style:{position:"relative",top:-1}})}return jsxRuntimeExports.jsx(InlineIcon,{...iconMinus})}const ChoiceIcon=function(props){const{checked,showCorrectness,correct,focused,hovered,multipleSelect,pos,previouslyAnswered,pressed}=props;const choiceIsChecked=checked||showCorrectness&&!correct&&previouslyAnswered;const choiceStyling=[styles$s.choiceBase,multipleSelect?styles$s.multiSelectShape:styles$s.singleSelectShape,showCorrectness?styles$s.choiceHasIcon:styles$s.choiceHasLetter,choiceIsChecked?styles$s.choiceIsChecked:styles$s.choiceIsUnchecked];if(showCorrectness&&correct&&checked){choiceStyling.push(styles$s.choiceCorrect);}else if(showCorrectness&&!correct&&(checked||previouslyAnswered)){choiceStyling.push(styles$s.choiceIncorrect);}else if(checked){choiceStyling.push(styles$s.choiceNeutral);}else if(pressed){choiceStyling.push(styles$s.activeNeutral);}else {choiceStyling.push(styles$s.uncheckedColors);}return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$t.iconWrapper),children:jsxRuntimeExports.jsx(FocusRing,{color:wonderBlocksTokens.color.blue,visible:focused||hovered,multipleSelect:multipleSelect,children:jsxRuntimeExports.jsx("div",{"data-testid":"choice-icon__library-choice-icon",className:aphrodite.css(...choiceStyling),"data-is-radio-icon":true,children:jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$s.innerWrapper),children:jsxRuntimeExports.jsx(ChoiceInner,{pos:pos,showCorrectness:showCorrectness,correct:correct})})})})})};const styles$s=aphrodite.StyleSheet.create({innerWrapper:{width:CHOICE_ICON_SIZE,height:CHOICE_ICON_SIZE,display:"flex",alignItems:"center",justifyContent:"center"},choiceBase:{width:CHOICE_ICON_SIZE,height:CHOICE_ICON_SIZE,boxSizing:"border-box",borderStyle:"solid",borderWidth:2,fontFamily:baseFontFamily,fontWeight:"bold",display:"flex",alignItems:"center",justifyContent:"center"},choiceHasLetter:{fontSize:12},choiceHasIcon:{fontSize:CHOICE_ICON_SIZE},choiceIsChecked:{color:wonderBlocksTokens.color.white},choiceIsUnchecked:{color:wonderBlocksTokens.color.offBlack64},choiceCorrect:{backgroundColor:wonderBlocksTokens.color.green,borderColor:wonderBlocksTokens.color.green},choiceIncorrect:{backgroundColor:wonderBlocksTokens.color.red,borderColor:wonderBlocksTokens.color.red},choiceNeutral:{backgroundColor:wonderBlocksTokens.color.blue,borderColor:wonderBlocksTokens.color.blue},activeNeutral:{color:wonderBlocksTokens.color.blue,borderColor:wonderBlocksTokens.color.blue,backgroundColor:"transparent"},multiSelectShape:{borderRadius:3},singleSelectShape:{borderRadius:CHOICE_ICON_SIZE},uncheckedColors:{borderColor:wonderBlocksTokens.color.offBlack64}});
1800
+ function ChoiceInner(props){const{pos,showCorrectness,correct}=props;const{strings}=usePerseusI18n();const letter=getChoiceLetter(pos,strings);if(!showCorrectness){return jsxRuntimeExports.jsx("span",{children:letter})}if(correct){return jsxRuntimeExports.jsx(InlineIcon,{...iconCheck,style:{position:"relative",top:-1}})}return jsxRuntimeExports.jsx(InlineIcon,{...iconMinus})}const ChoiceIcon=function(props){const{checked,showCorrectness,correct,focused,hovered,multipleSelect,pos,previouslyAnswered,pressed}=props;const choiceIsChecked=checked||showCorrectness&&!correct&&previouslyAnswered;const choiceStyling=[styles$s.choiceBase,multipleSelect?styles$s.multiSelectShape:styles$s.singleSelectShape,showCorrectness?styles$s.choiceHasIcon:styles$s.choiceHasLetter,choiceIsChecked?styles$s.choiceIsChecked:styles$s.choiceIsUnchecked];if(showCorrectness&&correct&&checked){choiceStyling.push(styles$s.choiceCorrect);}else if(showCorrectness&&!correct&&(checked||previouslyAnswered)){choiceStyling.push(styles$s.choiceIncorrect);}else if(checked){choiceStyling.push(styles$s.choiceNeutral);}else if(pressed){choiceStyling.push(styles$s.activeNeutral);}else {choiceStyling.push(styles$s.uncheckedColors);}return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$t.iconWrapper),children:jsxRuntimeExports.jsx(FocusRing,{color:wonderBlocksTokens.color.blue,visible:focused||hovered,multipleSelect:multipleSelect,children:jsxRuntimeExports.jsx("div",{"data-testid":"choice-icon__library-choice-icon",className:aphrodite.css(...choiceStyling),"data-is-radio-icon":true,children:jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$s.innerWrapper),children:jsxRuntimeExports.jsx(ChoiceInner,{pos:pos,showCorrectness:showCorrectness,correct:correct})})})})})};const styles$s=aphrodite.StyleSheet.create({innerWrapper:{width:CHOICE_ICON_SIZE,height:CHOICE_ICON_SIZE,display:"flex",alignItems:"center",justifyContent:"center"},choiceBase:{width:CHOICE_ICON_SIZE,height:CHOICE_ICON_SIZE,boxSizing:"border-box",borderStyle:"solid",borderWidth:2,fontFamily:baseFontFamily,fontWeight:"bold",display:"flex",alignItems:"center",justifyContent:"center"},choiceHasLetter:{fontSize:12},choiceHasIcon:{fontSize:CHOICE_ICON_SIZE},choiceIsChecked:{color:wonderBlocksTokens.color.white},choiceIsUnchecked:{color:wonderBlocksTokens.color.offBlack64},choiceCorrect:{backgroundColor:wonderBlocksTokens.color.green,borderColor:wonderBlocksTokens.color.green},choiceIncorrect:{backgroundColor:wonderBlocksTokens.color.red,borderColor:wonderBlocksTokens.color.red},choiceNeutral:{backgroundColor:wonderBlocksTokens.color.blue,borderColor:wonderBlocksTokens.color.blue},activeNeutral:{color:wonderBlocksTokens.color.blue,borderColor:wonderBlocksTokens.color.blue,backgroundColor:"transparent"},multiSelectShape:{borderRadius:3},singleSelectShape:{borderRadius:CHOICE_ICON_SIZE},uncheckedColors:{borderColor:wonderBlocksTokens.color.offBlack64}});
1799
1801
 
1800
1802
  function renderText(checked,correct,strings){if(correct){if(checked){return strings.correctSelected}return strings.correct}if(checked){return strings.incorrectSelected}return strings.incorrect}const OptionStatus=function(props){const{checked,correct,previouslyAnswered,reviewMode}=props;const{strings}=usePerseusI18n();if(!reviewMode&&!previouslyAnswered){return null}let textStyle;if(correct){textStyle=styles$r.correct;}else {if(checked||previouslyAnswered){textStyle=styles$r.incorrectAnswered;}else {textStyle=styles$r.incorrect;}}return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$r.text,textStyle),children:renderText(checked,correct,strings)})};const styles$r=aphrodite.StyleSheet.create({text:{alignItems:"center",display:"flex",fontSize:12,height:32,textTransform:"uppercase"},correct:{color:wonderBlocksTokens.color.green},incorrectAnswered:{color:wonderBlocksTokens.color.red},incorrect:{color:wonderBlocksTokens.color.offBlack64}});
1801
1803
 
1802
- const intermediateCheckboxPadding=`16px 16px`;const intermediateCheckboxPaddingPhone=`12px 16px`;const Choice=function(props){const{disabled=false,checked=false,content,showCorrectness,multipleSelect,onChange=newValues=>{},reviewMode,correct=false,apiOptions=ApiOptions.defaults,previouslyAnswered=false,pos=0,showRationale=false,rationale,forwardedRef}=props;const[isInputFocused,setIsInputFocused]=React.useState(false);const{strings}=usePerseusI18n();React.useEffect(()=>{if(isInputFocused&&disabled){setIsInputFocused(false);}},[disabled,isInputFocused,setIsInputFocused]);function sendChange(newValues){const updatedChecked=newValues.checked??checked;onChange({checked:updatedChecked});}const descriptionClassName=classNames__default.default("description",aphrodite.css(styles$q.description));const rationaleClassName=classNames__default.default("perseus-radio-rationale-content",aphrodite.css(styles$q.rationale));const showDimmed=!reviewMode&&apiOptions.readOnly;const letter=getChoiceLetter$1(pos,strings);const a11yText=getA11yText(letter,checked,correct,showCorrectness,strings);return jsxRuntimeExports.jsxs("div",{style:{dispay:"flex",flexDirection:"column",color:wonderBlocksTokens.color.offBlack},className:descriptionClassName,children:[jsxRuntimeExports.jsxs("div",{style:{display:"flex",flexDirection:"row",opacity:showDimmed?.5:1,overflowX:"auto",overflowY:"hidden"},children:[jsxRuntimeExports.jsx("div",{className:"perseus-sr-only",children:jsxRuntimeExports.jsxs("label",{children:[a11yText,"   ",content,jsxRuntimeExports.jsx("input",{type:multipleSelect?"checkbox":"radio",checked:checked,onClick:()=>{sendChange({checked:!checked});},onChange:()=>{},disabled:disabled||apiOptions.readOnly,tabIndex:-1,className:ClassNames.RADIO.OPTION_CONTENT})]})}),jsxRuntimeExports.jsx(Clickable__default.default,{onClick:()=>{sendChange({checked:!checked});},disabled:disabled||apiOptions.readOnly,style:{flex:1,color:wonderBlocksTokens.color.offBlack,userSelect:"text"},ref:forwardedRef,"aria-hidden":"true",children:({hovered,focused,pressed})=>jsxRuntimeExports.jsxs("div",{style:{display:"flex",flexDirection:"row",justifyContent:"center",alignContent:"center",paddingTop:wonderBlocksTokens.spacing.xSmall_8,paddingBottom:wonderBlocksTokens.spacing.xSmall_8,paddingLeft:wonderBlocksTokens.spacing.xSmall_8},children:[jsxRuntimeExports.jsx(ChoiceIcon,{pos:pos,correct:correct,pressed:pressed,focused:focused,checked:checked,hovered:hovered,showCorrectness:showCorrectness,multipleSelect:multipleSelect,reviewMode:reviewMode,previouslyAnswered:previouslyAnswered}),jsxRuntimeExports.jsxs("span",{style:{paddingLeft:wonderBlocksTokens.spacing.small_12,textAlign:"left",flex:1,paddingTop:4},children:[jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsx(OptionStatus,{checked:checked,correct:correct,previouslyAnswered:previouslyAnswered,reviewMode:reviewMode})}),jsxRuntimeExports.jsx("div",{children:content})]})]})})]}),showRationale&&jsxRuntimeExports.jsx("div",{className:rationaleClassName,"data-testid":`perseus-radio-rationale-content-${pos}`,children:rationale})]})};const styles$q=aphrodite.StyleSheet.create({description:{display:"inline-block",width:"100%"},rationale:{display:"block",padding:intermediateCheckboxPadding,paddingTop:0,marginLeft:54,color:wonderBlocksTokens.color.offBlack64,[mediaQueries.smOrSmaller]:{padding:intermediateCheckboxPaddingPhone,paddingTop:0}}});var Choice$1 = React__namespace.forwardRef(function ChoiceWithRef(props,ref){return jsxRuntimeExports.jsx(Choice,{...props,forwardedRef:ref})});
1804
+ const intermediateCheckboxPadding=`16px 16px`;const intermediateCheckboxPaddingPhone=`12px 16px`;const Choice=function(props){const{disabled=false,checked=false,content,showCorrectness,multipleSelect,onChange=newValues=>{},reviewMode,correct=false,apiOptions=ApiOptions.defaults,previouslyAnswered=false,pos=0,showRationale=false,rationale,forwardedRef}=props;const[isInputFocused,setIsInputFocused]=React.useState(false);const{strings}=usePerseusI18n();React.useEffect(()=>{if(isInputFocused&&disabled){setIsInputFocused(false);}},[disabled,isInputFocused,setIsInputFocused]);function sendChange(newValues){const updatedChecked=newValues.checked??checked;onChange({checked:updatedChecked});}const descriptionClassName=classNames__default.default("description",aphrodite.css(styles$q.description));const rationaleClassName=classNames__default.default("perseus-radio-rationale-content",aphrodite.css(styles$q.rationale));const showDimmed=!reviewMode&&apiOptions.readOnly;const letter=getChoiceLetter(pos,strings);const a11yText=getA11yText(letter,checked,correct,showCorrectness,strings);return jsxRuntimeExports.jsxs("div",{style:{dispay:"flex",flexDirection:"column",color:wonderBlocksTokens.color.offBlack},className:descriptionClassName,children:[jsxRuntimeExports.jsxs("div",{style:{display:"flex",flexDirection:"row",opacity:showDimmed?.5:1,overflowX:"auto",overflowY:"hidden"},children:[jsxRuntimeExports.jsx("div",{className:"perseus-sr-only",children:jsxRuntimeExports.jsxs("label",{children:[a11yText,"   ",content,jsxRuntimeExports.jsx("input",{type:multipleSelect?"checkbox":"radio",checked:checked,onClick:()=>{sendChange({checked:!checked});},onChange:()=>{},disabled:disabled||apiOptions.readOnly,tabIndex:-1,className:ClassNames.RADIO.OPTION_CONTENT})]})}),jsxRuntimeExports.jsx(Clickable__default.default,{onClick:()=>{sendChange({checked:!checked});},disabled:disabled||apiOptions.readOnly,style:{flex:1,color:wonderBlocksTokens.color.offBlack,userSelect:"text"},ref:forwardedRef,"aria-hidden":"true",children:({hovered,focused,pressed})=>jsxRuntimeExports.jsxs("div",{style:{display:"flex",flexDirection:"row",justifyContent:"center",alignContent:"center",paddingTop:wonderBlocksTokens.spacing.xSmall_8,paddingBottom:wonderBlocksTokens.spacing.xSmall_8,paddingLeft:wonderBlocksTokens.spacing.xSmall_8},children:[jsxRuntimeExports.jsx(ChoiceIcon,{pos:pos,correct:correct,pressed:pressed,focused:focused,checked:checked,hovered:hovered,showCorrectness:showCorrectness,multipleSelect:multipleSelect,reviewMode:reviewMode,previouslyAnswered:previouslyAnswered}),jsxRuntimeExports.jsxs("span",{style:{paddingLeft:wonderBlocksTokens.spacing.small_12,textAlign:"left",flex:1,paddingTop:4},children:[jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsx(OptionStatus,{checked:checked,correct:correct,previouslyAnswered:previouslyAnswered,reviewMode:reviewMode})}),jsxRuntimeExports.jsx("div",{children:content})]})]})})]}),showRationale&&jsxRuntimeExports.jsx("div",{className:rationaleClassName,"data-testid":`perseus-radio-rationale-content-${pos}`,children:rationale})]})};const styles$q=aphrodite.StyleSheet.create({description:{display:"inline-block",width:"100%"},rationale:{display:"block",padding:intermediateCheckboxPadding,paddingTop:0,marginLeft:54,color:wonderBlocksTokens.color.offBlack64,[mediaQueries.smOrSmaller]:{padding:intermediateCheckboxPaddingPhone,paddingTop:0}}});var Choice$1 = React__namespace.forwardRef(function ChoiceWithRef(props,ref){return jsxRuntimeExports.jsx(Choice,{...props,forwardedRef:ref})});
1803
1805
 
1804
1806
  const ChoiceNoneAbove=function({content,forwardedRef,showContent=true,...rest}){const{strings}=usePerseusI18n();const choiceProps={...rest,content:showContent?content:jsxRuntimeExports.jsx(Renderer,{content:strings.noneOfTheAbove,strings:strings},"noneOfTheAboveRenderer")};return jsxRuntimeExports.jsx(Choice$1,{...choiceProps,ref:forwardedRef})};var ChoiceNoneAbove$1 = React__namespace.forwardRef(function ChoiceNoneAboveWithRef(props,ref){return jsxRuntimeExports.jsx(ChoiceNoneAbove,{...props,forwardedRef:ref})});
1805
1807
 
1806
- const{captureScratchpadTouchStart: captureScratchpadTouchStart$1}=Util;function getInstructionsText(multipleSelect,countChoices,numCorrect,strings){if(multipleSelect){if(perseusCore.usesNumCorrect(multipleSelect,!!countChoices,numCorrect)){return strings.chooseNumAnswers({numCorrect:String(numCorrect)})}return strings.chooseAllAnswers}return strings.chooseOneAnswer}const BaseRadio=function({apiOptions,reviewModeRubric,reviewMode,choices,editMode=false,multipleSelect=false,labelWrap,countChoices,numCorrect,isLastUsedWidget,onChange,registerFocusFunction}){const{strings}=usePerseusI18n();const prevReviewModeRubric=React.useRef();const choiceRefs=React.useRef([]);React.useEffect(()=>{if(apiOptions.canScrollPage&&isLastUsedWidget&&reviewModeRubric&&!prevReviewModeRubric.current){const checkedIndex=choices.findIndex(c=>c.checked);if(checkedIndex>=0){const ref=choiceRefs.current[checkedIndex];const anyNode=ReactDOM__namespace.default.findDOMNode(ref.current);const buttonNode=anyNode;if(buttonNode){scrollElementIntoView(buttonNode);}}}prevReviewModeRubric.current=reviewModeRubric;},[apiOptions,choices,isLastUsedWidget,reviewModeRubric]);function updateChoice(choiceIndex,newValues){let newCheckedList;if(newValues.checked&&!multipleSelect){newCheckedList=choices.map(_=>false);}else {newCheckedList=choices.map(c=>c.checked);}newCheckedList[choiceIndex]=newValues.checked;onChange({checked:newCheckedList});}registerFocusFunction?.(choiceIndex=>{const ref=choiceRefs.current[choiceIndex||0];const anyNode=ReactDOM__namespace.default.findDOMNode(ref.current);const buttonNode=anyNode;if(buttonNode){buttonNode.focus();}else {return false}return true});const isMobile=apiOptions.isMobile;const firstChoiceHighlighted=choices[0].highlighted;const lastChoiceHighlighted=choices[choices.length-1].highlighted;const className=classNames__default.default("perseus-widget-radio",!editMode&&"perseus-rendered-radio",aphrodite.css(styles$p.radio,styles$p.responsiveRadioContainer,firstChoiceHighlighted&&isMobile&&styles$p.radioContainerFirstHighlighted,lastChoiceHighlighted&&isMobile&&styles$p.radioContainerLastHighlighted));const instructionsClassName=classNames__default.default("instructions",aphrodite.css(styles$p.instructions,isMobile&&styles$p.instructionsMobile));const instructions=getInstructionsText(multipleSelect,countChoices,numCorrect,strings);const responsiveClassName=aphrodite.css(styles$p.responsiveFieldset);const fieldset=jsxRuntimeExports.jsxs("fieldset",{className:`perseus-widget-radio-fieldset ${responsiveClassName}`,children:[jsxRuntimeExports.jsx("legend",{className:"perseus-sr-only",children:instructions}),jsxRuntimeExports.jsx("div",{className:instructionsClassName,"aria-hidden":"true",children:instructions}),jsxRuntimeExports.jsx("ul",{className:className,style:{listStyle:"none"},children:choices.map((choice,i)=>{let Element=Choice$1;const ref=React__namespace.createRef();choiceRefs.current[i]=ref;const elementProps={apiOptions:apiOptions,multipleSelect:multipleSelect,checked:choice.checked,previouslyAnswered:choice.previouslyAnswered,reviewMode,correct:choice.correct,rationale:choice.rationale,content:choice.content,disabled:apiOptions.readOnly||choice.disabled,showCorrectness:reviewMode||!!choice.showCorrectness,showRationale:choice.hasRationale&&(reviewMode||choice.showRationale),pos:i,onChange:newValues=>{if(editMode){return}updateChoice(i,newValues);}};if(choice.isNoneOfTheAbove){Element=ChoiceNoneAbove$1;___default.default.extend(elementProps,{showContent:choice.revealNoneOfTheAbove});}const nextChoice=choices[i+1];const nextChoiceHighlighted=!!nextChoice&&nextChoice.highlighted;const aphroditeClassName=checked=>{return aphrodite.css(styles$p.item,styles$p.responsiveItem,checked&&styles$p.selectedItem,checked&&choice.highlighted&&styles$p.aboveBackdrop,checked&&choice.highlighted&&apiOptions.isMobile&&styles$p.aboveBackdropMobile,nextChoiceHighlighted&&apiOptions.isMobile&&styles$p.nextHighlighted)};aphroditeClassName(true);let correctnessClass;if(reviewMode&&reviewModeRubric){correctnessClass=reviewModeRubric.choices[i].correct?ClassNames.CORRECT:ClassNames.INCORRECT;}const className=classNames__default.default(aphroditeClassName(choice.checked),ClassNames.RADIO.OPTION,choice.checked&&ClassNames.RADIO.SELECTED,correctnessClass);let listElem=null;let clickHandler;if(editMode){clickHandler=e=>{let elem=e.target;while(elem&&elem!==listElem){if(elem.getAttribute("data-is-radio-icon")){updateChoice(i,{checked:!choice.checked});return}elem=elem.parentNode;}};}return jsxRuntimeExports.jsx("li",{ref:e=>listElem=e,className:className,onClick:clickHandler,onTouchStart:labelWrap?undefined:captureScratchpadTouchStart$1,children:jsxRuntimeExports.jsx(Element,{...elementProps,ref:ref})},i)})})]});return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$p.responsiveContainer),children:fieldset})};const styles$p=aphrodite.StyleSheet.create({instructions:{display:"block",color:gray17,fontSize:14,lineHeight:1.25,fontFamily:"inherit",fontStyle:"normal",fontWeight:"bold",marginBottom:16},instructionsMobile:{fontSize:18,[mediaQueries.smOrSmaller]:{fontSize:16},[mediaQueries.xl]:{fontSize:20}},radio:{padding:0},responsiveRadioContainer:{borderBottom:`1px solid ${radioBorderColor$1}`,borderTop:`1px solid ${radioBorderColor$1}`,width:"auto",[mediaQueries.smOrSmaller]:{marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin}},radioContainerFirstHighlighted:{borderTop:`1px solid rgba(0, 0, 0, 0)`},radioContainerLastHighlighted:{borderBottom:`1px solid rgba(0, 0, 0, 0)`},item:{marginLeft:20},responsiveItem:{marginLeft:0,padding:0,":not(:last-child)":{borderBottom:`1px solid ${radioBorderColor$1}`}},selectedItem:{background:"white"},aboveBackdrop:{position:"relative",zIndex:1062},aboveBackdropMobile:{boxShadow:"0 0 4px 0 rgba(0, 0, 0, 0.2),"+"0 0 2px 0 rgba(0, 0, 0, 0.1)",":not(:last-child)":{borderBottom:`1px solid rgba(0, 0, 0, 0)`}},nextHighlighted:{":not(:last-child)":{borderBottom:`1px solid rgba(0, 0, 0, 0)`}},responsiveContainer:{overflow:"auto",marginLeft:negativePhoneMargin,paddingLeft:phoneMargin},responsiveFieldset:{paddingRight:phoneMargin,minWidth:"auto"}});
1808
+ const{captureScratchpadTouchStart: captureScratchpadTouchStart$1}=Util;function getInstructionsText(multipleSelect,countChoices,numCorrect,strings){if(multipleSelect){if(perseusCore.usesNumCorrect(multipleSelect,!!countChoices,numCorrect)){return strings.chooseNumAnswers({numCorrect:String(numCorrect)})}return strings.chooseAllAnswers}return strings.chooseOneAnswer}const BaseRadio=function({apiOptions,reviewModeRubric,reviewMode,choices,editMode=false,multipleSelect=false,labelWrap,countChoices,numCorrect,isLastUsedWidget,onChange,registerFocusFunction}){const{strings}=usePerseusI18n();const prevReviewModeRubric=React.useRef();const choiceRefs=React.useRef([]);React.useEffect(()=>{if(apiOptions.canScrollPage&&isLastUsedWidget&&reviewModeRubric&&!prevReviewModeRubric.current){const checkedIndex=choices.findIndex(c=>c.checked);if(checkedIndex>=0){const ref=choiceRefs.current[checkedIndex];const anyNode=ReactDOM__namespace.default.findDOMNode(ref.current);const buttonNode=anyNode;if(buttonNode){scrollElementIntoView(buttonNode);}}}prevReviewModeRubric.current=reviewModeRubric;},[apiOptions,choices,isLastUsedWidget,reviewModeRubric]);function updateChoice(choiceIndex,newValues){let newCheckedList;if(newValues.checked&&!multipleSelect){newCheckedList=choices.map(_=>false);}else {newCheckedList=choices.map(c=>c.checked);}newCheckedList[choiceIndex]=newValues.checked;onChange({checked:newCheckedList});}registerFocusFunction?.(choiceIndex=>{const ref=choiceRefs.current[choiceIndex||0];const anyNode=ReactDOM__namespace.default.findDOMNode(ref.current);const buttonNode=anyNode;if(buttonNode){buttonNode.focus();}else {return false}return true});const isMobile=apiOptions.isMobile;const firstChoiceHighlighted=choices[0].highlighted;const lastChoiceHighlighted=choices[choices.length-1].highlighted;const className=classNames__default.default("perseus-widget-radio",!editMode&&"perseus-rendered-radio",aphrodite.css(styles$p.radio,styles$p.responsiveRadioContainer,firstChoiceHighlighted&&isMobile&&styles$p.radioContainerFirstHighlighted,lastChoiceHighlighted&&isMobile&&styles$p.radioContainerLastHighlighted));const instructionsClassName=classNames__default.default("instructions",aphrodite.css(styles$p.instructions,isMobile&&styles$p.instructionsMobile));const instructions=getInstructionsText(multipleSelect,countChoices,numCorrect,strings);const responsiveClassName=aphrodite.css(styles$p.responsiveFieldset);const fieldset=jsxRuntimeExports.jsxs("fieldset",{className:`perseus-widget-radio-fieldset ${responsiveClassName}`,children:[jsxRuntimeExports.jsx("legend",{className:"perseus-sr-only",children:instructions}),jsxRuntimeExports.jsx("div",{className:instructionsClassName,"aria-hidden":"true",children:instructions}),jsxRuntimeExports.jsx("ul",{className:className,style:{listStyle:"none"},children:choices.map((choice,i)=>{let Element=Choice$1;const ref=React__namespace.createRef();choiceRefs.current[i]=ref;const elementProps={id:choice.id,apiOptions:apiOptions,multipleSelect:multipleSelect,checked:choice.checked,previouslyAnswered:choice.previouslyAnswered,reviewMode,correct:choice.correct,rationale:choice.rationale,content:choice.content,disabled:apiOptions.readOnly||choice.disabled,showCorrectness:reviewMode||!!choice.showCorrectness,showRationale:choice.hasRationale&&(reviewMode||choice.showRationale),pos:i,onChange:newValues=>{if(editMode){return}updateChoice(i,newValues);}};if(choice.isNoneOfTheAbove){Element=ChoiceNoneAbove$1;___default.default.extend(elementProps,{showContent:choice.revealNoneOfTheAbove});}const nextChoice=choices[i+1];const nextChoiceHighlighted=!!nextChoice&&nextChoice.highlighted;const aphroditeClassName=checked=>{return aphrodite.css(styles$p.item,styles$p.responsiveItem,checked&&styles$p.selectedItem,checked&&choice.highlighted&&styles$p.aboveBackdrop,checked&&choice.highlighted&&apiOptions.isMobile&&styles$p.aboveBackdropMobile,nextChoiceHighlighted&&apiOptions.isMobile&&styles$p.nextHighlighted)};aphroditeClassName(true);let correctnessClass;if(reviewMode&&reviewModeRubric){correctnessClass=reviewModeRubric.choices[i].correct?ClassNames.CORRECT:ClassNames.INCORRECT;}const className=classNames__default.default(aphroditeClassName(choice.checked),ClassNames.RADIO.OPTION,choice.checked&&ClassNames.RADIO.SELECTED,correctnessClass);let listElem=null;let clickHandler;if(editMode){clickHandler=e=>{let elem=e.target;while(elem&&elem!==listElem){if(elem.getAttribute("data-is-radio-icon")){updateChoice(i,{checked:!choice.checked});return}elem=elem.parentNode;}};}return jsxRuntimeExports.jsx("li",{ref:e=>listElem=e,className:className,onClick:clickHandler,onTouchStart:labelWrap?undefined:captureScratchpadTouchStart$1,children:jsxRuntimeExports.jsx(Element,{...elementProps,ref:ref})},choice.id)})})]});return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$p.responsiveContainer),children:fieldset})};const styles$p=aphrodite.StyleSheet.create({instructions:{display:"block",color:gray17,fontSize:14,lineHeight:1.25,fontFamily:"inherit",fontStyle:"normal",fontWeight:"bold",marginBottom:16},instructionsMobile:{fontSize:18,[mediaQueries.smOrSmaller]:{fontSize:16},[mediaQueries.xl]:{fontSize:20}},radio:{padding:0},responsiveRadioContainer:{borderBottom:`1px solid ${radioBorderColor$1}`,borderTop:`1px solid ${radioBorderColor$1}`,width:"auto",[mediaQueries.smOrSmaller]:{marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin}},radioContainerFirstHighlighted:{borderTop:`1px solid rgba(0, 0, 0, 0)`},radioContainerLastHighlighted:{borderBottom:`1px solid rgba(0, 0, 0, 0)`},item:{marginLeft:20},responsiveItem:{marginLeft:0,padding:0,":not(:last-child)":{borderBottom:`1px solid ${radioBorderColor$1}`}},selectedItem:{background:"white"},aboveBackdrop:{position:"relative",zIndex:1062},aboveBackdropMobile:{boxShadow:"0 0 4px 0 rgba(0, 0, 0, 0.2),"+"0 0 2px 0 rgba(0, 0, 0, 0.1)",":not(:last-child)":{borderBottom:`1px solid rgba(0, 0, 0, 0)`}},nextHighlighted:{":not(:last-child)":{borderBottom:`1px solid rgba(0, 0, 0, 0)`}},responsiveContainer:{overflow:"auto",marginLeft:negativePhoneMargin,paddingLeft:phoneMargin},responsiveFieldset:{paddingRight:phoneMargin,minWidth:"auto"}});
1807
1809
 
1808
- let Radio$2 = class Radio extends React__namespace.Component{focus(choiceIndex){if(this.focusFunction){return this.focusFunction(choiceIndex)}return false}registerFocusFunction(fun){this.focusFunction=fun;}getPromptJSON(){return getPromptJSON$q(this.props,this.props.userInput)}render(){const{choices}=this.props;const{strings}=this.context;let choiceStates;if(this.props.static){choiceStates=choices.map(choice=>({selected:!!choice.correct,crossedOut:false,readOnly:true,highlighted:false,rationaleShown:true,correctnessShown:true,previouslyAnswered:false}));}else if(this.props.showSolutions==="all"){choiceStates=choices.map(({correct})=>({selected:!!correct,crossedOut:false,readOnly:true,highlighted:false,rationaleShown:true,correctnessShown:true,previouslyAnswered:false}));}else if(this.props.choiceStates){choiceStates=this.props.choiceStates;}else if(this.props.values){choiceStates=this.props.values.map(val=>({selected:val,crossedOut:false,readOnly:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}));}else {choiceStates=choices.map(()=>({selected:false,crossedOut:false,readOnly:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}));}const choicesProp=choices.map((choice,i)=>{const content=choice.isNoneOfTheAbove&&!choice.content?strings.noneOfTheAbove:choice.content;const{selected,rationaleShown,correctnessShown,readOnly,highlighted,previouslyAnswered}=choiceStates[i];const reviewChoice=this.props.reviewModeRubric?.choices[i];return {content:this._renderRenderer(content),checked:selected,correct:choice.correct===undefined?!!reviewChoice&&!!reviewChoice.correct:choice.correct,disabled:readOnly,hasRationale:!!choice.rationale,rationale:this._renderRenderer(choice.rationale),showRationale:rationaleShown,showCorrectness:correctnessShown,isNoneOfTheAbove:!!choice.isNoneOfTheAbove,revealNoneOfTheAbove:!!(this.props.questionCompleted&&selected),highlighted,previouslyAnswered:previouslyAnswered}});return jsxRuntimeExports.jsx(BaseRadio,{labelWrap:true,multipleSelect:this.props.multipleSelect,countChoices:this.props.countChoices,numCorrect:this.props.numCorrect,choices:choicesProp,onChange:this.updateChoices,reviewModeRubric:this.props.reviewModeRubric,reviewMode:this.props.reviewMode,deselectEnabled:this.props.deselectEnabled,apiOptions:this.props.apiOptions,isLastUsedWidget:this.props.isLastUsedWidget,registerFocusFunction:i=>this.registerFocusFunction(i)})}constructor(...args){super(...args),this._renderRenderer=(content="")=>{let nextPassageRefId=1;const widgets={};const modContent=content.replace(/\{\{passage-ref (\d+) (\d+)(?: "([^"]*)")?\}\}/g,(match,passageNum,refNum,summaryText)=>{const widgetId="passage-ref "+nextPassageRefId;nextPassageRefId++;widgets[widgetId]={type:"passage-ref",graded:false,options:{passageNumber:parseInt(passageNum),referenceNumber:parseInt(refNum),summaryText:summaryText},version:PassageRef$1.version};return "[["+Util.snowman+" "+widgetId+"]]"});return jsxRuntimeExports.jsx(Renderer,{content:modContent,widgets:widgets,findExternalWidgets:this.props.findWidgets,alwaysUpdate:true,linterContext:{...this.props.linterContext,blockHighlight:true},strings:this.context.strings},"choiceContentRenderer")},this.updateChoices=newValueLists=>{const{choiceStates,choices}=this.props;const newChoiceStates=choiceStates?choiceStates.map(state=>({...state})):choices.map(()=>({selected:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false,readOnly:false}));newChoiceStates.forEach((choiceState,i)=>{choiceState.selected=newValueLists.checked[i];});this.props.onChange({choiceStates:newChoiceStates});this.props.trackInteraction();};}};Radio$2.contextType=PerseusI18nContext;Radio$2.defaultProps={choices:[],multipleSelect:false,countChoices:false,deselectEnabled:false,linterContext:PerseusLinter.linterContextDefault,showSolutions:"none"};
1810
+ let Radio$2 = class Radio extends React__namespace.Component{focus(choiceIndex){if(this.focusFunction){return this.focusFunction(choiceIndex)}return false}registerFocusFunction(fun){this.focusFunction=fun;}getPromptJSON(){return getPromptJSON$q(this.props,this.props.userInput)}render(){const{choices}=this.props;const{strings}=this.context;let choiceStates;if(this.props.static){choiceStates=choices.map(choice=>({selected:!!choice.correct,crossedOut:false,readOnly:true,highlighted:false,rationaleShown:true,correctnessShown:true,previouslyAnswered:false}));}else if(this.props.showSolutions==="all"){choiceStates=choices.map(({correct})=>({selected:!!correct,crossedOut:false,readOnly:true,highlighted:false,rationaleShown:true,correctnessShown:true,previouslyAnswered:false}));}else if(this.props.choiceStates){choiceStates=this.props.choiceStates;}else if(this.props.values){choiceStates=this.props.values.map(val=>({selected:val,crossedOut:false,readOnly:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}));}else {choiceStates=choices.map(()=>({selected:false,crossedOut:false,readOnly:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}));}const choicesProp=choices.map((choice,i)=>{const content=choice.isNoneOfTheAbove&&!choice.content?strings.noneOfTheAbove:choice.content;const{selected,rationaleShown,correctnessShown,readOnly,highlighted,previouslyAnswered}=choiceStates[i];const reviewChoice=this.props.reviewModeRubric?.choices[i];return {id:choice.id,content:this._renderRenderer(content),checked:selected,correct:choice.correct===undefined?!!reviewChoice&&!!reviewChoice.correct:choice.correct,disabled:readOnly,hasRationale:!!choice.rationale,rationale:this._renderRenderer(choice.rationale),showRationale:rationaleShown,showCorrectness:correctnessShown,isNoneOfTheAbove:!!choice.isNoneOfTheAbove,revealNoneOfTheAbove:!!(this.props.questionCompleted&&selected),highlighted,previouslyAnswered:previouslyAnswered}});return jsxRuntimeExports.jsx(BaseRadio,{labelWrap:true,multipleSelect:this.props.multipleSelect,countChoices:this.props.countChoices,numCorrect:this.props.numCorrect,choices:choicesProp,onChange:this.updateChoices,reviewModeRubric:this.props.reviewModeRubric,reviewMode:this.props.reviewMode,deselectEnabled:this.props.deselectEnabled,apiOptions:this.props.apiOptions,isLastUsedWidget:this.props.isLastUsedWidget,registerFocusFunction:i=>this.registerFocusFunction(i)})}constructor(...args){super(...args),this._renderRenderer=(content="")=>{let nextPassageRefId=1;const widgets={};const modContent=content.replace(/\{\{passage-ref (\d+) (\d+)(?: "([^"]*)")?\}\}/g,(match,passageNum,refNum,summaryText)=>{const widgetId="passage-ref "+nextPassageRefId;nextPassageRefId++;widgets[widgetId]={type:"passage-ref",graded:false,options:{passageNumber:parseInt(passageNum),referenceNumber:parseInt(refNum),summaryText:summaryText},version:PassageRef$1.version};return "[["+Util.snowman+" "+widgetId+"]]"});return jsxRuntimeExports.jsx(Renderer,{content:modContent,widgets:widgets,findExternalWidgets:this.props.findWidgets,alwaysUpdate:true,linterContext:{...this.props.linterContext,blockHighlight:true},strings:this.context.strings},"choiceContentRenderer")},this.updateChoices=newValueLists=>{const{choiceStates,choices}=this.props;const newChoiceStates=choiceStates?choiceStates.map(state=>({...state})):choices.map(()=>({selected:false,highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false,readOnly:false}));newChoiceStates.forEach((choiceState,i)=>{choiceState.selected=newValueLists.checked[i];});this.props.onChange({choiceStates:newChoiceStates});this.props.trackInteraction();};}};Radio$2.contextType=PerseusI18nContext;Radio$2.defaultProps={choices:[],multipleSelect:false,countChoices:false,deselectEnabled:false,linterContext:PerseusLinter.linterContextDefault,showSolutions:"none"};
1809
1811
 
1810
1812
  function initChoiceStates(choices){return choices.map(()=>({highlighted:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false,readOnly:false}))}let Radio$1 = class Radio extends Radio$2{UNSAFE_componentWillUpdate(nextProps){if(!___default.default.isEqual(nextProps.choices,this.props.choices)){this.setState({choiceStates:initChoiceStates(nextProps.choices)});}}getSerializedState(){const{userInput:_,...rest}=this._mergePropsAndState();return {...rest}}_handleChange(arg){const newChoiceStates=arg.choiceStates;if(newChoiceStates){this.setState({choiceStates:newChoiceStates.map(choiceState=>{const{selected:_,...rest}=choiceState;return {...rest}})},()=>{const props=this._mergePropsAndState();const mergedProps={...props,choiceStates:perseusCore.deepClone(props.choiceStates||[]).map((choiceState,index)=>{return {...choiceState,selected:newChoiceStates[index].selected}})};const unshuffledUserInput=getUserInputFromSerializedState$f(mergedProps);this.props.handleUserInput(unshuffledUserInput);});}else {throw new Error("unhandled onChange call in Radio!")}}_mergePropsAndState(){return {...this.props,choiceStates:this.state.choiceStates?.map((choiceState,index)=>{const choice=this.props.choices[index];const selected=this.props.userInput?.choicesSelected[choice.originalIndex];return {...choiceState,selected}}),onChange:arg=>this._handleChange(arg)}}focus(choiceIndex){if(this.radioRef.current?.focus){return this.radioRef.current.focus(choiceIndex)}return false}render(){const props=this._mergePropsAndState();return this.ffIsOn?jsxRuntimeExports.jsx(Radio$3,{...props}):jsxRuntimeExports.jsx(Radio$2,{ref:this.radioRef,...props})}constructor(props){super(props),this.ffIsOn=false,this.radioRef=React__namespace.createRef(),this.state={choiceStates:[]};this.ffIsOn=props.apiOptions.flags?.["new-radio-widget"]??false;this.state={choiceStates:initChoiceStates(props.choices)};}};
1811
1813
 
1812
- const _choiceTransform=(widgetOptions,strings)=>{const _maybeRandomize=function(array){return widgetOptions.randomize?perseusCore.randomizeArrayElements(array):array};const _addNoneOfAbove=function(choices){let noneOfTheAbove=null;const newChoices=choices.filter((choice,index)=>{if(choice.isNoneOfTheAbove){noneOfTheAbove=choice;return false}return true});if(noneOfTheAbove){newChoices.push(noneOfTheAbove);}return newChoices};const enforceOrdering=choices=>{const ReversedChoices=[[strings.false,strings.true],[strings.no,strings.yes]];const content=choices.map(c=>c.content);if(ReversedChoices.some(reversed=>___default.default.isEqual(content,reversed))){return [choices[1],choices[0]]}return choices};const choices=widgetOptions.choices.map((choice,i)=>{return {...choice,originalIndex:i,correct:Boolean(choice.correct)}});return _addNoneOfAbove(enforceOrdering(_maybeRandomize(choices)))};const transform$5=(widgetOptions,strings)=>{const choices=_choiceTransform(widgetOptions,strings);const{hasNoneOfTheAbove,multipleSelect,countChoices,deselectEnabled,numCorrect}=widgetOptions;return {numCorrect:numCorrect,hasNoneOfTheAbove,multipleSelect,countChoices,deselectEnabled,choices,selectedChoices:___default.default.pluck(choices,"correct")}};function getStartUserInput$g(options){return {choicesSelected:options.choices.map(()=>false)}}function getCorrectUserInput$6(options){return {choicesSelected:options.choices.map(option=>!!option.correct)}}var Radio = {name:"radio",displayName:"Radio / Multiple choice",widget:Radio$1,transform: transform$5,staticTransform:transform$5,getStartUserInput: getStartUserInput$g,getCorrectUserInput: getCorrectUserInput$6,version:perseusCore.radioLogic.version,isLintable:true,getUserInputFromSerializedState:serializedState=>{return getUserInputFromSerializedState$f(serializedState,true)}};
1814
+ const _choiceTransform=(widgetOptions,strings)=>{const _maybeRandomize=function(array){return widgetOptions.randomize?perseusCore.randomizeArrayElements(array):array};const _addNoneOfAbove=function(choices){let noneOfTheAbove=null;const newChoices=choices.filter((choice,index)=>{if(choice.isNoneOfTheAbove){noneOfTheAbove=choice;return false}return true});if(noneOfTheAbove){newChoices.push(noneOfTheAbove);}return newChoices};const enforceOrdering=choices=>{const ReversedChoices=[[strings.false,strings.true],[strings.no,strings.yes]];const content=choices.map(c=>c.content);if(ReversedChoices.some(reversed=>___default.default.isEqual(content,reversed))){return [choices[1],choices[0]]}return choices};const choices=widgetOptions.choices.map((choice,i)=>{return {...choice,originalIndex:i,correct:Boolean(choice.correct)}});return _addNoneOfAbove(enforceOrdering(_maybeRandomize(choices)))};const transform$1=(widgetOptions,strings)=>{const choices=_choiceTransform(widgetOptions,strings);const{hasNoneOfTheAbove,multipleSelect,countChoices,deselectEnabled,numCorrect}=widgetOptions;return {numCorrect:numCorrect,hasNoneOfTheAbove,multipleSelect,countChoices,deselectEnabled,choices,selectedChoices:___default.default.pluck(choices,"correct")}};function getStartUserInput$g(options){return {choicesSelected:options.choices.map(()=>false)}}function getCorrectUserInput$6(options){return {choicesSelected:options.choices.map(option=>!!option.correct)}}var Radio = {name:"radio",displayName:"Radio / Multiple choice",widget:Radio$1,transform: transform$1,staticTransform:transform$1,getStartUserInput: getStartUserInput$g,getCorrectUserInput: getCorrectUserInput$6,version:perseusCore.radioLogic.version,isLintable:true,getUserInputFromSerializedState:serializedState=>{return getUserInputFromSerializedState$f(serializedState,true)}};
1813
1815
 
1814
1816
  var basicWidgets = [Radio,InputNumber$1,NumericInput$1,Expression$1];
1815
1817
 
@@ -1817,7 +1819,7 @@ const{radioBorderColor,checkedColor,circleSize,radioMarginWidth}=constants;var s
1817
1819
 
1818
1820
  const getPromptJSON$n=renderProps=>{return {type:"categorizer",options:{items:renderProps.items,categories:renderProps.categories},userInput:{itemToCategoryMapping:renderProps.userInput.values}}};
1819
1821
 
1820
- class Categorizer extends React__namespace.Component{getSerializedState(){const{userInput,...rest}=this.props;return {...rest,values:userInput.values}}getPromptJSON(){return getPromptJSON$n(this.props)}_handleUserInput(itemNum,catNum){const values=[...this.props.userInput.values];values[itemNum]=catNum;this.props.handleUserInput({values});this.props.trackInteraction();}render(){const self=this;const isMobile=this.props.apiOptions.isMobile;let indexedItems=this.props.items.map((item,n)=>[item,n]);if(this.props.randomizeItems){indexedItems=perseusCore.shuffle(indexedItems,this.props.problemNum);}const table=jsxRuntimeExports.jsxs("table",{className:"categorizer-table "+aphrodite.css(styles$o.mobileTable),children:[jsxRuntimeExports.jsx("thead",{children:jsxRuntimeExports.jsxs("tr",{children:[jsxRuntimeExports.jsx("td",{className:aphrodite.css(styles$o.emptyHeaderCell)}),this.props.categories.map((category,i)=>{return jsxRuntimeExports.jsx("th",{className:aphrodite.css(styles$o.header),children:jsxRuntimeExports.jsx(Renderer,{content:category,linterContext:this.props.linterContext,strings:this.context.strings})},i)})]})}),jsxRuntimeExports.jsx("tbody",{children:indexedItems.map(indexedItem=>{const item=indexedItem[0];const itemNum=indexedItem[1];const uniqueId=self.state.uniqueId+"_"+itemNum;return jsxRuntimeExports.jsxs("tr",{children:[jsxRuntimeExports.jsx("td",{children:jsxRuntimeExports.jsx(Renderer,{content:item,linterContext:this.props.linterContext,strings:this.context.strings})}),self.props.categories.map((catName,catNum)=>{const selected=self.props.userInput.values[itemNum]===catNum;return jsxRuntimeExports.jsx("td",{className:"category "+aphrodite.css(styles$o.cell),children:jsxRuntimeExports.jsxs("div",{role:"button","aria-label":catName,onClick:()=>this._handleUserInput(itemNum,catNum),children:[isMobile&&jsxRuntimeExports.jsx("input",{type:"radio",name:uniqueId,className:aphrodite.css(sharedStyles.responsiveInput,sharedStyles.responsiveRadioInput),checked:selected,onChange:()=>this._handleUserInput(itemNum,catNum),onClick:e=>e.stopPropagation()}),!isMobile&&jsxRuntimeExports.jsx("span",{className:aphrodite.css(styles$o.radioSpan,selected&&styles$o.checkedRadioSpan,this.props.static&&selected&&styles$o.staticCheckedRadioSpan),children:selected?jsxRuntimeExports.jsx(InlineIcon,{...iconCircle}):jsxRuntimeExports.jsx(InlineIcon,{...iconCircleThin})})]})},catNum)})]},itemNum)})})]});const extraClassNames=classNames__default.default({"categorizer-container":true,"static-mode":this.props.static});const inlineStyles=this.props.apiOptions.isMobile?[styles$o.fullBleedContainer]:[];return jsxRuntimeExports.jsx("div",{className:extraClassNames+" "+aphrodite.css(...inlineStyles),children:table})}constructor(...args){super(...args),this.state={uniqueId:___default.default.uniqueId("perseus_radio_")};}}Categorizer.contextType=PerseusI18nContext;Categorizer.defaultProps={items:[],categories:[],linterContext:PerseusLinter.linterContextDefault,userInput:{values:[]}};const styles$o=aphrodite.StyleSheet.create({mobileTable:{[mediaQueries.smOrSmaller]:{minWidth:"auto"}},fullBleedContainer:{[mediaQueries.mdOrSmaller]:{marginLeft:-16,marginRight:-16,overflowX:"auto"}},header:{textAlign:"center",verticalAlign:"bottom"},cell:{textAlign:"center",padding:0,color:"#ccc",verticalAlign:"middle"},emptyHeaderCell:{backgroundColor:"inherit",borderBottom:"2px solid #ccc"},radioSpan:{fontSize:30,paddingRight:3,":hover":{color:"#999"}},checkedRadioSpan:{color:"#333"},staticCheckedRadioSpan:{color:"#888"}});function getUserInputFromSerializedState$e(serializedState){return {values:serializedState.values}}function getCorrectUserInput$5(options){return {values:options.values}}function getStartUserInput$f(){return {values:[]}}function transform$4(widgetOptions){return {items:widgetOptions.items,categories:widgetOptions.categories,randomizeItems:widgetOptions.randomizeItems}}var Categorizer$1 = {name:"categorizer",displayName:"Categorizer",hidden:true,widget:Categorizer,transform: transform$4,staticTransform:transform$4,getUserInputFromSerializedState: getUserInputFromSerializedState$e,getCorrectUserInput: getCorrectUserInput$5,getStartUserInput: getStartUserInput$f,isLintable:true};
1822
+ class Categorizer extends React__namespace.Component{getSerializedState(){const{userInput,...rest}=this.props;return {...rest,values:userInput.values}}getPromptJSON(){return getPromptJSON$n(this.props)}_handleUserInput(itemNum,catNum){const values=[...this.props.userInput.values];values[itemNum]=catNum;this.props.handleUserInput({values});this.props.trackInteraction();}render(){const self=this;const isMobile=this.props.apiOptions.isMobile;let indexedItems=this.props.items.map((item,n)=>[item,n]);if(this.props.randomizeItems){indexedItems=perseusCore.shuffle(indexedItems,this.props.problemNum);}const table=jsxRuntimeExports.jsxs("table",{className:"categorizer-table "+aphrodite.css(styles$o.mobileTable),children:[jsxRuntimeExports.jsx("thead",{children:jsxRuntimeExports.jsxs("tr",{children:[jsxRuntimeExports.jsx("td",{className:aphrodite.css(styles$o.emptyHeaderCell)}),this.props.categories.map((category,i)=>{return jsxRuntimeExports.jsx("th",{className:aphrodite.css(styles$o.header),children:jsxRuntimeExports.jsx(Renderer,{content:category,linterContext:this.props.linterContext,strings:this.context.strings})},i)})]})}),jsxRuntimeExports.jsx("tbody",{children:indexedItems.map(indexedItem=>{const item=indexedItem[0];const itemNum=indexedItem[1];const uniqueId=self.state.uniqueId+"_"+itemNum;return jsxRuntimeExports.jsxs("tr",{children:[jsxRuntimeExports.jsx("td",{children:jsxRuntimeExports.jsx(Renderer,{content:item,linterContext:this.props.linterContext,strings:this.context.strings})}),self.props.categories.map((catName,catNum)=>{const selected=self.props.userInput.values[itemNum]===catNum;return jsxRuntimeExports.jsx("td",{className:"category "+aphrodite.css(styles$o.cell),children:jsxRuntimeExports.jsxs("div",{role:"button","aria-label":catName,onClick:()=>this._handleUserInput(itemNum,catNum),children:[isMobile&&jsxRuntimeExports.jsx("input",{type:"radio",name:uniqueId,className:aphrodite.css(sharedStyles.responsiveInput,sharedStyles.responsiveRadioInput),checked:selected,onChange:()=>this._handleUserInput(itemNum,catNum),onClick:e=>e.stopPropagation()}),!isMobile&&jsxRuntimeExports.jsx("span",{className:aphrodite.css(styles$o.radioSpan,selected&&styles$o.checkedRadioSpan,this.props.static&&selected&&styles$o.staticCheckedRadioSpan),children:selected?jsxRuntimeExports.jsx(InlineIcon,{...iconCircle}):jsxRuntimeExports.jsx(InlineIcon,{...iconCircleThin})})]})},catNum)})]},itemNum)})})]});const extraClassNames=classNames__default.default({"categorizer-container":true,"static-mode":this.props.static});const inlineStyles=this.props.apiOptions.isMobile?[styles$o.fullBleedContainer]:[];return jsxRuntimeExports.jsx("div",{className:extraClassNames+" "+aphrodite.css(...inlineStyles),children:table})}constructor(...args){super(...args),this.state={uniqueId:___default.default.uniqueId("perseus_radio_")};}}Categorizer.contextType=PerseusI18nContext;Categorizer.defaultProps={items:[],categories:[],linterContext:PerseusLinter.linterContextDefault,userInput:{values:[]}};const styles$o=aphrodite.StyleSheet.create({mobileTable:{[mediaQueries.smOrSmaller]:{minWidth:"auto"}},fullBleedContainer:{[mediaQueries.mdOrSmaller]:{marginLeft:-16,marginRight:-16,overflowX:"auto"}},header:{textAlign:"center",verticalAlign:"bottom"},cell:{textAlign:"center",padding:0,color:"#ccc",verticalAlign:"middle"},emptyHeaderCell:{backgroundColor:"inherit",borderBottom:"2px solid #ccc"},radioSpan:{fontSize:30,paddingRight:3,":hover":{color:"#999"}},checkedRadioSpan:{color:"#333"},staticCheckedRadioSpan:{color:"#888"}});function getUserInputFromSerializedState$e(serializedState){return {values:serializedState.values}}function getCorrectUserInput$5(options){return {values:options.values}}function getStartUserInput$f(){return {values:[]}}var Categorizer$1 = {name:"categorizer",displayName:"Categorizer",hidden:true,widget:Categorizer,getUserInputFromSerializedState: getUserInputFromSerializedState$e,getCorrectUserInput: getCorrectUserInput$5,getStartUserInput: getStartUserInput$f,isLintable:true};
1821
1823
 
1822
1824
  const isFileProtocol=protocol=>{if(protocol&&protocol.toLowerCase()==="file:"){return true}return false};
1823
1825
 
@@ -1827,7 +1829,7 @@ const getUnsupportedPromptJSON=(widgetType,message="")=>{return {type:widgetType
1827
1829
 
1828
1830
  const getPromptJSON$m=()=>{return getUnsupportedPromptJSON("cs-program")};
1829
1831
 
1830
- const{updateQueryString: updateQueryString$1}=Util;function getUrlFromProgramID$1(programID){const{InitialRequestUrl}=getDependencies();const path="/computer-programming/program/"+`${programID}/embedded?embed=yes&author=no`;if(isFileProtocol(InitialRequestUrl.protocol)){return `https://khanacademy.org${path}`}return toAbsoluteUrl(path)}class CSProgram extends React__namespace.Component{componentDidMount(){$__default.default(window).on("message",this.handleMessageEvent);}componentWillUnmount(){$__default.default(window).off("message",this.handleMessageEvent);}getPromptJSON(){return getPromptJSON$m()}render(){if(!this.props.programID){return jsxRuntimeExports.jsx("div",{})}let styleContainer=false;let url=getUrlFromProgramID$1(this.props.programID);let className;const style={height:this.props.height,width:"100%"};if(this.props.showEditor){url+="&editor=yes";className="perseus-scratchpad-editor";}else {url+=`&editor=no&width=${articleMaxWidthInPx}`;className="perseus-scratchpad";if(this.props.programType!=="webpage"){styleContainer=true;}}if(this.props.showButtons){url+="&buttons=yes";style.height+=67;}else {url+="&buttons=no";}if(this.props.settings){const settings={};___default.default.each(this.props.settings,function(setting){if(setting.name&&setting.value){settings[setting.name]=setting.value;}});url=updateQueryString$1(url,"settings",JSON.stringify(settings));}const sandboxOptions=["allow-popups","allow-same-origin","allow-scripts","allow-top-navigation"].join(" ");return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$n.widthOverride,styleContainer&&styles$n.container),children:jsxRuntimeExports.jsx("iframe",{sandbox:sandboxOptions,src:url,style:style,className:className,allowFullScreen:true})})}constructor(...args){super(...args),this.handleMessageEvent=e=>{let data={};try{data=JSON.parse(e.originalEvent.data);}catch{return}if(___default.default.isUndefined(data.testsPassed)){return}const status=data.testsPassed?"correct":"incorrect";this.props.handleUserInput({status:status,message:data.message});};}}CSProgram.defaultProps={showEditor:false,showButtons:false,userInput:{status:"incomplete",message:null}};const styles$n=aphrodite.StyleSheet.create({widthOverride:{width:820},container:{margin:"auto"}});function getUserInputFromSerializedState$d(serializedState){return {status:serializedState.status,message:serializedState.message}}function getStartUserInput$e(){return {status:"incomplete",message:null}}var CSProgram$1 = {name:"cs-program",displayName:"CS Program",widget:CSProgram,hidden:true,getStartUserInput: getStartUserInput$e,getUserInputFromSerializedState: getUserInputFromSerializedState$d};
1832
+ const{updateQueryString: updateQueryString$1}=Util;function getUrlFromProgramID$1(programID){const{InitialRequestUrl}=getDependencies();const path="/computer-programming/program/"+`${programID}/embedded?embed=yes&author=no`;if(isFileProtocol(InitialRequestUrl.protocol)){return `https://khanacademy.org${path}`}return toAbsoluteUrl(path)}class CSProgram extends React__namespace.Component{componentDidMount(){$__default.default(window).on("message",this.handleMessageEvent);}componentWillUnmount(){$__default.default(window).off("message",this.handleMessageEvent);}getPromptJSON(){return getPromptJSON$m()}render(){if(!this.props.programID){return jsxRuntimeExports.jsx("div",{})}let styleContainer=false;let url=getUrlFromProgramID$1(this.props.programID);let className;const style={height:this.props.height,width:"100%"};if(this.props.showEditor){url+="&editor=yes";className="perseus-scratchpad-editor";}else {url+=`&editor=no&width=${articleMaxWidthInPx}`;className="perseus-scratchpad";if(this.props.programType!=="webpage"){styleContainer=true;}}if(this.props.showButtons){url+="&buttons=yes";style.height+=67;}else {url+="&buttons=no";}if(this.props.settings){const settings={};___default.default.each(this.props.settings,function(setting){if(setting.name&&setting.value){settings[setting.name]=setting.value;}});url=updateQueryString$1(url,"settings",JSON.stringify(settings));}const sandboxOptions=["allow-popups","allow-same-origin","allow-scripts","allow-top-navigation"].join(" ");return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styleContainer&&styles$n.container),children:jsxRuntimeExports.jsx("iframe",{sandbox:sandboxOptions,src:url,style:style,className:className,allowFullScreen:true})})}constructor(...args){super(...args),this.handleMessageEvent=e=>{let data={};try{data=JSON.parse(e.originalEvent.data);}catch{return}if(___default.default.isUndefined(data.testsPassed)){return}const status=data.testsPassed?"correct":"incorrect";this.props.handleUserInput({status:status,message:data.message});};}}CSProgram.defaultProps={showEditor:false,showButtons:false,userInput:{status:"incomplete",message:null}};const styles$n=aphrodite.StyleSheet.create({container:{margin:"auto"}});function getUserInputFromSerializedState$d(serializedState){return {status:serializedState.status,message:serializedState.message}}function getStartUserInput$e(){return {status:"incomplete",message:null}}var CSProgram$1 = {name:"cs-program",displayName:"CS Program",widget:CSProgram,hidden:true,getStartUserInput: getStartUserInput$e,getUserInputFromSerializedState: getUserInputFromSerializedState$d};
1831
1833
 
1832
1834
  const getPromptJSON$l=renderProps=>{return {type:"definition",definition:renderProps.definition,togglePrompt:renderProps.togglePrompt}};
1833
1835
 
@@ -1835,9 +1837,9 @@ class Definition extends React__namespace.Component{getPromptJSON(){return getPr
1835
1837
 
1836
1838
  class DeprecatedStandin extends React__namespace.default.Component{render(){return jsxRuntimeExports.jsx("div",{style:{paddingTop:8,paddingBottom:8},children:jsxRuntimeExports.jsx(Banner__default.default,{text:this.context.strings.deprecatedStandin,kind:"info",layout:"full-width"})})}constructor(...args){super(...args),this.isWidget=true;}}DeprecatedStandin.contextType=PerseusI18nContext;var DeprecatedStandin$1 = {name:"deprecated-standin",displayName:"Deprecated Standin",widget:DeprecatedStandin,hidden:true};
1837
1839
 
1838
- const getPromptJSON$k=renderProps=>{return {type:"dropdown",options:{items:renderProps.choices},userInput:{selectedIndex:renderProps.userInput.value-1}}};
1840
+ const getPromptJSON$k=renderProps=>{return {type:"dropdown",options:{items:renderProps.choices.map(choice=>choice.content)},userInput:{selectedIndex:renderProps.userInput.value-1}}};
1839
1841
 
1840
- class Dropdown extends React__namespace.Component{getPromptJSON(){return getPromptJSON$k(this.props)}getSerializedState(){const{userInput,...rest}=this.props;return {...rest,selected:userInput.value}}render(){const children=[jsxRuntimeExports.jsx(wonderBlocksDropdown.OptionItem,{value:"0",disabled:true,label:jsxRuntimeExports.jsx(Renderer,{content:this.props.placeholder,strings:this.context.strings}),labelAsText:this.props.placeholder},"placeholder"),...this.props.choices.map((choice,i)=>jsxRuntimeExports.jsx(wonderBlocksDropdown.OptionItem,{value:String(i+1),label:jsxRuntimeExports.jsx(Renderer,{content:choice,strings:this.context.strings}),labelAsText:choice},String(i+1)))];return jsxRuntimeExports.jsx(wonderBlocksCore.Id,{children:dropdownId=>jsxRuntimeExports.jsxs(wonderBlocksCore.View,{onClick:e=>{e.stopPropagation();},onTouchStart:e=>{e.stopPropagation();},children:[this.props.visibleLabel&&jsxRuntimeExports.jsx(wonderBlocksTypography.LabelLarge,{tag:"label",htmlFor:dropdownId,children:this.props.visibleLabel}),jsxRuntimeExports.jsx(wonderBlocksDropdown.SingleSelect,{id:dropdownId,placeholder:"",className:"perseus-dropdown",onChange:value=>this._handleChange(parseInt(value)),selectedValue:String(this.props.userInput.value),disabled:this.props.apiOptions.readOnly,"aria-label":this.props.ariaLabel||this.props.visibleLabel||this.context.strings.selectAnAnswer,showOpenerLabelAsText:false,children:children})]})})}constructor(...args){super(...args),this.focus=()=>{ReactDOM__namespace.default.findDOMNode(this).focus();return true},this._handleChangeEvent=e=>{this._handleChange(parseInt(e.target.value));},this._handleChange=selected=>{this.props.trackInteraction();this.props.handleUserInput({value:selected});};}}Dropdown.contextType=PerseusI18nContext;Dropdown.defaultProps={choices:[],placeholder:"",apiOptions:ApiOptions.defaults,userInput:{value:0}};function transform$3(widgetOptions){return {placeholder:widgetOptions.placeholder,visibleLabel:widgetOptions.visibleLabel,ariaLabel:widgetOptions.ariaLabel,choices:widgetOptions.choices.map(choice=>choice.content)}}function getUserInputFromSerializedState$c(serializedState){return {value:serializedState.selected}}function getStartUserInput$d(){return {value:0}}var Dropdown$1 = {name:"dropdown",displayName:"Drop down",widget:Dropdown,transform: transform$3,getStartUserInput: getStartUserInput$d,getUserInputFromSerializedState: getUserInputFromSerializedState$c};
1842
+ class Dropdown extends React__namespace.Component{getPromptJSON(){return getPromptJSON$k(this.props)}getSerializedState(){const{userInput,choices,...rest}=this.props;return {...rest,choices:choices.map(choice=>choice.content),selected:userInput.value}}restoreSerializedState(state){return {state,choices:state.choices.map(content=>({content}))}}render(){const children=[jsxRuntimeExports.jsx(wonderBlocksDropdown.OptionItem,{value:"0",disabled:true,label:jsxRuntimeExports.jsx(Renderer,{content:this.props.placeholder,strings:this.context.strings}),labelAsText:this.props.placeholder},"placeholder"),...this.props.choices.map((choice,i)=>jsxRuntimeExports.jsx(wonderBlocksDropdown.OptionItem,{value:String(i+1),label:jsxRuntimeExports.jsx(Renderer,{content:choice.content,strings:this.context.strings}),labelAsText:choice.content},String(i+1)))];return jsxRuntimeExports.jsx(wonderBlocksCore.Id,{children:dropdownId=>jsxRuntimeExports.jsxs(wonderBlocksCore.View,{onClick:e=>{e.stopPropagation();},onTouchStart:e=>{e.stopPropagation();},children:[this.props.visibleLabel&&jsxRuntimeExports.jsx(wonderBlocksTypography.LabelLarge,{tag:"label",htmlFor:dropdownId,children:this.props.visibleLabel}),jsxRuntimeExports.jsx(wonderBlocksDropdown.SingleSelect,{id:dropdownId,placeholder:"",className:"perseus-dropdown",onChange:value=>this._handleChange(parseInt(value)),selectedValue:String(this.props.userInput.value),disabled:this.props.apiOptions.readOnly,"aria-label":this.props.ariaLabel||this.props.visibleLabel||this.context.strings.selectAnAnswer,showOpenerLabelAsText:false,children:children})]})})}constructor(...args){super(...args),this.focus=()=>{ReactDOM__namespace.default.findDOMNode(this).focus();return true},this._handleChangeEvent=e=>{this._handleChange(parseInt(e.target.value));},this._handleChange=selected=>{this.props.trackInteraction();this.props.handleUserInput({value:selected});};}}Dropdown.contextType=PerseusI18nContext;Dropdown.defaultProps={choices:[],placeholder:"",apiOptions:ApiOptions.defaults,userInput:{value:0}};function getUserInputFromSerializedState$c(serializedState){return {value:serializedState.selected}}function getStartUserInput$d(){return {value:0}}var Dropdown$1 = {name:"dropdown",displayName:"Drop down",widget:Dropdown,getStartUserInput: getStartUserInput$d,getUserInputFromSerializedState: getUserInputFromSerializedState$c};
1841
1843
 
1842
1844
  const USAGE="Usage:\n"+" this.change({propName: 5}, callback);\n"+' this.change("propName", 5, callback);\n'+' this.change("propName")';const _changeMultiple=function(component,newProps,callback){const currProps=excludeDenylistKeys(component.props);const nextProps=___default.default.extend(currProps,newProps);component.props.onChange(nextProps,callback);};const _changeSingle=function(component,propName,value,callback){if(value===undefined){return ___default.default.partial(_changeSingle,component,propName)}const newProps={};newProps[propName]=value;_changeMultiple(component,newProps,callback);};const change=function(newPropsOrSinglePropName,propValue,callback){if(___default.default.isObject(newPropsOrSinglePropName)&&callback===undefined){callback=propValue;return _changeMultiple(this,newPropsOrSinglePropName,callback)}if(typeof newPropsOrSinglePropName==="string"){return _changeSingle(this,newPropsOrSinglePropName,propValue,callback)}throw new perseusCore.PerseusError("Invalid types sent to this.change(): "+___default.default.toArray(arguments).join()+"\n"+USAGE,perseusCore.Errors.Internal)};const propTypes={onChange:PropTypes__default.default.func.isRequired};
1843
1845
 
@@ -1851,7 +1853,7 @@ const getPromptJSON$j=renderProps=>{return {type:"explanation",showPrompt:render
1851
1853
 
1852
1854
  function mediaQueryIsMatched(mediaQuery){if(typeof window.matchMedia!=="function"){return false}return window.matchMedia(mediaQuery).matches}class Explanation extends React__namespace.Component{componentDidMount(){this._mounted=true;}componentWillUnmount(){this._mounted=false;}getPromptJSON(){return getPromptJSON$j(this.props)}render(){const promptText=this.state.expanded?this.props.hidePrompt:this.props.showPrompt;const caretIcon=this.state.expanded?caretUp__default.default:caretDown__default.default;const allowTransition=this._mounted&&mediaQueryIsMatched("(prefers-reduced-motion: no-preference)");const buttonStyleOverrides={height:"auto",lineHeight:"inherit",marginLeft:"-2px",marginRight:"2px",paddingLeft:"2px"};const labelStyle={fontSize:"18px",lineHeight:"inherit","text-align":"left",marginRight:"-6px","white-space":"normal"};const contentStyling=[styles$l.content,this.state.expanded?styles$l.contentExpanded:styles$l.contentCollapsed,allowTransition&&(this.state.expanded?styles$l.transitionExpanded:styles$l.transitionCollapsed)];return jsxRuntimeExports.jsx(wonderBlocksCore.Id,{children:contentId=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Button__default.default,{"aria-expanded":this.state.expanded,"aria-controls":contentId,endIcon:caretIcon,kind:"tertiary",labelStyle:labelStyle,onClick:this._onClick,size:"small",style:buttonStyleOverrides,children:promptText}),jsxRuntimeExports.jsx(wonderBlocksCore.View,{id:contentId,style:contentStyling,"aria-hidden":!this.state.expanded,testId:"content-container",children:jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:styles$l.contentWrapper,children:jsxRuntimeExports.jsx(Renderer,{apiOptions:this.props.apiOptions,content:this.props.explanation,widgets:this.props.widgets,linterContext:this.props.linterContext,strings:this.context.strings})})})]})})}constructor(...args){super(...args),this.isWidget=true,this.state={expanded:false},this._mounted=false,this.change=(...args)=>{return change.apply(this,args)},this._onClick=()=>{this.setState({expanded:!this.state.expanded});this.props.trackInteraction();};}}Explanation.contextType=PerseusI18nContext;Explanation.defaultProps={showPrompt:"Explain",hidePrompt:"Hide explanation",explanation:"explanation goes here\n\nmore explanation",widgets:{},linterContext:PerseusLinter.linterContextDefault};const leftBorderSpacing=23;const verticalContentPadding=10;const arrowHeight=14;const styles$l=aphrodite.StyleSheet.create({content:{borderLeft:"0px solid #ccc",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",marginLeft:-23,minWidth:"100%",paddingLeft:leftBorderSpacing,paddingBottom:verticalContentPadding,visibility:"visible",marginBottom:arrowHeight,marginTop:arrowHeight},contentWrapper:{overflow:"hidden"},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"}});var Explanation$1 = {name:"explanation",displayName:"Explanation",widget:Explanation,isLintable:true};
1853
1855
 
1854
- class FreeResponse extends React__namespace.Component{isOverLimit(){return !this.props.allowUnlimitedCharacters&&this.characterCount()>this.props.characterLimit}renderCharacterCount(){if(this.props.allowUnlimitedCharacters){return null}const characterCountText=this.context.strings.characterCount({used:this.characterCount(),num:this.props.characterLimit});return jsxRuntimeExports.jsx(wonderBlocksCore.View,{children:jsxRuntimeExports.jsxs(wonderBlocksCore.Text,{role:"status",style:[styles$k.characterCountText,this.isOverLimit()?styles$k.overCharacterLimit:undefined],children:[this.isOverLimit()&&jsxRuntimeExports.jsx(wonderBlocksIcon.PhosphorIcon,{icon:warningCircleIcon__default.default,size:"small",style:styles$k.warningCircleIcon}),characterCountText]})})}render(){return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{style:styles$k.container,className:"free-response",children:[jsxRuntimeExports.jsx(wonderBlocksLabeledField.LabeledField,{label:jsxRuntimeExports.jsx(wonderBlocksCore.View,{className:"free-response-question",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.question,strings:this.context.strings})}),field:jsxRuntimeExports.jsx(wonderBlocksForm.TextArea,{error:this.isOverLimit(),onChange:this._handleUserInput,placeholder:this.props.placeholder,style:styles$k.textarea,value:this.props.userInput.currentValue}),styles:{label:styles$k.questionLabel}}),this.renderCharacterCount()]})}constructor(...args){super(...args),this.isWidget=true,this.characterCount=()=>{return this.props.userInput.currentValue.replace(/\n/g,"").length},this._handleUserInput=newValue=>{this.props.handleUserInput({currentValue:newValue});};}}FreeResponse.contextType=PerseusI18nContext;FreeResponse.defaultProps={userInput:{currentValue:""}};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=aphrodite.StyleSheet.create({container:{gap:wonderBlocksTokens.spacing.xSmall_8},characterCountText:{color:wonderBlocksTokens.semanticColor.core.foreground.neutral.default,fontSize:wonderBlocksTokens.font.size.small},overCharacterLimit:{color:wonderBlocksTokens.color.red},questionLabel:{fontWeight:wonderBlocksTokens.font.weight.bold},textarea:{padding:wonderBlocksTokens.spacing.medium_16},warningCircleIcon:{marginInlineEnd:wonderBlocksTokens.spacing.xSmall_8}});
1856
+ class FreeResponse extends React__namespace.Component{isOverLimit(){return !this.props.allowUnlimitedCharacters&&this.characterCount()>this.props.characterLimit}renderCharacterCount(){if(this.props.allowUnlimitedCharacters){return null}const characterCountText=this.context.strings.characterCount({used:this.characterCount(),num:this.props.characterLimit});return jsxRuntimeExports.jsx(wonderBlocksCore.View,{children:jsxRuntimeExports.jsxs(wonderBlocksCore.Text,{role:"status",style:[styles$k.characterCountText,this.isOverLimit()?styles$k.overCharacterLimit:undefined],children:[this.isOverLimit()&&jsxRuntimeExports.jsx(wonderBlocksIcon.PhosphorIcon,{icon:warningCircleIcon__default.default,size:"small",style:styles$k.warningCircleIcon}),characterCountText]})})}render(){return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{style:styles$k.container,className:"free-response",children:[jsxRuntimeExports.jsx(wonderBlocksLabeledField.LabeledField,{label:jsxRuntimeExports.jsx(wonderBlocksCore.View,{className:"free-response-question",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.question,strings:this.context.strings})}),field:jsxRuntimeExports.jsx(wonderBlocksForm.TextArea,{error:this.isOverLimit(),onChange:this._handleUserInput,placeholder:this.props.placeholder,style:styles$k.textarea,value:this.props.userInput.currentValue})}),this.renderCharacterCount()]})}constructor(...args){super(...args),this.isWidget=true,this.characterCount=()=>{return this.props.userInput.currentValue.replace(/\n/g,"").length},this._handleUserInput=newValue=>{this.props.handleUserInput({currentValue:newValue});};}}FreeResponse.contextType=PerseusI18nContext;FreeResponse.defaultProps={userInput:{currentValue:""}};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=aphrodite.StyleSheet.create({container:{gap:wonderBlocksTokens.spacing.xSmall_8},characterCountText:{color:wonderBlocksTokens.semanticColor.core.foreground.neutral.default,fontSize:wonderBlocksTokens.font.size.small},overCharacterLimit:{color:wonderBlocksTokens.color.red},textarea:{padding:wonderBlocksTokens.spacing.medium_16},warningCircleIcon:{marginInlineEnd:wonderBlocksTokens.spacing.xSmall_8}});
1855
1857
 
1856
1858
  function getWidgetTypeByWidgetId(widgetId,widgetMap){const widget=widgetMap[widgetId];return widget?.type??null}function getWidgetSubTypeByWidgetId(widgetId,widgetMap){const widget=widgetMap[widgetId];const widgetType=widget?.type??null;switch(widgetType){case "interactive-graph":const graph=widget.options.graph;return graph?.type??null;default:return null}}function contentHasWidgetType(type,content,widgetMap){return perseusCore.getWidgetIdsFromContentByType(type,content,widgetMap).length>0}function getWidgetsMapFromItemData(itemData){return itemData.question.widgets}function getWidgetFromWidgetMap(widgetId,widgetMap){return widgetMap[widgetId]??null}function getWidgetsFromWidgetMap(widgetIds,widgetMap){const widgets={};widgetIds.forEach(widgetId=>{const widget=getWidgetFromWidgetMap(widgetId,widgetMap);if(widget){widgets[widgetId]=widget;}});return widgets}
1857
1859
 
@@ -1873,7 +1875,7 @@ const getPromptJSON$g=renderProps=>{const{userInput}=renderProps;const{type,coor
1873
1875
 
1874
1876
  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=perseusCore.GrapherUtil.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 kmath.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=perseusCore.GrapherUtil.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=___default.default.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);const staticUrl=getDependencies().staticUrl;return {value:type,title:capitalized,content:jsxRuntimeExports.jsx("img",{src:staticUrl(perseusCore.GrapherUtil.functionForType(type).url),alt:capitalized})}};
1875
1877
 
1876
- const MovablePoint$3=Graphie.MovablePoint;const MovableLine$2=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__namespace.Component{render(){const pointForCoord=(coord,i)=>{return jsxRuntimeExports.jsx(MovablePoint$3,{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||!kmath.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=perseusCore.deepClone(this._coords());const oldCoord=perseusCore.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 kmath.point.reflectOverLine(coord,asymptote)});}else {coords=perseusCore.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,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,setDrawingAreaAvailable:this.props.setDrawingAreaAvailable,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:this.props.isMobile?KhanColors.BLUE_C:KhanColors.DYNAMIC,...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 React.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={strokeDasharray:"- "};return showAsymptote&&jsxRuntimeExports.jsx(MovableLine$2,{onMove:(newCoord,oldCoord)=>{const delta=kmath.vector.subtract(newCoord,oldCoord);const newAsymptote=this._asymptote().map(coord=>kmath.vector.add(coord,delta));this.props.onChange({asymptote:newAsymptote});},constraints:[Interactive2.MovableLine.constraints.bound(),Interactive2.MovableLine.constraints.snap(),(newCoord,oldCoord)=>{const delta=kmath.vector.subtract(newCoord,oldCoord);const proposedAsymptote=this._asymptote().map(coord=>kmath.vector.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$3,{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__namespace.Component{_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:_,...rest}=this.props;return {...rest,plot:this.props.userInput}}render(){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:this.props.availableTypes.map(typeToButton),onChange:this.handleActiveTypeChange})});const box=getInteractiveBoxFromSizeClass(this.props.containerSizeClass);const options={...this.props.graph,...getGridAndSnapSteps(this.props.graph,box[0]),gridConfig:this._getGridConfig({...this.props.graph,box:box,...getGridAndSnapSteps(this.props.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&&perseusCore.GrapherUtil.functionForType(type),coords:coords,asymptote:asymptote,static:this.props.static,setDrawingAreaAvailable:this.props.apiOptions.setDrawingAreaAvailable,isMobile:this.props.apiOptions.isMobile,showTooltips:this.props.graph.showTooltips,showHairlines:this.showHairlines,hideHairlines:this.hideHairlines};return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(FunctionGrapher,{...grapherProps}),this.props.availableTypes.length>1&&typeSelector]})}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.graph;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)});}if(this.props.apiOptions.isMobile){const hairlineStyle={normalStyle:{strokeWidth:1}};this.horizHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.horizHairline.attr({stroke:KhanColors.INTERACTIVE});this.horizHairline.hide();this.vertHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.vertHairline.attr({stroke:KhanColors.INTERACTIVE});this.vertHairline.hide();}},this.showHairlines=point=>{if(this.props.apiOptions.isMobile){this.horizHairline.moveTo([this.props.graph.range[0][0],point[1]],[this.props.graph.range[0][1],point[1]]);this.horizHairline.show();this.vertHairline.moveTo([point[0],this.props.graph.range[1][0]],[point[0],this.props.graph.range[1][1]]);this.vertHairline.show();}},this.hideHairlines=()=>{if(this.props.apiOptions.isMobile){this.horizHairline.hide();this.vertHairline.hide();}};}}function transform$2(options){const{availableTypes,graph}=options;return {availableTypes,graph}}function staticTransform$1(options){return {...transform$2(options),availableTypes:[options.correct.type],plot:options.correct}}function getUserInputFromSerializedState$b(serializedState){return serializedState.plot}function getStartUserInput$b(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){return options.correct}var Grapher$1 = {name:"grapher",displayName:"Grapher",hidden:true,widget:Grapher,transform: transform$2,staticTransform: staticTransform$1,getUserInputFromSerializedState: getUserInputFromSerializedState$b,getStartUserInput: getStartUserInput$b,getCorrectUserInput: getCorrectUserInput$4};
1878
+ const MovablePoint$3=Graphie.MovablePoint;const MovableLine$2=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__namespace.Component{render(){const pointForCoord=(coord,i)=>{return jsxRuntimeExports.jsx(MovablePoint$3,{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||!kmath.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=perseusCore.deepClone(this._coords());const oldCoord=perseusCore.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 kmath.point.reflectOverLine(coord,asymptote)});}else {coords=perseusCore.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,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,setDrawingAreaAvailable:this.props.setDrawingAreaAvailable,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:this.props.isMobile?KhanColors.BLUE_C:KhanColors.DYNAMIC,...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 React.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={strokeDasharray:"- "};return showAsymptote&&jsxRuntimeExports.jsx(MovableLine$2,{onMove:(newCoord,oldCoord)=>{const delta=kmath.vector.subtract(newCoord,oldCoord);const newAsymptote=this._asymptote().map(coord=>kmath.vector.add(coord,delta));this.props.onChange({asymptote:newAsymptote});},constraints:[Interactive2.MovableLine.constraints.bound(),Interactive2.MovableLine.constraints.snap(),(newCoord,oldCoord)=>{const delta=kmath.vector.subtract(newCoord,oldCoord);const proposedAsymptote=this._asymptote().map(coord=>kmath.vector.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$3,{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__namespace.Component{_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:_,correct:__,...rest}=this.props;return {...rest,plot:this.props.userInput}}render(){const availableTypes=this.props.static?[this.props.correct.type]:this.props.availableTypes;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 options={...this.props.graph,...getGridAndSnapSteps(this.props.graph,box[0]),gridConfig:this._getGridConfig({...this.props.graph,box:box,...getGridAndSnapSteps(this.props.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&&perseusCore.GrapherUtil.functionForType(type),coords:coords,asymptote:asymptote,static:this.props.static,setDrawingAreaAvailable:this.props.apiOptions.setDrawingAreaAvailable,isMobile:this.props.apiOptions.isMobile,showTooltips:this.props.graph.showTooltips,showHairlines:this.showHairlines,hideHairlines:this.hideHairlines};return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(FunctionGrapher,{...grapherProps}),availableTypes.length>1&&typeSelector]})}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.graph;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)});}if(this.props.apiOptions.isMobile){const hairlineStyle={normalStyle:{strokeWidth:1}};this.horizHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.horizHairline.attr({stroke:KhanColors.INTERACTIVE});this.horizHairline.hide();this.vertHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.vertHairline.attr({stroke:KhanColors.INTERACTIVE});this.vertHairline.hide();}},this.showHairlines=point=>{if(this.props.apiOptions.isMobile){this.horizHairline.moveTo([this.props.graph.range[0][0],point[1]],[this.props.graph.range[0][1],point[1]]);this.horizHairline.show();this.vertHairline.moveTo([point[0],this.props.graph.range[1][0]],[point[0],this.props.graph.range[1][1]]);this.vertHairline.show();}},this.hideHairlines=()=>{if(this.props.apiOptions.isMobile){this.horizHairline.hide();this.vertHairline.hide();}};}}function getUserInputFromSerializedState$b(serializedState){return serializedState.plot}function getStartUserInput$b(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){return options.correct}var Grapher$1 = {name:"grapher",displayName:"Grapher",hidden:true,widget:Grapher,getUserInputFromSerializedState: getUserInputFromSerializedState$b,getStartUserInput: getStartUserInput$b,getCorrectUserInput: getCorrectUserInput$4};
1877
1879
 
1878
1880
  const getPromptJSON$f=rendererJSON=>{if(!rendererJSON){return {type:"group",content:"",widgets:{}}}return {...rendererJSON,type:"group"}};
1879
1881
 
@@ -1909,13 +1911,13 @@ function lerp(a,b,fraction){return (b-a)*clamp(fraction,0,1)+a}
1909
1911
 
1910
1912
  const segmentsIntersect=([[a,b],[c,d]],[[p,q],[r,s]])=>{const determinant=(c-a)*(s-q)-(r-p)*(d-b);if(determinant===0){return false}else {const lambda=((s-q)*(r-a)+(p-r)*(s-b))/determinant;const gamma=((b-d)*(r-a)+(c-a)*(s-b))/determinant;return 0<lambda&&lambda<1&&0<gamma&&gamma<1}};function findIntersectionOfRays([[a,b],[c,d]],[[p,q],[r,s]]){const determinant=(c-a)*(s-q)-(r-p)*(d-b);if(determinant===0){return undefined}else {const lambda=((s-q)*(r-a)+(p-r)*(s-b))/determinant;const gamma=((b-d)*(r-a)+(c-a)*(s-b))/determinant;if(lambda<=0||gamma>=1){return undefined}const initialPoint=[a,b];const direction=mafs.vec.sub([c,d],initialPoint);return mafs.vec.add(initialPoint,mafs.vec.scale(direction,lambda))}}
1911
1913
 
1912
- const defaultGraphConfig={range:[[0,1],[0,1]],tickStep:[1,1],gridStep:[1,1],snapStep:[1,1],markings:"none",showTooltips:false,graphDimensionsInPixels:[1,1],width:0,height:0,labels:[],labelLocation:"onAxis",disableKeyboardInteraction:false,interactiveColor:"var(--mafs-blue)"};const GraphConfigContext=React.createContext(defaultGraphConfig);function useGraphConfig(){return React__namespace.default.useContext(GraphConfigContext)}
1914
+ const defaultGraphConfig={range:[[0,1],[0,1]],tickStep:[1,1],gridStep:[1,1],snapStep:[1,1],markings:"none",showTooltips:false,graphDimensionsInPixels:[1,1],width:0,height:0,labels:[],labelLocation:"onAxis",disableKeyboardInteraction:false,interactiveColor:"var(--mafs-blue)",showAxisArrows:{xMin:true,xMax:true,yMin:true,yMax:true}};const GraphConfigContext=React.createContext(defaultGraphConfig);function useGraphConfig(){return React__namespace.default.useContext(GraphConfigContext)}
1913
1915
 
1914
1916
  const matrixBuilder=mafs.vec.matrixBuilder;function vectorsToPixels(vectors,graphState,translation=[0,0]){const{range,width,height}=graphState;const[[xMin,xMax],[yMin,yMax]]=range;const transformToPx=matrixBuilder().translate(...translation).scale(width/(xMax-xMin),-height/(yMax-yMin)).get();return vectors.map(p=>mafs.vec.transform(p,transformToPx))}function dimensionsToPixels(dimens,graphState){const{range,width,height}=graphState;const[[xMin,xMax],[yMin,yMax]]=range;const transformToPx=matrixBuilder().scale(width/(xMax-xMin),height/(yMax-yMin)).get();return dimens.map(d=>mafs.vec.transform(d,transformToPx))}function pointToPixel(point,graphState){const[[xMin],[,yMax]]=graphState.range;const[a,b]=[-xMin,-yMax];return vectorsToPixels([point],graphState,[a,b])[0]}const useTransformVectorsToPixels=(...vectors)=>{const graphState=useGraphConfig();return vectorsToPixels(vectors,graphState)};const useTransformDimensionsToPixels=(...dimens)=>{const graphState=useGraphConfig();return dimensionsToPixels(dimens,graphState)};function pixelsToVectors(pixels,graphState){const[[xMin,xMax],[yMin,yMax]]=graphState.range;const{width,height}=graphState;const xSpan=xMax-xMin;const ySpan=yMax-yMin;return pixels.map(pixel=>{const x=pixel[X]/width*xSpan+xMin;const y=yMax-pixel[Y]/height*ySpan;return [x,y]})}
1915
1917
 
1916
1918
  const arrowPath=pathBuilder().move(-3,4).curve(-2.75,2.5,0,.25,.75,0).curve(0,-0.25,-2.75,-2.5,-3,-4).scale(1.4).build();function Arrowhead(props){const[point]=useTransformVectorsToPixels(props.tip);return jsxRuntimeExports.jsx("g",{"aria-hidden":true,className:"interactive-graph-arrowhead",transform:`translate(${point[X]} ${point[Y]}) rotate(${props.angle})`,children:jsxRuntimeExports.jsx("g",{transform:"translate(-1.5)",children:jsxRuntimeExports.jsx("path",{d:arrowPath,fill:"none",style:{stroke:props.color??"inherit"},strokeLinejoin:"round",strokeLinecap:"round",strokeWidth:`${props.strokeWidth??2}px`})})})}
1917
1919
 
1918
- function AxisArrows(){const{range:[[xMin,xMax],[yMin,yMax]]}=useGraphConfig();const axisColor="var(--mafs-fg)";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[!(yMin>0||yMax<0)&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[xMin,0],angle:180}),jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[xMax,0],angle:0})]}),!(xMin>0||xMax<0)&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[0,yMin],angle:90}),jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[0,yMax],angle:270})]})]})}
1920
+ function AxisArrows(){const{range:[[xMin,xMax],[yMin,yMax]],showAxisArrows}=useGraphConfig();const axisColor="var(--mafs-fg)";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[!(yMin>0||yMax<0)&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[showAxisArrows.xMin&&jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[xMin,0],angle:180}),showAxisArrows.xMax&&jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[xMax,0],angle:0})]}),!(xMin>0||xMax<0)&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[showAxisArrows.yMin&&jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[0,yMin],angle:90}),showAxisArrows.yMax&&jsxRuntimeExports.jsx(Arrowhead,{color:axisColor,tip:[0,yMax],angle:270})]})]})}
1919
1921
 
1920
1922
  const TARGET_SIZE=44;const REMOVE_BUTTON_ID="perseus_mafs_remove_button";const normalizePoints=(range,step,coordsList,noSnap)=>coordsList.map(coords=>coords.map((coord,i)=>{const axisRange=range[i];if(noSnap){return axisRange[MIN]+size(axisRange)*coord}const axisStep=step[i];const nSteps=Math.floor(size(axisRange)/axisStep);const tick=Math.round(coord*nSteps);return axisRange[MIN]+axisStep*tick}));const normalizeCoords=(coordsList,ranges)=>coordsList.map(coords=>coords.map((coord,i)=>{return (coord+ranges[i][1])/size(ranges[i])}));function bound$1({snapStep,range,point}){const boundingBox=inset(snapStep,range);return clampToBox(boundingBox,point)}function boundToEdge({range,point}){return clampToBox(range,point)}function isUnlimitedGraphState(state){return state.type==="point"&&state.numPoints==="unlimited"||state.type==="polygon"&&state.numSides==="unlimited"}const mathOnlyParser=SimpleMarkdown__default.default.parserFor({math:{...pureMarkdown.pureMarkdownRules.math,order:0},text:{order:1,match:SimpleMarkdown__default.default.anyScopeRegex(/^([^$\\{}]+)/),parse:capture=>({content:capture[0]})},specialCharacter:{order:2,match:SimpleMarkdown__default.default.anyScopeRegex(/^(\\[\S\s]|\$|\\$|{|})/),parse:capture=>({content:capture[0]})}},{inline:true});function replaceOutsideTeX(mathString){const parsed=mathOnlyParser(mathString);let result="";for(const piece of parsed){piece.type==="math"?result+="$"+piece.content+"$":piece.type==="specialCharacter"?result+=escapeIfUnescaped(piece.content):result+=piece.content;}return `\\text{${result}}`}function escapeIfUnescaped(character){if(character.length===1){return "\\"+character}else {return character}}const getRangeDiff=range=>{const[min,max]=range;return Math.abs(max-min)};const calculateNestedSVGCoords=(range,width,height)=>{let viewboxX=0;const totalXRange=getRangeDiff(range[X]);const gridCellWidth=width/totalXRange;const minX=range[X][MIN];if(minX>0){viewboxX=gridCellWidth*Math.abs(minX);}if(minX<0){viewboxX=-gridCellWidth*Math.abs(minX);}let viewboxY=-height;const totalYRange=getRangeDiff(range[Y]);const gridCellHeight=height/totalYRange;const minY=range[Y][MIN];if(minY>0){viewboxY=-height-gridCellHeight*Math.abs(minY);}if(minY<0){viewboxY=gridCellHeight*Math.abs(minY)-height;}return {viewboxX,viewboxY}};
1921
1923
 
@@ -2040,13 +2042,13 @@ function renderSinusoidGraph(state,dispatch,i18n){return {graph:jsxRuntimeExport
2040
2042
 
2041
2043
  const{calculateAngleInDegrees,convertDegreesToRadians}=kmath.angles;const protractorImage="https://cdn.kastatic.org/images/perseus/protractor.svg";const centerToTopLeft=[-195,-190];const centerToRotationHandle=[-201,-15];function Protractor(){const staticUrl=getDependencies().staticUrl;const{range,snapStep}=useGraphConfig();const[[xMin,xMax],[yMin,yMax]]=range;const initialCenter=[lerp(xMin,xMax,.5),lerp(yMin,yMax,.25)];const[center,setCenter]=React.useState(initialCenter);const[rotationHandleOffset,setRotationHandleOffset]=React.useState(centerToRotationHandle);const draggableRef=React.useRef(null);const{dragging}=useDraggable({gestureTarget:draggableRef,onMove:setCenter,point:center,constrainKeyboardMovement:point=>bound$1({snapStep,range,point})});const rotationHandleRef=React.useRef(null);useDraggablePx({gestureTarget:rotationHandleRef,onMove:setRotationHandleOffset,point:rotationHandleOffset,constrain:constrainToCircle});const[centerPx]=useTransformVectorsToPixels(center);const topLeftPx=mafs.vec.add(centerPx,centerToTopLeft);const angle=calculateAngleInDegrees(rotationHandleOffset)-calculateAngleInDegrees(centerToRotationHandle);return jsxRuntimeExports.jsxs("g",{ref:draggableRef,transform:`translate(${topLeftPx[X]}, ${topLeftPx[Y]}), rotate(${angle})`,style:{transformOrigin:`${-centerToTopLeft[X]}px ${-centerToTopLeft[Y]}px`,cursor:dragging?"grabbing":"grab"},children:[jsxRuntimeExports.jsx("image",{href:staticUrl(protractorImage)}),jsxRuntimeExports.jsx("g",{transform:`translate(5, ${-centerToTopLeft[1]})`,ref:rotationHandleRef,children:jsxRuntimeExports.jsx(RotationArrow,{})})]})}function RotationArrow(){const radius=175;const angleDeg=10;const angleRad=convertDegreesToRadians(angleDeg);const endX=radius*(1-Math.cos(angleRad));const endY=radius*-Math.sin(angleRad);const rotationArrow=pathBuilder().move(0,0).circularArc(radius,endX,endY,{sweep:true}).build();const arrowhead=pathBuilder().move(-8,0).line(0,10).line(8,0).build();const targetRadius=TARGET_SIZE/2;return jsxRuntimeExports.jsxs("g",{className:"protractor-rotation-handle",children:[jsxRuntimeExports.jsx("path",{className:"protractor-rotation-handle-arrow-arc",d:rotationArrow}),jsxRuntimeExports.jsx("path",{className:"protractor-rotation-handle-arrowhead",d:arrowhead}),jsxRuntimeExports.jsx("path",{className:"protractor-rotation-handle-arrowhead",d:arrowhead,transform:`translate(${endX}, ${endY}), rotate(${180+angleDeg})`}),jsxRuntimeExports.jsx("ellipse",{cx:"0px",cy:"-15px",rx:targetRadius,ry:targetRadius,fill:"none"})]})}const protractorRadius=mafs.vec.mag(centerToRotationHandle);function constrainToCircle(edgePoint){return mafs.vec.withMag(edgePoint,protractorRadius)}function useDraggablePx(args){const{gestureTarget:target,onMove,point,constrain=p=>p}=args;const pickupPx=React__namespace.useRef([0,0]);react.useDrag(state=>{const{event,first,movement:pixelMovement}=state;event?.stopPropagation();if(first){pickupPx.current=point;}if(mafs.vec.mag(pixelMovement)===0){return}onMove?.(constrain(mafs.vec.add(pickupPx.current,pixelMovement)));},{target,eventOptions:{passive:false}});}
2042
2044
 
2043
- const GRAPH_LEFT_MARGIN=20;const MafsGraph=props=>{const{state,dispatch,labels,labelLocation,readOnly,fullGraphAriaLabel,fullGraphAriaDescription}=props;const{type}=state;const[width,height]=props.box;const tickStep=props.step;const uniqueId=React__namespace.useId();const descriptionId=`interactive-graph-description-${uniqueId}`;const interactiveElementsDescriptionId=`interactive-graph-interactive-elements-description-${uniqueId}`;const unlimitedGraphKeyboardPromptId=`unlimited-graph-keyboard-prompt-${uniqueId}`;const instructionsId=`instructions-${uniqueId}`;const graphRef=React__namespace.useRef(null);const{analytics}=useDependencies();const{viewboxX,viewboxY}=calculateNestedSVGCoords(state.range,width,height);const viewBox=`${viewboxX} ${viewboxY} ${width} ${height}`;const nestedSVGAttributes={width,height,viewBox,preserveAspectRatio:"xMidYMin",x:viewboxX,y:viewboxY};const i18n=usePerseusI18n();const{strings}=i18n;const interactionPrompt=isUnlimitedGraphState(state)&&state.showKeyboardInteractionInvitation;wonderBlocksCore.useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:type,widgetType:"INTERACTIVE_GRAPH",widgetId:"interactive-graph"}});});const{graph,interactiveElementsDescription}=renderGraphElements({state,dispatch,i18n,markings:props.markings});const disableInteraction=readOnly||!!props.static;const graphInfo={range:state.range,width,height};const[xAxisLabelLocation,yAxisLabelLocation]=getLabelPosition(graphInfo,labelLocation,tickStep);const needsExtraMargin=labelLocation==="alongEdge"&&yAxisLabelLocation[0]<-14*fontSizeYAxisLabelMultiplier;const marginLabelDiff=GRAPH_LEFT_MARGIN-fontSize*fontSizeYAxisLabelMultiplier;const marginWithExtraOffset=-1*(yAxisLabelLocation[X]-marginLabelDiff);return jsxRuntimeExports.jsx(GraphConfigContext.Provider,{value:{range:state.range,snapStep:state.snapStep,markings:props.markings,tickStep:tickStep,gridStep:props.gridStep,showTooltips:!!props.showTooltips,graphDimensionsInPixels:props.box,width,height,labels,labelLocation,disableKeyboardInteraction:disableInteraction,interactiveColor:disableInteraction?"var(--static-gray)":"var(--mafs-blue)"},children:jsxRuntimeExports.jsxs(wonderBlocksCore.View,{className:"mafs-graph-container",children:[jsxRuntimeExports.jsxs(wonderBlocksCore.View,{className:"mafs-graph",style:{position:"relative",padding:"25px 25px 0 0",boxSizing:"content-box",marginLeft:needsExtraMargin?`${marginWithExtraOffset}px`:`${GRAPH_LEFT_MARGIN}px`,marginBottom:"30px",pointerEvents:props.static?"none":"auto",userSelect:"none",width,height},onKeyUp:event=>{handleKeyboardEvent(event,state,dispatch);},"aria-label":fullGraphAriaLabel,"aria-describedby":describedByIds(fullGraphAriaDescription&&descriptionId,interactiveElementsDescription&&interactiveElementsDescriptionId,isUnlimitedGraphState(state)&&unlimitedGraphKeyboardPromptId,state.type!=="none"&&!disableInteraction&&instructionsId),ref:graphRef,tabIndex:0,onFocus:event=>{handleFocusEvent(event,state,dispatch);},onBlur:event=>{handleBlurEvent(event,state,dispatch);},children:[fullGraphAriaDescription&&jsxRuntimeExports.jsx(wonderBlocksCore.View,{id:descriptionId,tabIndex:-1,className:"mafs-sr-only",children:fullGraphAriaDescription}),interactiveElementsDescription&&jsxRuntimeExports.jsx(wonderBlocksCore.View,{id:interactiveElementsDescriptionId,tabIndex:-1,className:"mafs-sr-only",children:interactiveElementsDescription}),state.type!=="none"&&jsxRuntimeExports.jsx(wonderBlocksCore.View,{id:instructionsId,tabIndex:-1,className:"mafs-sr-only",children:isUnlimitedGraphState(state)?strings.srUnlimitedGraphInstructions:strings.srGraphInstructions}),jsxRuntimeExports.jsx(LegacyGrid,{box:props.box,backgroundImage:props.backgroundImage}),jsxRuntimeExports.jsxs(wonderBlocksCore.View,{style:{position:"absolute",bottom:0,left:0},children:[(props.markings==="graph"||props.markings==="axes")&&jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:jsxRuntimeExports.jsx(AxisLabels,{i18n:i18n,xAxisLabelLocation:xAxisLabelLocation,yAxisLabelLocation:yAxisLabelLocation})}),jsxRuntimeExports.jsx(wonderBlocksCore.View,{"aria-hidden":props.lockedFigures.length===0,children:jsxRuntimeExports.jsxs(mafs.Mafs,{preserveAspectRatio:false,viewBox:{x:state.range[X],y:state.range[Y],padding:0},pan:false,zoom:false,width:width,height:height,children:[jsxRuntimeExports.jsx(SvgDefs,{}),jsxRuntimeExports.jsx("svg",{...nestedSVGAttributes,children:jsxRuntimeExports.jsx(Grid,{gridStep:props.gridStep,range:state.range,containerSizeClass:props.containerSizeClass,markings:props.markings,width:width,height:height})}),(props.markings==="graph"||props.markings==="axes")&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(AxisTicks,{}),jsxRuntimeExports.jsx(AxisArrows,{})]}),props.lockedFigures.length>0&&jsxRuntimeExports.jsx("svg",{...nestedSVGAttributes,children:jsxRuntimeExports.jsx(GraphLockedLayer,{lockedFigures:props.lockedFigures,range:state.range})})]})}),jsxRuntimeExports.jsx(GraphLockedLabelsLayer,{lockedFigures:props.lockedFigures}),jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:{position:"absolute"},children:jsxRuntimeExports.jsx(mafs.Mafs,{preserveAspectRatio:false,viewBox:{x:state.range[X],y:state.range[Y],padding:0},pan:false,zoom:false,width:width,height:height,children:jsxRuntimeExports.jsxs("svg",{...nestedSVGAttributes,style:{overflow:type==="point"?"visible":"hidden"},children:[props.showProtractor&&jsxRuntimeExports.jsx(Protractor,{}),graph]})})})]}),interactionPrompt&&jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:{display:interactionPrompt?undefined:"hidden",textAlign:"center",backgroundColor:"white",border:"1px solid #21242C52",padding:"16px 0",boxShadow:"0px 8px 8px 0px #21242C14",top:"50%",transform:"translateY(-50%)"},children:jsxRuntimeExports.jsx(wonderBlocksTypography.LabelMedium,{id:unlimitedGraphKeyboardPromptId,children:strings.graphKeyboardPrompt})})]}),renderGraphControls({state,dispatch,width,perseusStrings:strings})]})})};const renderPointGraphControls=props=>{const{interactionMode,showRemovePointButton,focusedPointIndex}=props.state;const{perseusStrings}=props;const shouldShowRemoveButton=showRemovePointButton&&focusedPointIndex!==null;return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{style:{flexDirection:"row",width:props.width},children:[interactionMode==="keyboard"&&jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",style:{width:"100%",marginLeft:"20px"},tabIndex:0,onClick:()=>{props.dispatch(actions.pointGraph.addPoint([0,0]));},children:perseusStrings.addPoint}),interactionMode==="mouse"&&jsxRuntimeExports.jsx(Button__default.default,{id:REMOVE_BUTTON_ID,kind:"secondary",actionType:"destructive",tabIndex:-1,style:{width:"100%",marginLeft:"20px",visibility:shouldShowRemoveButton?"visible":"hidden"},onClick:_event=>{props.dispatch(actions.pointGraph.removePoint(props.state.focusedPointIndex));},children:perseusStrings.removePoint})]})};const renderPolygonGraphControls=props=>{const{interactionMode,showRemovePointButton,focusedPointIndex,closedPolygon,coords}=props.state;const{perseusStrings}=props;const shouldShowRemoveButton=showRemovePointButton&&focusedPointIndex!==null;const disableCloseButton=getArrayWithoutDuplicates(coords).length<3;const polygonButton=closedPolygon?jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",style:{width:"100%",marginLeft:"20px"},tabIndex:0,onClick:()=>{props.dispatch(actions.polygon.openPolygon());},children:perseusStrings.openPolygon}):jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",disabled:disableCloseButton,style:{width:"100%",marginLeft:"20px"},tabIndex:disableCloseButton?-1:0,onClick:()=>{props.dispatch(actions.polygon.closePolygon());},children:perseusStrings.closePolygon});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:jsxRuntimeExports.jsxs(wonderBlocksCore.View,{style:{flexDirection:"row",width:props.width},children:[interactionMode==="keyboard"&&jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",style:{width:"100%",marginLeft:"20px"},disabled:closedPolygon,tabIndex:closedPolygon?-1:0,onClick:()=>{props.dispatch(actions.polygon.addPoint([0,0]));},children:perseusStrings.addPoint}),interactionMode==="mouse"&&jsxRuntimeExports.jsx(Button__default.default,{id:REMOVE_BUTTON_ID,kind:"secondary",actionType:"destructive",disabled:closedPolygon||!shouldShowRemoveButton,tabIndex:-1,style:{width:"100%",marginLeft:"20px"},onClick:_event=>{props.dispatch(actions.polygon.removePoint(props.state.focusedPointIndex));},children:perseusStrings.removePoint}),polygonButton]})})};const renderGraphControls=props=>{const{state,dispatch,width,perseusStrings}=props;const{type}=state;switch(type){case "point":if(state.numPoints==="unlimited"){return renderPointGraphControls({state,dispatch,width,perseusStrings})}return null;case "polygon":if(state.numSides==="unlimited"){return renderPolygonGraphControls({state,dispatch,width,perseusStrings})}return null;default:return null}};function handleFocusEvent(event,state,dispatch){if(isUnlimitedGraphState(state)){if(event.target.classList.contains("mafs-graph")&&state.interactionMode==="mouse"){dispatch(actions.global.changeKeyboardInvitationVisibility(true));}}}function handleBlurEvent(_event,state,dispatch){if(isUnlimitedGraphState(state)){dispatch(actions.global.changeKeyboardInvitationVisibility(false));}}function handleKeyboardEvent(event,state,dispatch){if(isUnlimitedGraphState(state)){if(event.key==="Backspace"||event.key==="Delete"){if(document.activeElement?.classList.contains("movable-point__focusable-handle")){if(state.type==="point"||state.type==="polygon"&&!state.closedPolygon){dispatch(actions.global.deleteIntent());}}document.activeElement.blur();}else if(event.shiftKey&&event.key==="Enter"){dispatch(actions.global.changeInteractionMode("keyboard"));}else if(state.interactionMode==="keyboard"&&event.key==="a"){dispatch(actions.pointGraph.addPoint([0,0]));}}}const renderGraphElements=props=>{const{state,dispatch,i18n,markings}=props;const{type}=state;switch(type){case "angle":return renderAngleGraph(state,dispatch,i18n);case "segment":return renderSegmentGraph(state,dispatch,i18n);case "linear-system":return renderLinearSystemGraph(state,dispatch,i18n);case "linear":return renderLinearGraph(state,dispatch,i18n);case "ray":return renderRayGraph(state,dispatch,i18n);case "polygon":return renderPolygonGraph(state,dispatch,i18n,markings);case "point":return renderPointGraph(state,dispatch,i18n);case "circle":return renderCircleGraph(state,dispatch,i18n);case "quadratic":return renderQuadraticGraph(state,dispatch,i18n);case "sinusoid":return renderSinusoidGraph(state,dispatch,i18n);case "none":return {graph:null,interactiveElementsDescription:null};default:throw new wonderStuffCore.UnreachableCaseError(type)}};function describedByIds(...args){return args.filter(Boolean).join(" ")||undefined}
2045
+ const GRAPH_LEFT_MARGIN=20;const MafsGraph=props=>{const{state,dispatch,labels,labelLocation,readOnly,fullGraphAriaLabel,fullGraphAriaDescription}=props;const{type}=state;const[width,height]=props.box;const tickStep=props.step;const uniqueId=React__namespace.useId();const descriptionId=`interactive-graph-description-${uniqueId}`;const interactiveElementsDescriptionId=`interactive-graph-interactive-elements-description-${uniqueId}`;const unlimitedGraphKeyboardPromptId=`unlimited-graph-keyboard-prompt-${uniqueId}`;const instructionsId=`instructions-${uniqueId}`;const graphRef=React__namespace.useRef(null);const{analytics}=useDependencies();const{viewboxX,viewboxY}=calculateNestedSVGCoords(state.range,width,height);const viewBox=`${viewboxX} ${viewboxY} ${width} ${height}`;const nestedSVGAttributes={width,height,viewBox,preserveAspectRatio:"xMidYMin",x:viewboxX,y:viewboxY};const i18n=usePerseusI18n();const{strings}=i18n;const interactionPrompt=isUnlimitedGraphState(state)&&state.showKeyboardInteractionInvitation;wonderBlocksCore.useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:type,widgetType:"INTERACTIVE_GRAPH",widgetId:"interactive-graph"}});});const{graph,interactiveElementsDescription}=renderGraphElements({state,dispatch,i18n,markings:props.markings});const disableInteraction=readOnly||!!props.static;const graphInfo={range:state.range,width,height};const[xAxisLabelLocation,yAxisLabelLocation]=getLabelPosition(graphInfo,labelLocation,tickStep);const needsExtraMargin=labelLocation==="alongEdge"&&yAxisLabelLocation[0]<-14*fontSizeYAxisLabelMultiplier;const marginLabelDiff=GRAPH_LEFT_MARGIN-fontSize*fontSizeYAxisLabelMultiplier;const marginWithExtraOffset=-1*(yAxisLabelLocation[X]-marginLabelDiff);return jsxRuntimeExports.jsx(GraphConfigContext.Provider,{value:{range:state.range,snapStep:state.snapStep,markings:props.markings,tickStep:tickStep,gridStep:props.gridStep,showTooltips:!!props.showTooltips,showAxisArrows:props.showAxisArrows,graphDimensionsInPixels:props.box,width,height,labels,labelLocation,disableKeyboardInteraction:disableInteraction,interactiveColor:disableInteraction?"var(--static-gray)":"var(--mafs-blue)"},children:jsxRuntimeExports.jsxs(wonderBlocksCore.View,{className:"mafs-graph-container",children:[jsxRuntimeExports.jsxs(wonderBlocksCore.View,{className:"mafs-graph",style:{position:"relative",padding:"25px 25px 0 0",boxSizing:"content-box",marginLeft:needsExtraMargin?`${marginWithExtraOffset}px`:`${GRAPH_LEFT_MARGIN}px`,marginBottom:"30px",pointerEvents:props.static?"none":"auto",userSelect:"none",width,height},onKeyUp:event=>{handleKeyboardEvent(event,state,dispatch);},"aria-label":fullGraphAriaLabel,"aria-describedby":describedByIds(fullGraphAriaDescription&&descriptionId,interactiveElementsDescription&&interactiveElementsDescriptionId,isUnlimitedGraphState(state)&&unlimitedGraphKeyboardPromptId,state.type!=="none"&&!disableInteraction&&instructionsId),ref:graphRef,tabIndex:0,onFocus:event=>{handleFocusEvent(event,state,dispatch);},onBlur:event=>{handleBlurEvent(event,state,dispatch);},children:[fullGraphAriaDescription&&jsxRuntimeExports.jsx(wonderBlocksCore.View,{id:descriptionId,tabIndex:-1,className:"mafs-sr-only",children:fullGraphAriaDescription}),interactiveElementsDescription&&jsxRuntimeExports.jsx(wonderBlocksCore.View,{id:interactiveElementsDescriptionId,tabIndex:-1,className:"mafs-sr-only",children:interactiveElementsDescription}),state.type!=="none"&&jsxRuntimeExports.jsx(wonderBlocksCore.View,{id:instructionsId,tabIndex:-1,className:"mafs-sr-only",children:isUnlimitedGraphState(state)?strings.srUnlimitedGraphInstructions:strings.srGraphInstructions}),jsxRuntimeExports.jsx(LegacyGrid,{box:props.box,backgroundImage:props.backgroundImage}),jsxRuntimeExports.jsxs(wonderBlocksCore.View,{style:{position:"absolute",bottom:0,left:0},children:[(props.markings==="graph"||props.markings==="axes")&&jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:jsxRuntimeExports.jsx(AxisLabels,{i18n:i18n,xAxisLabelLocation:xAxisLabelLocation,yAxisLabelLocation:yAxisLabelLocation})}),jsxRuntimeExports.jsx(wonderBlocksCore.View,{"aria-hidden":props.lockedFigures.length===0,children:jsxRuntimeExports.jsxs(mafs.Mafs,{preserveAspectRatio:false,viewBox:{x:state.range[X],y:state.range[Y],padding:0},pan:false,zoom:false,width:width,height:height,children:[jsxRuntimeExports.jsx(SvgDefs,{}),jsxRuntimeExports.jsx("svg",{...nestedSVGAttributes,children:jsxRuntimeExports.jsx(Grid,{gridStep:props.gridStep,range:state.range,containerSizeClass:props.containerSizeClass,markings:props.markings,width:width,height:height})}),(props.markings==="graph"||props.markings==="axes")&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(AxisTicks,{}),jsxRuntimeExports.jsx(AxisArrows,{})]}),props.lockedFigures.length>0&&jsxRuntimeExports.jsx("svg",{...nestedSVGAttributes,children:jsxRuntimeExports.jsx(GraphLockedLayer,{lockedFigures:props.lockedFigures,range:state.range})})]})}),jsxRuntimeExports.jsx(GraphLockedLabelsLayer,{lockedFigures:props.lockedFigures}),jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:{position:"absolute"},children:jsxRuntimeExports.jsx(mafs.Mafs,{preserveAspectRatio:false,viewBox:{x:state.range[X],y:state.range[Y],padding:0},pan:false,zoom:false,width:width,height:height,children:jsxRuntimeExports.jsxs("svg",{...nestedSVGAttributes,style:{overflow:type==="point"?"visible":"hidden"},children:[props.showProtractor&&jsxRuntimeExports.jsx(Protractor,{}),graph]})})})]}),interactionPrompt&&jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:{display:interactionPrompt?undefined:"hidden",textAlign:"center",backgroundColor:"white",border:"1px solid #21242C52",padding:"16px 0",boxShadow:"0px 8px 8px 0px #21242C14",top:"50%",transform:"translateY(-50%)"},children:jsxRuntimeExports.jsx(wonderBlocksTypography.LabelMedium,{id:unlimitedGraphKeyboardPromptId,children:strings.graphKeyboardPrompt})})]}),renderGraphControls({state,dispatch,width,perseusStrings:strings})]})})};const renderPointGraphControls=props=>{const{interactionMode,showRemovePointButton,focusedPointIndex}=props.state;const{perseusStrings}=props;const shouldShowRemoveButton=showRemovePointButton&&focusedPointIndex!==null;return jsxRuntimeExports.jsxs(wonderBlocksCore.View,{style:{flexDirection:"row",width:props.width},children:[interactionMode==="keyboard"&&jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",style:{width:"100%",marginLeft:"20px"},tabIndex:0,onClick:()=>{props.dispatch(actions.pointGraph.addPoint([0,0]));},children:perseusStrings.addPoint}),interactionMode==="mouse"&&jsxRuntimeExports.jsx(Button__default.default,{id:REMOVE_BUTTON_ID,kind:"secondary",actionType:"destructive",tabIndex:-1,style:{width:"100%",marginLeft:"20px",visibility:shouldShowRemoveButton?"visible":"hidden"},onClick:_event=>{props.dispatch(actions.pointGraph.removePoint(props.state.focusedPointIndex));},children:perseusStrings.removePoint})]})};const renderPolygonGraphControls=props=>{const{interactionMode,showRemovePointButton,focusedPointIndex,closedPolygon,coords}=props.state;const{perseusStrings}=props;const shouldShowRemoveButton=showRemovePointButton&&focusedPointIndex!==null;const disableCloseButton=getArrayWithoutDuplicates(coords).length<3;const polygonButton=closedPolygon?jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",style:{width:"100%",marginLeft:"20px"},tabIndex:0,onClick:()=>{props.dispatch(actions.polygon.openPolygon());},children:perseusStrings.openPolygon}):jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",disabled:disableCloseButton,style:{width:"100%",marginLeft:"20px"},tabIndex:disableCloseButton?-1:0,onClick:()=>{props.dispatch(actions.polygon.closePolygon());},children:perseusStrings.closePolygon});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:jsxRuntimeExports.jsxs(wonderBlocksCore.View,{style:{flexDirection:"row",width:props.width},children:[interactionMode==="keyboard"&&jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",style:{width:"100%",marginLeft:"20px"},disabled:closedPolygon,tabIndex:closedPolygon?-1:0,onClick:()=>{props.dispatch(actions.polygon.addPoint([0,0]));},children:perseusStrings.addPoint}),interactionMode==="mouse"&&jsxRuntimeExports.jsx(Button__default.default,{id:REMOVE_BUTTON_ID,kind:"secondary",actionType:"destructive",disabled:closedPolygon||!shouldShowRemoveButton,tabIndex:-1,style:{width:"100%",marginLeft:"20px"},onClick:_event=>{props.dispatch(actions.polygon.removePoint(props.state.focusedPointIndex));},children:perseusStrings.removePoint}),polygonButton]})})};const renderGraphControls=props=>{const{state,dispatch,width,perseusStrings}=props;const{type}=state;switch(type){case "point":if(state.numPoints==="unlimited"){return renderPointGraphControls({state,dispatch,width,perseusStrings})}return null;case "polygon":if(state.numSides==="unlimited"){return renderPolygonGraphControls({state,dispatch,width,perseusStrings})}return null;default:return null}};function handleFocusEvent(event,state,dispatch){if(isUnlimitedGraphState(state)){if(event.target.classList.contains("mafs-graph")&&state.interactionMode==="mouse"){dispatch(actions.global.changeKeyboardInvitationVisibility(true));}}}function handleBlurEvent(_event,state,dispatch){if(isUnlimitedGraphState(state)){dispatch(actions.global.changeKeyboardInvitationVisibility(false));}}function handleKeyboardEvent(event,state,dispatch){if(isUnlimitedGraphState(state)){if(event.key==="Backspace"||event.key==="Delete"){if(document.activeElement?.classList.contains("movable-point__focusable-handle")){if(state.type==="point"||state.type==="polygon"&&!state.closedPolygon){dispatch(actions.global.deleteIntent());}}document.activeElement.blur();}else if(event.shiftKey&&event.key==="Enter"){dispatch(actions.global.changeInteractionMode("keyboard"));}else if(state.interactionMode==="keyboard"&&event.key==="a"){dispatch(actions.pointGraph.addPoint([0,0]));}}}const renderGraphElements=props=>{const{state,dispatch,i18n,markings}=props;const{type}=state;switch(type){case "angle":return renderAngleGraph(state,dispatch,i18n);case "segment":return renderSegmentGraph(state,dispatch,i18n);case "linear-system":return renderLinearSystemGraph(state,dispatch,i18n);case "linear":return renderLinearGraph(state,dispatch,i18n);case "ray":return renderRayGraph(state,dispatch,i18n);case "polygon":return renderPolygonGraph(state,dispatch,i18n,markings);case "point":return renderPointGraph(state,dispatch,i18n);case "circle":return renderCircleGraph(state,dispatch,i18n);case "quadratic":return renderQuadraticGraph(state,dispatch,i18n);case "sinusoid":return renderSinusoidGraph(state,dispatch,i18n);case "none":return {graph:null,interactiveElementsDescription:null};default:throw new wonderStuffCore.UnreachableCaseError(type)}};function describedByIds(...args){return args.filter(Boolean).join(" ")||undefined}
2044
2046
 
2045
2047
  function mafsStateToInteractiveGraph(state,originalGraph){switch(state.type){case "angle":invariant__default.default(originalGraph.type==="angle");return {...originalGraph,coords:state.coords};case "quadratic":invariant__default.default(originalGraph.type==="quadratic");return {...originalGraph,coords:state.coords};case "circle":invariant__default.default(originalGraph.type==="circle");return {...originalGraph,center:state.center,radius:getRadius(state)};case "linear":invariant__default.default(originalGraph.type==="linear");return {...originalGraph,coords:state.coords};case "ray":invariant__default.default(originalGraph.type==="ray");return {...originalGraph,coords:state.coords};case "sinusoid":invariant__default.default(originalGraph.type==="sinusoid");return {...originalGraph,coords:state.coords};case "segment":invariant__default.default(originalGraph.type==="segment");return {...originalGraph,coords:state.coords};case "linear-system":invariant__default.default(originalGraph.type==="linear-system");return {...originalGraph,coords:state.coords};case "polygon":invariant__default.default(originalGraph.type==="polygon");return {...originalGraph,coords:state.coords};case "point":invariant__default.default(originalGraph.type==="point");return {...originalGraph,coords:state.coords};case "none":invariant__default.default(originalGraph.type==="none");return {...originalGraph};default:throw new wonderStuffCore.UnreachableCaseError(state)}}
2046
2048
 
2047
2049
  const StatefulMafsGraph=React__namespace.forwardRef(function StatefulMafsGraphWithRef(props,ref){const{onChange,graph}=props;const[state,dispatch]=React__namespace.useReducer(interactiveGraphReducer,props,initializeGraphState);React.useImperativeHandle(ref,()=>({getUserInput:()=>getGradableGraph(state,graph)}));const prevState=React.useRef(state);React.useEffect(()=>{if(prevState.current!==state){onChange(mafsStateToInteractiveGraph(state,graph));}prevState.current=state;},[onChange,state,graph]);const[xSnap,ySnap]=props.snapStep;React.useEffect(()=>{dispatch(changeSnapStep([xSnap,ySnap]));},[dispatch,xSnap,ySnap]);const[[xMinRange,xMaxRange],[yMinRange,yMaxRange]]=props.range;React.useEffect(()=>{dispatch(changeRange([[xMinRange,xMaxRange],[yMinRange,yMaxRange]]));},[dispatch,xMinRange,xMaxRange,yMinRange,yMaxRange]);const numSegments=graph.type==="segment"?graph.numSegments:null;const numPoints=graph.type==="point"?graph.numPoints:null;const numSides=graph.type==="polygon"?graph.numSides:null;const snapTo=graph.type==="polygon"?graph.snapTo:null;const showAngles=graph.type==="polygon"||graph.type==="angle"?graph.showAngles:null;const allowReflexAngles=graph.type==="angle"?graph.allowReflexAngles:null;const showSides=graph.type==="polygon"?graph.showSides:null;const startCoords="startCoords"in graph?graph.startCoords:undefined;const originalPropsRef=React.useRef(props);const latestPropsRef=wonderBlocksCore.useLatestRef(props);React.useEffect(()=>{if(latestPropsRef.current!==originalPropsRef.current){dispatch(reinitialize(latestPropsRef.current));}},[graph.type,numPoints,numSegments,numSides,snapTo,showAngles,showSides,latestPropsRef,startCoords,allowReflexAngles]);if(props.static&&props.correct){return jsxRuntimeExports.jsx(MafsGraph,{...props,state:initializeGraphState({...props,graph:props.correct}),dispatch:dispatch})}return jsxRuntimeExports.jsx(MafsGraph,{...props,state:state,dispatch:dispatch})});
2048
2050
 
2049
- const{getClockwiseAngle}=kmath.angles;const{getLineEquation,getLineIntersectionString,magnitude,vector}=kmath.geometry;const defaultBackgroundImage={url:null};const UNLIMITED="unlimited";function numSteps(range,step){return Math.floor((range[1]-range[0])/step)}const makeInvalidTypeError=(functionName,graphType)=>{return new perseusCore.PerseusError(`${functionName} called but current graph type is not a '${graphType}'`,perseusCore.Errors.NotAllowed,{metadata:{graphType}})};function getSinusoidCoefficients(coords){const p1=coords[0];const p2=coords[1];const amplitude=p2[1]-p1[1];const angularFrequency=Math.PI/(2*(p2[0]-p1[0]));const phase=p1[0]*angularFrequency;const verticalOffset=p1[1];return [amplitude,angularFrequency,phase,verticalOffset]}function getQuadraticCoefficients(coords){const p1=coords[0];const p2=coords[1];const p3=coords[2];const denom=(p1[0]-p2[0])*(p1[0]-p3[0])*(p2[0]-p3[0]);if(denom===0){return}const a=(p3[0]*(p2[1]-p1[1])+p2[0]*(p1[1]-p3[1])+p1[0]*(p3[1]-p2[1]))/denom;const b=(p3[0]*p3[0]*(p1[1]-p2[1])+p2[0]*p2[0]*(p3[1]-p1[1])+p1[0]*p1[0]*(p2[1]-p3[1]))/denom;const c=(p2[0]*p3[0]*(p2[0]-p3[0])*p1[1]+p3[0]*p1[0]*(p3[0]-p1[0])*p2[1]+p1[0]*p2[0]*(p1[0]-p2[0])*p3[1])/denom;return [a,b,c]}class InteractiveGraph extends React__namespace.Component{getUserInput(){if(this.mafsRef.current?.getUserInput){return this.mafsRef.current.getUserInput()}throw new perseusCore.PerseusError("Cannot getUserInput from a graph that has never rendered",perseusCore.Errors.NotAllowed)}getPromptJSON(){return getPromptJSON$b(this.props,this.getUserInput())}getSerializedState(){const{userInput:_,...rest}=this.props;return {...rest,graph:this.props.userInput}}render(){const box=getInteractiveBoxFromSizeClass(this.props.containerSizeClass);const gridStep=this.props.gridStep||Util.getGridStep(this.props.range,this.props.step,box[0]);const snapStep=this.props.snapStep||Util.snapStepFromGridStep(gridStep);const mafsProps={...this.props,graph:this.props.userInput,onChange:()=>this.props.handleUserInput(this.mafsRef.current?.getUserInput())};return jsxRuntimeExports.jsx(StatefulMafsGraph,{...mafsProps,ref:this.mafsRef,gridStep:gridStep,snapStep:snapStep,box:box,showTooltips:!!this.props.showTooltips,readOnly:this.props.apiOptions?.readOnly})}static getLineCoords(graph,props){return graph.coords||InteractiveGraph.pointsFromNormalized(props,[[.25,.75],[.75,.75]])}static getPointCoords(graph,props){const numPoints=graph.numPoints||1;let coords=graph.coords;if(coords){return coords}switch(numPoints){case 1:coords=[graph.coord||[0,0]];break;case 2:coords=[[-5,0],[5,0]];break;case 3:coords=[[-5,0],[0,0],[5,0]];break;case 4:coords=[[-6,0],[-2,0],[2,0],[6,0]];break;case 5:coords=[[-6,0],[-3,0],[0,0],[3,0],[6,0]];break;case 6:coords=[[-5,0],[-3,0],[-1,0],[1,0],[3,0],[5,0]];break;case UNLIMITED:coords=[];break}const range=[[-10,10],[-10,10]];const newCoords=InteractiveGraph.normalizeCoords(coords,range);return InteractiveGraph.pointsFromNormalized(props,newCoords)}static getLinearSystemCoords(graph,props){return graph.coords||___default.default.map([[[.25,.75],[.75,.75]],[[.25,.25],[.75,.25]]],coords=>{return InteractiveGraph.pointsFromNormalized(props,coords)})}static getPolygonCoords(graph,props){if(graph.type!=="polygon"){throw makeInvalidTypeError("toggleShowSides","polygon")}let coords=graph.coords;if(coords){return coords}const n=graph.numSides||3;if(n===UNLIMITED){coords=[];}else {const angle=2*Math.PI/n;const offset=(1/n-1/2)*Math.PI;const radius=graph.snapTo==="sides"?Math.sqrt(3)/3*7:4;coords=___default.default.times(n,function(i){return [radius*Math.cos(i*angle+offset),radius*Math.sin(i*angle+offset)]});}const ranges=[[-10,10],[-10,10]];coords=InteractiveGraph.normalizeCoords(coords,ranges);const snapToGrid=!___default.default.contains(["angles","sides"],graph.snapTo);coords=InteractiveGraph.pointsFromNormalized(props,coords,!snapToGrid);return coords}static getSegmentCoords(graph,props){const coords=graph.coords;if(coords){return coords}const n=graph.numSegments||1;const ys={1:[5],2:[5,-5],3:[5,0,-5],4:[6,2,-2,-6],5:[6,3,0,-3,-6],6:[5,3,1,-1,-3,-5]}[n];const range=[[-10,10],[-10,10]];return ys.map(function(y){let segment=[[-5,y],[5,y]];segment=InteractiveGraph.normalizeCoords(segment,range);segment=InteractiveGraph.pointsFromNormalized(props,segment);return segment})}static getAngleCoords(graph,props){let coords=graph.coords;if(coords){return coords}const snap=graph.snapDegrees||1;let angle=snap;while(angle<20){angle+=snap;}angle=angle*Math.PI/180;const offset=(graph.angleOffsetDeg||0)*Math.PI/180;coords=InteractiveGraph.pointsFromNormalized(props,[[.85,.5],[.5,.5]]);const radius=magnitude(vector(...coords));coords[0]=[coords[1][0]+radius*Math.cos(offset),coords[1][1]+radius*Math.sin(offset)];coords[2]=[coords[1][0]+radius*Math.cos(angle+offset),coords[1][1]+radius*Math.sin(angle+offset)];return coords}static normalizeCoords(coordsList,ranges){return ___default.default.map(coordsList,function(coords){return ___default.default.map(coords,function(coord,i){const extent=ranges[i][1]-ranges[i][0];return (coord+ranges[i][1])/extent})})}static getEquationString(props){const type=props.userInput.type;switch(type){case "none":return InteractiveGraph.getNoneEquationString();case "linear":return InteractiveGraph.getLinearEquationString(props);case "quadratic":return InteractiveGraph.getQuadraticEquationString(props);case "sinusoid":return InteractiveGraph.getSinusoidEquationString(props);case "circle":return InteractiveGraph.getCircleEquationString(props);case "linear-system":return InteractiveGraph.getLinearSystemEquationString(props);case "point":return InteractiveGraph.getPointEquationString(props);case "segment":return InteractiveGraph.getSegmentEquationString(props);case "ray":return InteractiveGraph.getRayEquationString(props);case "polygon":return InteractiveGraph.getPolygonEquationString(props);case "angle":return InteractiveGraph.getAngleEquationString(props);default:throw new wonderStuffCore.UnreachableCaseError(type)}}static pointsFromNormalized(props,coordsList,noSnap){return ___default.default.map(coordsList,function(coords){return ___default.default.map(coords,function(coord,i){const range=props.range[i];if(noSnap){return range[0]+(range[1]-range[0])*coord}const step=props.step[i];const nSteps=numSteps(range,step);const tick=Math.round(coord*nSteps);return range[0]+step*tick})})}static getNoneEquationString(){return ""}static getLinearEquationString(props){const coords=InteractiveGraph.getLineCoords(props.userInput,props);if(perseusCore.approximateEqual(coords[0][0],coords[1][0])){return "x = "+coords[0][0].toFixed(3)}const m=(coords[1][1]-coords[0][1])/(coords[1][0]-coords[0][0]);const b=coords[0][1]-m*coords[0][0];if(perseusCore.approximateEqual(m,0)){return "y = "+b.toFixed(3)}return "y = "+m.toFixed(3)+"x + "+b.toFixed(3)}static getCurrentQuadraticCoefficients(props){const coords=props.userInput.coords||InteractiveGraph.defaultQuadraticCoords(props);return getQuadraticCoefficients(coords)}static defaultQuadraticCoords(props){const coords=[[.25,.75],[.5,.25],[.75,.75]];return InteractiveGraph.pointsFromNormalized(props,coords)}static getQuadraticEquationString(props){const coeffs=InteractiveGraph.getCurrentQuadraticCoefficients(props);return "y = "+coeffs[0].toFixed(3)+"x^2 + "+coeffs[1].toFixed(3)+"x + "+coeffs[2].toFixed(3)}static getCurrentSinusoidCoefficients(props){const coords=props.userInput.coords||InteractiveGraph.defaultSinusoidCoords(props);return getSinusoidCoefficients(coords)}static defaultSinusoidCoords(props){const coords=[[.5,.5],[.65,.6]];return InteractiveGraph.pointsFromNormalized(props,coords)}static getSinusoidEquationString(props){const coeffs=InteractiveGraph.getCurrentSinusoidCoefficients(props);return "y = "+coeffs[0].toFixed(3)+"sin("+coeffs[1].toFixed(3)+"x - "+coeffs[2].toFixed(3)+") + "+coeffs[3].toFixed(3)}static getCircleEquationString(props){const graph=props.userInput;const center=graph.center||[0,0];const radius=graph.radius||2;return "center ("+center[0]+", "+center[1]+"), radius "+radius}static getLinearSystemEquationString(props){const coords=InteractiveGraph.getLinearSystemCoords(props.userInput,props);return "\n"+getLineEquation(coords[0][0],coords[0][1])+"\n"+getLineEquation(coords[1][0],coords[1][1])+"\n"+getLineIntersectionString(coords[0],coords[1])}static getPointEquationString(props){if(props.userInput.type!=="point"){throw makeInvalidTypeError("getPointEquationString","point")}const coords=InteractiveGraph.getPointCoords(props.userInput,props);return coords.map(function(coord){return "("+coord[0]+", "+coord[1]+")"}).join(", ")}static getSegmentEquationString(props){if(props.userInput.type!=="segment"){throw makeInvalidTypeError("getSegmentEquationString","segment")}const segments=InteractiveGraph.getSegmentCoords(props.userInput,props);return ___default.default.map(segments,function(segment){return "["+___default.default.map(segment,function(coord){return "("+coord.join(", ")+")"}).join(" ")+"]"}).join(" ")}static getRayEquationString(props){if(props.userInput.type!=="ray"){throw makeInvalidTypeError("createPointForPolygonType","ray")}const coords=InteractiveGraph.getLineCoords(props.userInput,props);const a=coords[0];const b=coords[1];let eq=InteractiveGraph.getLinearEquationString(props);if(a[0]>b[0]){eq+=" (for x <= "+a[0].toFixed(3)+")";}else if(a[0]<b[0]){eq+=" (for x >= "+a[0].toFixed(3)+")";}else if(a[1]>b[1]){eq+=" (for y <= "+a[1].toFixed(3)+")";}else {eq+=" (for y >= "+a[1].toFixed(3)+")";}return eq}static getPolygonEquationString(props){if(props.userInput.type!=="polygon"){throw makeInvalidTypeError("getPolygonEquationString","polygon")}const coords=InteractiveGraph.getPolygonCoords(props.userInput,props);return ___default.default.map(coords,function(coord){return "("+coord.join(", ")+")"}).join(" ")}static getAngleEquationString(props){if(props.userInput.type!=="angle"){throw makeInvalidTypeError("getAngleEquationString","angle")}const coords=InteractiveGraph.getAngleCoords(props.userInput,props);const allowReflexAngles=props.userInput.allowReflexAngles;const angle=getClockwiseAngle(coords,allowReflexAngles);return angle.toFixed(0)+"° angle"+" at ("+coords[1].join(", ")+")"}constructor(...args){super(...args),this.mafsRef=React__namespace.createRef();}}InteractiveGraph.defaultProps={labels:["x","y"],labelLocation:"onAxis",range:[[-10,10],[-10,10]],step:[1,1],backgroundImage:defaultBackgroundImage,markings:"graph",showTooltips:false,showProtractor:false,userInput:{type:"linear"}};function getUserInputFromSerializedState$8(serializedState){return serializedState.graph}function getStartUserInput$8(options){return options.graph}function getCorrectUserInput$3(options){return options.correct}var InteractiveGraph$1 = {name:"interactive-graph",displayName:"Interactive graph",widget:InteractiveGraph,staticTransform:___default.default.identity,getStartUserInput: getStartUserInput$8,getCorrectUserInput: getCorrectUserInput$3,getUserInputFromSerializedState: getUserInputFromSerializedState$8};
2051
+ const{getClockwiseAngle}=kmath.angles;const{getLineEquation,getLineIntersectionString,magnitude,vector}=kmath.geometry;const defaultBackgroundImage={url:null};const UNLIMITED="unlimited";function numSteps(range,step){return Math.floor((range[1]-range[0])/step)}const makeInvalidTypeError=(functionName,graphType)=>{return new perseusCore.PerseusError(`${functionName} called but current graph type is not a '${graphType}'`,perseusCore.Errors.NotAllowed,{metadata:{graphType}})};function getSinusoidCoefficients(coords){const p1=coords[0];const p2=coords[1];const amplitude=p2[1]-p1[1];const angularFrequency=Math.PI/(2*(p2[0]-p1[0]));const phase=p1[0]*angularFrequency;const verticalOffset=p1[1];return [amplitude,angularFrequency,phase,verticalOffset]}function getQuadraticCoefficients(coords){const p1=coords[0];const p2=coords[1];const p3=coords[2];const denom=(p1[0]-p2[0])*(p1[0]-p3[0])*(p2[0]-p3[0]);if(denom===0){return}const a=(p3[0]*(p2[1]-p1[1])+p2[0]*(p1[1]-p3[1])+p1[0]*(p3[1]-p2[1]))/denom;const b=(p3[0]*p3[0]*(p1[1]-p2[1])+p2[0]*p2[0]*(p3[1]-p1[1])+p1[0]*p1[0]*(p2[1]-p3[1]))/denom;const c=(p2[0]*p3[0]*(p2[0]-p3[0])*p1[1]+p3[0]*p1[0]*(p3[0]-p1[0])*p2[1]+p1[0]*p2[0]*(p1[0]-p2[0])*p3[1])/denom;return [a,b,c]}class InteractiveGraph extends React__namespace.Component{getUserInput(){if(this.mafsRef.current?.getUserInput){return this.mafsRef.current.getUserInput()}throw new perseusCore.PerseusError("Cannot getUserInput from a graph that has never rendered",perseusCore.Errors.NotAllowed)}getPromptJSON(){return getPromptJSON$b(this.props,this.getUserInput())}getSerializedState(){const{userInput:_,...rest}=this.props;return {...rest,graph:this.props.userInput}}render(){const box=getInteractiveBoxFromSizeClass(this.props.containerSizeClass);const gridStep=this.props.gridStep||Util.getGridStep(this.props.range,this.props.step,box[0]);const snapStep=this.props.snapStep||Util.snapStepFromGridStep(gridStep);const mafsProps={...this.props,graph:this.props.userInput,onChange:()=>this.props.handleUserInput(this.mafsRef.current?.getUserInput())};return jsxRuntimeExports.jsx(StatefulMafsGraph,{...mafsProps,ref:this.mafsRef,gridStep:gridStep,snapStep:snapStep,box:box,showTooltips:!!this.props.showTooltips,readOnly:this.props.apiOptions?.readOnly})}static getLineCoords(graph,props){return graph.coords||InteractiveGraph.pointsFromNormalized(props,[[.25,.75],[.75,.75]])}static getPointCoords(graph,props){const numPoints=graph.numPoints||1;let coords=graph.coords;if(coords){return coords}switch(numPoints){case 1:coords=[graph.coord||[0,0]];break;case 2:coords=[[-5,0],[5,0]];break;case 3:coords=[[-5,0],[0,0],[5,0]];break;case 4:coords=[[-6,0],[-2,0],[2,0],[6,0]];break;case 5:coords=[[-6,0],[-3,0],[0,0],[3,0],[6,0]];break;case 6:coords=[[-5,0],[-3,0],[-1,0],[1,0],[3,0],[5,0]];break;case UNLIMITED:coords=[];break}const range=[[-10,10],[-10,10]];const newCoords=InteractiveGraph.normalizeCoords(coords,range);return InteractiveGraph.pointsFromNormalized(props,newCoords)}static getLinearSystemCoords(graph,props){return graph.coords||___default.default.map([[[.25,.75],[.75,.75]],[[.25,.25],[.75,.25]]],coords=>{return InteractiveGraph.pointsFromNormalized(props,coords)})}static getPolygonCoords(graph,props){if(graph.type!=="polygon"){throw makeInvalidTypeError("toggleShowSides","polygon")}let coords=graph.coords;if(coords){return coords}const n=graph.numSides||3;if(n===UNLIMITED){coords=[];}else {const angle=2*Math.PI/n;const offset=(1/n-1/2)*Math.PI;const radius=graph.snapTo==="sides"?Math.sqrt(3)/3*7:4;coords=___default.default.times(n,function(i){return [radius*Math.cos(i*angle+offset),radius*Math.sin(i*angle+offset)]});}const ranges=[[-10,10],[-10,10]];coords=InteractiveGraph.normalizeCoords(coords,ranges);const snapToGrid=!___default.default.contains(["angles","sides"],graph.snapTo);coords=InteractiveGraph.pointsFromNormalized(props,coords,!snapToGrid);return coords}static getSegmentCoords(graph,props){const coords=graph.coords;if(coords){return coords}const n=graph.numSegments||1;const ys={1:[5],2:[5,-5],3:[5,0,-5],4:[6,2,-2,-6],5:[6,3,0,-3,-6],6:[5,3,1,-1,-3,-5]}[n];const range=[[-10,10],[-10,10]];return ys.map(function(y){let segment=[[-5,y],[5,y]];segment=InteractiveGraph.normalizeCoords(segment,range);segment=InteractiveGraph.pointsFromNormalized(props,segment);return segment})}static getAngleCoords(graph,props){let coords=graph.coords;if(coords){return coords}const snap=graph.snapDegrees||1;let angle=snap;while(angle<20){angle+=snap;}angle=angle*Math.PI/180;const offset=(graph.angleOffsetDeg||0)*Math.PI/180;coords=InteractiveGraph.pointsFromNormalized(props,[[.85,.5],[.5,.5]]);const radius=magnitude(vector(...coords));coords[0]=[coords[1][0]+radius*Math.cos(offset),coords[1][1]+radius*Math.sin(offset)];coords[2]=[coords[1][0]+radius*Math.cos(angle+offset),coords[1][1]+radius*Math.sin(angle+offset)];return coords}static normalizeCoords(coordsList,ranges){return ___default.default.map(coordsList,function(coords){return ___default.default.map(coords,function(coord,i){const extent=ranges[i][1]-ranges[i][0];return (coord+ranges[i][1])/extent})})}static getEquationString(props){const type=props.userInput.type;switch(type){case "none":return InteractiveGraph.getNoneEquationString();case "linear":return InteractiveGraph.getLinearEquationString(props);case "quadratic":return InteractiveGraph.getQuadraticEquationString(props);case "sinusoid":return InteractiveGraph.getSinusoidEquationString(props);case "circle":return InteractiveGraph.getCircleEquationString(props);case "linear-system":return InteractiveGraph.getLinearSystemEquationString(props);case "point":return InteractiveGraph.getPointEquationString(props);case "segment":return InteractiveGraph.getSegmentEquationString(props);case "ray":return InteractiveGraph.getRayEquationString(props);case "polygon":return InteractiveGraph.getPolygonEquationString(props);case "angle":return InteractiveGraph.getAngleEquationString(props);default:throw new wonderStuffCore.UnreachableCaseError(type)}}static pointsFromNormalized(props,coordsList,noSnap){return ___default.default.map(coordsList,function(coords){return ___default.default.map(coords,function(coord,i){const range=props.range[i];if(noSnap){return range[0]+(range[1]-range[0])*coord}const step=props.step[i];const nSteps=numSteps(range,step);const tick=Math.round(coord*nSteps);return range[0]+step*tick})})}static getNoneEquationString(){return ""}static getLinearEquationString(props){const coords=InteractiveGraph.getLineCoords(props.userInput,props);if(perseusCore.approximateEqual(coords[0][0],coords[1][0])){return "x = "+coords[0][0].toFixed(3)}const m=(coords[1][1]-coords[0][1])/(coords[1][0]-coords[0][0]);const b=coords[0][1]-m*coords[0][0];if(perseusCore.approximateEqual(m,0)){return "y = "+b.toFixed(3)}return "y = "+m.toFixed(3)+"x + "+b.toFixed(3)}static getCurrentQuadraticCoefficients(props){const coords=props.userInput.coords||InteractiveGraph.defaultQuadraticCoords(props);return getQuadraticCoefficients(coords)}static defaultQuadraticCoords(props){const coords=[[.25,.75],[.5,.25],[.75,.75]];return InteractiveGraph.pointsFromNormalized(props,coords)}static getQuadraticEquationString(props){const coeffs=InteractiveGraph.getCurrentQuadraticCoefficients(props);return "y = "+coeffs[0].toFixed(3)+"x^2 + "+coeffs[1].toFixed(3)+"x + "+coeffs[2].toFixed(3)}static getCurrentSinusoidCoefficients(props){const coords=props.userInput.coords||InteractiveGraph.defaultSinusoidCoords(props);return getSinusoidCoefficients(coords)}static defaultSinusoidCoords(props){const coords=[[.5,.5],[.65,.6]];return InteractiveGraph.pointsFromNormalized(props,coords)}static getSinusoidEquationString(props){const coeffs=InteractiveGraph.getCurrentSinusoidCoefficients(props);return "y = "+coeffs[0].toFixed(3)+"sin("+coeffs[1].toFixed(3)+"x - "+coeffs[2].toFixed(3)+") + "+coeffs[3].toFixed(3)}static getCircleEquationString(props){const graph=props.userInput;const center=graph.center||[0,0];const radius=graph.radius||2;return "center ("+center[0]+", "+center[1]+"), radius "+radius}static getLinearSystemEquationString(props){const coords=InteractiveGraph.getLinearSystemCoords(props.userInput,props);return "\n"+getLineEquation(coords[0][0],coords[0][1])+"\n"+getLineEquation(coords[1][0],coords[1][1])+"\n"+getLineIntersectionString(coords[0],coords[1])}static getPointEquationString(props){if(props.userInput.type!=="point"){throw makeInvalidTypeError("getPointEquationString","point")}const coords=InteractiveGraph.getPointCoords(props.userInput,props);return coords.map(function(coord){return "("+coord[0]+", "+coord[1]+")"}).join(", ")}static getSegmentEquationString(props){if(props.userInput.type!=="segment"){throw makeInvalidTypeError("getSegmentEquationString","segment")}const segments=InteractiveGraph.getSegmentCoords(props.userInput,props);return ___default.default.map(segments,function(segment){return "["+___default.default.map(segment,function(coord){return "("+coord.join(", ")+")"}).join(" ")+"]"}).join(" ")}static getRayEquationString(props){if(props.userInput.type!=="ray"){throw makeInvalidTypeError("createPointForPolygonType","ray")}const coords=InteractiveGraph.getLineCoords(props.userInput,props);const a=coords[0];const b=coords[1];let eq=InteractiveGraph.getLinearEquationString(props);if(a[0]>b[0]){eq+=" (for x <= "+a[0].toFixed(3)+")";}else if(a[0]<b[0]){eq+=" (for x >= "+a[0].toFixed(3)+")";}else if(a[1]>b[1]){eq+=" (for y <= "+a[1].toFixed(3)+")";}else {eq+=" (for y >= "+a[1].toFixed(3)+")";}return eq}static getPolygonEquationString(props){if(props.userInput.type!=="polygon"){throw makeInvalidTypeError("getPolygonEquationString","polygon")}const coords=InteractiveGraph.getPolygonCoords(props.userInput,props);return ___default.default.map(coords,function(coord){return "("+coord.join(", ")+")"}).join(" ")}static getAngleEquationString(props){if(props.userInput.type!=="angle"){throw makeInvalidTypeError("getAngleEquationString","angle")}const coords=InteractiveGraph.getAngleCoords(props.userInput,props);const allowReflexAngles=props.userInput.allowReflexAngles;const angle=getClockwiseAngle(coords,allowReflexAngles);return angle.toFixed(0)+"° angle"+" at ("+coords[1].join(", ")+")"}constructor(...args){super(...args),this.mafsRef=React__namespace.createRef();}}InteractiveGraph.defaultProps={labels:["x","y"],labelLocation:"onAxis",range:[[-10,10],[-10,10]],showAxisArrows:{xMin:true,xMax:true,yMin:true,yMax:true},step:[1,1],backgroundImage:defaultBackgroundImage,markings:"graph",showTooltips:false,showProtractor:false,userInput:{type:"linear"}};function getUserInputFromSerializedState$8(serializedState){return serializedState.graph}function getStartUserInput$8(options){return options.graph}function getCorrectUserInput$3(options){return options.correct}var InteractiveGraph$1 = {name:"interactive-graph",displayName:"Interactive graph",widget:InteractiveGraph,getStartUserInput: getStartUserInput$8,getCorrectUserInput: getCorrectUserInput$3,getUserInputFromSerializedState: getUserInputFromSerializedState$8};
2050
2052
 
2051
2053
  const bodyXsmallBold={fontFamily:"inherit",fontSize:15,fontWeight:"bold",lineHeight:"22px"};
2052
2054
 
@@ -2070,7 +2072,7 @@ const HACKY_CSS_CLASSNAME="perseus-widget-matcher";class Matcher extends React__
2070
2072
 
2071
2073
  const getPromptJSON$8=renderProps=>{return {type:"matrix",options:{height:renderProps.matrixBoardSize[0],width:renderProps.matrixBoardSize[1]},userInput:{answerRows:renderProps.userInput.answers}}};
2072
2074
 
2073
- const{assert: assert$2}=InteractiveUtil;const NORMAL_DIMENSIONS={INPUT_MARGIN:3,INPUT_HEIGHT:30,INPUT_WIDTH:40};const KEYPAD_INPUT_DIMENSIONS={INPUT_MARGIN:4,INPUT_HEIGHT:36,INPUT_WIDTH:64};function getInputPath$1(row,column){return [""+row,""+column]}const getDefaultPath$1=function(){return getInputPath$1(0,0)};const getRowFromPath$1=function(path){assert$2(Array.isArray(path)&&path.length===2);return +path[0]};const getColumnFromPath$1=function(path){assert$2(Array.isArray(path)&&path.length===2);return +path[1]};const getRefForPath$1=function(path){const row=getRowFromPath$1(path);const column=getColumnFromPath$1(path);return "answer"+row+","+column};class Matrix extends React__namespace.Component{componentDidMount(){this.cursorPosition=[0,0];}getDOMNodeForPath(path){const inputID=getRefForPath$1(path);return ReactDOM__namespace.default.findDOMNode(this.refs[inputID])}getPromptJSON(){return getPromptJSON$8(this.props)}getSerializedState(){const{userInput,...rest}=this.props;return {...rest,answers:userInput.answers}}render(){let dimensions;if(this.props.apiOptions.customKeypad){dimensions=KEYPAD_INPUT_DIMENSIONS;}else {dimensions=NORMAL_DIMENSIONS;}const{INPUT_MARGIN,INPUT_HEIGHT,INPUT_WIDTH}=dimensions;const matrixSize=perseusCore.getMatrixSize(this.props.userInput.answers);const maxRows=this.props.matrixBoardSize[0];const maxCols=this.props.matrixBoardSize[1];const cursorRow=this.props.cursorPosition[0];const cursorCol=this.props.cursorPosition[1];const highlightedRow=Math.max(cursorRow,matrixSize[0]-1);const highlightedCol=Math.max(cursorCol,matrixSize[1]-1);const bracketHeight=(highlightedRow+1)*(INPUT_HEIGHT+2*INPUT_MARGIN);const bracketOffset=(highlightedCol+1)*(INPUT_WIDTH+2*INPUT_MARGIN);const className=classNames__default.default({"perseus-matrix":true,"static-mode":this.props.static,"the-matrix":this.state.enterTheMatrix>=5});return jsxRuntimeExports.jsxs("div",{className:className,children:[this.props.prefix&&jsxRuntimeExports.jsx("div",{className:"matrix-prefix",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.prefix,linterContext:this.props.linterContext,strings:this.context.strings})}),jsxRuntimeExports.jsxs("div",{className:"matrix-input",children:[jsxRuntimeExports.jsx("div",{className:"matrix-bracket bracket-left",style:{height:bracketHeight}}),jsxRuntimeExports.jsx("div",{className:"matrix-bracket bracket-right",style:{height:bracketHeight,left:bracketOffset}}),___default.default(maxRows).times(row=>{const rowVals=this.props.userInput.answers[row];return jsxRuntimeExports.jsx("div",{className:"matrix-row",children:___default.default(maxCols).times(col=>{const outside=row>highlightedRow||col>highlightedCol;const inputProps={className:outside?"outside":"inside",ref:getRefForPath$1(getInputPath$1(row,col)),value:rowVals?rowVals[col]:null,style:{height:INPUT_HEIGHT,width:INPUT_WIDTH,margin:INPUT_MARGIN},disabled:this.props.apiOptions.readOnly,onFocus:()=>{this.cursorPosition=[row,col];this.props.onChange({cursorPosition:[row,col]},()=>{return false});this._handleFocus(row,col);},onBlur:()=>{if(row===this.cursorPosition[0]&&col===this.cursorPosition[1]){this.props.onChange({cursorPosition:[0,0]},()=>{return false});}this._handleBlur(row,col);},onKeyDown:e=>{this.handleKeyDown(row,col,e);},onChange:(value,cb)=>{this.onValueChange(row,col,value,cb);}};let MatrixInput;if(this.props.apiOptions.customKeypad){const style={margin:INPUT_MARGIN,minWidth:INPUT_WIDTH,minHeight:INPUT_HEIGHT,boxSizing:"border-box",backgroundColor:outside?"#f3f3f3":"#fff"};MatrixInput=jsxRuntimeExports.jsx(SimpleKeypadInput,{...inputProps,style:style,scrollable:true,keypadElement:this.props.keypadElement});}else {const updatedProps={...inputProps,style:aphrodite.StyleSheet.create({input:{...inputProps.style,display:"inline-block",padding:0,backgroundColor:outside?"#f3f3f3":"#fff"}}).input};MatrixInput=jsxRuntimeExports.jsx(TextInput,{...updatedProps});}return jsxRuntimeExports.jsx("span",{className:"matrix-input-field",children:MatrixInput},col)})},row)})]}),this.props.suffix&&jsxRuntimeExports.jsx("div",{className:"matrix-suffix",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.suffix,linterContext:this.props.linterContext,strings:this.context.strings})})]})}constructor(...args){super(...args),this.state={enterTheMatrix:0},this.getInputPaths=()=>{const inputPaths=[];const maxRows=this.props.matrixBoardSize[0];const maxCols=this.props.matrixBoardSize[1];for(let row=0;row<maxRows;row++){for(let col=0;col<maxCols;col++){const inputPath=getInputPath$1(row,col);inputPaths.push(inputPath);}}return inputPaths},this._handleFocus=(row,col)=>{this.props.onFocus(getInputPath$1(row,col));},this._handleBlur=(row,col)=>{this.props.onBlur(getInputPath$1(row,col));},this.focus=()=>{this.focusInputPath(getDefaultPath$1());return true},this.focusInputPath=path=>{const inputID=getRefForPath$1(path);this.refs[inputID].focus();},this.blurInputPath=path=>{if(path.length===0){path=getDefaultPath$1();}const inputID=getRefForPath$1(path);this.refs[inputID].blur();},this.handleKeyDown=(row,col,e)=>{const maxRow=this.props.matrixBoardSize[0];const maxCol=this.props.matrixBoardSize[1];let enterTheMatrix=null;const curInput=this.refs[getRefForPath$1(getInputPath$1(row,col))];const curValueString=curInput.getStringValue();const cursorStartPosition=curInput.getSelectionStart();const cursorEndPosition=curInput.getSelectionEnd();let nextPath=null;if(e.key==="ArrowUp"&&row>0){nextPath=getInputPath$1(row-1,col);}else if(e.key==="ArrowDown"&&row+1<maxRow){nextPath=getInputPath$1(row+1,col);}else if(e.key==="ArrowLeft"&&col>0){if(cursorStartPosition===0&&cursorEndPosition===0){nextPath=getInputPath$1(row,col-1);}}else if(e.key==="ArrowRight"&&col+1<maxCol){if(cursorStartPosition===curValueString.length){nextPath=getInputPath$1(row,col+1);}}else if(e.key==="Enter"){enterTheMatrix=this.state.enterTheMatrix+1;}else if(e.key==="Escape"){enterTheMatrix=0;}if(nextPath){e.preventDefault();const input=this.refs[getRefForPath$1(nextPath)];const inputValString=input.getStringValue();const valueLength=inputValString.length*2;input.focus();if(e.key==="ArrowRight"){input.setSelectionRange(0,0);}else {input.setSelectionRange(valueLength,valueLength);}}if(enterTheMatrix!=null){this.setState({enterTheMatrix:enterTheMatrix});}},this.onValueChange=(row,column,value,cb)=>{const answers=this.props.userInput.answers.map(answer=>[...answer]);if(!answers[row]){answers[row]=[];}answers[row][column]=value;this.props.handleUserInput({answers},cb);this.props.trackInteraction();};}}Matrix.contextType=PerseusI18nContext;Matrix.defaultProps={matrixBoardSize:[3,3],prefix:"",suffix:"",cursorPosition:[0,0],apiOptions:ApiOptions.defaults,linterContext:PerseusLinter.linterContextDefault,userInput:{answers:[[]]}};function transform$1(widgetOptions){const{matrixBoardSize,prefix,suffix}=widgetOptions;return {matrixBoardSize,prefix,suffix}}function getStartUserInput$5(){return {answers:[[]]}}function getCorrectUserInput$2(options){return {answers:options.answers}}function getUserInputFromSerializedState$5(serializedState){return {answers:serializedState.answers}}var Matrix$1 = {name:"matrix",displayName:"Matrix",hidden:true,widget:Matrix,transform: transform$1,staticTransform:transform$1,isLintable:true,getStartUserInput: getStartUserInput$5,getCorrectUserInput: getCorrectUserInput$2,getUserInputFromSerializedState: getUserInputFromSerializedState$5};
2075
+ const{assert: assert$2}=InteractiveUtil;const NORMAL_DIMENSIONS={INPUT_MARGIN:3,INPUT_HEIGHT:30,INPUT_WIDTH:40};const KEYPAD_INPUT_DIMENSIONS={INPUT_MARGIN:4,INPUT_HEIGHT:36,INPUT_WIDTH:64};function getInputPath$1(row,column){return [""+row,""+column]}const getDefaultPath$1=function(){return getInputPath$1(0,0)};const getRowFromPath$1=function(path){assert$2(Array.isArray(path)&&path.length===2);return +path[0]};const getColumnFromPath$1=function(path){assert$2(Array.isArray(path)&&path.length===2);return +path[1]};const getRefForPath$1=function(path){const row=getRowFromPath$1(path);const column=getColumnFromPath$1(path);return "answer"+row+","+column};class Matrix extends React__namespace.Component{componentDidMount(){this.cursorPosition=[0,0];}getDOMNodeForPath(path){const inputID=getRefForPath$1(path);return ReactDOM__namespace.default.findDOMNode(this.refs[inputID])}getPromptJSON(){return getPromptJSON$8(this.props)}getSerializedState(){const{userInput,...rest}=this.props;return {...rest,answers:userInput.answers}}render(){let dimensions;if(this.props.apiOptions.customKeypad){dimensions=KEYPAD_INPUT_DIMENSIONS;}else {dimensions=NORMAL_DIMENSIONS;}const{INPUT_MARGIN,INPUT_HEIGHT,INPUT_WIDTH}=dimensions;const matrixSize=perseusCore.getMatrixSize(this.props.userInput.answers);const maxRows=this.props.matrixBoardSize[0];const maxCols=this.props.matrixBoardSize[1];const cursorRow=this.props.cursorPosition[0];const cursorCol=this.props.cursorPosition[1];const highlightedRow=Math.max(cursorRow,matrixSize[0]-1);const highlightedCol=Math.max(cursorCol,matrixSize[1]-1);const bracketHeight=(highlightedRow+1)*(INPUT_HEIGHT+2*INPUT_MARGIN);const bracketOffset=(highlightedCol+1)*(INPUT_WIDTH+2*INPUT_MARGIN);const className=classNames__default.default({"perseus-matrix":true,"static-mode":this.props.static,"the-matrix":this.state.enterTheMatrix>=5});return jsxRuntimeExports.jsxs("div",{className:className,children:[this.props.prefix&&jsxRuntimeExports.jsx("div",{className:"matrix-prefix",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.prefix,linterContext:this.props.linterContext,strings:this.context.strings})}),jsxRuntimeExports.jsxs("div",{className:"matrix-input",children:[jsxRuntimeExports.jsx("div",{className:"matrix-bracket bracket-left",style:{height:bracketHeight}}),jsxRuntimeExports.jsx("div",{className:"matrix-bracket bracket-right",style:{height:bracketHeight,left:bracketOffset}}),___default.default(maxRows).times(row=>{const rowVals=this.props.userInput.answers[row];return jsxRuntimeExports.jsx("div",{className:"matrix-row",children:___default.default(maxCols).times(col=>{const outside=row>highlightedRow||col>highlightedCol;const inputProps={className:outside?"outside":"inside",ref:getRefForPath$1(getInputPath$1(row,col)),value:rowVals?rowVals[col]:null,style:{height:INPUT_HEIGHT,width:INPUT_WIDTH,margin:INPUT_MARGIN},disabled:this.props.apiOptions.readOnly,onFocus:()=>{this.cursorPosition=[row,col];this.props.onChange({cursorPosition:[row,col]},()=>{return false});this._handleFocus(row,col);},onBlur:()=>{if(row===this.cursorPosition[0]&&col===this.cursorPosition[1]){this.props.onChange({cursorPosition:[0,0]},()=>{return false});}this._handleBlur(row,col);},onKeyDown:e=>{this.handleKeyDown(row,col,e);},onChange:(value,cb)=>{this.onValueChange(row,col,value,cb);}};let MatrixInput;if(this.props.apiOptions.customKeypad){const style={margin:INPUT_MARGIN,minWidth:INPUT_WIDTH,minHeight:INPUT_HEIGHT,boxSizing:"border-box",backgroundColor:outside?"#f3f3f3":"#fff"};MatrixInput=jsxRuntimeExports.jsx(SimpleKeypadInput,{...inputProps,style:style,scrollable:true,keypadElement:this.props.keypadElement});}else {const updatedProps={...inputProps,style:aphrodite.StyleSheet.create({input:{...inputProps.style,display:"inline-block",padding:0,backgroundColor:outside?"#f3f3f3":"#fff"}}).input};MatrixInput=jsxRuntimeExports.jsx(TextInput,{...updatedProps});}return jsxRuntimeExports.jsx("span",{className:"matrix-input-field",children:MatrixInput},col)})},row)})]}),this.props.suffix&&jsxRuntimeExports.jsx("div",{className:"matrix-suffix",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.suffix,linterContext:this.props.linterContext,strings:this.context.strings})})]})}constructor(...args){super(...args),this.state={enterTheMatrix:0},this.getInputPaths=()=>{const inputPaths=[];const maxRows=this.props.matrixBoardSize[0];const maxCols=this.props.matrixBoardSize[1];for(let row=0;row<maxRows;row++){for(let col=0;col<maxCols;col++){const inputPath=getInputPath$1(row,col);inputPaths.push(inputPath);}}return inputPaths},this._handleFocus=(row,col)=>{this.props.onFocus(getInputPath$1(row,col));},this._handleBlur=(row,col)=>{this.props.onBlur(getInputPath$1(row,col));},this.focus=()=>{this.focusInputPath(getDefaultPath$1());return true},this.focusInputPath=path=>{const inputID=getRefForPath$1(path);this.refs[inputID].focus();},this.blurInputPath=path=>{if(path.length===0){path=getDefaultPath$1();}const inputID=getRefForPath$1(path);this.refs[inputID].blur();},this.handleKeyDown=(row,col,e)=>{const maxRow=this.props.matrixBoardSize[0];const maxCol=this.props.matrixBoardSize[1];let enterTheMatrix=null;const curInput=this.refs[getRefForPath$1(getInputPath$1(row,col))];const curValueString=curInput.getStringValue();const cursorStartPosition=curInput.getSelectionStart();const cursorEndPosition=curInput.getSelectionEnd();let nextPath=null;if(e.key==="ArrowUp"&&row>0){nextPath=getInputPath$1(row-1,col);}else if(e.key==="ArrowDown"&&row+1<maxRow){nextPath=getInputPath$1(row+1,col);}else if(e.key==="ArrowLeft"&&col>0){if(cursorStartPosition===0&&cursorEndPosition===0){nextPath=getInputPath$1(row,col-1);}}else if(e.key==="ArrowRight"&&col+1<maxCol){if(cursorStartPosition===curValueString.length){nextPath=getInputPath$1(row,col+1);}}else if(e.key==="Enter"){enterTheMatrix=this.state.enterTheMatrix+1;}else if(e.key==="Escape"){enterTheMatrix=0;}if(nextPath){e.preventDefault();const input=this.refs[getRefForPath$1(nextPath)];const inputValString=input.getStringValue();const valueLength=inputValString.length*2;input.focus();if(e.key==="ArrowRight"){input.setSelectionRange(0,0);}else {input.setSelectionRange(valueLength,valueLength);}}if(enterTheMatrix!=null){this.setState({enterTheMatrix:enterTheMatrix});}},this.onValueChange=(row,column,value,cb)=>{const answers=this.props.userInput.answers.map(answer=>[...answer]);if(!answers[row]){answers[row]=[];}answers[row][column]=value;this.props.handleUserInput({answers},cb);this.props.trackInteraction();};}}Matrix.contextType=PerseusI18nContext;Matrix.defaultProps={matrixBoardSize:[3,3],prefix:"",suffix:"",cursorPosition:[0,0],apiOptions:ApiOptions.defaults,linterContext:PerseusLinter.linterContextDefault,userInput:{answers:[[]]}};function getStartUserInput$5(){return {answers:[[]]}}function getCorrectUserInput$2(options){return {answers:options.answers.map(row=>row.map(num=>String(num)))}}function getUserInputFromSerializedState$5(serializedState){return {answers:serializedState.answers}}var Matrix$1 = {name:"matrix",displayName:"Matrix",hidden:true,widget:Matrix,isLintable:true,getStartUserInput: getStartUserInput$5,getCorrectUserInput: getCorrectUserInput$2,getUserInputFromSerializedState: getUserInputFromSerializedState$5};
2074
2076
 
2075
2077
  const getPromptJSON$7=()=>{return getUnsupportedPromptJSON("measurer")};
2076
2078
 
@@ -2090,9 +2092,9 @@ const MovablePoint=Graphie.MovablePoint;const Line=Graphie.Line;const{assert: as
2090
2092
 
2091
2093
  const getPromptJSON$5=renderProps=>{return {type:"orderer",options:{options:renderProps.options.map(option=>option.content)},userInput:{values:renderProps.userInput.current}}};
2092
2094
 
2093
- class PlaceholderCard extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("div",{className:"card-wrap",style:{width:this.props.width},children:jsxRuntimeExports.jsx("div",{className:"card placeholder",style:{height:this.props.width}})})}}class DragHintCard extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("div",{className:"card-wrap",children:jsxRuntimeExports.jsx("div",{className:"card drag-hint"})})}}class Card extends React__namespace.Component{componentDidMount(){this.mouseMoveUpBound=false;document.addEventListener("touchmove",this.onMouseMove,Util.supportsPassiveEvents()?{passive:false}:false);}shouldComponentUpdate(nextProps,nextState){return this.props.floating||nextProps.floating||this.props.content!==nextProps.content||this.props.fakeRef!==nextProps.fakeRef}componentDidUpdate(prevProps,prevState){if(this.props.animating&&!prevProps.animating&&this.props.animateTo&&this.props.startOffset){const ms=15*Math.sqrt(Math.sqrt(Math.pow(this.props.animateTo.left-this.props.startOffset.left,2)+Math.pow(this.props.animateTo.top-this.props.startOffset.top,2)));$__default.default(ReactDOM__namespace.default.findDOMNode(this)).animate(this.props.animateTo,Math.max(ms,1),this.props.onAnimationEnd);}}componentWillUnmount(){if(this.mouseMoveUpBound){Log.error("Removing an element with bound event handlers.",perseusCore.Errors.Internal);this.unbindMouseMoveUp();Util.resetTouchHandlers();}document.removeEventListener("touchmove",this.onMouseMove);}render(){let style={};if(this.props.floating){style={position:"absolute",left:this.props.startOffset?.left,top:this.props.startOffset?.top};}if(this.props.width){style.width=this.props.width;}const className=["card"];if(this.props.stack){className.push("stack");}if(this.props.floating&&!this.props.animating&&this.props.mouse&&this.props.startMouse){className.push("dragging");style.left+=this.props.mouse.left-this.props.startMouse.left;style.top+=this.props.mouse.top-this.props.startMouse.top;}const rendererProps={content:this.props.content};const onMouseDown=this.props.animating?$__default.default.noop:this.onMouseDown;return jsxRuntimeExports.jsx("div",{className:"card-wrap",style:style,onMouseDown:onMouseDown,onTouchStart:onMouseDown,onTouchEnd:this.onMouseUp,onTouchCancel:this.onMouseUp,children:jsxRuntimeExports.jsx("div",{className:className.join(" "),children:jsxRuntimeExports.jsx(Renderer,{...rendererProps,linterContext:this.props.linterContext,strings:this.context.strings})})})}constructor(...args){super(...args),this.state={dragging:false},this.bindMouseMoveUp=()=>{this.mouseMoveUpBound=true;$__default.default(document).on("mousemove",this.onMouseMove);$__default.default(document).on("mouseup",this.onMouseUp);},this.unbindMouseMoveUp=()=>{this.mouseMoveUpBound=false;$__default.default(document).off("mousemove",this.onMouseMove);$__default.default(document).off("mouseup",this.onMouseUp);},this.onMouseDown=event=>{event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.setState({dragging:true});this.bindMouseMoveUp();this.props.onMouseDown?.(loc,this);}},this.onMouseMove=event=>{if(!this.state.dragging){return}event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.props.onMouseMove?.(loc);}},this.onMouseUp=event=>{event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.setState({dragging:false});this.unbindMouseMoveUp();this.props.onMouseUp?.(loc);}};}}Card.contextType=PerseusI18nContext;Card.defaultProps={stack:false,animating:false,linterContext:PerseusLinter.linterContextDefault};class Orderer extends React__namespace.Component{getPromptJSON(){return getPromptJSON$5(this.props)}getSerializedState(){const{userInput,...rest}=this.props;return {...rest,current:userInput.current.map(e=>({content:e}))}}render(){const dragging=this.state.dragging&&jsxRuntimeExports.jsx(Card,{ref:"dragging",floating:true,content:this.state.dragContent,startOffset:this.state.offsetPos,startMouse:this.state.grabPos,mouse:this.state.mousePos,width:this.state.dragWidth,onMouseUp:this.onRelease,onMouseMove:this.onMouseMove,linterContext:this.props.linterContext},this.state.dragKey||"draggingCard");const animating=this.state.animating&&jsxRuntimeExports.jsx(Card,{floating:true,animating:true,content:this.state.dragContent,startOffset:this.state.offsetPos,width:this.state.dragWidth,animateTo:this.state.animateTo,onAnimationEnd:this.state.onAnimationEnd,linterContext:this.props.linterContext},this.state.dragKey||"draggingCard");const sortableCards=this.props.userInput.current.map((opt,i)=>{return jsxRuntimeExports.jsx(Card,{ref:"sortable"+i,fakeRef:"sortable"+i,floating:false,content:opt,linterContext:this.props.linterContext,onMouseDown:this.state.animating?$__default.default.noop:this.onClick.bind(null,"current",i)},`sortableCard${i}`)});if(this.state.placeholderIndex!=null){const placeholder=jsxRuntimeExports.jsx(PlaceholderCard,{ref:"placeholder",width:this.state.dragWidth,height:this.state.dragHeight},"placeholder");sortableCards.splice(this.state.placeholderIndex,0,placeholder);}const anySortableCards=sortableCards.length>0;sortableCards.push(dragging,animating);const sortable=jsxRuntimeExports.jsxs("div",{className:"perseus-clearfix draggable-box",children:[!anySortableCards&&jsxRuntimeExports.jsx(DragHintCard,{}),jsxRuntimeExports.jsx("div",{ref:"dragList",children:sortableCards})]});const bank=jsxRuntimeExports.jsx("div",{ref:"bank",className:"bank perseus-clearfix",children:this.props.options.map((opt,i)=>{return jsxRuntimeExports.jsx(Card,{ref:"bank"+i,floating:false,content:opt.content,stack:true,linterContext:this.props.linterContext,onMouseDown:this.state.animating?$__default.default.noop:this.onClick.bind(null,"bank",i),onMouseMove:this.onMouseMove,onMouseUp:this.onRelease},i)})});return jsxRuntimeExports.jsxs("div",{className:"draggy-boxy-thing orderer "+"height-"+this.props.height+" "+"layout-"+this.props.layout+" "+"blank-background "+"perseus-clearfix ",ref:"orderer",children:[bank,sortable]})}constructor(...args){super(...args),this.state={dragging:false,placeholderIndex:null,dragKey:null,animating:false,dragContent:null,dragWidth:null,dragHeight:null,offsetPos:null,animateTo:null,grabPos:null},this.onClick=(type,index,loc,draggable)=>{const $draggable=$__default.default(ReactDOM__namespace.default.findDOMNode(draggable));const list=this.props.userInput.current.slice();let opt;let placeholderIndex=null;if(type==="current"){list.splice(index,1);opt=this.props.userInput.current[index];placeholderIndex=index;}else if(type==="bank"){opt=this.props.options[index];}this.props.handleUserInput({current:list});this.setState({dragging:true,placeholderIndex:placeholderIndex,dragKey:opt.key,dragContent:opt.content,dragWidth:$draggable.width(),dragHeight:$draggable.height(),grabPos:loc,mousePos:loc,offsetPos:$draggable.position()});},this.onRelease=loc=>{const draggable=this.refs.dragging;if(draggable==null){return}const inCardBank=this.isCardInBank(draggable);const index=this.state.placeholderIndex||0;const onAnimationEnd=()=>{const list=this.props.userInput.current.slice();if(!inCardBank){const newCard={content:this.state.dragContent,key:___default.default.uniqueId("perseus_draggable_card_"),width:this.state.dragWidth};list.splice(index,0,newCard.content);}this.props.handleUserInput({current:list});this.setState({dragging:false,placeholderIndex:null,animating:false});this.props.trackInteraction();};const offset=$__default.default(ReactDOM__namespace.default.findDOMNode(draggable)).position();let finalOffset=null;if(inCardBank){this.props.options.forEach((opt,i)=>{if(opt.content===this.state.dragContent){const card=ReactDOM__namespace.default.findDOMNode(this.refs["bank"+i]);finalOffset=$__default.default(card).position();}});}else if(this.refs.placeholder!=null){finalOffset=$__default.default(ReactDOM__namespace.default.findDOMNode(this.refs.placeholder)).position();}if(finalOffset==null){onAnimationEnd();}else {this.setState({offsetPos:offset,animateTo:finalOffset,onAnimationEnd:onAnimationEnd,animating:true,dragging:false});}},this.onMouseMove=loc=>{const draggable=this.refs.dragging;if(draggable==null){return}let index;if(this.isCardInBank(draggable)){index=null;}else {index=this.findCorrectIndex(draggable,this.props.userInput.current);}this.setState({mousePos:loc,placeholderIndex:index});},this.findCorrectIndex=(draggable,list)=>{const isHorizontal=this.props.layout==="horizontal";const $dragList=$__default.default(ReactDOM__namespace.default.findDOMNode(this.refs.dragList));const leftEdge=$dragList.offset().left;const topEdge=$dragList.offset().top;const midWidth=$__default.default(ReactDOM__namespace.default.findDOMNode(draggable)).offset().left-leftEdge;const midHeight=$__default.default(ReactDOM__namespace.default.findDOMNode(draggable)).offset().top-topEdge;let index=0;let sumWidth=0;let sumHeight=0;if(isHorizontal){list.forEach((opt,i)=>{const card=ReactDOM__namespace.default.findDOMNode(this.refs["sortable"+i]);const outerWidth=$__default.default(card).outerWidth(true);if(midWidth>sumWidth+outerWidth/2){index+=1;}sumWidth+=outerWidth;});}else {list.forEach((_,i)=>{const card=ReactDOM__namespace.default.findDOMNode(this.refs["sortable"+i]);const outerHeight=$__default.default(card).outerHeight(true);if(midHeight>sumHeight+outerHeight/2){index+=1;}sumHeight+=outerHeight;});}return index},this.isCardInBank=draggable=>{if(draggable==null){return false}const isHorizontal=this.props.layout==="horizontal";const $draggable=$__default.default(ReactDOM__namespace.default.findDOMNode(draggable));const $bank=$__default.default(ReactDOM__namespace.default.findDOMNode(this.refs.bank));const draggableOffset=$draggable.offset();const bankOffset=$bank.offset();const draggableHeight=$draggable.outerHeight(true);const bankHeight=$bank.outerHeight(true);const bankWidth=$bank.outerWidth(true);const draggableWidth=$draggable.outerWidth(true);if(isHorizontal){return draggableOffset.top+draggableHeight/2<bankOffset.top+bankHeight}return draggableOffset.left+draggableWidth/2<bankOffset.left+bankWidth},this.setListValues=values=>{this.props.handleUserInput({current:values});};}}Orderer.defaultProps={options:[],height:"normal",layout:"horizontal",linterContext:PerseusLinter.linterContextDefault,userInput:{current:[]}};function getUserInputFromSerializedState$3(serializedState){return {current:serializedState.current.map(e=>e.content)}}function getStartUserInput$3(){return {current:[]}}var Orderer$1 = {name:"orderer",displayName:"Orderer",hidden:true,widget:Orderer,isLintable:true,getStartUserInput: getStartUserInput$3,getUserInputFromSerializedState: getUserInputFromSerializedState$3};
2095
+ class PlaceholderCard extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("div",{className:"card-wrap",style:{width:this.props.width},children:jsxRuntimeExports.jsx("div",{className:"card placeholder",style:{height:this.props.width}})})}}class DragHintCard extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("div",{className:"card-wrap",children:jsxRuntimeExports.jsx("div",{className:"card drag-hint"})})}}class Card extends React__namespace.Component{componentDidMount(){this.mouseMoveUpBound=false;document.addEventListener("touchmove",this.onMouseMove,Util.supportsPassiveEvents()?{passive:false}:false);}shouldComponentUpdate(nextProps,nextState){return this.props.floating||nextProps.floating||this.props.content!==nextProps.content||this.props.fakeRef!==nextProps.fakeRef}componentDidUpdate(prevProps,prevState){if(this.props.animating&&!prevProps.animating&&this.props.animateTo&&this.props.startOffset){const ms=15*Math.sqrt(Math.sqrt(Math.pow(this.props.animateTo.left-this.props.startOffset.left,2)+Math.pow(this.props.animateTo.top-this.props.startOffset.top,2)));$__default.default(ReactDOM__namespace.default.findDOMNode(this)).animate(this.props.animateTo,Math.max(ms,1),this.props.onAnimationEnd);}}componentWillUnmount(){if(this.mouseMoveUpBound){Log.error("Removing an element with bound event handlers.",perseusCore.Errors.Internal);this.unbindMouseMoveUp();Util.resetTouchHandlers();}document.removeEventListener("touchmove",this.onMouseMove);}render(){let style={};if(this.props.floating){style={position:"absolute",left:this.props.startOffset?.left,top:this.props.startOffset?.top};}if(this.props.width){style.width=this.props.width;}const className=["card"];if(this.props.stack){className.push("stack");}if(this.props.floating&&!this.props.animating&&this.props.mouse&&this.props.startMouse){className.push("dragging");style.left+=this.props.mouse.left-this.props.startMouse.left;style.top+=this.props.mouse.top-this.props.startMouse.top;}const rendererProps={content:this.props.content};const onMouseDown=this.props.animating?$__default.default.noop:this.onMouseDown;return jsxRuntimeExports.jsx("div",{className:"card-wrap",style:style,onMouseDown:onMouseDown,onTouchStart:onMouseDown,onTouchEnd:this.onMouseUp,onTouchCancel:this.onMouseUp,children:jsxRuntimeExports.jsx("div",{className:className.join(" "),children:jsxRuntimeExports.jsx(Renderer,{...rendererProps,linterContext:this.props.linterContext,strings:this.context.strings})})})}constructor(...args){super(...args),this.state={dragging:false},this.bindMouseMoveUp=()=>{this.mouseMoveUpBound=true;$__default.default(document).on("mousemove",this.onMouseMove);$__default.default(document).on("mouseup",this.onMouseUp);},this.unbindMouseMoveUp=()=>{this.mouseMoveUpBound=false;$__default.default(document).off("mousemove",this.onMouseMove);$__default.default(document).off("mouseup",this.onMouseUp);},this.onMouseDown=event=>{event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.setState({dragging:true});this.bindMouseMoveUp();this.props.onMouseDown?.(loc,this);}},this.onMouseMove=event=>{if(!this.state.dragging){return}event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.props.onMouseMove?.(loc);}},this.onMouseUp=event=>{event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.setState({dragging:false});this.unbindMouseMoveUp();this.props.onMouseUp?.(loc);}};}}Card.contextType=PerseusI18nContext;Card.defaultProps={stack:false,animating:false,linterContext:PerseusLinter.linterContextDefault};class Orderer extends React__namespace.Component{getPromptJSON(){return getPromptJSON$5(this.props)}getSerializedState(){const{userInput,...rest}=this.props;return {...rest,current:userInput.current.map(e=>({content:e}))}}render(){const dragging=this.state.dragging&&jsxRuntimeExports.jsx(Card,{ref:"dragging",floating:true,content:this.state.dragContent,startOffset:this.state.offsetPos,startMouse:this.state.grabPos,mouse:this.state.mousePos,width:this.state.dragWidth,onMouseUp:this.onRelease,onMouseMove:this.onMouseMove,linterContext:this.props.linterContext},this.state.dragKey||"draggingCard");const animating=this.state.animating&&jsxRuntimeExports.jsx(Card,{floating:true,animating:true,content:this.state.dragContent,startOffset:this.state.offsetPos,width:this.state.dragWidth,animateTo:this.state.animateTo,onAnimationEnd:this.state.onAnimationEnd,linterContext:this.props.linterContext},this.state.dragKey||"draggingCard");const sortableCards=this.props.userInput.current.map((opt,i)=>{return jsxRuntimeExports.jsx(Card,{ref:"sortable"+i,fakeRef:"sortable"+i,floating:false,content:opt,linterContext:this.props.linterContext,onMouseDown:this.state.animating?$__default.default.noop:this.onClick.bind(null,"current",i)},`sortableCard${i}`)});if(this.state.placeholderIndex!=null){const placeholder=jsxRuntimeExports.jsx(PlaceholderCard,{ref:"placeholder",width:this.state.dragWidth,height:this.state.dragHeight},"placeholder");sortableCards.splice(this.state.placeholderIndex,0,placeholder);}const anySortableCards=sortableCards.length>0;sortableCards.push(dragging,animating);const sortable=jsxRuntimeExports.jsxs("div",{className:"perseus-clearfix draggable-box",children:[!anySortableCards&&jsxRuntimeExports.jsx(DragHintCard,{}),jsxRuntimeExports.jsx("div",{ref:"dragList",children:sortableCards})]});const bank=jsxRuntimeExports.jsx("div",{ref:"bank",className:"bank perseus-clearfix",children:this.props.options.map((opt,i)=>{return jsxRuntimeExports.jsx(Card,{ref:"bank"+i,floating:false,content:opt.content,stack:true,linterContext:this.props.linterContext,onMouseDown:this.state.animating?$__default.default.noop:this.onClick.bind(null,"bank",i),onMouseMove:this.onMouseMove,onMouseUp:this.onRelease},i)})});return jsxRuntimeExports.jsxs("div",{className:"draggy-boxy-thing orderer "+"height-"+this.props.height+" "+"layout-"+this.props.layout+" "+"blank-background "+"perseus-clearfix ",ref:"orderer",children:[bank,sortable]})}constructor(...args){super(...args),this.state={dragging:false,placeholderIndex:null,dragKey:null,animating:false,dragContent:null,dragWidth:null,dragHeight:null,offsetPos:null,animateTo:null,grabPos:null},this.onClick=(type,index,loc,draggable)=>{const $draggable=$__default.default(ReactDOM__namespace.default.findDOMNode(draggable));const list=this.props.userInput.current.slice();let opt;let placeholderIndex=null;if(type==="current"){list.splice(index,1);opt=this.props.userInput.current[index];placeholderIndex=index;}else if(type==="bank"){opt=this.props.options[index];}this.props.handleUserInput({current:list});this.setState({dragging:true,placeholderIndex:placeholderIndex,dragKey:opt.key,dragContent:opt.content,dragWidth:$draggable.width(),dragHeight:$draggable.height(),grabPos:loc,mousePos:loc,offsetPos:$draggable.position()});},this.onRelease=loc=>{const draggable=this.refs.dragging;if(draggable==null){return}const inCardBank=this.isCardInBank(draggable);const index=this.state.placeholderIndex||0;const onAnimationEnd=()=>{const list=this.props.userInput.current.slice();if(!inCardBank){const cardContent=this.state.dragContent;if(typeof cardContent==="string"){const newCard={content:cardContent,key:___default.default.uniqueId("perseus_draggable_card_"),width:this.state.dragWidth};list.splice(index,0,newCard.content);}}this.props.handleUserInput({current:list});this.setState({dragging:false,placeholderIndex:null,animating:false});this.props.trackInteraction();};const offset=$__default.default(ReactDOM__namespace.default.findDOMNode(draggable)).position();let finalOffset=null;if(inCardBank){this.props.options.forEach((opt,i)=>{if(opt.content===this.state.dragContent){const card=ReactDOM__namespace.default.findDOMNode(this.refs["bank"+i]);finalOffset=$__default.default(card).position();}});}else if(this.refs.placeholder!=null){finalOffset=$__default.default(ReactDOM__namespace.default.findDOMNode(this.refs.placeholder)).position();}if(finalOffset==null){onAnimationEnd();}else {this.setState({offsetPos:offset,animateTo:finalOffset,onAnimationEnd:onAnimationEnd,animating:true,dragging:false});}},this.onMouseMove=loc=>{const draggable=this.refs.dragging;if(draggable==null){return}let index;if(this.isCardInBank(draggable)){index=null;}else {index=this.findCorrectIndex(draggable,this.props.userInput.current);}this.setState({mousePos:loc,placeholderIndex:index});},this.findCorrectIndex=(draggable,list)=>{const isHorizontal=this.props.layout==="horizontal";const $dragList=$__default.default(ReactDOM__namespace.default.findDOMNode(this.refs.dragList));const leftEdge=$dragList.offset().left;const topEdge=$dragList.offset().top;const midWidth=$__default.default(ReactDOM__namespace.default.findDOMNode(draggable)).offset().left-leftEdge;const midHeight=$__default.default(ReactDOM__namespace.default.findDOMNode(draggable)).offset().top-topEdge;let index=0;let sumWidth=0;let sumHeight=0;if(isHorizontal){list.forEach((opt,i)=>{const card=ReactDOM__namespace.default.findDOMNode(this.refs["sortable"+i]);const outerWidth=$__default.default(card).outerWidth(true);if(midWidth>sumWidth+outerWidth/2){index+=1;}sumWidth+=outerWidth;});}else {list.forEach((_,i)=>{const card=ReactDOM__namespace.default.findDOMNode(this.refs["sortable"+i]);const outerHeight=$__default.default(card).outerHeight(true);if(midHeight>sumHeight+outerHeight/2){index+=1;}sumHeight+=outerHeight;});}return index},this.isCardInBank=draggable=>{if(draggable==null){return false}const isHorizontal=this.props.layout==="horizontal";const $draggable=$__default.default(ReactDOM__namespace.default.findDOMNode(draggable));const $bank=$__default.default(ReactDOM__namespace.default.findDOMNode(this.refs.bank));const draggableOffset=$draggable.offset();const bankOffset=$bank.offset();const draggableHeight=$draggable.outerHeight(true);const bankHeight=$bank.outerHeight(true);const bankWidth=$bank.outerWidth(true);const draggableWidth=$draggable.outerWidth(true);if(isHorizontal){return draggableOffset.top+draggableHeight/2<bankOffset.top+bankHeight}return draggableOffset.left+draggableWidth/2<bankOffset.left+bankWidth},this.setListValues=values=>{this.props.handleUserInput({current:values});};}}Orderer.defaultProps={options:[],height:"normal",layout:"horizontal",linterContext:PerseusLinter.linterContextDefault,userInput:{current:[]}};function getUserInputFromSerializedState$3(serializedState){return {current:serializedState.current.map(e=>e.content)}}function getStartUserInput$3(){return {current:[]}}var Orderer$1 = {name:"orderer",displayName:"Orderer",hidden:true,widget:Orderer,isLintable:true,getStartUserInput: getStartUserInput$3,getUserInputFromSerializedState: getUserInputFromSerializedState$3};
2094
2096
 
2095
- class PassageRefTarget extends React__namespace.Component{render(){return jsxRuntimeExports.jsx(Renderer,{content:this.props.content,apiOptions:this.props.apiOptions,linterContext:this.props.linterContext,strings:this.context.strings})}constructor(...args){super(...args),this.isWidget=true;}}PassageRefTarget.contextType=PerseusI18nContext;PassageRefTarget.defaultProps={content:"",linterContext:PerseusLinter.linterContextDefault};var PassageRefTarget$1 = {name:"passage-ref-target",displayName:"PassageRefTarget",widget:PassageRefTarget,hidden:true,transform:editorProps=>{return ___default.default.pick(editorProps,"content")},isLintable:true};
2097
+ class PassageRefTarget extends React__namespace.Component{render(){return jsxRuntimeExports.jsx(Renderer,{content:this.props.content,apiOptions:this.props.apiOptions,linterContext:this.props.linterContext,strings:this.context.strings})}constructor(...args){super(...args),this.isWidget=true;}}PassageRefTarget.contextType=PerseusI18nContext;PassageRefTarget.defaultProps={content:"",linterContext:PerseusLinter.linterContextDefault};var PassageRefTarget$1 = {name:"passage-ref-target",displayName:"PassageRefTarget",widget:PassageRefTarget,hidden:true,isLintable:true};
2096
2098
 
2097
2099
  const getPromptJSON$4=()=>{return getUnsupportedPromptJSON("phet-simulation")};
2098
2100
 
@@ -2100,7 +2102,7 @@ const MOBILE_APP_BOTTOM_BAR_HEIGHT=66;class PhetSimulation extends React__namesp
2100
2102
 
2101
2103
  const getPromptJSON$3=()=>{return getUnsupportedPromptJSON("plotter")};
2102
2104
 
2103
- class Plotter extends React__namespace.Component{componentDidMount(){this._isMounted=true;this.setupGraphie(this.props.userInput);}UNSAFE_componentWillReceiveProps(nextProps){const props=["type","labels","categories","scaleY","maxY","snapsPerLine","picUrl","labelInterval","static"];this.shouldSetupGraphie=___default.default.any(props,prop=>!___default.default.isEqual(this.props[prop],nextProps[prop]),this);if(!___default.default.isEqual(this.props.starting,nextProps.starting)&&!___default.default.isEqual(this.props.userInput,nextProps.starting)){this.shouldSetupGraphie=true;this.props.handleUserInput(nextProps.starting);}}componentDidUpdate(prevProps,prevState){this.shouldSetupGraphie=this.shouldSetupGraphie||!___default.default.isEqual(this.state.categoryHeights,prevState.categoryHeights);if(this.shouldSetupGraphie){this.setupGraphie(prevProps.userInput);}}componentWillUnmount(){this._isMounted=false;}setupGraphie(prevValues){const self=this;self.shouldSetupGraphie=false;$__default.default(this.graphieDiv.current).empty();const graphie=GraphUtils.createGraphie(this.graphieDiv.current);self.graphie=graphie;self.graphie.pics=[];self.graphie.dotTicks=[];const isBar=self.props.type==="bar";const isLine=self.props.type==="line";const isPic=self.props.type==="pic";const isHistogram=self.props.type==="histogram";const isDotplot=self.props.type==="dotplot";const isTiledPlot=isPic||isDotplot;const config={};const c=config;const isMobile=this.props.apiOptions.isMobile;c.graph={lines:[],bars:[],points:[],dividers:[]};c.scaleY=self.props.scaleY;c.dimX=self.props.categories.length;const plotDimensions=isMobile?[288,336]:self.props.plotDimensions;if(isLine){c.dimX+=isMobile?-0.2:1;}else if(isHistogram){c.barPad=0;c.barWidth=1;}else if(isBar){c.barPad=isMobile?.08:.15;c.barWidth=1-2*c.barPad;c.dimX+=(isMobile?-2:2)*c.barPad;}else if(isTiledPlot){c.picBoxHeight=self.props.picBoxHeight;c.picBoxWidthPx=plotDimensions[0]/self.props.categories.length;const picPadAllWidth=plotDimensions[0]-c.dimX*c.picBoxWidthPx;c.picPad=picPadAllWidth/(2*c.dimX+2);const picFullWidth=c.picBoxWidthPx+2*c.picPad;c.picPad=c.picPad/picFullWidth;c.picBoxWidth=c.picBoxWidthPx/picFullWidth;c.dimX+=2*c.picPad;}if(isDotplot){c.picBoxHeight=this.DOT_PLOT_POINT_SIZE()*2+this.DOT_PLOT_POINT_PADDING();}c.dimY=Math.ceil(self.props.maxY/c.scaleY)*c.scaleY;let padX=25;if((isBar||isLine)&&isMobile){padX=self.props.labels[1].length!==0?17:11;}if(isDotplot){padX/=2;}if(isMobile&&isTiledPlot&&self.props.labels[1].length===0){padX=0;}let padTop=25;let padBottom=25*3;if(isMobile&&(isBar||isTiledPlot)){const maxCategoryHeight=Math.max(0,...Object.values(self.state.categoryHeights));if(maxCategoryHeight){let offsetY=25;if(isTiledPlot){offsetY+=10;}padBottom=offsetY+maxCategoryHeight;}}if(isMobile){c.scale=[(plotDimensions[0]-padX*4)/c.dimX,(plotDimensions[1]-(padTop+padBottom))/c.dimY];}else {c.scale=___default.default.map([c.dimX,c.dimY],function(dim,i){return plotDimensions[i]/dim});}if(isTiledPlot){c.scale[1]=c.picBoxHeight/c.scaleY;}padX/=c.scale[0];padTop/=c.scale[1];padBottom/=c.scale[1];graphie.init({range:[[-3*padX,c.dimX+padX],[-padBottom,c.dimY+padTop]],scale:c.scale,isMobile:this.props.apiOptions.isMobile});graphie.addMouseLayer({allowScratchpad:true,setDrawingAreaAvailable:this.props.apiOptions.setDrawingAreaAvailable});if(!isTiledPlot){const initialY=isMobile?c.scaleY:0;for(let y=initialY;y<=c.dimY;y+=c.scaleY){graphie.label([0,y],kmath.KhanMath.roundToApprox(y,2),"left",true);graphie.style({stroke:isMobile?"#e9ebec":"#000",strokeWidth:1,opacity:isMobile?1:.3},function(){graphie.line([0,y],[c.dimX,y]);});}}if((isBar||isLine)&&isMobile&&!this.props.static){self.graphie.dragPrompt=graphie.label([c.dimX/2,c.dimY/2],this.context.strings.dragHandles,"center",false).css("font-weight","bold").css("color",KhanColors.KA_GREEN).css("display","none");}self.setupCategories(config);if(isTiledPlot&&isMobile){self.graphie.dotPrompt=graphie.label([c.dimX/2,c.dimY/2],this.context.strings.tapAddPoints,"center",false).css("font-weight","bold").css("color",KhanColors.KA_GREEN).css("display","none");}if(isTiledPlot){self.drawPicHeights(self.props.userInput,prevValues);}graphie.style({stroke:"#000",strokeWidth:2,opacity:1},function(){if(isTiledPlot){if(isDotplot){graphie.style({stroke:isMobile?KhanColors.GRAY_G:"#000",strokeWidth:isMobile?1:2},()=>graphie.line([isMobile?0:.5,0],[c.dimX-(isMobile?0:.5),0]));}else {graphie.line([0,0],[c.dimX,0]);if(self.props.labels[1].length!==0||!isMobile){graphie.style({stroke:isMobile?KhanColors.GRAY_G:"#000",strokeWidth:isMobile?1:2},()=>graphie.line([0,0],[0,c.dimY]));}}}else {graphie.style({stroke:isMobile?KhanColors.GRAY_G:"#000",strokeWidth:isMobile?1:2},()=>graphie.line([isMobile?-padX*3:0,0],[c.dimX+(isMobile?padX:0),0]));if(!((isBar||isLine)&&isMobile)){graphie.style({stroke:isMobile?KhanColors.GRAY_G:"#000",strokeWidth:isMobile?1:2},()=>graphie.line([0,0],[0,c.dimY]));}}});graphie.label([c.dimX/2,isMobile?-padBottom:-35/c.scale[1]],self.props.labels[0],isMobile?"above":"below",false).css("font-weight","bold").css("color",isMobile&&KhanColors.GRAY_F);graphie.label([(isMobile?-35:-60)/c.scale[0],c.dimY/2],self.props.labels[1],"center",false).css("font-weight","bold").css("color",isMobile&&KhanColors.GRAY_F).addClass("rotate");if(this.props.apiOptions.isMobile){this.horizHairline=new WrappedLine(this.graphie,[0,0],[0,0],{normalStyle:{strokeWidth:1}});this.horizHairline.attr({stroke:KhanColors.INTERACTIVE});this.horizHairline.hide();this.hairlineRange=[[0,c.dimX],[0,c.dimY]];}}_testInsertUserInput(userInput){this.props.handleUserInput(userInput);}drawPicHeights(values,prevValues){const self=this;const graphie=self.graphie;const pics=graphie.pics;const isMobile=this.props.apiOptions.isMobile;if(isMobile){const shouldDisplay=values.every(v=>v===0);graphie.dotPrompt[0].style.display=shouldDisplay?"inline":"none";}___default.default.each(pics,function(ps,i){___default.default.each(ps,function(pic,j){const y=(j+1)*self.props.scaleY;const show=y<=values[i];if(self.props.type==="dotplot"){const wasShown=y<=prevValues[i];const wasJustShown=show&&!wasShown;if(wasJustShown){pic.animate({"stroke-width":8},75,()=>pic.animate({"stroke-width":2},75));}}$__default.default(pic[0]).css({display:show?"inline":"none"});graphie.dotTicks[i][j][0].style.display=show||!isMobile?"none":"inline";});});}getPromptJSON(){return getPromptJSON$3()}getSerializedState(){const{userInput:_,...rest}=this.props;return {...rest,values:this.props.userInput}}render(){const paddingForBottomLabel=75;const style={marginBottom:this.props.labels[0]?paddingForBottomLabel:0};return jsxRuntimeExports.jsx("div",{className:"perseus-widget-plotter graphie",ref:this.graphieDiv,style:style})}constructor(...args){super(...args),this._isMounted=false,this.graphieDiv=React__namespace.createRef(),this.state={categoryHeights:{}},this.DOT_PLOT_POINT_SIZE=()=>{return this.props.apiOptions.isMobile?6:4},this.DOT_PLOT_POINT_PADDING=()=>{return 8},this.DOT_TICK_POINT_SIZE=()=>{return 2},this.showHairlines=point=>{if(this.props.apiOptions.isMobile){this.horizHairline.moveTo([this.hairlineRange[0][0],point[1]],[this.hairlineRange[0][1],point[1]]);this.horizHairline.show();}},this.hideHairlines=()=>{if(this.props.apiOptions.isMobile){this.horizHairline.hide();}},this.labelCategory=(x,category)=>{const isMobile=this.props.apiOptions.isMobile;const graphie=this.graphie;category=category+"";let isTeX=false;const mathyCategory=category.match(/^\$(.*)\$$/);if(mathyCategory){category=mathyCategory[1];isTeX=true;}const translateX=5;const rotationDeg=45;const rotationRad=rotationDeg*(Math.PI/180);const labelRotation=`translateX(-50%) translateX(${translateX}px) `+`translateY(-50%) rotate(-${rotationDeg}deg)`;const shouldRotate=isMobile&&!mathyCategory;return new Promise(resolve=>{graphie.style({color:isMobile?KhanColors.GRAY_G:"inherit",transform:shouldRotate?labelRotation:"none",transformOrigin:"100%"},()=>{const $span=graphie.label([x,isMobile?-0.5:0],category,"below",isTeX);const height=14+(shouldRotate?Math.round($span.height()*Math.cos(rotationRad)+($span.width()+translateX)*Math.sin(rotationRad)):$span.height());resolve({category,height});});})},this.setupCategories=config=>{const self=this;const c=config;const graphie=self.graphie;const isMobile=this.props.apiOptions.isMobile;const categoryHeightPromises=[];if(self.props.type==="histogram"){___default.default.times(self.props.categories.length-1,function(i){self.setupBar({index:i,startHeight:self.props.userInput[i],config:config,isHistogram:true});});___default.default.each(self.props.categories,function(category,i){const x=.5+i*c.barWidth;categoryHeightPromises.push(self.labelCategory(x,category));const tickHeight=6/c.scale[1];graphie.style({stroke:"#000",strokeWidth:isMobile?1:2,opacity:1},function(){graphie.line([x,-tickHeight],[x,0]);});});}else {___default.default.each(self.props.categories,function(category,i){const startHeight=self.props.userInput[i];let x;if(self.props.type==="bar"){x=self.setupBar({index:i,startHeight:startHeight,config:config,isHistogram:false});}else if(self.props.type==="line"){x=self.setupLine(i,startHeight,config);}else if(self.props.type==="pic"){x=self.setupPic(i,config);}else if(self.props.type==="dotplot"){x=self.setupDotplot(i,config);}let tickStart=0;let tickEnd=-6/c.scale[1];if(self.props.type==="dotplot"&&!isMobile){tickStart=-tickEnd;}if(self.props.type==="dotplot"){if(i%self.props.labelInterval===0||i===self.props.categories.length-1){categoryHeightPromises.push(self.labelCategory(x,category));tickStart*=1.5;tickEnd*=1.5;}}else {categoryHeightPromises.push(self.labelCategory(x,category));}graphie.style({stroke:isMobile?KhanColors.GRAY_G:"#000",strokeWidth:isMobile?1:2,opacity:1},function(){graphie.line([x,tickStart],[x,tickEnd]);});});}Promise.all(categoryHeightPromises).then(measurements=>{if(self._isMounted){const categoryHeights={};measurements.forEach(({category,height})=>categoryHeights[category]=height);self.setState({categoryHeights});}});},this._clampValue=(v,min,max)=>{return Math.max(Math.min(v,max),min)},this._maybeShowDragPrompt=()=>{if(this.graphie.dragPrompt!=null){this.graphie.dragPrompt[0].style.display="inline";}},this._maybeHideDragPrompt=()=>{if(this.graphie.dragPrompt!=null){this.graphie.dragPrompt[0].style.display="none";}},this.setupBar=args=>{const isMobile=this.props.apiOptions.isMobile;const i=args.index;const startHeight=args.startHeight;const config=args.config;const isHistogram=args.isHistogram;const self=this;const graphie=self.graphie;const barHalfWidth=config.barWidth/2;let x;if(isHistogram){x=.5+i*config.barWidth+barHalfWidth;}else {x=(isMobile?barHalfWidth:.5+config.barPad)+i;}const scaleBar=function(i,height){const center=graphie.scalePoint(0);config.graph.bars[i].scale(1,Math.max(isMobile?.2:.01,height/config.scaleY),center[0],center[1]);if(isHistogram){const leftDivider=config.graph.dividers[i-1];const rightDivider=config.graph.dividers[i];if(leftDivider){const divHeight=Math.min(self.props.userInput[i-1],height);leftDivider.scale(1,Math.max(.01,divHeight/config.scaleY),center[0],center[1]);}if(rightDivider){const divHeight=Math.min(self.props.userInput[i+1],height);rightDivider.scale(1,Math.max(.01,divHeight/config.scaleY),center[0],center[1]);}}};graphie.style({stroke:"none",fill:isMobile?KhanColors.BLUE_C:KhanColors.LIGHT_BLUE,opacity:1},function(){config.graph.bars[i]=graphie.path([[x-barHalfWidth,0],[x-barHalfWidth,config.scaleY],[x+barHalfWidth,config.scaleY],[x+barHalfWidth,0],[x-barHalfWidth,0]]);});if(isHistogram){if(i>0){graphie.style({stroke:"#000",strokeWidth:1,opacity:.3},function(){config.graph.dividers.push(graphie.path([[x-barHalfWidth,0],[x-barHalfWidth,config.scaleY]]));});}}if(isMobile){const snap=config.scaleY/self.props.snapsPerLine;config.graph.lines[i]=Interactive2.addMaybeMobileMovablePoint(this,{coord:[x,startHeight],constraints:[(coord,prev,options)=>{return [x,this._clampValue(Math.round(coord[1]/snap)*snap,0,config.dimY)]}],onMoveStart:function(){config.graph.bars[i].attr({fill:KhanColors.INTERACTIVE});},onMove:function(){const y=config.graph.lines[i].coord()[1];const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);self._maybeHideDragPrompt();scaleBar(i,y);},onMoveEnd:function(){config.graph.bars[i].attr({fill:KhanColors.BLUE_C});}});config.graph.lines[i].state.visibleShape.wrapper.style.zIndex="1";self._maybeShowDragPrompt();}else {config.graph.lines[i]=graphie.addMovableLineSegment({coordA:[x-barHalfWidth,startHeight],coordZ:[x+barHalfWidth,startHeight],snapY:config.scaleY/self.props.snapsPerLine,constraints:{constrainX:true},normalStyle:{stroke:KhanColors.INTERACTIVE,"stroke-width":this.props.static?0:4}});config.graph.lines[i].onMove=function(dx,dy){let y=this.coordA[1];if(y<0||y>config.dimY){y=Math.min(Math.max(y,0),config.dimY);this.coordA[1]=this.coordZ[1]=y;this.transform();}const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);scaleBar(i,y);};}scaleBar(i,startHeight);return x},this.setupLine=(i,startHeight,config)=>{const isMobile=this.props.apiOptions.isMobile;const self=this;const c=config;const graphie=self.graphie;const x=i+(isMobile?.4:1);if(isMobile){const snap=config.scaleY/self.props.snapsPerLine;c.graph.points[i]=Interactive2.addMaybeMobileMovablePoint(this,{coord:[x,startHeight],constraints:[(coord,prev,options)=>{return [x,this._clampValue(Math.round(coord[1]/snap)*snap,0,config.dimY)]}],onMove:function(){const y=c.graph.points[i].coord()[1];const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);self._maybeHideDragPrompt();}});self._maybeShowDragPrompt();if(i>0){c.graph.lines[i]=Interactive2.addMovableLine(graphie,{points:[c.graph.points[i-1],c.graph.points[i]],constraints:Interactive2.MovablePoint.constraints.fixed(),normalStyle:{stroke:KhanColors.BLUE_C,"stroke-width":2},highlightStyle:{stroke:KhanColors.BLUE_C,"stroke-width":2}});}}else {c.graph.points[i]=graphie.addMovablePoint({coord:[x,startHeight],constraints:{constrainX:true},normalStyle:{fill:KhanColors.INTERACTIVE,stroke:KhanColors.INTERACTIVE},snapY:c.scaleY/self.props.snapsPerLine});c.graph.points[i].onMove=function(x,y){y=Math.min(Math.max(y,0),c.dimY);const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);return [x,y]};if(i>0){c.graph.lines[i]=graphie.addMovableLineSegment({pointA:c.graph.points[i-1],pointZ:c.graph.points[i],constraints:{fixed:true},normalStyle:{stroke:"#9ab8ed","stroke-width":2}});}}return x},this.setupDotplot=(i,config)=>{const graphie=this.graphie;const isMobile=this.props.apiOptions.isMobile;return this.setupTiledPlot(i,isMobile?.5:1,config,(x,y)=>{return graphie.ellipse([x,y],[this.DOT_PLOT_POINT_SIZE()/graphie.scale[0],this.DOT_PLOT_POINT_SIZE()/graphie.scale[1]],{fill:KhanColors.INTERACTIVE,stroke:KhanColors.INTERACTIVE})})},this.setupPic=(i,config)=>{const graphie=this.graphie;return this.setupTiledPlot(i,0,config,(x,y)=>{const scaledCenter=graphie.scalePoint([x,y]);const size=this.props.picSize;return graphie.raphael.image(this.props.picUrl,scaledCenter[0]-size/2,scaledCenter[1]-size/2,size,size)})},this.setupTiledPlot=(i,bottomMargin,config,createImage)=>{const self=this;const c=config;const graphie=self.graphie;const pics=graphie.pics;const dotTicks=graphie.dotTicks;const x=i+.5+c.picPad;graphie.mouselayer.canvas.style.touchAction="none";pics[i]=[];dotTicks[i]=[];const n=Math.round(c.dimY/c.scaleY)+1;___default.default(n).times(function(j){j-=1;const midY=(j+.5)*c.scaleY;const leftX=x-c.picBoxWidth/2;const topY=midY+.5*c.scaleY;const coord=graphie.scalePoint([leftX,topY+bottomMargin]);const mouseRect=graphie.mouselayer.rect(coord[0],coord[1],c.picBoxWidthPx,c.picBoxHeight);$__default.default(mouseRect[0]).css({fill:"#000",opacity:0,cursor:"pointer"}).on("vmousedown",function(e){e.preventDefault();self.whichPicClicked=i;self.setPicHeight(i,topY);$__default.default(document).on("vmouseup.plotTile",function(e){$__default.default(document).unbind(".plotTile");});$__default.default(document).on("vmousemove.plotTile",function(e){e.preventDefault();const yCoord=graphie.getMouseCoord(e)[1];const adjustedCoord=Math.floor(yCoord-bottomMargin);const newJ=Math.max(-1,Math.floor(adjustedCoord/c.scaleY));const newMidY=(newJ+.5)*c.scaleY;const newTopY=Math.min(newMidY+.5*c.scaleY,c.dimY);self.setPicHeight(self.whichPicClicked,newTopY);});});if(j<0){return}pics[i][j]=createImage(x,midY+bottomMargin);dotTicks[i][j]=graphie.ellipse([x,midY+bottomMargin],[self.DOT_TICK_POINT_SIZE()/graphie.scale[0],self.DOT_TICK_POINT_SIZE()/graphie.scale[1]],{fill:"#dee1e3",stroke:"#dee1e3"});});return x},this.setPicHeight=(i,y)=>{const values=[...this.props.userInput];values[i]=y;this.drawPicHeights(values,this.props.userInput);this.changeAndTrack(values);},this.changeAndTrack=userInput=>{this.props.handleUserInput(userInput);this.props.trackInteraction();};}}Plotter.contextType=PerseusI18nContext;Plotter.defaultProps={type:"bar",labels:["",""],categories:[""],scaleY:1,maxY:10,snapsPerLine:2,picSize:40,picBoxHeight:48,picUrl:"",plotDimensions:[380,300],labelInterval:1};function getStartUserInput$2(options){return options.starting}function getCorrectUserInput(options){return options.correct}function getUserInputFromSerializedState$2(serializedState){return serializedState.values}var Plotter$1 = {name:"plotter",displayName:"Plotter",hidden:true,widget:Plotter,getCorrectUserInput,staticTransform:___default.default.identity,getStartUserInput: getStartUserInput$2,getUserInputFromSerializedState: getUserInputFromSerializedState$2};
2105
+ class Plotter extends React__namespace.Component{componentDidMount(){this._isMounted=true;this.setupGraphie(this.props.userInput);}UNSAFE_componentWillReceiveProps(nextProps){const props=["type","labels","categories","scaleY","maxY","snapsPerLine","picUrl","labelInterval","static"];this.shouldSetupGraphie=___default.default.any(props,prop=>!___default.default.isEqual(this.props[prop],nextProps[prop]),this);if(!___default.default.isEqual(this.props.starting,nextProps.starting)&&!___default.default.isEqual(this.props.userInput,nextProps.starting)){this.shouldSetupGraphie=true;this.props.handleUserInput(nextProps.starting);}}componentDidUpdate(prevProps,prevState){this.shouldSetupGraphie=this.shouldSetupGraphie||!___default.default.isEqual(this.state.categoryHeights,prevState.categoryHeights);if(this.shouldSetupGraphie){this.setupGraphie(prevProps.userInput);}}componentWillUnmount(){this._isMounted=false;}setupGraphie(prevValues){const self=this;self.shouldSetupGraphie=false;$__default.default(this.graphieDiv.current).empty();const graphie=GraphUtils.createGraphie(this.graphieDiv.current);self.graphie=graphie;self.graphie.pics=[];self.graphie.dotTicks=[];const isBar=self.props.type==="bar";const isLine=self.props.type==="line";const isPic=self.props.type==="pic";const isHistogram=self.props.type==="histogram";const isDotplot=self.props.type==="dotplot";const isTiledPlot=isPic||isDotplot;const config={};const c=config;const isMobile=this.props.apiOptions.isMobile;c.graph={lines:[],bars:[],points:[],dividers:[]};c.scaleY=self.props.scaleY;c.dimX=self.props.categories.length;const plotDimensions=isMobile?[288,336]:self.props.plotDimensions;if(isLine){c.dimX+=isMobile?-0.2:1;}else if(isHistogram){c.barPad=0;c.barWidth=1;}else if(isBar){c.barPad=isMobile?.08:.15;c.barWidth=1-2*c.barPad;c.dimX+=(isMobile?-2:2)*c.barPad;}else if(isTiledPlot){c.picBoxHeight=self.props.picBoxHeight;c.picBoxWidthPx=plotDimensions[0]/self.props.categories.length;const picPadAllWidth=plotDimensions[0]-c.dimX*c.picBoxWidthPx;c.picPad=picPadAllWidth/(2*c.dimX+2);const picFullWidth=c.picBoxWidthPx+2*c.picPad;c.picPad=c.picPad/picFullWidth;c.picBoxWidth=c.picBoxWidthPx/picFullWidth;c.dimX+=2*c.picPad;}if(isDotplot){c.picBoxHeight=this.DOT_PLOT_POINT_SIZE()*2+this.DOT_PLOT_POINT_PADDING();}c.dimY=Math.ceil(self.props.maxY/c.scaleY)*c.scaleY;let padX=25;if((isBar||isLine)&&isMobile){padX=self.props.labels[1].length!==0?17:11;}if(isDotplot){padX/=2;}if(isMobile&&isTiledPlot&&self.props.labels[1].length===0){padX=0;}let padTop=25;let padBottom=25*3;if(isMobile&&(isBar||isTiledPlot)){const maxCategoryHeight=Math.max(0,...Object.values(self.state.categoryHeights));if(maxCategoryHeight){let offsetY=25;if(isTiledPlot){offsetY+=10;}padBottom=offsetY+maxCategoryHeight;}}if(isMobile){c.scale=[(plotDimensions[0]-padX*4)/c.dimX,(plotDimensions[1]-(padTop+padBottom))/c.dimY];}else {c.scale=___default.default.map([c.dimX,c.dimY],function(dim,i){return plotDimensions[i]/dim});}if(isTiledPlot){c.scale[1]=c.picBoxHeight/c.scaleY;}padX/=c.scale[0];padTop/=c.scale[1];padBottom/=c.scale[1];graphie.init({range:[[-3*padX,c.dimX+padX],[-padBottom,c.dimY+padTop]],scale:c.scale,isMobile:this.props.apiOptions.isMobile});graphie.addMouseLayer({allowScratchpad:true,setDrawingAreaAvailable:this.props.apiOptions.setDrawingAreaAvailable});if(!isTiledPlot){const initialY=isMobile?c.scaleY:0;for(let y=initialY;y<=c.dimY;y+=c.scaleY){graphie.label([0,y],kmath.KhanMath.roundToApprox(y,2),"left",true);graphie.style({stroke:isMobile?"#e9ebec":"#000",strokeWidth:1,opacity:isMobile?1:.3},function(){graphie.line([0,y],[c.dimX,y]);});}}if((isBar||isLine)&&isMobile&&!this.props.static){self.graphie.dragPrompt=graphie.label([c.dimX/2,c.dimY/2],this.context.strings.dragHandles,"center",false).css("font-weight","bold").css("color",KhanColors.KA_GREEN).css("display","none");}self.setupCategories(config);if(isTiledPlot&&isMobile){self.graphie.dotPrompt=graphie.label([c.dimX/2,c.dimY/2],this.context.strings.tapAddPoints,"center",false).css("font-weight","bold").css("color",KhanColors.KA_GREEN).css("display","none");}if(isTiledPlot){self.drawPicHeights(self.props.userInput,prevValues);}graphie.style({stroke:"#000",strokeWidth:2,opacity:1},function(){if(isTiledPlot){if(isDotplot){graphie.style({stroke:isMobile?KhanColors.GRAY_G:"#000",strokeWidth:isMobile?1:2},()=>graphie.line([isMobile?0:.5,0],[c.dimX-(isMobile?0:.5),0]));}else {graphie.line([0,0],[c.dimX,0]);if(self.props.labels[1].length!==0||!isMobile){graphie.style({stroke:isMobile?KhanColors.GRAY_G:"#000",strokeWidth:isMobile?1:2},()=>graphie.line([0,0],[0,c.dimY]));}}}else {graphie.style({stroke:isMobile?KhanColors.GRAY_G:"#000",strokeWidth:isMobile?1:2},()=>graphie.line([isMobile?-padX*3:0,0],[c.dimX+(isMobile?padX:0),0]));if(!((isBar||isLine)&&isMobile)){graphie.style({stroke:isMobile?KhanColors.GRAY_G:"#000",strokeWidth:isMobile?1:2},()=>graphie.line([0,0],[0,c.dimY]));}}});graphie.label([c.dimX/2,isMobile?-padBottom:-35/c.scale[1]],self.props.labels[0],isMobile?"above":"below",false).css("font-weight","bold").css("color",isMobile&&KhanColors.GRAY_F);graphie.label([(isMobile?-35:-60)/c.scale[0],c.dimY/2],self.props.labels[1],"center",false).css("font-weight","bold").css("color",isMobile&&KhanColors.GRAY_F).addClass("rotate");if(this.props.apiOptions.isMobile){this.horizHairline=new WrappedLine(this.graphie,[0,0],[0,0],{normalStyle:{strokeWidth:1}});this.horizHairline.attr({stroke:KhanColors.INTERACTIVE});this.horizHairline.hide();this.hairlineRange=[[0,c.dimX],[0,c.dimY]];}}_testInsertUserInput(userInput){this.props.handleUserInput(userInput);}drawPicHeights(values,prevValues){const self=this;const graphie=self.graphie;const pics=graphie.pics;const isMobile=this.props.apiOptions.isMobile;if(isMobile){const shouldDisplay=values.every(v=>v===0);graphie.dotPrompt[0].style.display=shouldDisplay?"inline":"none";}___default.default.each(pics,function(ps,i){___default.default.each(ps,function(pic,j){const y=(j+1)*self.props.scaleY;const show=y<=values[i];if(self.props.type==="dotplot"){const wasShown=y<=prevValues[i];const wasJustShown=show&&!wasShown;if(wasJustShown){pic.animate({"stroke-width":8},75,()=>pic.animate({"stroke-width":2},75));}}$__default.default(pic[0]).css({display:show?"inline":"none"});graphie.dotTicks[i][j][0].style.display=show||!isMobile?"none":"inline";});});}getPromptJSON(){return getPromptJSON$3()}getSerializedState(){const{userInput:_,...rest}=this.props;return {...rest,values:this.props.userInput}}render(){const paddingForBottomLabel=75;const style={marginBottom:this.props.labels[0]?paddingForBottomLabel:0};return jsxRuntimeExports.jsx("div",{className:"perseus-widget-plotter graphie",ref:this.graphieDiv,style:style})}constructor(...args){super(...args),this._isMounted=false,this.graphieDiv=React__namespace.createRef(),this.state={categoryHeights:{}},this.DOT_PLOT_POINT_SIZE=()=>{return this.props.apiOptions.isMobile?6:4},this.DOT_PLOT_POINT_PADDING=()=>{return 8},this.DOT_TICK_POINT_SIZE=()=>{return 2},this.showHairlines=point=>{if(this.props.apiOptions.isMobile){this.horizHairline.moveTo([this.hairlineRange[0][0],point[1]],[this.hairlineRange[0][1],point[1]]);this.horizHairline.show();}},this.hideHairlines=()=>{if(this.props.apiOptions.isMobile){this.horizHairline.hide();}},this.labelCategory=(x,category)=>{const isMobile=this.props.apiOptions.isMobile;const graphie=this.graphie;category=category+"";let isTeX=false;const mathyCategory=category.match(/^\$(.*)\$$/);if(mathyCategory){category=mathyCategory[1];isTeX=true;}const translateX=5;const rotationDeg=45;const rotationRad=rotationDeg*(Math.PI/180);const labelRotation=`translateX(-50%) translateX(${translateX}px) `+`translateY(-50%) rotate(-${rotationDeg}deg)`;const shouldRotate=isMobile&&!mathyCategory;return new Promise(resolve=>{graphie.style({color:isMobile?KhanColors.GRAY_G:"inherit",transform:shouldRotate?labelRotation:"none",transformOrigin:"100%"},()=>{const $span=graphie.label([x,isMobile?-0.5:0],category,"below",isTeX);const height=14+(shouldRotate?Math.round($span.height()*Math.cos(rotationRad)+($span.width()+translateX)*Math.sin(rotationRad)):$span.height());resolve({category,height});});})},this.setupCategories=config=>{const self=this;const c=config;const graphie=self.graphie;const isMobile=this.props.apiOptions.isMobile;const categoryHeightPromises=[];if(self.props.type==="histogram"){___default.default.times(self.props.categories.length-1,function(i){self.setupBar({index:i,startHeight:self.props.userInput[i],config:config,isHistogram:true});});___default.default.each(self.props.categories,function(category,i){const x=.5+i*c.barWidth;categoryHeightPromises.push(self.labelCategory(x,category));const tickHeight=6/c.scale[1];graphie.style({stroke:"#000",strokeWidth:isMobile?1:2,opacity:1},function(){graphie.line([x,-tickHeight],[x,0]);});});}else {___default.default.each(self.props.categories,function(category,i){const startHeight=self.props.userInput[i];let x;if(self.props.type==="bar"){x=self.setupBar({index:i,startHeight:startHeight,config:config,isHistogram:false});}else if(self.props.type==="line"){x=self.setupLine(i,startHeight,config);}else if(self.props.type==="pic"){x=self.setupPic(i,config);}else if(self.props.type==="dotplot"){x=self.setupDotplot(i,config);}let tickStart=0;let tickEnd=-6/c.scale[1];if(self.props.type==="dotplot"&&!isMobile){tickStart=-tickEnd;}if(self.props.type==="dotplot"){if(i%self.props.labelInterval===0||i===self.props.categories.length-1){categoryHeightPromises.push(self.labelCategory(x,category));tickStart*=1.5;tickEnd*=1.5;}}else {categoryHeightPromises.push(self.labelCategory(x,category));}graphie.style({stroke:isMobile?KhanColors.GRAY_G:"#000",strokeWidth:isMobile?1:2,opacity:1},function(){graphie.line([x,tickStart],[x,tickEnd]);});});}Promise.all(categoryHeightPromises).then(measurements=>{if(self._isMounted){const categoryHeights={};measurements.forEach(({category,height})=>categoryHeights[category]=height);self.setState({categoryHeights});}});},this._clampValue=(v,min,max)=>{return Math.max(Math.min(v,max),min)},this._maybeShowDragPrompt=()=>{if(this.graphie.dragPrompt!=null){this.graphie.dragPrompt[0].style.display="inline";}},this._maybeHideDragPrompt=()=>{if(this.graphie.dragPrompt!=null){this.graphie.dragPrompt[0].style.display="none";}},this.setupBar=args=>{const isMobile=this.props.apiOptions.isMobile;const i=args.index;const startHeight=args.startHeight;const config=args.config;const isHistogram=args.isHistogram;const self=this;const graphie=self.graphie;const barHalfWidth=config.barWidth/2;let x;if(isHistogram){x=.5+i*config.barWidth+barHalfWidth;}else {x=(isMobile?barHalfWidth:.5+config.barPad)+i;}const scaleBar=function(i,height){const center=graphie.scalePoint(0);config.graph.bars[i].scale(1,Math.max(isMobile?.2:.01,height/config.scaleY),center[0],center[1]);if(isHistogram){const leftDivider=config.graph.dividers[i-1];const rightDivider=config.graph.dividers[i];if(leftDivider){const divHeight=Math.min(self.props.userInput[i-1],height);leftDivider.scale(1,Math.max(.01,divHeight/config.scaleY),center[0],center[1]);}if(rightDivider){const divHeight=Math.min(self.props.userInput[i+1],height);rightDivider.scale(1,Math.max(.01,divHeight/config.scaleY),center[0],center[1]);}}};graphie.style({stroke:"none",fill:isMobile?KhanColors.BLUE_C:KhanColors.LIGHT_BLUE,opacity:1},function(){config.graph.bars[i]=graphie.path([[x-barHalfWidth,0],[x-barHalfWidth,config.scaleY],[x+barHalfWidth,config.scaleY],[x+barHalfWidth,0],[x-barHalfWidth,0]]);});if(isHistogram){if(i>0){graphie.style({stroke:"#000",strokeWidth:1,opacity:.3},function(){config.graph.dividers.push(graphie.path([[x-barHalfWidth,0],[x-barHalfWidth,config.scaleY]]));});}}if(isMobile){const snap=config.scaleY/self.props.snapsPerLine;config.graph.lines[i]=Interactive2.addMaybeMobileMovablePoint(this,{coord:[x,startHeight],constraints:[(coord,prev,options)=>{return [x,this._clampValue(Math.round(coord[1]/snap)*snap,0,config.dimY)]}],onMoveStart:function(){config.graph.bars[i].attr({fill:KhanColors.INTERACTIVE});},onMove:function(){const y=config.graph.lines[i].coord()[1];const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);self._maybeHideDragPrompt();scaleBar(i,y);},onMoveEnd:function(){config.graph.bars[i].attr({fill:KhanColors.BLUE_C});}});config.graph.lines[i].state.visibleShape.wrapper.style.zIndex="1";self._maybeShowDragPrompt();}else {config.graph.lines[i]=graphie.addMovableLineSegment({coordA:[x-barHalfWidth,startHeight],coordZ:[x+barHalfWidth,startHeight],snapY:config.scaleY/self.props.snapsPerLine,constraints:{constrainX:true},normalStyle:{stroke:KhanColors.INTERACTIVE,"stroke-width":this.props.static?0:4}});config.graph.lines[i].onMove=function(dx,dy){let y=this.coordA[1];if(y<0||y>config.dimY){y=Math.min(Math.max(y,0),config.dimY);this.coordA[1]=this.coordZ[1]=y;this.transform();}const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);scaleBar(i,y);};}scaleBar(i,startHeight);return x},this.setupLine=(i,startHeight,config)=>{const isMobile=this.props.apiOptions.isMobile;const self=this;const c=config;const graphie=self.graphie;const x=i+(isMobile?.4:1);if(isMobile){const snap=config.scaleY/self.props.snapsPerLine;c.graph.points[i]=Interactive2.addMaybeMobileMovablePoint(this,{coord:[x,startHeight],constraints:[(coord,prev,options)=>{return [x,this._clampValue(Math.round(coord[1]/snap)*snap,0,config.dimY)]}],onMove:function(){const y=c.graph.points[i].coord()[1];const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);self._maybeHideDragPrompt();}});self._maybeShowDragPrompt();if(i>0){c.graph.lines[i]=Interactive2.addMovableLine(graphie,{points:[c.graph.points[i-1],c.graph.points[i]],constraints:Interactive2.MovablePoint.constraints.fixed(),normalStyle:{stroke:KhanColors.BLUE_C,"stroke-width":2},highlightStyle:{stroke:KhanColors.BLUE_C,"stroke-width":2}});}}else {c.graph.points[i]=graphie.addMovablePoint({coord:[x,startHeight],constraints:{constrainX:true},normalStyle:{fill:KhanColors.INTERACTIVE,stroke:KhanColors.INTERACTIVE},snapY:c.scaleY/self.props.snapsPerLine});c.graph.points[i].onMove=function(x,y){y=Math.min(Math.max(y,0),c.dimY);const values=[...self.props.userInput];values[i]=y;self.changeAndTrack(values);return [x,y]};if(i>0){c.graph.lines[i]=graphie.addMovableLineSegment({pointA:c.graph.points[i-1],pointZ:c.graph.points[i],constraints:{fixed:true},normalStyle:{stroke:"#9ab8ed","stroke-width":2}});}}return x},this.setupDotplot=(i,config)=>{const graphie=this.graphie;const isMobile=this.props.apiOptions.isMobile;return this.setupTiledPlot(i,isMobile?.5:1,config,(x,y)=>{return graphie.ellipse([x,y],[this.DOT_PLOT_POINT_SIZE()/graphie.scale[0],this.DOT_PLOT_POINT_SIZE()/graphie.scale[1]],{fill:KhanColors.INTERACTIVE,stroke:KhanColors.INTERACTIVE})})},this.setupPic=(i,config)=>{const graphie=this.graphie;return this.setupTiledPlot(i,0,config,(x,y)=>{const scaledCenter=graphie.scalePoint([x,y]);const size=this.props.picSize;return graphie.raphael.image(this.props.picUrl,scaledCenter[0]-size/2,scaledCenter[1]-size/2,size,size)})},this.setupTiledPlot=(i,bottomMargin,config,createImage)=>{const self=this;const c=config;const graphie=self.graphie;const pics=graphie.pics;const dotTicks=graphie.dotTicks;const x=i+.5+c.picPad;graphie.mouselayer.canvas.style.touchAction="none";pics[i]=[];dotTicks[i]=[];const n=Math.round(c.dimY/c.scaleY)+1;___default.default(n).times(function(j){j-=1;const midY=(j+.5)*c.scaleY;const leftX=x-c.picBoxWidth/2;const topY=midY+.5*c.scaleY;const coord=graphie.scalePoint([leftX,topY+bottomMargin]);const mouseRect=graphie.mouselayer.rect(coord[0],coord[1],c.picBoxWidthPx,c.picBoxHeight);$__default.default(mouseRect[0]).css({fill:"#000",opacity:0,cursor:"pointer"}).on("vmousedown",function(e){e.preventDefault();self.whichPicClicked=i;self.setPicHeight(i,topY);$__default.default(document).on("vmouseup.plotTile",function(e){$__default.default(document).unbind(".plotTile");});$__default.default(document).on("vmousemove.plotTile",function(e){e.preventDefault();const yCoord=graphie.getMouseCoord(e)[1];const adjustedCoord=Math.floor(yCoord-bottomMargin);const newJ=Math.max(-1,Math.floor(adjustedCoord/c.scaleY));const newMidY=(newJ+.5)*c.scaleY;const newTopY=Math.min(newMidY+.5*c.scaleY,c.dimY);self.setPicHeight(self.whichPicClicked,newTopY);});});if(j<0){return}pics[i][j]=createImage(x,midY+bottomMargin);dotTicks[i][j]=graphie.ellipse([x,midY+bottomMargin],[self.DOT_TICK_POINT_SIZE()/graphie.scale[0],self.DOT_TICK_POINT_SIZE()/graphie.scale[1]],{fill:"#dee1e3",stroke:"#dee1e3"});});return x},this.setPicHeight=(i,y)=>{const values=[...this.props.userInput];values[i]=y;this.drawPicHeights(values,this.props.userInput);this.changeAndTrack(values);},this.changeAndTrack=userInput=>{this.props.handleUserInput(userInput);this.props.trackInteraction();};}}Plotter.contextType=PerseusI18nContext;Plotter.defaultProps={type:"bar",labels:["",""],categories:[""],scaleY:1,maxY:10,snapsPerLine:2,picSize:40,picBoxHeight:48,picUrl:"",plotDimensions:[380,300],labelInterval:1};function getStartUserInput$2(options){return options.starting}function getCorrectUserInput(options){return options.correct}function getUserInputFromSerializedState$2(serializedState){return serializedState.values}var Plotter$1 = {name:"plotter",displayName:"Plotter",hidden:true,widget:Plotter,getCorrectUserInput,getStartUserInput: getStartUserInput$2,getUserInputFromSerializedState: getUserInputFromSerializedState$2};
2104
2106
 
2105
2107
  const getPromptJSON$2=()=>{return getUnsupportedPromptJSON("python-program")};
2106
2108
 
@@ -2122,7 +2124,7 @@ var extraWidgets = [CSProgram$1,Categorizer$1,Definition$1,DeprecatedStandin$1,D
2122
2124
 
2123
2125
  const init=function(){registerWidgets(basicWidgets);registerWidgets(extraWidgets);replaceDeprecatedWidgets();};
2124
2126
 
2125
- const libName="@khanacademy/perseus";const libVersion="66.2.2";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
2127
+ const libName="@khanacademy/perseus";const libVersion="66.4.0";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
2126
2128
 
2127
2129
  const apiVersion={major:12,minor:0};
2128
2130
 
@@ -2158,7 +2160,7 @@ ${items.join("\n")}
2158
2160
  | --- | --- |`;const tableRows=left.map((leftItem,index)=>{return `| ${leftItem} | ${right[index]} |`});const table=[tableHeader,...tableRows].join("\n");const matcherWidgetExplanation="The user needs to move items in the right column to match the correct option on the left. The order of items on the right side will be different from what the user sees.";context=context.replace(`[[☃ ${widgetID}]]`,`${matcherWidgetExplanation}
2159
2161
  ${table}`);}break;case "numeric-input":case "input-number":case "expression":context=context.replace(`[[☃ ${widgetID}]]`,"?");break;default:context=context.replace(`[[☃ ${widgetID}]]`,`[[Unsupported ${widget.type} widget: Explain to the user that you are unable to understand the content in this widget and ask them to describe it.]]`);}});return context}function getImagesWithoutAltData(perseusRenderer){if(!perseusRenderer.widgets){return ""}const imgsWithoutAltData=[];Object.entries(perseusRenderer.widgets).forEach(([widgetId,widget])=>{if(!widget.options){return}if(widget.type==="image"&&!widget.options.alt&&widget.options.backgroundImage?.url){imgsWithoutAltData.push({widgetId,imgUrl:widget.options.backgroundImage.url});}});return JSON.stringify(imgsWithoutAltData)}const INDIVIDUAL_ANSWER_WIDGETS=["interactive-graph","categorizer","grapher"];const SUPPORTED_WIDGETS=["radio","numeric-input","input-number","expression",...INDIVIDUAL_ANSWER_WIDGETS];const isWrongAnswerSupported=(widgetIds,widgetMap)=>{return widgetIds.length!==0&&widgetIds.every(widgetId=>SUPPORTED_WIDGETS.includes(getWidgetTypeByWidgetId(widgetId,widgetMap)))};const shouldHaveIndividualAnswer=(widgetId,widgetMap)=>{return INDIVIDUAL_ANSWER_WIDGETS.includes(getWidgetTypeByWidgetId(widgetId,widgetMap))};const getAnswerFromUserInput=(widgetType,userInput)=>{switch(widgetType){case "categorizer":return userInput.values;case "input-number":return userInput.currentValue;case "numeric-input":return userInput.currentValue;case "radio":return userInput.choicesSelected}return userInput};const getCorrectAnswerForWidgetId=(widgetId,itemData)=>{const rubric=itemData.question.widgets[widgetId].options;const widgetMap=getWidgetsMapFromItemData(itemData);const widgetType=getWidgetTypeByWidgetId(widgetId,widgetMap);const widget=getWidgetExport(widgetType);return widget?.getOneCorrectAnswerFromRubric?.(rubric)};const isWidgetIdInContent=(perseusItem,widgetId)=>{return perseusItem.question.content.indexOf(widgetId)!==-1};const getValidWidgetIds=perseusItem=>{const{widgets}=perseusItem.question;return wonderStuffCore.keys(widgets).filter(id=>isWidgetIdInContent(perseusItem,id))};
2160
2162
 
2161
- function generateTestRadioWidget(){return {type:"radio",options:{choices:[]}}}function generateTestInteractiveGraphWidget(){return {type:"interactive-graph",options:{step:[1,1],gridStep:[1,1],snapStep:[1,1],markings:"graph",labels:["x","y"],lockedFigures:[],showProtractor:false,range:[[-10,10],[-10,10]],graph:{type:"angle"},correct:{type:"angle"}}}}function generateTestCategorizerWidget(){return {type:"categorizer",options:{items:[],categories:[],randomizeItems:false,static:false,values:[]}}}function generateTestExpressionWidget(){return {type:"expression",options:{answerForms:[],buttonSets:["basic"],functions:[],times:false}}}function generateTestNumericInputWidget(){return {type:"numeric-input",options:{answers:[],labelText:"",size:"normal",coefficient:false,static:false}}}
2163
+ function generateTestRadioWidget(){return {type:"radio",options:{choices:[]}}}function generateTestInteractiveGraphWidget(){return {type:"interactive-graph",options:{step:[1,1],gridStep:[1,1],snapStep:[1,1],markings:"graph",labels:["x","y"],lockedFigures:[],showProtractor:false,range:[[-10,10],[-10,10]],graph:{type:"angle"},correct:{type:"angle"},showAxisArrows:{xMin:true,xMax:true,yMin:true,yMax:true}}}}function generateTestCategorizerWidget(){return {type:"categorizer",options:{items:[],categories:[],randomizeItems:false,static:false,values:[]}}}function generateTestExpressionWidget(){return {type:"expression",options:{answerForms:[],buttonSets:["basic"],functions:[],times:false}}}function generateTestNumericInputWidget(){return {type:"numeric-input",options:{answers:[],labelText:"",size:"normal",coefficient:false,static:false}}}
2162
2164
 
2163
2165
  const widgetNameToEnum={categorizer:"CATEGORIZER","cs-program":"CS_PROGRAM",definition:"DEFINITION","deprecated-standin":"DEPRECATED_STANDIN",dropdown:"DROPDOWN",explanation:"EXPLANATION",expression:"EXPRESSION","free-response":"FREE_RESPONSE","graded-group-set":"GRADED_GROUP_SET","graded-group":"GRADED_GROUP",grapher:"GRAPHER",group:"GROUP",iframe:"IFRAME",image:"IMAGE","input-number":"INPUT_NUMBER",interaction:"INTERACTIVE","interactive-graph":"INTERACTIVE_GRAPH","label-image":"LABEL_IMAGE","lights-puzzle":"LIGHTS_PUZZLE",matcher:"MATCHER",matrix:"MATRIX",measurer:"MEASURER","molecule-renderer":"MOLECULE","number-line":"NUMBER_LINE","numeric-input":"NUMERIC_INPUT",orderer:"ORDERER",passage:"PASSAGE","passage-ref":"PASSAGE_REF","passage-ref-target":"PASSAGE_REF_TARGET","phet-simulation":"PHET_SIMULATION",plotter:"PLOTTER","python-program":"PYTHON_PROGRAM","reaction-diagram":"REACTION_DIAGRAM",radio:"RADIO",sequence:"SEQUENCE",simulator:"SIMULATOR",sorter:"SORTER",table:"TABLE",video:"VIDEO"};function convertWidgetNameToEnum(name){const widgetEnum=widgetNameToEnum[name];if(!widgetEnum){throw new Error(`Unknown widget name: ${name}`)}return widgetEnum}
2164
2166
 
@@ -2216,6 +2218,7 @@ exports.Renderer = Renderer;
2216
2218
  exports.ScoringUtil = ScoringUtil;
2217
2219
  exports.ServerItemRenderer = serverItemRenderer;
2218
2220
  exports.TableWidget = Table$1;
2221
+ exports.UserInputManager = UserInputManager;
2219
2222
  exports.Util = Util;
2220
2223
  exports.Widgets = widgets$1;
2221
2224
  exports.apiVersion = apiVersion;