@khanacademy/perseus 86.0.1 → 87.0.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.
package/dist/index.js CHANGED
@@ -1749,7 +1749,7 @@ const getPromptJSON$o=(widgetData,userInput)=>{const choices=widgetData.options.
1749
1749
 
1750
1750
  var styles$t = {"scrollButtonsContainer":"perseus_kjDHiWdD"};
1751
1751
 
1752
- const SCROLL_DISTANCE=100;const scrollInstances=new Map;function ScrollableArea({overflowX,overflowY,children,className,scrollDescription,style,role="group",id:providedId,...additionalProps}){const{strings}=usePerseusI18n();const containerRef=React.useRef(null);const[isScrollable,setIsScrollable]=React.useState(false);const[isScrolling,setIsScrolling]=React.useState(false);const generatedId=React__namespace.useId();const id=providedId||generatedId;const scrollableThreshold=React__namespace.useMemo(()=>{return window.innerWidth<=767?8:5},[]);const scroll=React__namespace.useCallback(direction=>{if(!containerRef.current||isScrolling){return}setIsScrolling(true);const contentIsRtl=getComputedStyle(containerRef.current).direction==="rtl";const scrollNegative=contentIsRtl&&direction==="end"||!contentIsRtl&&direction==="start";const scrollAmount=scrollNegative?-100:SCROLL_DISTANCE;containerRef.current.scrollBy({left:scrollAmount,behavior:"smooth"});setTimeout(()=>{setIsScrolling(false);},150);},[isScrolling]);const updateScrollState=React__namespace.useCallback(()=>{if(!containerRef.current){return}const{scrollLeft,scrollWidth,clientWidth}=containerRef.current;const newIsRtl=getComputedStyle(containerRef.current).direction==="rtl";const newIsScrollable=scrollWidth>clientWidth+scrollableThreshold;setIsScrollable(newIsScrollable);let newCanScrollStart;let newCanScrollEnd;if(newIsRtl){newCanScrollStart=scrollLeft<-scrollableThreshold;newCanScrollEnd=Math.abs(scrollLeft)<scrollWidth-clientWidth-scrollableThreshold;}else {newCanScrollStart=scrollLeft>scrollableThreshold;newCanScrollEnd=scrollLeft+clientWidth<scrollWidth-scrollableThreshold;}const scrollState={isScrollable:newIsScrollable,canScrollStart:newCanScrollStart,canScrollEnd:newCanScrollEnd,isRTL:newIsRtl,scroll,scrollDescription:scrollDescription||strings.scrollAnswers};scrollInstances.set(id,scrollState);},[id,scrollableThreshold,scrollDescription,strings.scrollAnswers,scroll]);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);scrollInstances.delete(id);}},[children,updateScrollState,id]);const mergeStyle={overflowX:isScrollable&&overflowX==="auto"?"scroll":overflowX,overflowY:isScrollable&&overflowY==="auto"?"scroll":overflowY,scrollbarWidth:"thin",...style};return jsxRuntimeExports.jsx("div",{...additionalProps,id:id,role:role,className:className,style:mergeStyle,ref:containerRef,children:children})}function ScrollControls({target,scrollDescription:overrideDescription}){const{strings}=usePerseusI18n();const[scrollState,setScrollState]=React.useState(null);React.useEffect(()=>{if(!target){return}const checkForScrollState=()=>{const state=scrollInstances.get(target);if(state){setScrollState(state);}};checkForScrollState();const interval=setInterval(checkForScrollState,100);return ()=>{clearInterval(interval);}},[target]);if(!scrollState||!scrollState.isScrollable){return null}const description=overrideDescription||scrollState.scrollDescription;return jsxRuntimeExports.jsxs("div",{className:styles$t.scrollButtonsContainer,"aria-live":"polite",role:"group","aria-label":description,children:[jsxRuntimeExports.jsx(IconButton__default.default,{icon:scrollState.isRTL?caretRightIcon__default.default:caretLeftIcon__default.default,actionType:"neutral",kind:"secondary",size:"small",onClick:()=>scrollState.scroll("start"),"aria-label":strings.scrollStart,disabled:!scrollState.canScrollStart}),jsxRuntimeExports.jsx(IconButton__default.default,{icon:scrollState.isRTL?caretLeftIcon__default.default:caretRightIcon__default.default,actionType:"neutral",kind:"secondary",size:"small",onClick:()=>scrollState.scroll("end"),"aria-label":strings.scrollEnd,disabled:!scrollState.canScrollEnd}),jsxRuntimeExports.jsx(wonderBlocksTypography.BodyText,{size:"small",children:description})]})}const ScrollableView=ScrollableArea;ScrollableView.Controls=ScrollControls;
1752
+ const SCROLL_DISTANCE=100;const scrollInstances=new Map;function ScrollableArea({overflowX,overflowY,children,className,scrollDescription,style,role="group",id:providedId,...additionalProps}){const{strings}=usePerseusI18n();const containerRef=React.useRef(null);const[isScrollable,setIsScrollable]=React.useState(false);const[isScrolling,setIsScrolling]=React.useState(false);const generatedId=React__namespace.useId();const id=providedId||generatedId;const scrollableThreshold=React__namespace.useMemo(()=>{return window.innerWidth<=767?8:5},[]);const scroll=React__namespace.useCallback(direction=>{if(!containerRef.current||isScrolling){return}setIsScrolling(true);const contentIsRtl=getComputedStyle(containerRef.current).direction==="rtl";const scrollNegative=contentIsRtl&&direction==="end"||!contentIsRtl&&direction==="start";const scrollAmount=scrollNegative?-100:SCROLL_DISTANCE;containerRef.current.scrollBy({left:scrollAmount,behavior:"smooth"});setTimeout(()=>{setIsScrolling(false);},150);},[isScrolling]);const updateScrollState=React__namespace.useCallback(()=>{if(!containerRef.current){return}const{scrollLeft,scrollWidth,clientWidth}=containerRef.current;const newIsRtl=getComputedStyle(containerRef.current).direction==="rtl";const newIsScrollable=scrollWidth>clientWidth+scrollableThreshold;setIsScrollable(newIsScrollable);let newCanScrollStart;let newCanScrollEnd;if(newIsRtl){newCanScrollStart=scrollLeft<-scrollableThreshold;newCanScrollEnd=Math.abs(scrollLeft)<scrollWidth-clientWidth-scrollableThreshold;}else {newCanScrollStart=scrollLeft>scrollableThreshold;newCanScrollEnd=scrollLeft+clientWidth<scrollWidth-scrollableThreshold;}const scrollState={isScrollable:newIsScrollable,canScrollStart:newCanScrollStart,canScrollEnd:newCanScrollEnd,scroll,scrollDescription:scrollDescription||strings.scrollAnswers};scrollInstances.set(id,scrollState);},[id,scrollableThreshold,scrollDescription,strings.scrollAnswers,scroll]);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);scrollInstances.delete(id);}},[children,updateScrollState,id]);const mergeStyle={overflowX:isScrollable&&overflowX==="auto"?"scroll":overflowX,overflowY:isScrollable&&overflowY==="auto"?"scroll":overflowY,scrollbarWidth:"thin",...style};return jsxRuntimeExports.jsx("div",{...additionalProps,id:id,role:role,className:className,style:mergeStyle,ref:containerRef,children:children})}function ScrollControls({target,scrollDescription:overrideDescription}){const{strings}=usePerseusI18n();const[scrollState,setScrollState]=React.useState(null);React.useEffect(()=>{if(!target){return}const checkForScrollState=()=>{const state=scrollInstances.get(target);if(state){setScrollState(state);}};checkForScrollState();const interval=setInterval(checkForScrollState,100);return ()=>{clearInterval(interval);}},[target]);if(!scrollState||!scrollState.isScrollable){return null}const description=overrideDescription||scrollState.scrollDescription;return jsxRuntimeExports.jsxs("div",{className:styles$t.scrollButtonsContainer,"aria-live":"polite",role:"group","aria-label":description,children:[jsxRuntimeExports.jsx(IconButton__default.default,{icon:caretLeftIcon__default.default,actionType:"neutral",kind:"secondary",size:"small",onClick:()=>scrollState.scroll("start"),"aria-label":strings.scrollStart,disabled:!scrollState.canScrollStart}),jsxRuntimeExports.jsx(IconButton__default.default,{icon:caretRightIcon__default.default,actionType:"neutral",kind:"secondary",size:"small",onClick:()=>scrollState.scroll("end"),"aria-label":strings.scrollEnd,disabled:!scrollState.canScrollEnd}),jsxRuntimeExports.jsx(wonderBlocksTypography.BodyText,{size:"small",children:description})]})}const ScrollableView=ScrollableArea;ScrollableView.Controls=ScrollControls;
1753
1753
 
1754
1754
  var styles$s = {"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"};
1755
1755
 
@@ -1827,13 +1827,13 @@ const getPromptJSON$i=(title,rendererJSON,hintRendererJSON)=>{if(!rendererJSON){
1827
1827
 
1828
1828
  class GradedGroupAnswerBar extends React__namespace.Component{render(){const{apiOptions,answerBarState,onCheckAnswer,onNextQuestion}=this.props;const{keepTrying,tryAgain,check,correctExcited,nextQuestion}=this.context.strings;const answerBarStyle={...styles$h.answerBar,backgroundColor:answerBarState==="CORRECT"?wonderBlocksTokens.semanticColor.core.background.base.subtle:wonderBlocksTokens.semanticColor.core.background.base.default,justifyContent:answerBarState==="CORRECT"&&!onNextQuestion?"center":"space-between"};const message=answerBarState==="INCORRECT"?jsxRuntimeExports.jsxs("span",{style:styles$h.text,children:[jsxRuntimeExports.jsx("span",{style:styles$h.tryAgainIcon,children:jsxRuntimeExports.jsx(InlineIcon,{...iconTryAgain})}),jsxRuntimeExports.jsx("span",{style:{marginInlineStart:8},children:keepTrying})]}):jsxRuntimeExports.jsx("span",{});if(answerBarState!=="CORRECT"){const buttonLabel=answerBarState==="INCORRECT"?tryAgain:check;return jsxRuntimeExports.jsxs("div",{style:answerBarStyle,children:[message,jsxRuntimeExports.jsx(Button__default.default,{disabled:apiOptions.readOnly||answerBarState!=="ACTIVE",onClick:onCheckAnswer,children:buttonLabel})]})}return jsxRuntimeExports.jsxs("div",{style:answerBarStyle,children:[jsxRuntimeExports.jsxs("span",{style:styles$h.text,children:[jsxRuntimeExports.jsx("span",{style:{color:wonderBlocksTokens.semanticColor.core.foreground.success.default},children:jsxRuntimeExports.jsx(InlineIcon,{...iconStar,style:{marginBlockEnd:5}})}),jsxRuntimeExports.jsx("span",{role:"alert","aria-label":correctExcited,style:{marginInlineStart:8},children:correctExcited})]}),onNextQuestion&&jsxRuntimeExports.jsx(Button__default.default,{onClick:onNextQuestion,children:nextQuestion})]})}}GradedGroupAnswerBar.contextType=PerseusI18nContext;const styles$h={answerBar:{display:"flex",alignItems:"center",height:68,marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin,marginBottom:negativePhoneMargin,marginTop:phoneMargin,paddingLeft:phoneMargin,paddingRight:10,borderTop:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.default}`},tryAgainIcon:{color:wonderBlocksTokens.semanticColor.core.foreground.neutral.subtle,transform:"scale(-1,1) rotate(-268deg)"},text:{display:"flex",flexDirection:"row",alignItems:"center",fontWeight:wonderBlocksTokens.font.weight.bold,fontSize:wonderBlocksTokens.font.body.size.medium}};
1829
1829
 
1830
- const GRADING_STATUSES={ungraded:"ungraded",correct:"correct",incorrect:"incorrect",invalid:"invalid"};const getNextState=(currentState,answerable)=>{switch(currentState){case "ACTIVE":return !answerable?"INACTIVE":currentState;case "INACTIVE":return answerable?"ACTIVE":currentState;case "INCORRECT":return answerable?"ACTIVE":"INACTIVE";default:return currentState}};class GradedGroup extends React__namespace.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group",widgetSubType:"null",widgetId:this.props.widgetId}});}_handleUserInput(_userInput,widgetsEmpty){this.setState({status:GRADING_STATUSES.ungraded,message:""});const answerable=!widgetsEmpty;const answerBarState=this.state.answerBarState;const nextState=getNextState(answerBarState,answerable);this.setState({answerBarState:nextState});}getPromptJSON(){const hint=this.hintRendererRef.current?.getPromptJSON()||{content:this.props.options.hint?.content||"",widgets:{}};return getPromptJSON$i(this.props.options.title,this.rendererRef.current?.getPromptJSON(),hint)}render(){const apiOptions=___default.default.extend({},ApiOptions.defaults,this.props.apiOptions,{onFocusChange:(newFocus,oldFocus)=>{if(oldFocus){this.props.onBlur(oldFocus);}if(newFocus){this.props.onFocus(newFocus);}}});let gradeStatus=null;let icon=null;if(this.state.status===GRADING_STATUSES.correct){icon=jsxRuntimeExports.jsx(InlineIcon,{...iconOk,style:{color:wonderBlocksTokens.semanticColor.core.foreground.success.default}});gradeStatus=this.context.strings.correct;}else if(this.state.status===GRADING_STATUSES.incorrect){icon=jsxRuntimeExports.jsx(InlineIcon,{...iconRemove,style:{color:wonderBlocksTokens.semanticColor.core.foreground.critical.default}});gradeStatus=this.context.strings.incorrect;}const mobileClass=this.props.inGradedGroupSet?aphrodite.css(styles$g.gradedGroupInSet):aphrodite.css(styles$g.gradedGroup);const classes=classNames__default.default({[mobileClass]:apiOptions.isMobile,"perseus-graded-group":true,"answer-correct":apiOptions.isMobile?false:this.state.status===GRADING_STATUSES.correct,"answer-incorrect":apiOptions.isMobile?false:this.state.status===GRADING_STATUSES.incorrect});const{answerBarState}=this.state;const isCorrect=answerBarState==="CORRECT";const readOnly=apiOptions.readOnly||apiOptions.isMobile&&isCorrect;const showSolutions=isCorrect?"all":"none";return jsxRuntimeExports.jsxs("div",{className:classes,children:[!!this.props.options.title&&jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$g.title),children:this.props.options.title}),jsxRuntimeExports.jsx(UserInputManager,{widgets:this.props.options.widgets,handleUserInput:(userInput,widgetsEmpty)=>this._handleUserInput(userInput,widgetsEmpty),problemNum:this.props.problemNum??0,children:({userInput,handleUserInput})=>jsxRuntimeExports.jsx(Renderer,{content:this.props.options.content,widgets:this.props.options.widgets,images:this.props.options.images,userInput:userInput,handleUserInput:handleUserInput,problemNum:this.props.problemNum??0,ref:this.rendererRef,keypadElement:this.props.keypadElement,apiOptions:{...apiOptions,readOnly},showSolutions:showSolutions,linterContext:this.props.linterContext,strings:this.context.strings})}),!apiOptions.isMobile&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[icon!=null&&jsxRuntimeExports.jsx("div",{className:"group-icon",children:icon}),gradeStatus&&jsxRuntimeExports.jsx("div",{className:aphrodite.css(a11y.srOnly),role:"alert","aria-label":gradeStatus,children:gradeStatus}),jsxRuntimeExports.jsx("div",{role:"status","aria-live":"polite",children:jsxRuntimeExports.jsx(Renderer,{content:this.state.message,strings:this.context.strings})}),this.props.options.answerArea&&apiOptions.renderExtras?.(this.props.options.answerArea,this.props.widgetId),jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",disabled:this.props.apiOptions.readOnly,onClick:this._checkAnswer,children:this.context.strings.check}),isCorrect&&this.props.onNextQuestion&&jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",disabled:this.props.apiOptions.readOnly,onClick:this.props.onNextQuestion,style:{marginInlineStart:5},children:this.context.strings.nextQuestion})]}),this.props.options.hint?.content&&(this.state.showHint?jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("button",{tabIndex:"0",className:aphrodite.css(styles$g.explanationTitle),onClick:()=>this.setState({showHint:false}),onKeyPress:e=>{e.preventDefault();this.setState({showHint:false});},children:this.context.strings.hideExplanation}),jsxRuntimeExports.jsx(UserInputManager,{widgets:this.props.options.hint.widgets,problemNum:this.props.problemNum??0,children:({userInput,handleUserInput,initializeUserInput})=>{const{content,widgets,images}=this.props.options.hint;return jsxRuntimeExports.jsx(Renderer,{content:content,widgets:widgets,images:images,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,ref:this.hintRendererRef,apiOptions:apiOptions,linterContext:this.props.linterContext,strings:this.context.strings,showSolutions:showSolutions})}})]}):jsxRuntimeExports.jsx("button",{tabIndex:"0",onClick:()=>this.setState({showHint:true}),onKeyPress:e=>{e.preventDefault();this.setState({showHint:true});},className:aphrodite.css(styles$g.showHintLink),children:this.context.strings.explain})),apiOptions.isMobile&&jsxRuntimeExports.jsx(GradedGroupAnswerBar,{apiOptions:apiOptions,answerBarState:answerBarState,onCheckAnswer:this._checkAnswer,onNextQuestion:this.props.onNextQuestion})]})}constructor(...args){super(...args),this.state={status:GRADING_STATUSES.ungraded,showHint:false,message:"",answerBarState:"INACTIVE"},this.rendererRef=React__namespace.createRef(),this.hintRendererRef=React__namespace.createRef(),this._checkAnswer=()=>{const score=this.rendererRef.current?.score()||{type:"invalid"};const{INVALID_MESSAGE_PREFIX,DEFAULT_INVALID_MESSAGE_1,DEFAULT_INVALID_MESSAGE_2}=this.context.strings;const status=score.type==="points"?score.total===score.earned?GRADING_STATUSES.correct:GRADING_STATUSES.incorrect:GRADING_STATUSES.invalid;const message=score.type==="points"?score.message||"":score.message?`${INVALID_MESSAGE_PREFIX} ${mapErrorToString(score.message,this.context.strings)}`:`${INVALID_MESSAGE_PREFIX} ${DEFAULT_INVALID_MESSAGE_1}${DEFAULT_INVALID_MESSAGE_2}`;this.setState({status:status,message:message,answerBarState:status==="correct"?"CORRECT":"INCORRECT"});this.props.trackInteraction({status:status});},this.getInputPaths=()=>{return this.rendererRef.current?.getInputPaths()||[]},this.focus=()=>{return !!this.rendererRef.current?.focus()},this.focusInputPath=path=>{this.rendererRef.current?.focusPath(path);},this.blurInputPath=path=>{this.rendererRef.current?.blurPath(path);};}}GradedGroup.contextType=PerseusI18nContext;const styles$g=aphrodite.StyleSheet.create({gradedGroupInSet:{marginInlineStart:0,paddingInlineStart:0},gradedGroup:{borderBlockStart:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"},showHintLink:{backgroundColor:"unset",fontSize:wonderBlocksTokens.font.body.size.small,padding:0,border:"none",marginBlockStart:20,color:wonderBlocksTokens.semanticColor.core.foreground.instructive.default,cursor:"pointer",display:"block",clear:"both"},explanationTitle:{backgroundColor:"unset",marginBlockStart:20,color:wonderBlocksTokens.semanticColor.core.foreground.instructive.default,marginBlockEnd:10,cursor:"pointer",fontSize:wonderBlocksTokens.font.body.size.small,padding:0,border:"none",display:"block",clear:"both"},title:{fontSize:wonderBlocksTokens.font.heading.size.small,color:wonderBlocksTokens.semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8}});const WrappedGradedGroup=withDependencies(GradedGroup);var GradedGroup$1 = {name:"graded-group",displayName:"Graded group (articles only)",widget:WrappedGradedGroup,hidden:false,tracking:"all",isLintable:true};
1830
+ const GRADING_STATUSES={ungraded:"ungraded",correct:"correct",incorrect:"incorrect",invalid:"invalid"};const getNextState=(currentState,answerable)=>{switch(currentState){case "ACTIVE":return !answerable?"INACTIVE":currentState;case "INACTIVE":return answerable?"ACTIVE":currentState;case "INCORRECT":return answerable?"ACTIVE":"INACTIVE";default:return currentState}};const GradedGroup=React.forwardRef(function GradedGroup(props,ref){const{strings}=usePerseusI18n();const dependencies=useDependencies();const[status,setStatus]=React.useState(GRADING_STATUSES.ungraded);const[showHint,setShowHint]=React.useState(false);const[message,setMessage]=React.useState("");const[answerBarState,setAnswerBarState]=React.useState("INACTIVE");const rendererRef=React.useRef(null);const hintRendererRef=React.useRef(null);wonderBlocksCore.useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group",widgetSubType:"null",widgetId:props.widgetId}});});React.useImperativeHandle(ref,()=>({getInputPaths(){return rendererRef.current?.getInputPaths()||[]},getPromptJSON(){const hint=hintRendererRef.current?.getPromptJSON()||{content:props.options.hint?.content||"",widgets:{}};return getPromptJSON$i(props.options.title,rendererRef.current?.getPromptJSON(),hint)},focus(){return !!rendererRef.current?.focus()},focusInputPath(path){rendererRef.current?.focusPath(path);},blurInputPath(path){rendererRef.current?.blurPath(path);}}));function handleUserInput(_userInput,widgetsEmpty){setStatus(GRADING_STATUSES.ungraded);setMessage("");const answerable=!widgetsEmpty;const nextState=getNextState(answerBarState,answerable);setAnswerBarState(nextState);}function checkAnswer(){const score=rendererRef.current?.score()||{type:"invalid"};const{INVALID_MESSAGE_PREFIX,DEFAULT_INVALID_MESSAGE_1,DEFAULT_INVALID_MESSAGE_2}=strings;const status=score.type==="points"?score.total===score.earned?GRADING_STATUSES.correct:GRADING_STATUSES.incorrect:GRADING_STATUSES.invalid;const message=score.type==="points"?score.message||"":score.message?`${INVALID_MESSAGE_PREFIX} ${mapErrorToString(score.message,strings)}`:`${INVALID_MESSAGE_PREFIX} ${DEFAULT_INVALID_MESSAGE_1}${DEFAULT_INVALID_MESSAGE_2}`;setStatus(status);setMessage(message);setAnswerBarState(status==="correct"?"CORRECT":"INCORRECT");props.trackInteraction({status:status});}const apiOptions=___default.default.extend({},ApiOptions.defaults,props.apiOptions,{onFocusChange:(newFocus,oldFocus)=>{if(oldFocus){props.onBlur(oldFocus);}if(newFocus){props.onFocus(newFocus);}}});let gradeStatus=null;let icon=null;if(status===GRADING_STATUSES.correct){icon=jsxRuntimeExports.jsx(InlineIcon,{...iconOk,style:{color:wonderBlocksTokens.semanticColor.core.foreground.success.default}});gradeStatus=strings.correct;}else if(status===GRADING_STATUSES.incorrect){icon=jsxRuntimeExports.jsx(InlineIcon,{...iconRemove,style:{color:wonderBlocksTokens.semanticColor.core.foreground.critical.default}});gradeStatus=strings.incorrect;}const mobileClass=props.inGradedGroupSet?aphrodite.css(styles$g.gradedGroupInSet):aphrodite.css(styles$g.gradedGroup);const classes=classNames__default.default({[mobileClass]:apiOptions.isMobile,"perseus-graded-group":true,"answer-correct":apiOptions.isMobile?false:status===GRADING_STATUSES.correct,"answer-incorrect":apiOptions.isMobile?false:status===GRADING_STATUSES.incorrect});const isCorrect=answerBarState==="CORRECT";const readOnly=apiOptions.readOnly||apiOptions.isMobile&&isCorrect;const showSolutions=isCorrect?"all":"none";return jsxRuntimeExports.jsxs("div",{className:classes,children:[!!props.options.title&&jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$g.title),children:props.options.title}),jsxRuntimeExports.jsx(UserInputManager,{widgets:props.options.widgets,handleUserInput:(userInput,widgetsEmpty)=>handleUserInput(userInput,widgetsEmpty),problemNum:props.problemNum??0,children:({userInput,handleUserInput})=>jsxRuntimeExports.jsx(Renderer,{content:props.options.content,widgets:props.options.widgets,images:props.options.images,userInput:userInput,handleUserInput:handleUserInput,problemNum:props.problemNum??0,ref:rendererRef,keypadElement:props.keypadElement,apiOptions:{...apiOptions,readOnly},showSolutions:showSolutions,linterContext:props.linterContext,strings:strings})}),!apiOptions.isMobile&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[icon!=null&&jsxRuntimeExports.jsx("div",{className:"group-icon",children:icon}),gradeStatus&&jsxRuntimeExports.jsx("div",{className:aphrodite.css(a11y.srOnly),role:"alert","aria-label":gradeStatus,children:gradeStatus}),jsxRuntimeExports.jsx("div",{role:"status","aria-live":"polite",children:jsxRuntimeExports.jsx(Renderer,{content:message,strings:strings})}),props.options.answerArea&&apiOptions.renderExtras?.(props.options.answerArea,props.widgetId),jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",disabled:props.apiOptions.readOnly,onClick:checkAnswer,children:strings.check}),isCorrect&&props.onNextQuestion&&jsxRuntimeExports.jsx(Button__default.default,{kind:"secondary",disabled:props.apiOptions.readOnly,onClick:props.onNextQuestion,style:{marginInlineStart:5},children:strings.nextQuestion})]}),props.options.hint?.content&&(showHint?jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("button",{tabIndex:"0",className:aphrodite.css(styles$g.explanationTitle),onClick:()=>setShowHint(false),onKeyPress:e=>{e.preventDefault();setShowHint(false);},children:strings.hideExplanation}),jsxRuntimeExports.jsx(UserInputManager,{widgets:props.options.hint.widgets,problemNum:props.problemNum??0,children:({userInput,handleUserInput,initializeUserInput})=>{const{content,widgets,images}=props.options.hint;return jsxRuntimeExports.jsx(Renderer,{content:content,widgets:widgets,images:images,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,ref:hintRendererRef,apiOptions:apiOptions,linterContext:props.linterContext,strings:strings,showSolutions:showSolutions})}})]}):jsxRuntimeExports.jsx("button",{tabIndex:"0",onClick:()=>setShowHint(true),onKeyPress:e=>{e.preventDefault();setShowHint(true);},className:aphrodite.css(styles$g.showHintLink),children:strings.explain})),apiOptions.isMobile&&jsxRuntimeExports.jsx(GradedGroupAnswerBar,{apiOptions:apiOptions,answerBarState:answerBarState,onCheckAnswer:checkAnswer,onNextQuestion:props.onNextQuestion})]})});const styles$g=aphrodite.StyleSheet.create({gradedGroupInSet:{marginInlineStart:0,paddingInlineStart:0},gradedGroup:{borderBlockStart:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"},showHintLink:{backgroundColor:"unset",fontSize:wonderBlocksTokens.font.body.size.small,padding:0,border:"none",marginBlockStart:20,color:wonderBlocksTokens.semanticColor.core.foreground.instructive.default,cursor:"pointer",display:"block",clear:"both"},explanationTitle:{backgroundColor:"unset",marginBlockStart:20,color:wonderBlocksTokens.semanticColor.core.foreground.instructive.default,marginBlockEnd:10,cursor:"pointer",fontSize:wonderBlocksTokens.font.body.size.small,padding:0,border:"none",display:"block",clear:"both"},title:{fontSize:wonderBlocksTokens.font.heading.size.small,color:wonderBlocksTokens.semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8}});var GradedGroup$1 = {name:"graded-group",displayName:"Graded group (articles only)",widget:GradedGroup,hidden:false,tracking:"all",isLintable:true};
1831
1831
 
1832
1832
  const getPromptJSON$h=(widgetData,activeGroupJSON)=>{return {type:"graded-group-set",options:{groupCount:widgetData.options.gradedGroups.length,currentGroup:activeGroupJSON}}};
1833
1833
 
1834
- class Indicators extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames__default.default(aphrodite.css(styles$f.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>{const isCurrent=i===this.props.currentGroup;return jsxRuntimeExports.jsx("li",{className:aphrodite.css(styles$f.indicator),children:jsxRuntimeExports.jsx(Clickable__default.default,{role:"button","aria-label":title,"aria-current":isCurrent,style:styles$f.indicatorButton,onClick:()=>this.props.onChangeCurrentGroup(i),onKeyDown:e=>this.handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:[styles$f.indicatorDot,isCurrent&&styles$f.indicatorDotActive,(hovered||focused||pressed)&&styles$f.indicatorDotFocused]})})},i)})})}constructor(...args){super(...args),this.handleKeyDown=(e,i)=>{if(e.key==="Enter"||e.key===" "){this.props.onChangeCurrentGroup(i);}};}}Indicators.contextType=PerseusI18nContext;class GradedGroupSet extends React__namespace.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group-set",widgetSubType:"null",widgetId:this.props.widgetId}});}getPromptJSON(){const activeGroupPromptJSON=this._childGroup.getPromptJSON();return getPromptJSON$h(this.props,activeGroupPromptJSON)}render(){const{gradedGroups}=this.props.options;const{JIPT}=getDependencies();if(JIPT.useJIPT&&gradedGroups.length>1){return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$f.container),children:gradedGroups.map((gradedGroup,i)=>{return jsxRuntimeExports.jsx(GradedGroup,{...this.props,problemNum:(this.props.problemNum??0)+i,options:gradedGroup,inGradedGroupSet:false,linterContext:this.props.linterContext},i)})})}const currentGroup=gradedGroups[this.state.currentGroup];if(!currentGroup){return jsxRuntimeExports.jsx("span",{children:"No current group..."})}const numGroups=gradedGroups.length;const handleNextQuestion=this.state.currentGroup<numGroups-1?this.handleNextQuestion:undefined;return jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$f.container),children:[jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$f.top),children:[jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$f.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$f.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroup:this.state.currentGroup,gradedGroups:gradedGroups,onChangeCurrentGroup:currentGroup=>this.setState({currentGroup})})]}),jsxRuntimeExports.jsx(GradedGroup,{ref:comp=>this._childGroup=comp,...this.props,problemNum:(this.props.problemNum??0)+this.state.currentGroup,options:{...currentGroup,title:""},inGradedGroupSet:true,onNextQuestion:handleNextQuestion,linterContext:this.props.linterContext},this.state.currentGroup)]})}constructor(...args){super(...args),this.state={currentGroup:0},this.getInputPaths=()=>{return this._childGroup.getInputPaths()},this.focus=()=>{return this._childGroup.focus()},this.focusInputPath=path=>{this._childGroup.focusInputPath(path);},this.blurInputPath=path=>{this._childGroup.blurInputPath(path);},this.handleNextQuestion=()=>{const{currentGroup}=this.state;const numGroups=this.props.options.gradedGroups.length;if(currentGroup<numGroups-1){this.setState({currentGroup:currentGroup+1});}};}}const WrappedGradedGroupSet=withDependencies(GradedGroupSet);var GradedGroupSet$1 = {name:"graded-group-set",displayName:"Graded group set (articles only)",widget:WrappedGradedGroupSet,hidden:false,tracking:"all",isLintable:true};const styles$f=aphrodite.StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:wonderBlocksTokens.font.heading.size.small,color:wonderBlocksTokens.semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyleType:"none",margin:"unset",paddingInlineStart:"unset",flexWrap:"wrap"},indicator:{width:24,height:24},indicatorButton:{width:"100%",height:"100%",display:"flex",flexWrap:"wrap",placeContent:"center",cursor:"pointer",":focus":{outline:"none"}},indicatorDot:{boxSizing:"content-box",width:10,height:10,borderRadius:wonderBlocksTokens.border.radius.radius_full,borderWidth:wonderBlocksTokens.border.width.medium,borderColor:wonderBlocksTokens.semanticColor.core.border.instructive.default,borderStyle:"solid"},indicatorDotFocused:{outlineColor:wonderBlocksTokens.semanticColor.focus.outer,outlineStyle:"solid",outlineWidth:wonderBlocksTokens.border.width.medium,outlineOffset:wonderBlocksTokens.border.width.medium,boxShadow:`0 0 0 ${wonderBlocksTokens.border.width.medium} ${wonderBlocksTokens.semanticColor.focus.inner}`},indicatorDotActive:{backgroundColor:wonderBlocksTokens.semanticColor.core.foreground.instructive.default,borderColor:wonderBlocksTokens.semanticColor.core.transparent},container:{borderBlockStart:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"}});
1834
+ function Indicators(props){function handleKeyDown(e,i){if(e.key==="Enter"||e.key===" "){props.onChangeGroupIndex(i);}}return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames__default.default(aphrodite.css(styles$f.indicatorContainer),"indicatorContainer"),children:props.gradedGroups.map(({title},i)=>{const isCurrent=i===props.currentGroupIndex;return jsxRuntimeExports.jsx("li",{className:aphrodite.css(styles$f.indicator),children:jsxRuntimeExports.jsx(Clickable__default.default,{role:"button","aria-label":title,"aria-current":isCurrent,style:styles$f.indicatorButton,onClick:()=>props.onChangeGroupIndex(i),onKeyDown:e=>handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:[styles$f.indicatorDot,isCurrent&&styles$f.indicatorDotActive,(hovered||focused||pressed)&&styles$f.indicatorDotFocused]})})},i)})})}const GradedGroupSet=React.forwardRef(function GradedGroupSet(props,ref){const dependencies=useDependencies();const childGroup=React.useRef(null);const[currentGroupIndex,setCurrentGroupIndex]=React.useState(0);wonderBlocksCore.useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group-set",widgetSubType:"null",widgetId:props.widgetId}});});React.useImperativeHandle(ref,()=>({getInputPaths(){return childGroup.current?.getInputPaths?.()??[]},getPromptJSON(){invariant__default.default(childGroup.current,"GradedGroupSet must have at least one group");return getPromptJSON$h(props,childGroup.current.getPromptJSON())},focus(){return childGroup.current?.focus()??false},focusInputPath(path){childGroup.current?.focusInputPath(path);},blurInputPath(path){childGroup.current?.blurInputPath(path);}}));const{gradedGroups}=props.options;const{JIPT}=getDependencies();if(JIPT.useJIPT&&gradedGroups.length>1){return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$f.container),children:gradedGroups.map((gradedGroup,i)=>{return jsxRuntimeExports.jsx(GradedGroup,{...props,problemNum:(props.problemNum??0)+i,options:gradedGroup,inGradedGroupSet:false,linterContext:props.linterContext},i)})})}const currentGroup=gradedGroups[currentGroupIndex];if(currentGroup==null){return jsxRuntimeExports.jsx("span",{children:"No current group..."})}const numGroups=gradedGroups.length;const atEnd=currentGroupIndex>=numGroups-1;const handleNextQuestion=atEnd?undefined:()=>setCurrentGroupIndex(currentGroupIndex+1);return jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$f.container),children:[jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$f.top),children:[jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$f.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$f.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroupIndex:currentGroupIndex,gradedGroups:gradedGroups,onChangeGroupIndex:setCurrentGroupIndex})]}),jsxRuntimeExports.jsx(GradedGroup,{ref:childGroup,...props,problemNum:(props.problemNum??0)+currentGroupIndex,options:{...currentGroup,title:""},inGradedGroupSet:true,onNextQuestion:handleNextQuestion,linterContext:props.linterContext},currentGroupIndex)]})});var GradedGroupSet$1 = {name:"graded-group-set",displayName:"Graded group set (articles only)",widget:GradedGroupSet,hidden:false,tracking:"all",isLintable:true};const styles$f=aphrodite.StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:wonderBlocksTokens.font.heading.size.small,color:wonderBlocksTokens.semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyleType:"none",margin:"unset",paddingInlineStart:"unset",flexWrap:"wrap"},indicator:{width:24,height:24},indicatorButton:{width:"100%",height:"100%",display:"flex",flexWrap:"wrap",placeContent:"center",cursor:"pointer",":focus":{outline:"none"}},indicatorDot:{boxSizing:"content-box",width:10,height:10,borderRadius:wonderBlocksTokens.border.radius.radius_full,borderWidth:wonderBlocksTokens.border.width.medium,borderColor:wonderBlocksTokens.semanticColor.core.border.instructive.default,borderStyle:"solid"},indicatorDotFocused:{outlineColor:wonderBlocksTokens.semanticColor.focus.outer,outlineStyle:"solid",outlineWidth:wonderBlocksTokens.border.width.medium,outlineOffset:wonderBlocksTokens.border.width.medium,boxShadow:`0 0 0 ${wonderBlocksTokens.border.width.medium} ${wonderBlocksTokens.semanticColor.focus.inner}`},indicatorDotActive:{backgroundColor:wonderBlocksTokens.semanticColor.core.foreground.instructive.default,borderColor:wonderBlocksTokens.semanticColor.core.transparent},container:{borderBlockStart:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"}});
1835
1835
 
1836
- class ButtonGroup extends React__namespace.Component{componentWillUnmount(){this.container=null;}focus(){if(this.container){this.container.focus();return true}}toggleSelect(newValue){const value=this.props.value;if(this.props.allowEmpty){this.props.onChange(value!==newValue?newValue:null);}else {this.props.onChange(newValue);}}render(){const value=this.props.value;const buttons=this.props.buttons.map((button,i)=>{return jsxRuntimeExports.jsx("button",{title:button.title,type:"button",disabled:this.props.disabled,className:aphrodite.css(buttonGroupStyles.buttonStyle,button.value===value&&buttonGroupStyles.selectedStyle,button.value===value&&this.props.selectedButtonStyle,this.props.disabled&&buttonGroupStyles.disabledStyle),onClick:()=>this.toggleSelect(button.value),children:button.content||""+button.value},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:node=>this.container=node,children:buttons})}}ButtonGroup.defaultProps={value:null,allowEmpty:true};const buttonGroupStyles=aphrodite.StyleSheet.create({buttonStyle:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.default,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderInlineStart:"0",color:wonderBlocksTokens.semanticColor.core.foreground.neutral.strong,cursor:"pointer",margin:"0",paddingBlock:"5px",paddingInline:"10px",position:"relative",":first-child":{borderInlineStart:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderStartStartRadius:wonderBlocksTokens.border.radius.radius_040,borderEndStartRadius:wonderBlocksTokens.border.radius.radius_040},":last-child":{borderInlineEnd:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderStartEndRadius:wonderBlocksTokens.border.radius.radius_040,borderEndEndRadius:wonderBlocksTokens.border.radius.radius_040},":hover":{backgroundColor:wonderBlocksTokens.semanticColor.core.background.instructive.subtle},":focus":{zIndex:2}},selectedStyle:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.instructive.subtle,boxShadow:`inset 0 calc(-1 * ${wonderBlocksTokens.border.width.thick}) 0 ${wonderBlocksTokens.semanticColor.core.border.instructive.default}`},disabledStyle:{cursor:"not-allowed",backgroundColor:wonderBlocksTokens.semanticColor.core.background.disabled.default,color:wonderBlocksTokens.semanticColor.core.foreground.disabled.strong,":hover":{backgroundColor:wonderBlocksTokens.semanticColor.core.background.disabled.default}}});
1836
+ class ButtonGroup extends React__namespace.Component{componentWillUnmount(){this.container=null;}focus(){if(this.container){this.container.focus();return true}}toggleSelect(newValue){if(this.props.value!==newValue){this.props.onChange(newValue);}}render(){const value=this.props.value;const buttons=this.props.buttons.map((button,i)=>{return jsxRuntimeExports.jsx("button",{title:button.title,type:"button",disabled:this.props.disabled,className:aphrodite.css(buttonGroupStyles.buttonStyle,button.value===value&&buttonGroupStyles.selectedStyle,button.value===value&&this.props.selectedButtonStyle,this.props.disabled&&buttonGroupStyles.disabledStyle),onClick:()=>this.toggleSelect(button.value),children:button.content||""+button.value},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:node=>this.container=node,children:buttons})}}ButtonGroup.defaultProps={value:null};const buttonGroupStyles=aphrodite.StyleSheet.create({buttonStyle:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.default,border:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderInlineStart:"0",color:wonderBlocksTokens.semanticColor.core.foreground.neutral.strong,cursor:"pointer",margin:"0",paddingBlock:"5px",paddingInline:"10px",position:"relative",":first-child":{borderInlineStart:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderStartStartRadius:wonderBlocksTokens.border.radius.radius_040,borderEndStartRadius:wonderBlocksTokens.border.radius.radius_040},":last-child":{borderInlineEnd:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderStartEndRadius:wonderBlocksTokens.border.radius.radius_040,borderEndEndRadius:wonderBlocksTokens.border.radius.radius_040},":hover":{backgroundColor:wonderBlocksTokens.semanticColor.core.background.instructive.subtle},":focus":{zIndex:2}},selectedStyle:{backgroundColor:wonderBlocksTokens.semanticColor.core.background.instructive.subtle,boxShadow:`inset 0 calc(-1 * ${wonderBlocksTokens.border.width.thick}) 0 ${wonderBlocksTokens.semanticColor.core.border.instructive.default}`},disabledStyle:{cursor:"not-allowed",backgroundColor:wonderBlocksTokens.semanticColor.core.background.disabled.default,color:wonderBlocksTokens.semanticColor.core.foreground.disabled.strong,":hover":{backgroundColor:wonderBlocksTokens.semanticColor.core.background.disabled.default}}});
1837
1837
 
1838
1838
  const getPromptJSON$g=widgetData=>{const{userInput}=widgetData;const{type,coords}=userInput;const input={type,coords};if(userInput.type==="logarithm"||userInput.type==="exponential"){input["asymptote"]=userInput.asymptote;}return {type:"grapher",options:{availableTypes:widgetData.options.availableTypes,range:widgetData.options.graph.range,labels:widgetData.options.graph.labels,tickStep:widgetData.options.graph.step,gridStep:widgetData.options.graph.gridStep,snapStep:widgetData.options.graph.snapStep,backgroundImageUrl:widgetData.options.graph.backgroundImage.url},userInput:input}};
1839
1839
 
@@ -2072,7 +2072,7 @@ const paths={linear:"M8 42L42 8",quadratic:"M8 8Q25 72 42 8",sinusoid:"M8 25C11.
2072
2072
 
2073
2073
  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);return {value:type,title:capitalized,content:jsxRuntimeExports.jsx(FunctionTypeIcon,{type:type,label:capitalized})}};
2074
2074
 
2075
- const MovablePoint$2=Graphie.MovablePoint;const MovableLine$1=Graphie.MovableLine;function isFlipped(newCoord,oldCoord,line){const CCW=(a,b,c)=>{return (b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1])};return CCW(line[0],line[1],oldCoord)>0!==CCW(line[0],line[1],newCoord)>0}const typeSelectorStyle={padding:"5px 5px"};class FunctionGrapher extends React__namespace.Component{render(){const pointForCoord=(coord,i)=>{return jsxRuntimeExports.jsx(MovablePoint$2,{coord:coord,static:this.props.static,constraints:[Interactive2.MovablePoint.constraints.bound(),Interactive2.MovablePoint.constraints.snap(),coord=>{const isFunction=this._coords().every((otherCoord,j)=>{return i===j||!otherCoord||!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,allowZoom:false,width:imageDescription.width,height:imageDescription.height,scale:scale});}return jsxRuntimeExports.jsx("div",{className:"perseus-widget "+"perseus-widget-grapher",style:{width:box[0],height:box[1],boxSizing:"initial"},children:jsxRuntimeExports.jsxs("div",{className:"graphie-container blank-background",style:{width:box[0],height:box[1]},children:[image,jsxRuntimeExports.jsxs(Graphie,{...this.props.graph,children:[this.props.model&&this.renderPlot(),this.props.model&&this.renderAsymptote(),this.props.model&&points]})]})})}constructor(...args){super(...args),this._coords=()=>{const props=this.props;const graph=props.graph;const defaultModelCoords=props.model&&maybePointsFromNormalized(props.model.defaultCoords,graph.range,graph.step,graph.snapStep);return props.coords||defaultModelCoords||null},this._asymptote=()=>{return this.props.asymptote},this.renderPlot=()=>{const model=this.props.model;const xRange=this.props.graph.range[0];const style={stroke:wonderBlocksTokens.tokenValue(this.props.static?wonderBlocksTokens.semanticColor.core.foreground.disabled.strong:wonderBlocksTokens.semanticColor.core.foreground.instructive.default),...this.props.isMobile?{"stroke-width":3}:{}};const coeffs=model.getCoefficients(this._coords(),this._asymptote());if(!coeffs){return}const functionProps=model.getPropsForCoeffs(coeffs,xRange);const Movable=movableTypeToComponent[model.movable];return 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={"stroke-dasharray":"- "};return showAsymptote&&jsxRuntimeExports.jsx(MovableLine$1,{static:this.props.static,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$2,{coord:coord,static:true,draw:null,extendLine:true,showHairlines:this.props.showHairlines,hideHairlines:this.props.hideHairlines,showTooltips:this.props.showTooltips,isMobile:this.props.isMobile},`asymptoteCoord-${i}`))})};}}FunctionGrapher.defaultProps={graph:{range:[[-10,10],[-10,10]],step:[1,1]},coords:null,asymptote:null,isMobile:false};class Grapher extends React__namespace.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"grapher",widgetSubType:"null",widgetId:this.props.widgetId}});}_getGridConfig(options){return options.step.map((step,i)=>{return Util.gridDimensionConfig(step,options.range[i],options.box[i],options.gridStep[i])})}_calculateMobileTickStep(gridStep,step,ranges){const tickStep=Util.constrainedTickStepsFromTickSteps(step,ranges);tickStep[0]=tickStep[0]/gridStep[0];tickStep[1]=tickStep[1]/gridStep[1];return tickStep}getPromptJSON(){return getPromptJSON$g(this.props)}getSerializedState(){const{userInput,options,...rest}=this.props;const{correct,...optionsRest}=options;return {...optionsRest,...rest,plot:this.props.userInput}}getAvailableTypes(){const{correct,availableTypes}=this.props.options;if(this.props.static){invariant__default.default(correct,"static widgets must have a correct answer");return [correct.type]}return availableTypes}renderLegacyGrapher(){const availableTypes=this.getAvailableTypes();const type=this.props.userInput.type;const coords=this.props.userInput.coords;const asymptote="asymptote"in this.props.userInput?this.props.userInput.asymptote:undefined;const typeSelector=jsxRuntimeExports.jsx("div",{style:typeSelectorStyle,children:jsxRuntimeExports.jsx(ButtonGroup,{value:type,allowEmpty:true,buttons:availableTypes.map(typeToButton),onChange:this.handleActiveTypeChange})});const box=getInteractiveBoxFromSizeClass(this.props.containerSizeClass);const{graph}=this.props.options;const options={...graph,...getGridAndSnapSteps(graph,box[0]),gridConfig:this._getGridConfig({...graph,box:box,...getGridAndSnapSteps(graph,box[0])})};const grapherProps={graph:{box:box,range:options.range,step:options.step,snapStep:options.snapStep,backgroundImage:options.backgroundImage,options:options,setup:this._setupGraphie},onChange:this.handlePlotChanges,model:type&&perseusCore.GrapherUtil.functionForType(type),coords:coords,asymptote:asymptote,static:this.props.static,isMobile:this.props.apiOptions.isMobile,showTooltips:graph.showTooltips,showHairlines:this.showHairlines,hideHairlines:this.hideHairlines};return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(FunctionGrapher,{...grapherProps}),availableTypes.length>1&&typeSelector]})}render(){const{options,...universalProps}=this.props;const interactiveGraphOptions=perseusCore.convertGrapherOptionsToInteractiveGraph(options);if(interactiveGraphOptions==null){return this.renderLegacyGrapher()}const interactiveGraphUserInput=perseusCore.convertGrapherUserInputToInteractiveGraph(this.props.userInput);return jsxRuntimeExports.jsx(InteractiveGraph$1.widget,{...universalProps,options:interactiveGraphOptions,userInput:interactiveGraphUserInput,handleUserInput:interactiveGraphUserInput=>this.props.handleUserInput(perseusCore.convertInteractiveGraphUserInputToGrapher(interactiveGraphUserInput))})}constructor(...args){super(...args),this.handlePlotChanges=newPlot=>{const plot={...this.props.userInput,...newPlot};this.props.handleUserInput(plot);this.props.trackInteraction();},this.handleActiveTypeChange=newType=>{const{graph}=this.props.options;const plot={...this.props.userInput,...defaultPlotProps(newType,graph)};this.props.handleUserInput(plot);},this._setupGraphie=(graphie,options)=>{const isMobile=this.props.apiOptions.isMobile;if(options.markings==="graph"){graphie.graphInit({range:options.range,scale:options.gridConfig.map(e=>e.scale),axisArrows:"<->",labelFormat:function(s){return "\\small{"+s+"}"},gridStep:options.gridStep,snapStep:options.snapStep,tickStep:isMobile?this._calculateMobileTickStep(options.gridStep,options.step,options.range):options.gridConfig.map(e=>e.tickStep),labelStep:1,unityLabels:options.gridConfig.map(e=>e.unityLabel),isMobile:isMobile});graphie.label([0,options.range[1][1]],options.labels[1],isMobile?"below right":"above");graphie.label([options.range[0][1],0],options.labels[0],isMobile?"above left":"right");}else if(options.markings==="grid"){graphie.graphInit({range:options.range,scale:options.gridConfig.map(e=>e.scale),gridStep:options.gridStep,axes:false,ticks:false,labels:false,isMobile:isMobile});}else if(options.markings==="none"){graphie.init({range:options.range,scale:options.gridConfig.map(e=>e.scale)});}const hairlineStyle={normalStyle:{strokeWidth:1}};this.horizHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.horizHairline.attr({stroke:wonderBlocksTokens.tokenValue(wonderBlocksTokens.semanticColor.core.border.instructive.default)});this.horizHairline.hide();this.vertHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.vertHairline.attr({stroke:wonderBlocksTokens.tokenValue(wonderBlocksTokens.semanticColor.core.border.instructive.default)});this.vertHairline.hide();},this.showHairlines=point=>{const{graph}=this.props.options;this.horizHairline.moveTo([graph.range[0][0],point[1]],[graph.range[0][1],point[1]]);this.horizHairline.show();this.vertHairline.moveTo([point[0],graph.range[1][0]],[point[0],graph.range[1][1]]);this.vertHairline.show();},this.hideHairlines=()=>{this.horizHairline.hide();this.vertHairline.hide();};}}function getUserInputFromSerializedState$a(serializedState){return serializedState.plot}function getStartUserInput$a(options){if(options.availableTypes.length===1){const graph=options.graph;const type=chooseType(options.availableTypes);if(type){return defaultPlotProps(type,graph)}}return DEFAULT_GRAPHER_PROPS.plot}function getCorrectUserInput$4(options){invariant__default.default(options.correct,"getCorrectUserInput should only be called for static widgets");return options.correct}const WrappedGrapher=withDependencies(Grapher);var Grapher$1 = {name:"grapher",displayName:"Grapher",hidden:true,widget:WrappedGrapher,getUserInputFromSerializedState: getUserInputFromSerializedState$a,getStartUserInput: getStartUserInput$a,getCorrectUserInput: getCorrectUserInput$4};
2075
+ const MovablePoint$2=Graphie.MovablePoint;const MovableLine$1=Graphie.MovableLine;function isFlipped(newCoord,oldCoord,line){const CCW=(a,b,c)=>{return (b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1])};return CCW(line[0],line[1],oldCoord)>0!==CCW(line[0],line[1],newCoord)>0}const typeSelectorStyle={padding:"5px 5px"};class FunctionGrapher extends React__namespace.Component{render(){const pointForCoord=(coord,i)=>{return jsxRuntimeExports.jsx(MovablePoint$2,{coord:coord,static:this.props.static,constraints:[Interactive2.MovablePoint.constraints.bound(),Interactive2.MovablePoint.constraints.snap(),coord=>{const isFunction=this._coords().every((otherCoord,j)=>{return i===j||!otherCoord||!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,allowZoom:false,width:imageDescription.width,height:imageDescription.height,scale:scale});}return jsxRuntimeExports.jsx("div",{className:"perseus-widget "+"perseus-widget-grapher",style:{width:box[0],height:box[1],boxSizing:"initial"},children:jsxRuntimeExports.jsxs("div",{className:"graphie-container blank-background",style:{width:box[0],height:box[1]},children:[image,jsxRuntimeExports.jsxs(Graphie,{...this.props.graph,children:[this.props.model&&this.renderPlot(),this.props.model&&this.renderAsymptote(),this.props.model&&points]})]})})}constructor(...args){super(...args),this._coords=()=>{const props=this.props;const graph=props.graph;const defaultModelCoords=props.model&&maybePointsFromNormalized(props.model.defaultCoords,graph.range,graph.step,graph.snapStep);return props.coords||defaultModelCoords||null},this._asymptote=()=>{return this.props.asymptote},this.renderPlot=()=>{const model=this.props.model;const xRange=this.props.graph.range[0];const style={stroke:wonderBlocksTokens.tokenValue(this.props.static?wonderBlocksTokens.semanticColor.core.foreground.disabled.strong:wonderBlocksTokens.semanticColor.core.foreground.instructive.default),...this.props.isMobile?{"stroke-width":3}:{}};const coeffs=model.getCoefficients(this._coords(),this._asymptote());if(!coeffs){return}const functionProps=model.getPropsForCoeffs(coeffs,xRange);const Movable=movableTypeToComponent[model.movable];return 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={"stroke-dasharray":"- "};return showAsymptote&&jsxRuntimeExports.jsx(MovableLine$1,{static:this.props.static,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$2,{coord:coord,static:true,draw:null,extendLine:true,showHairlines:this.props.showHairlines,hideHairlines:this.props.hideHairlines,showTooltips:this.props.showTooltips,isMobile:this.props.isMobile},`asymptoteCoord-${i}`))})};}}FunctionGrapher.defaultProps={graph:{range:[[-10,10],[-10,10]],step:[1,1]},coords:null,asymptote:null,isMobile:false};class Grapher extends React__namespace.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"grapher",widgetSubType:"null",widgetId:this.props.widgetId}});}_getGridConfig(options){return options.step.map((step,i)=>{return Util.gridDimensionConfig(step,options.range[i],options.box[i],options.gridStep[i])})}_calculateMobileTickStep(gridStep,step,ranges){const tickStep=Util.constrainedTickStepsFromTickSteps(step,ranges);tickStep[0]=tickStep[0]/gridStep[0];tickStep[1]=tickStep[1]/gridStep[1];return tickStep}getPromptJSON(){return getPromptJSON$g(this.props)}getSerializedState(){const{userInput,options,...rest}=this.props;const{correct,...optionsRest}=options;return {...optionsRest,...rest,plot:this.props.userInput}}getAvailableTypes(){const{correct,availableTypes}=this.props.options;if(this.props.static){invariant__default.default(correct,"static widgets must have a correct answer");return [correct.type]}return availableTypes}renderLegacyGrapher(){const availableTypes=this.getAvailableTypes();const type=this.props.userInput.type;const coords=this.props.userInput.coords;const asymptote="asymptote"in this.props.userInput?this.props.userInput.asymptote:undefined;const typeSelector=jsxRuntimeExports.jsx("div",{style:typeSelectorStyle,children:jsxRuntimeExports.jsx(ButtonGroup,{value:type,buttons:availableTypes.map(typeToButton),onChange:this.handleActiveTypeChange})});const box=getInteractiveBoxFromSizeClass(this.props.containerSizeClass);const{graph}=this.props.options;const options={...graph,...getGridAndSnapSteps(graph,box[0]),gridConfig:this._getGridConfig({...graph,box:box,...getGridAndSnapSteps(graph,box[0])})};const grapherProps={graph:{box:box,range:options.range,step:options.step,snapStep:options.snapStep,backgroundImage:options.backgroundImage,options:options,setup:this._setupGraphie},onChange:this.handlePlotChanges,model:type&&perseusCore.GrapherUtil.functionForType(type),coords:coords,asymptote:asymptote,static:this.props.static,isMobile:this.props.apiOptions.isMobile,showTooltips:graph.showTooltips,showHairlines:this.showHairlines,hideHairlines:this.hideHairlines};return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(FunctionGrapher,{...grapherProps}),availableTypes.length>1&&typeSelector]})}render(){const{options,...universalProps}=this.props;const interactiveGraphOptions=perseusCore.convertGrapherOptionsToInteractiveGraph(options);if(interactiveGraphOptions==null){return this.renderLegacyGrapher()}const interactiveGraphUserInput=perseusCore.convertGrapherUserInputToInteractiveGraph(this.props.userInput);return jsxRuntimeExports.jsx(InteractiveGraph$1.widget,{...universalProps,options:interactiveGraphOptions,userInput:interactiveGraphUserInput,handleUserInput:interactiveGraphUserInput=>this.props.handleUserInput(perseusCore.convertInteractiveGraphUserInputToGrapher(interactiveGraphUserInput))})}constructor(...args){super(...args),this.handlePlotChanges=newPlot=>{const plot={...this.props.userInput,...newPlot};this.props.handleUserInput(plot);this.props.trackInteraction();},this.handleActiveTypeChange=newType=>{const{graph}=this.props.options;const plot={...this.props.userInput,...defaultPlotProps(newType,graph)};this.props.handleUserInput(plot);},this._setupGraphie=(graphie,options)=>{const isMobile=this.props.apiOptions.isMobile;if(options.markings==="graph"){graphie.graphInit({range:options.range,scale:options.gridConfig.map(e=>e.scale),axisArrows:"<->",labelFormat:function(s){return "\\small{"+s+"}"},gridStep:options.gridStep,snapStep:options.snapStep,tickStep:isMobile?this._calculateMobileTickStep(options.gridStep,options.step,options.range):options.gridConfig.map(e=>e.tickStep),labelStep:1,unityLabels:options.gridConfig.map(e=>e.unityLabel),isMobile:isMobile});graphie.label([0,options.range[1][1]],options.labels[1],isMobile?"below right":"above");graphie.label([options.range[0][1],0],options.labels[0],isMobile?"above left":"right");}else if(options.markings==="grid"){graphie.graphInit({range:options.range,scale:options.gridConfig.map(e=>e.scale),gridStep:options.gridStep,axes:false,ticks:false,labels:false,isMobile:isMobile});}else if(options.markings==="none"){graphie.init({range:options.range,scale:options.gridConfig.map(e=>e.scale)});}const hairlineStyle={normalStyle:{strokeWidth:1}};this.horizHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.horizHairline.attr({stroke:wonderBlocksTokens.tokenValue(wonderBlocksTokens.semanticColor.core.border.instructive.default)});this.horizHairline.hide();this.vertHairline=new WrappedLine(graphie,[0,0],[0,0],hairlineStyle);this.vertHairline.attr({stroke:wonderBlocksTokens.tokenValue(wonderBlocksTokens.semanticColor.core.border.instructive.default)});this.vertHairline.hide();},this.showHairlines=point=>{const{graph}=this.props.options;this.horizHairline.moveTo([graph.range[0][0],point[1]],[graph.range[0][1],point[1]]);this.horizHairline.show();this.vertHairline.moveTo([point[0],graph.range[1][0]],[point[0],graph.range[1][1]]);this.vertHairline.show();},this.hideHairlines=()=>{this.horizHairline.hide();this.vertHairline.hide();};}}function getUserInputFromSerializedState$a(serializedState){return serializedState.plot}function getStartUserInput$a(options){if(options.availableTypes.length===1){const graph=options.graph;const type=chooseType(options.availableTypes);if(type){return defaultPlotProps(type,graph)}}return DEFAULT_GRAPHER_PROPS.plot}function getCorrectUserInput$4(options){invariant__default.default(options.correct,"getCorrectUserInput should only be called for static widgets");return options.correct}const WrappedGrapher=withDependencies(Grapher);var Grapher$1 = {name:"grapher",displayName:"Grapher",hidden:true,widget:WrappedGrapher,getUserInputFromSerializedState: getUserInputFromSerializedState$a,getStartUserInput: getStartUserInput$a,getCorrectUserInput: getCorrectUserInput$4};
2076
2076
 
2077
2077
  const getPromptJSON$e=rendererJSON=>{if(!rendererJSON){return {type:"group",content:"",widgets:{}}}return {...rendererJSON,type:"group"}};
2078
2078
 
@@ -2172,7 +2172,7 @@ var extraWidgets = [Blank,CSProgram$1,Categorizer$1,Definition$1,DeprecatedStand
2172
2172
 
2173
2173
  const init=function(){registerWidgets(basicWidgets);registerWidgets(extraWidgets);replaceDeprecatedWidgets();};
2174
2174
 
2175
- const libName="@khanacademy/perseus";const libVersion="86.0.1";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
2175
+ const libName="@khanacademy/perseus";const libVersion="87.0.0";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
2176
2176
 
2177
2177
  const apiVersion={major:12,minor:0};
2178
2178