@khanacademy/perseus 82.0.0 → 82.0.1
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
|
@@ -1499,7 +1499,7 @@ const Log={log:(message,extra)=>{getDependencies().Log.log(message,extra);},erro
|
|
|
1499
1499
|
|
|
1500
1500
|
const svgLocalLabelsRegex=/^file\+graphie:/;const hashRegex=/\/([^/]+)$/;function getLocale(){const{JIPT,kaLocale}=getDependencies();return JIPT.useJIPT?"en-pt":kaLocale}function shouldUseLocalizedData(){return getLocale()!=="en"}const splitHashRegex=/\/(?=[^/]+$)/;function getLocalizedDataUrl(url){if(svgLocalLabelsRegex.test(url)){return Util.getDataUrl(url)}const[base,hash]=Util.getBaseUrl(url).split(splitHashRegex);return `${base}/${getLocale()}/${hash}-data.json`}function getUrlHash(url){const match=url.match(hashRegex);if(match==null){throw new perseusCore.PerseusError("not a valid URL",perseusCore.Errors.InvalidInput)}return match&&match[1]}function parseDataFromJSONP(graphieHash,graphieJSONP,errorCallback){const match=graphieJSONP.match(new RegExp(`^(?:svgData|svgOtherData)${graphieHash}\\((.+)\\);$`));const jsonToParse=match?match[1]:graphieJSONP;try{return JSON.parse(jsonToParse)}catch(error){errorCallback(error);return null}}let labelDataCache={};function loadGraphie(url,onDataLoaded){const hash=getUrlHash(url);const entry=labelDataCache[hash];if(entry!=null){if(entry.loaded){const{data,localized}=entry;onDataLoaded(data,localized);}else {entry.dataCallbacks.push(onDataLoaded);}}else {const cacheData={loaded:false,dataCallbacks:[onDataLoaded],localized:shouldUseLocalizedData()};labelDataCache[hash]=cacheData;const retrieveData=async(url,errorCallback)=>{const response=await fetch(url);if(!response?.ok){errorCallback();return}const jsonp=await response.text();const data=parseDataFromJSONP(hash,jsonp,error=>{Log.error("Failed to parse JSONP for svg-image",perseusCore.Errors.Service,{cause:error,loggedMetadata:{dataUrl:Util.getDataUrl(url),jsonp}});});if(!data){return}const newCacheEntry=labelDataCache[hash]={...labelDataCache[hash],loaded:true,data};newCacheEntry.dataCallbacks.forEach(callback=>{callback(newCacheEntry.data,cacheData.localized);});};const dataLoadErrorHandler=(x,status,error)=>{Log.error("Data load failed for svg-image",perseusCore.Errors.Service,{cause:error,loggedMetadata:{dataUrl:Util.getDataUrl(url),status}});};if(shouldUseLocalizedData()){retrieveData(getLocalizedDataUrl(url),()=>{cacheData.localized=false;retrieveData(Util.getDataUrl(url),dataLoadErrorHandler);});}else {retrieveData(Util.getDataUrl(url),dataLoadErrorHandler);}}}
|
|
1501
1501
|
|
|
1502
|
-
const baseFontFamily="'Lato', sans-serif";const boldFontFamily="'Lato-Bold', 'Lato', sans-serif";const kaGreen="#71B307";const white="#FFFFFF";const gray97="#F6F7F7";const gray85="#D6D8DA";const gray76="#BABEC2";const gray68="#888D93";const gray17="#21242c";const pureSmMin="568px";const pureMdMin$1="768px";const pureLgMin$1="1024px";const pureXlMin="1280px";const pureXsMax$1="567px";const pureSmMax$1="767px";const pureMdMax$1="1023px";const pureLgMax$1="1279px";const
|
|
1502
|
+
const baseFontFamily="'Lato', sans-serif";const boldFontFamily="'Lato-Bold', 'Lato', sans-serif";const kaGreen="#71B307";const white="#FFFFFF";const gray97="#F6F7F7";const gray85="#D6D8DA";const gray76="#BABEC2";const gray68="#888D93";const gray17="#21242c";const pureSmMin="568px";const pureMdMin$1="768px";const pureLgMin$1="1024px";const pureXlMin="1280px";const pureXsMax$1="567px";const pureSmMax$1="767px";const pureMdMax$1="1023px";const pureLgMax$1="1279px";const phoneMargin=16;const negativePhoneMargin=-16;const hintBorderWidth=4;const baseUnitPx=16;const interactiveSizes$1={defaultBoxSize:400,defaultBoxSizeSmall:288};const circleSize$1=24;const radioMarginWidth$1=2;const warningColor="#f86700";const warningColorHover="#df5c00";const warningColorActive="#c75300";const publishBlockingErrorColor="#be2612";const radioBorderColor$1="#BABEC2";const checkedColor$1="#71B307";const articleMaxWidthInPx=688;const articleMaxWidthTableInPx=512;
|
|
1503
1503
|
|
|
1504
1504
|
var constants = /*#__PURE__*/Object.freeze({
|
|
1505
1505
|
__proto__: null,
|
|
@@ -1531,7 +1531,6 @@ var constants = /*#__PURE__*/Object.freeze({
|
|
|
1531
1531
|
pureXsMax: pureXsMax$1,
|
|
1532
1532
|
radioBorderColor: radioBorderColor$1,
|
|
1533
1533
|
radioMarginWidth: radioMarginWidth$1,
|
|
1534
|
-
tableBackgroundAccent: tableBackgroundAccent,
|
|
1535
1534
|
warningColor: warningColor,
|
|
1536
1535
|
warningColorActive: warningColorActive,
|
|
1537
1536
|
warningColorHover: warningColorHover,
|
|
@@ -1829,13 +1828,13 @@ class FreeResponse extends React__namespace.Component{isOverLimit(){return !this
|
|
|
1829
1828
|
|
|
1830
1829
|
const getPromptJSON$i=(title,rendererJSON,hintRendererJSON)=>{if(!rendererJSON){return {type:"graded-group",title,content:"",widgets:{},hint:hintRendererJSON}}return {...rendererJSON,title,type:"graded-group",hint:hintRendererJSON}};
|
|
1831
1830
|
|
|
1832
|
-
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$k.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$k.text,children:[jsxRuntimeExports.jsx("span",{style:styles$k.tryAgainIcon,children:jsxRuntimeExports.jsx(InlineIcon,{...iconTryAgain})}),jsxRuntimeExports.jsx("span",{style:{marginLeft: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$k.text,children:[jsxRuntimeExports.jsx("span",{style:{fontSize:
|
|
1831
|
+
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$k.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$k.text,children:[jsxRuntimeExports.jsx("span",{style:styles$k.tryAgainIcon,children:jsxRuntimeExports.jsx(InlineIcon,{...iconTryAgain})}),jsxRuntimeExports.jsx("span",{style:{marginLeft: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$k.text,children:[jsxRuntimeExports.jsx("span",{style:{fontSize:wonderBlocksTokens.font.heading.size.xlarge,color:wonderBlocksTokens.semanticColor.core.foreground.success.default},children:jsxRuntimeExports.jsx(InlineIcon,{...iconStar,style:{marginBottom:5}})}),jsxRuntimeExports.jsx("span",{role:"alert","aria-label":correctExcited,style:{marginLeft:8},children:correctExcited})]}),onNextQuestion&&jsxRuntimeExports.jsx(Button__default.default,{onClick:onNextQuestion,children:nextQuestion})]})}}GradedGroupAnswerBar.contextType=PerseusI18nContext;const styles$k={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:{fontSize:wonderBlocksTokens.font.heading.size.xlarge,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.heading.size.medium}};
|
|
1833
1832
|
|
|
1834
|
-
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}});}shouldComponentUpdate(nextProps,nextState){return nextProps!==this.props||nextState!==this.state}_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.hint?.content||"",widgets:{}};return getPromptJSON$i(this.props.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:
|
|
1833
|
+
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}});}shouldComponentUpdate(nextProps,nextState){return nextProps!==this.props||nextState!==this.state}_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.hint?.content||"",widgets:{}};return getPromptJSON$i(this.props.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$j.gradedGroupInSet):aphrodite.css(styles$j.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.title&&jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$j.title),children:this.props.title}),jsxRuntimeExports.jsx(UserInputManager,{widgets:this.props.widgets,handleUserInput:(userInput,widgetsEmpty)=>this._handleUserInput(userInput,widgetsEmpty),problemNum:0,children:({userInput,handleUserInput})=>jsxRuntimeExports.jsx(Renderer,{content:this.props.content,widgets:this.props.widgets,images:this.props.images,userInput:userInput,handleUserInput:handleUserInput,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})}),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:{marginLeft:5},children:this.context.strings.nextQuestion})]}),this.props.hint?.content&&(this.state.showHint?jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("button",{tabIndex:"0",className:aphrodite.css(styles$j.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.hint.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>{const{content,widgets,images}=this.props.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$j.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;GradedGroup.defaultProps={title:"",content:"",widgets:{},images:{},hint:null,hasHint:false,linterContext:PerseusLinter.linterContextDefault};const styles$j=aphrodite.StyleSheet.create({gradedGroupInSet:{marginLeft:0,paddingLeft:0},gradedGroup:{borderTop:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderBottom:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.subtle,marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin,paddingBottom:phoneMargin,paddingLeft:phoneMargin,paddingRight:phoneMargin,paddingTop:10,width:"auto"},showHintLink:{backgroundColor:"unset",fontSize:wonderBlocksTokens.font.body.size.small,padding:0,border:"none",marginTop:20,color:wonderBlocksTokens.semanticColor.core.foreground.instructive.default,cursor:"pointer",display:"block",clear:"both"},explanationTitle:{backgroundColor:"unset",marginTop:20,color:wonderBlocksTokens.semanticColor.core.foreground.instructive.default,marginBottom: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",marginBottom: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};
|
|
1835
1834
|
|
|
1836
1835
|
const getPromptJSON$h=(widgetData,activeGroupJSON)=>{return {type:"graded-group-set",options:{groupCount:widgetData.gradedGroups.length,currentGroup:activeGroupJSON}}};
|
|
1837
1836
|
|
|
1838
|
-
class Indicators extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames__default.default(aphrodite.css(styles$i.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>jsxRuntimeExports.jsx("li",{className:aphrodite.css(styles$i.indicator),children:jsxRuntimeExports.jsx(Clickable__default.default,{role:"button","aria-label":title,"aria-current":
|
|
1837
|
+
class Indicators extends React__namespace.Component{render(){return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames__default.default(aphrodite.css(styles$i.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>{const isCurrent=i===this.props.currentGroup;return jsxRuntimeExports.jsx("li",{className:aphrodite.css(styles$i.indicator),children:jsxRuntimeExports.jsx(Clickable__default.default,{role:"button","aria-label":title,"aria-current":isCurrent,style:styles$i.indicatorButton,onClick:()=>this.props.onChangeCurrentGroup(i),onKeyDown:e=>this.handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(wonderBlocksCore.View,{style:[styles$i.indicatorDot,isCurrent&&styles$i.indicatorDotActive,(hovered||focused||pressed)&&styles$i.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}});}shouldComponentUpdate(nextProps,nextState){return nextProps!==this.props||nextState!==this.state}getPromptJSON(){const activeGroupPromptJSON=this._childGroup.getPromptJSON();return getPromptJSON$h(this.props,activeGroupPromptJSON)}render(){const{JIPT}=getDependencies();if(JIPT.useJIPT&&this.props.gradedGroups.length>1){return jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$i.container),children:this.props.gradedGroups.map((gradedGroup,i)=>{return jsxRuntimeExports.jsx(GradedGroup,{...this.props,...gradedGroup,inGradedGroupSet:false,linterContext:this.props.linterContext},i)})})}const currentGroup=this.props.gradedGroups[this.state.currentGroup];if(!currentGroup){return jsxRuntimeExports.jsx("span",{children:"No current group..."})}const numGroups=this.props.gradedGroups.length;const handleNextQuestion=this.state.currentGroup<numGroups-1?this.handleNextQuestion:null;return jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$i.container),children:[jsxRuntimeExports.jsxs("div",{className:aphrodite.css(styles$i.top),children:[jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$i.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:aphrodite.css(styles$i.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroup:this.state.currentGroup,gradedGroups:this.props.gradedGroups,onChangeCurrentGroup:currentGroup=>this.setState({currentGroup})})]}),jsxRuntimeExports.jsx(GradedGroup,{ref:comp=>this._childGroup=comp,...this.props,...currentGroup,inGradedGroupSet:true,title:null,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.gradedGroups.length;if(currentGroup<numGroups-1){this.setState({currentGroup:currentGroup+1});}};}}GradedGroupSet.defaultProps={gradedGroups:[],linterContext:PerseusLinter.linterContextDefault};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$i=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",marginBottom: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.foreground.instructive.default},container:{borderTop:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,borderBottom:`${wonderBlocksTokens.border.width.thin} solid ${wonderBlocksTokens.semanticColor.core.border.neutral.subtle}`,backgroundColor:wonderBlocksTokens.semanticColor.core.background.base.subtle,marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin,paddingBottom:phoneMargin,paddingLeft:phoneMargin,paddingRight:phoneMargin,paddingTop:10,width:"auto"}});
|
|
1839
1838
|
|
|
1840
1839
|
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(styles$h.buttonStyle,button.value===value&&styles$h.selectedStyle,button.value===value&&this.props.selectedButtonStyle,this.props.disabled&&styles$h.disabledStyle),onClick:()=>this.toggleSelect(button.value),children:button.content||""+button.value},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:node=>this.container=node,children:buttons})}}ButtonGroup.defaultProps={value:null,allowEmpty:true};const styles$h=aphrodite.StyleSheet.create({buttonStyle:{backgroundColor:"white",border:"1px solid #ccc",borderLeft:"0",cursor:"pointer",margin:"0",padding:"5px 10px",position:"relative",":first-child":{borderLeft:"1px solid #ccc",borderTopLeftRadius:"3px",borderBottomLeftRadius:"3px"},":last-child":{borderRight:"1px solid #ccc",borderTopRightRadius:"3px",borderBottomRightRadius:"3px"},":hover":{backgroundColor:"#ccc"},":focus":{zIndex:2}},selectedStyle:{backgroundColor:"#ddd"},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}}});
|
|
1841
1840
|
|
|
@@ -2024,9 +2023,11 @@ function getMovablePointLabels(state){if(!state.showPointLabels){return []}const
|
|
|
2024
2023
|
|
|
2025
2024
|
function MovablePointLabelsLayer({state}){const labeledPoints=getMovablePointLabels(state);if(labeledPoints.length===0){return null}return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(LabelStrokeFilter,{}),labeledPoints.map(label=>jsxRuntimeExports.jsx(MovablePointLabelView,{label:label,range:state.range},label.key))]})}function MovablePointLabelView({label,range}){const graphConfig=useGraphConfig();const[x,y]=pointToPixel(label.coord,graphConfig);const attach=getLabelAttach(label.coord,range);return jsxRuntimeExports.jsx("span",{className:"movable-point-label","data-testid":"movable-point__visible-label","aria-hidden":true,style:{position:"absolute",left:x,top:y,transform:translateOutward(attach),color:wonderBlocksTokens.semanticColor.core.foreground.neutral.default,fontFamily:'Symbola, "Times New Roman", serif',fontSize:wonderBlocksTokens.font.heading.size.medium,fontWeight:wonderBlocksTokens.font.weight.black,whiteSpace:"nowrap",pointerEvents:"none",filter:"url(#math-stroke)"},children:label.text})}const LABEL_PADDING_PX=12;function translateOutward(attach){const p=LABEL_PADDING_PX;switch(attach){case "n":return `translate(-50%, calc(-100% - ${p}px))`;case "ne":return `translate(${p}px, calc(-100% - ${p}px))`;case "e":return `translate(${p}px, -50%)`;case "se":return `translate(${p}px, ${p}px)`;case "s":return `translate(-50%, ${p}px)`;case "sw":return `translate(calc(-100% - ${p}px), ${p}px)`;case "w":return `translate(calc(-100% - ${p}px), -50%)`;case "nw":return `translate(calc(-100% - ${p}px), calc(-100% - ${p}px))`}}
|
|
2026
2025
|
|
|
2026
|
+
function DashedAsymptoteLine(props){const{start,end,color,className,testId}=props;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(SVGLine,{start:start,end:end,style:{stroke:wonderBlocksTokens.semanticColor.core.background.base.default,strokeWidth:"var(--movable-asymptote-stroke-weight)",strokeLinecap:"round"},className:className}),jsxRuntimeExports.jsx(SVGLine,{start:start,end:end,style:{stroke:color,strokeWidth:"var(--movable-asymptote-stroke-weight)",strokeDasharray:"var(--movable-asymptote-dash-length) var(--movable-asymptote-dash-gap)",strokeLinecap:"round"},className:className,testId:testId})]})}
|
|
2027
|
+
|
|
2027
2028
|
const ACTIVE_MAJOR=22;const ACTIVE_MINOR=12;const INACTIVE_MAJOR=16;const INACTIVE_MINOR=6;const RING_PAD=2;const HALO_PAD=3;const FOCUS_RING_PAD=2;const GRIP_DOT_MAJOR_OFFSETS=[-3,0,3];const GRIP_DOT_MINOR_OFFSETS=[-2,2];function MovablePillHandle(props){const{center,active,focused,rotation=0}=props;const[cx,cy]=center;const{interactiveColor}=useGraphConfig();const majorSize=active?ACTIVE_MAJOR:INACTIVE_MAJOR;const minorSize=active?ACTIVE_MINOR:INACTIVE_MINOR;const pillW=majorSize;const pillH=minorSize;const pillRadius=pillH/2;const haloW=pillW+(RING_PAD+HALO_PAD)*2;const haloH=pillH+(RING_PAD+HALO_PAD)*2;const haloRadius=haloH/2;const ringW=pillW+RING_PAD*2;const ringH=pillH+RING_PAD*2;const ringRadius=ringH/2;const focusRingW=haloW+FOCUS_RING_PAD*2;const focusRingH=haloH+FOCUS_RING_PAD*2;const focusRingRadius=focusRingH/2;return jsxRuntimeExports.jsxs("g",{"aria-hidden":true,style:{pointerEvents:"none"},transform:`translate(${cx} ${cy}) rotate(${rotation})`,"data-testid":"movable-pill-handle",children:[focused&&jsxRuntimeExports.jsx("rect",{className:"movable-pill-handle-focus-ring","data-testid":"movable-pill-handle-focus-ring",x:-focusRingW/2,y:-focusRingH/2,width:focusRingW,height:focusRingH,rx:focusRingRadius,ry:focusRingRadius,stroke:interactiveColor}),jsxRuntimeExports.jsx("rect",{className:"movable-pill-handle-halo",x:-haloW/2,y:-haloH/2,width:haloW,height:haloH,rx:haloRadius,ry:haloRadius,fill:interactiveColor}),jsxRuntimeExports.jsx("rect",{className:"movable-pill-handle-ring",x:-ringW/2,y:-ringH/2,width:ringW,height:ringH,rx:ringRadius,ry:ringRadius}),jsxRuntimeExports.jsx("rect",{className:"movable-pill-handle","data-testid":"movable-pill-handle-pill",x:-pillW/2,y:-pillH/2,width:pillW,height:pillH,rx:pillRadius,ry:pillRadius,fill:interactiveColor}),active&&GRIP_DOT_MINOR_OFFSETS.map(dy=>GRIP_DOT_MAJOR_OFFSETS.map(dx=>jsxRuntimeExports.jsx("circle",{className:"movable-pill-handle-dot","data-testid":"movable-pill-handle-dot",cx:dx,cy:dy},`${dx},${dy}`)))]})}
|
|
2028
2029
|
|
|
2029
|
-
function MovableAsymptote(props){const{start,end,mid,point,onMove,constrainKeyboardMovement,orientation,ariaLabel,children}=props;const{interactiveColor,disableKeyboardInteraction}=useGraphConfig();const[focused,setFocused]=React__namespace.useState(false);const[hovered,setHovered]=React__namespace.useState(false);const groupRef=React__namespace.useRef(null);const asymptoteHitboxRef=React__namespace.useRef(null);useDraggable({gestureTarget:groupRef,point,onMove,constrainKeyboardMovement:constrainKeyboardMovement??(p=>p)});const{dragging}=useDraggable({gestureTarget:asymptoteHitboxRef,point,onMove,constrainKeyboardMovement:constrainKeyboardMovement??(p=>p)});const asymptoteHitbox=useHitbox({shape:{kind:"box",center:point,sizePx:HANDLE_HITBOX_SIZE_PX},hitboxRef:asymptoteHitboxRef,layer:"handle",dragging,onHoverChange:setHovered,testId:"movable-asymptote__hitbox"});React__namespace.useLayoutEffect(()=>{if(dragging&&!focused){groupRef.current?.focus({preventScroll:true});}},[dragging,focused]);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[asymptoteHitbox,jsxRuntimeExports.jsxs("g",{ref:groupRef,tabIndex:disableKeyboardInteraction?-1:0,"aria-disabled":disableKeyboardInteraction,"aria-label":ariaLabel,className:hovered?"movable-line movable-line--hover":"movable-line",style:{cursor:dragging?"grabbing":"grab"},role:"button","data-testid":"movable-asymptote",onFocus:()=>setFocused(true),onBlur:()=>setFocused(false),onMouseEnter:()=>setHovered(true),onMouseLeave:()=>setHovered(false),children:[jsxRuntimeExports.jsx(SVGLine,{start:start,end:end,style:{stroke:"transparent",strokeWidth:TARGET_SIZE}}),jsxRuntimeExports.jsx(
|
|
2030
|
+
function MovableAsymptote(props){const{start,end,mid,point,onMove,constrainKeyboardMovement,orientation,ariaLabel,children}=props;const{interactiveColor,disableKeyboardInteraction}=useGraphConfig();const[focused,setFocused]=React__namespace.useState(false);const[hovered,setHovered]=React__namespace.useState(false);const groupRef=React__namespace.useRef(null);const asymptoteHitboxRef=React__namespace.useRef(null);useDraggable({gestureTarget:groupRef,point,onMove,constrainKeyboardMovement:constrainKeyboardMovement??(p=>p)});const{dragging}=useDraggable({gestureTarget:asymptoteHitboxRef,point,onMove,constrainKeyboardMovement:constrainKeyboardMovement??(p=>p)});const asymptoteHitbox=useHitbox({shape:{kind:"box",center:point,sizePx:HANDLE_HITBOX_SIZE_PX},hitboxRef:asymptoteHitboxRef,layer:"handle",dragging,onHoverChange:setHovered,testId:"movable-asymptote__hitbox"});React__namespace.useLayoutEffect(()=>{if(dragging&&!focused){groupRef.current?.focus({preventScroll:true});}},[dragging,focused]);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[asymptoteHitbox,jsxRuntimeExports.jsxs("g",{ref:groupRef,tabIndex:disableKeyboardInteraction?-1:0,"aria-disabled":disableKeyboardInteraction,"aria-label":ariaLabel,className:hovered?"movable-line movable-line--hover":"movable-line",style:{cursor:dragging?"grabbing":"grab"},role:"button","data-testid":"movable-asymptote",onFocus:()=>setFocused(true),onBlur:()=>setFocused(false),onMouseEnter:()=>setHovered(true),onMouseLeave:()=>setHovered(false),children:[jsxRuntimeExports.jsx(SVGLine,{start:start,end:end,style:{stroke:"transparent",strokeWidth:TARGET_SIZE}}),jsxRuntimeExports.jsx(DashedAsymptoteLine,{start:start,end:end,color:interactiveColor,className:dragging?"movable-dragging":"",testId:"movable-asymptote__line"}),children,jsxRuntimeExports.jsx(MovablePillHandle,{center:mid,rotation:orientation==="vertical"?90:0,active:dragging||focused||hovered,focused:focused})]})]})}
|
|
2030
2031
|
|
|
2031
2032
|
const{getExponentialCoefficients: getExponentialCoefficients$1}=kmath.coefficients;function renderExponentialGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(ExponentialGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeExponentialGraph(state,i18n).srExponentialInteractiveElements}}function ExponentialGraph(props){const{dispatch,graphState}=props;const{interactiveColor,range}=useGraphConfig();const i18n=usePerseusI18n();const id=React__namespace.useId();const descriptionId=id+"-description";const{coords,asymptote,snapStep}=graphState;const coeffs=getExponentialCoefficients$1(coords,asymptote);const asymptoteY=asymptote;const yMin=range[1][0];const yMax=range[1][1];const yPadding=(yMax-yMin)*4;const{srExponentialGraph,srExponentialDescription,srExponentialPoint1,srExponentialPoint2,srExponentialAsymptote}=describeExponentialGraph(graphState,i18n);const asymptoteLeft=[range[0][0],asymptoteY];const asymptoteRight=[range[0][1],asymptoteY];const handleCoord=getAsymptoteHandleCoord("horizontal",range,asymptote);const[leftPx,rightPx,midPx]=useTransformVectorsToPixels(asymptoteLeft,asymptoteRight,handleCoord);return jsxRuntimeExports.jsxs("g",{"aria-label":srExponentialGraph,"aria-describedby":descriptionId,children:[jsxRuntimeExports.jsx(MovableAsymptote,{start:leftPx,end:rightPx,mid:midPx,point:handleCoord,onMove:newPoint=>dispatch(actions.exponential.moveCenter(newPoint)),constrainKeyboardMovement:p=>skipAsymptoteKeyboardOverPoint(p,asymptote,coords,handleCoord,snapStep,"horizontal"),orientation:"horizontal",ariaLabel:srExponentialAsymptote,children:coeffs!==undefined&&jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(mafs.Plot.OfX,{y:x=>{const y=computeExponential(x,coeffs);if(y<yMin-yPadding||y>yMax+yPadding){return NaN}return y},color:interactiveColor,svgPathProps:{"aria-hidden":true,style:{pointerEvents:"none"}}})})}),coords.map((coord,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{ariaLabel:i===0?srExponentialPoint1:srExponentialPoint2,point:coord,sequenceNumber:i+1,constrain:getExponentialKeyboardConstraint(coords,asymptote,snapStep,i,range),onMove:destination=>dispatch(actions.exponential.movePoint(i,destination))},"point-"+i)),jsxRuntimeExports.jsx(SRDescInSVG,{id:descriptionId,children:srExponentialDescription})]})}const getExponentialKeyboardConstraint=(coords,asymptote,snapStep,pointIndex,range)=>{const otherPoint=coords[1-pointIndex];const handleCoord=getAsymptoteHandleCoord("horizontal",range,asymptote);return getAsymptoteGraphKeyboardConstraint(coords,snapStep,pointIndex,coord=>{const clamped=boundToEdgeAndSnapToGrid(coord,{snapStep,range});const clampedX=clamped[X];const clampedY=clamped[Y];if(coord[X]===otherPoint[X]||clampedX===otherPoint[X]){return false}if(clampedX===handleCoord[X]&&clampedY===handleCoord[Y]){return false}return true})};const computeExponential=function(x,coefficients){const{a,b,c}=coefficients;return a*Math.exp(b*x)+c};
|
|
2032
2033
|
|
|
@@ -2040,7 +2041,7 @@ const{getLogarithmCoefficients: getLogarithmCoefficients$1}=kmath.coefficients;f
|
|
|
2040
2041
|
|
|
2041
2042
|
function describePointGraph(state,i18n){const{strings,locale}=i18n;if(state.coords.length===0){return strings.srNoInteractiveElements}const pointDescriptions=state.coords.map((point,index)=>buildPointAriaLabel(state.pointLabels,index,point,strings,locale)??strings.srPointAtCoordinates({pointLabel:`${index+1}`,x:srFormatNumber(point[0],locale),y:srFormatNumber(point[1],locale)}));return strings.srInteractiveElements({elements:pointDescriptions.join(" ")})}
|
|
2042
2043
|
|
|
2043
|
-
function renderPointGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(PointGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describePointGraph(state,i18n)}}function PointGraph(props){const{numPoints}=props.graphState;const graphConfig=useGraphConfig();const pointsRef=React__namespace.useRef([]);const{range:[x,y]}=graphConfig;const[[left,top]]=useTransformVectorsToPixels([x[0],y[1]]);React__namespace.useEffect(()=>{const focusedIndex=props.graphState.focusedPointIndex;if(focusedIndex!=null){pointsRef.current[focusedIndex]?.focus();}},[props.graphState.focusedPointIndex,props.graphState.coords.length,pointsRef]);const statefulProps={...props,graphConfig,pointsRef,top,left};if(numPoints==="unlimited"){return UnlimitedPointGraph
|
|
2044
|
+
function renderPointGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(PointGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describePointGraph(state,i18n)}}function PointGraph(props){const{numPoints}=props.graphState;const graphConfig=useGraphConfig();const pointsRef=React__namespace.useRef([]);const{range:[x,y]}=graphConfig;const[[left,top]]=useTransformVectorsToPixels([x[0],y[1]]);React__namespace.useEffect(()=>{const focusedIndex=props.graphState.focusedPointIndex;if(focusedIndex!=null){pointsRef.current[focusedIndex]?.focus();}},[props.graphState.focusedPointIndex,props.graphState.coords.length,pointsRef]);const statefulProps={...props,graphConfig,pointsRef,top,left};if(numPoints==="unlimited"){return jsxRuntimeExports.jsx(UnlimitedPointGraph,{...statefulProps})}return jsxRuntimeExports.jsx(LimitedPointGraph,{...statefulProps})}function LimitedPointGraph(statefulProps){const{dispatch}=statefulProps;const{coords,pointLabels}=statefulProps.graphState;const buildLabel=usePointAriaLabel(pointLabels);return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:coords.map((point,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{point:point,sequenceNumber:i+1,ariaLabel:buildLabel(i,point),onMove:destination=>dispatch(actions.pointGraph.movePoint(i,destination))},i))})}function UnlimitedPointGraph(statefulProps){const{dispatch,graphConfig,pointsRef,top,left}=statefulProps;const{coords,pointLabels}=statefulProps.graphState;const buildLabel=usePointAriaLabel(pointLabels);const[isCurrentlyDragging,setIsCurrentlyDragging]=React__namespace.useState(false);const dragEndCallbackTimer=wonderBlocksTiming.useTimeout(()=>setIsCurrentlyDragging(false),400);const{graphDimensionsInPixels}=graphConfig;const widthPx=graphDimensionsInPixels[0];const heightPx=graphDimensionsInPixels[1];return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("rect",{"data-testid":"unlimited-point-graph-add-target",style:{fill:"none",pointerEvents:"all",cursor:"crosshair"},width:widthPx,height:heightPx,x:left,y:top,onClick:event=>{if(isCurrentlyDragging){return}const elementRect=event.currentTarget.getBoundingClientRect();const zoomFactor=getCSSZoomFactor(event.currentTarget);const x=(event.clientX-elementRect.x)/zoomFactor;const y=(event.clientY-elementRect.y)/zoomFactor;const graphCoordinates=pixelsToVectors([[x,y]],graphConfig);dispatch(actions.pointGraph.addPoint(graphCoordinates[0]));}}),coords.map((point,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{point:point,sequenceNumber:i+1,ariaLabel:buildLabel(i,point),onDragStart:()=>{dragEndCallbackTimer.clear();setIsCurrentlyDragging(true);},onMove:destination=>{dispatch(actions.pointGraph.movePoint(i,destination));},onDragEnd:()=>{dragEndCallbackTimer.set();},ref:ref=>{pointsRef.current[i]=ref;},onFocus:()=>{dispatch(actions.pointGraph.focusPoint(i));},onClick:()=>{dispatch(actions.pointGraph.clickPoint(i));}},i))]})}
|
|
2044
2045
|
|
|
2045
2046
|
const{magnitude: magnitude$1,vector: vector$1}=kmath.geometry;function initializeGraphState(params){const{graph,step,snapStep,range}=params;const shared={hasBeenInteractedWith:false,range,snapStep,pointLabels:"pointLabels"in graph?graph.pointLabels:undefined,showPointLabels:"showPointLabels"in graph?Boolean(graph.showPointLabels):undefined};switch(graph.type){case "segment":return {...shared,type:"segment",coords:getSegmentCoords(graph,range,step)};case "linear":return {...shared,type:graph.type,coords:getLineCoords(graph,range,step)};case "ray":return {...shared,type:graph.type,coords:getLineCoords(graph,range,step)};case "linear-system":return {...shared,type:graph.type,coords:getLinearSystemCoords(graph,range,step)};case "polygon":return {...shared,type:"polygon",numSides:graph.numSides||0,showAngles:Boolean(graph.showAngles),showSides:Boolean(graph.showSides),coords:getPolygonCoords(graph,range,step),snapTo:graph.snapTo??"grid",focusedPointIndex:null,showRemovePointButton:false,interactionMode:"mouse",showKeyboardInteractionInvitation:false,closedPolygon:false};case "point":return {...shared,type:graph.type,coords:getPointCoords(graph,range,step),numPoints:graph.numPoints||0,focusedPointIndex:null,showRemovePointButton:false,interactionMode:"mouse",showKeyboardInteractionInvitation:false};case "circle":return {...shared,type:graph.type,...getCircleCoords(graph)};case "quadratic":return {...shared,type:graph.type,coords:getQuadraticCoords(graph,range,step)};case "sinusoid":return {...shared,type:graph.type,coords:getSinusoidCoords(graph,range,step)};case "exponential":return {...shared,type:graph.type,...getExponentialCoords(graph,range,step)};case "angle":return {...shared,type:graph.type,showAngles:Boolean(graph.showAngles),coords:getAngleCoords({graph,range,step}),angleOffsetDeg:graph.angleOffsetDeg??0,allowReflexAngles:Boolean(graph.allowReflexAngles),snapDegrees:Number(graph.snapDegrees)};case "none":return {...shared,type:"none"};case "absolute-value":return {...shared,type:graph.type,coords:getAbsoluteValueCoords(graph,range,step)};case "tangent":return {...shared,type:graph.type,coords:getTangentCoords(graph,range,step)};case "logarithm":return {...shared,type:graph.type,...getLogarithmCoords(graph,range,step)};case "vector":return {...shared,type:graph.type,coords:getVectorCoords(graph,range,step)};default:throw new wonderStuffCore.UnreachableCaseError(graph)}}function getPointCoords(graph,range,step){const numPoints=graph.numPoints||1;let coords=graph.coords?.slice();if(coords){return coords}const startCoords=graph.startCoords?.slice();if(startCoords){return startCoords}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;default:coords=[];break}const newCoords=normalizeCoords(coords,[[-10,10],[-10,10]]);return normalizePoints(range,step,newCoords)}function getSegmentCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}const ys=n=>{switch(n){case 2:return [5,-5];case 3:return [5,0,-5];case 4:return [6,2,-2,-6];case 5:return [6,3,0,-3,-6];case 6:return [5,3,1,-1,-3,-5];default:return [5]}};const defaultRange=[[-10,10],[-10,10]];return ys(graph.numSegments).map(y=>{let endpoints=[[-5,y],[5,y]];endpoints=normalizeCoords(endpoints,defaultRange);endpoints=normalizePoints(range,step,endpoints);return endpoints})}const defaultLinearCoords=[[[.25,.75],[.75,.75]],[[.25,.25],[.75,.25]]];function getLineCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}return normalizePoints(range,step,defaultLinearCoords[0])}function getVectorCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}return normalizePoints(range,step,[[.6,.6],[.85,.85]])}function getLinearSystemCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}return defaultLinearCoords.map(points=>normalizePoints(range,step,points))}function getPolygonCoords(graph,range,step){let coords=graph.coords?.slice();if(coords){return coords}const startCoords=graph.startCoords?.slice();if(startCoords){return startCoords}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=[...Array(n).keys()].map(i=>[radius*Math.cos(i*angle+offset),radius*Math.sin(i*angle+offset)]);}coords=normalizeCoords(coords,[[-10,10],[-10,10]]);const snapToGrid=!["angles","sides"].includes(graph.snapTo||"");coords=normalizePoints(range,step,coords,!snapToGrid);return coords}function getSinusoidCoords(graph,range,step){if(graph.coords){return [graph.coords[0],graph.coords[1]]}if(graph.startCoords){return [graph.startCoords[0],graph.startCoords[1]]}let coords=[[.5,.5],[.65,.6]];coords=normalizePoints(range,step,coords,true);return coords}function getAbsoluteValueCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}const defaultCoords=[[.5,.5],[.75,.75]];return normalizePoints(range,step,defaultCoords,true)}function getTangentCoords(graph,range,step){if(graph.coords){return [graph.coords[0],graph.coords[1]]}if(graph.startCoords){return [graph.startCoords[0],graph.startCoords[1]]}let coords=[[.5,.5],[.75,.75]];coords=normalizePoints(range,step,coords,true);return coords}function getQuadraticCoords(graph,range,step){if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}const defaultCoords=[[.25,.75],[.5,.25],[.75,.75]];return normalizePoints(range,step,defaultCoords,true)}function getCircleCoords(graph){if(graph.center!=null&&graph.radius!=null){return {center:graph.center,radiusPoint:mafs.vec.add(graph.center,[graph.radius,0])}}if(graph.startCoords?.center&&graph.startCoords.radius){return {center:graph.startCoords.center,radiusPoint:mafs.vec.add(graph.startCoords.center,[graph.startCoords.radius,0])}}return {center:[0,0],radiusPoint:[2,0]}}function getExponentialCoords(graph,range,step){if(graph.coords&&graph.asymptote!=null){return {coords:[graph.coords[0],graph.coords[1]],asymptote:graph.asymptote}}let defaultCoords=[[.5,.6],[.75,.75]];defaultCoords=normalizePoints(range,step,defaultCoords,true);const coords=graph.startCoords?graph.startCoords.coords:defaultCoords;const asymptote=graph.startCoords?graph.startCoords.asymptote:0;return {coords,asymptote}}function getLogarithmCoords(graph,range,step){if(graph.coords&&graph.asymptote!=null){return {coords:[graph.coords[0],graph.coords[1]],asymptote:graph.asymptote}}let defaultCoords=[[.6,.55],[.75,.75]];defaultCoords=normalizePoints(range,step,defaultCoords,true);const coords=graph.startCoords?graph.startCoords.coords:defaultCoords;const asymptote=graph.startCoords?graph.startCoords.asymptote:0;return {coords,asymptote}}const getAngleCoords=params=>{const{graph,range,step}=params;if(graph.coords){return graph.coords}if(graph.startCoords){return graph.startCoords}const{snapDegrees,angleOffsetDeg}=graph;const snap=snapDegrees||1;let angle=snap;while(angle<20){angle+=snap;}angle=angle*Math.PI/180;const offset=(angleOffsetDeg||0)*Math.PI/180;let defaultCoords=[[.85,.5],[.5,.5]];defaultCoords=normalizePoints(range,step,defaultCoords,true);const radius=magnitude$1(vector$1(...defaultCoords));const coords=[...defaultCoords,[0,0]];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};
|
|
2046
2047
|
|
|
@@ -2056,7 +2057,7 @@ function renderSegmentGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports
|
|
|
2056
2057
|
|
|
2057
2058
|
function renderSinusoidGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(SinusoidGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeSinusoidGraph(state,i18n).srSinusoidInteractiveElements}}function SinusoidGraph(props){const{dispatch,graphState}=props;const{interactiveColor}=useGraphConfig();const i18n=usePerseusI18n();const id=React__namespace.useId();const descriptionId=id+"-description";const{coords,snapStep}=graphState;const coeffRef=React__namespace.useRef({amplitude:1,angularFrequency:1,phase:1,verticalOffset:0});const coeffs=getSinusoidCoefficients(coords);if(coeffs!==undefined){coeffRef.current=coeffs;}const{srSinusoidGraph,srSinusoidDescription,srSinusoidRootPoint,srSinusoidPeakPoint}=describeSinusoidGraph(graphState,i18n);return jsxRuntimeExports.jsxs("g",{"aria-label":srSinusoidGraph,"aria-describedby":descriptionId,children:[jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(mafs.Plot.OfX,{y:x=>computeSine(x,coeffRef.current),color:interactiveColor,svgPathProps:{"aria-hidden":true}})}),coords.map((coord,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{ariaLabel:i===0?srSinusoidRootPoint:srSinusoidPeakPoint,point:coord,sequenceNumber:i+1,constrain:getSinusoidKeyboardConstraint(coords,snapStep,i),onMove:destination=>dispatch(actions.sinusoid.movePoint(i,destination))},"point-"+i)),jsxRuntimeExports.jsx(SRDescInSVG,{id:descriptionId,children:srSinusoidDescription})]})}const getSinusoidKeyboardConstraint=(coords,snapStep,pointIndex)=>{const coordToBeMoved=coords[pointIndex];const otherPoint=coords[1-pointIndex];const movePointWithConstraint=moveFunc=>{let movedCoord=moveFunc(coordToBeMoved);if(movedCoord[X]===otherPoint[X]){movedCoord=moveFunc(movedCoord);}return movedCoord};return {up:movePointWithConstraint(coord=>mafs.vec.add(coord,[0,snapStep[1]])),down:movePointWithConstraint(coord=>mafs.vec.sub(coord,[0,snapStep[1]])),left:movePointWithConstraint(coord=>mafs.vec.sub(coord,[snapStep[0],0])),right:movePointWithConstraint(coord=>mafs.vec.add(coord,[snapStep[0],0]))}};const computeSine=function(x,sinusoidCoefficients){const{amplitude:a,angularFrequency:b,phase:c,verticalOffset:d}=sinusoidCoefficients;return a*Math.sin(b*x-c)+d};const getSinusoidCoefficients=coords=>{const p1=coords[0];const p2=coords[1];if(p2[X]===p1[X]){return}const amplitude=p2[Y]-p1[Y];const angularFrequency=Math.PI/(2*(p2[X]-p1[X]));const phase=p1[X]*angularFrequency;const verticalOffset=p1[Y];return {amplitude,angularFrequency,phase,verticalOffset}};
|
|
2058
2059
|
|
|
2059
|
-
function renderTangentGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(TangentGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeTangentGraph(state,i18n).srTangentInteractiveElements}}function TangentGraph(props){const{dispatch,graphState}=props;const{interactiveColor,range}=useGraphConfig();const i18n=usePerseusI18n();const id=React__namespace.useId();const descriptionId=id+"-description";const{coords,snapStep}=graphState;const coeffRef=React__namespace.useRef({amplitude:1,angularFrequency:1,phase:1,verticalOffset:0});const coeffs=getTangentCoefficients(coords);if(coeffs!==undefined){coeffRef.current=coeffs;}const xRange=[range[0][0],range[0][1]];const
|
|
2060
|
+
function renderTangentGraph(state,dispatch,i18n){return {graph:jsxRuntimeExports.jsx(TangentGraph,{graphState:state,dispatch:dispatch}),interactiveElementsDescription:describeTangentGraph(state,i18n).srTangentInteractiveElements}}function TangentGraph(props){const{dispatch,graphState}=props;const{interactiveColor,range}=useGraphConfig();const i18n=usePerseusI18n();const id=React__namespace.useId();const descriptionId=id+"-description";const{coords,snapStep}=graphState;const coeffRef=React__namespace.useRef({amplitude:1,angularFrequency:1,phase:1,verticalOffset:0});const coeffs=getTangentCoefficients(coords);if(coeffs!==undefined){coeffRef.current=coeffs;}const xRange=[range[0][0],range[0][1]];const yRange=[range[1][0],range[1][1]];const asymptotes=getAsymptotePositions(coeffRef.current,xRange);const segments=getPlotSegments(asymptotes,xRange);const{srTangentGraph,srTangentDescription,srTangentInflectionPoint,srTangentControlPoint}=describeTangentGraph(graphState,i18n);return jsxRuntimeExports.jsxs("g",{"aria-label":srTangentGraph,"aria-describedby":descriptionId,children:[jsxRuntimeExports.jsx(TangentAsymptotes,{asymptotes:asymptotes,yRange:yRange,color:interactiveColor}),jsxRuntimeExports.jsx(ClipToGraphBounds,{children:segments.map(([segStart,segEnd],i)=>jsxRuntimeExports.jsx(mafs.Plot.OfX,{y:x=>computeTangent(x,coeffRef.current),domain:[segStart,segEnd],color:interactiveColor,svgPathProps:{"aria-hidden":true}},`tangent-segment-${i}`))}),coords.map((coord,i)=>jsxRuntimeExports.jsx(MovablePoint$3,{ariaLabel:i===0?srTangentInflectionPoint:srTangentControlPoint,point:coord,sequenceNumber:i+1,constrain:getTangentKeyboardConstraint(coords,snapStep,i),onMove:destination=>dispatch(actions.tangent.movePoint(i,destination))},"point-"+i)),jsxRuntimeExports.jsx(SRDescInSVG,{id:descriptionId,children:srTangentDescription})]})}const getTangentKeyboardConstraint=(coords,snapStep,pointIndex)=>{const coordToBeMoved=coords[pointIndex];const otherPoint=coords[1-pointIndex];const movePointWithConstraint=moveFunc=>{let movedCoord=moveFunc(coordToBeMoved);if(movedCoord[X]===otherPoint[X]){movedCoord=moveFunc(movedCoord);}return movedCoord};return {up:movePointWithConstraint(coord=>mafs.vec.add(coord,[0,snapStep[1]])),down:movePointWithConstraint(coord=>mafs.vec.sub(coord,[0,snapStep[1]])),left:movePointWithConstraint(coord=>mafs.vec.sub(coord,[snapStep[0],0])),right:movePointWithConstraint(coord=>mafs.vec.add(coord,[snapStep[0],0]))}};const computeTangent=function(x,tangentCoefficients){const{amplitude:a,angularFrequency:b,phase:c,verticalOffset:d}=tangentCoefficients;const arg=b*x-c;const normalized=(arg-Math.PI/2)/Math.PI%1;const distToAsymptote=Math.abs(normalized>.5?normalized-1:normalized<-0.5?normalized+1:normalized);if(distToAsymptote<.001){return NaN}return a*Math.tan(arg)+d};const getTangentCoefficients=coords=>{const p1=coords[0];const p2=coords[1];if(p2[X]===p1[X]){return}const amplitude=p2[Y]-p1[Y];const angularFrequency=Math.PI/(4*(p2[X]-p1[X]));const phase=p1[X]*angularFrequency;const verticalOffset=p1[Y];return {amplitude,angularFrequency,phase,verticalOffset}};function getAsymptotePositions(coeffs,xRange){const{angularFrequency:b,phase:c}=coeffs;if(b===0){return []}const period=Math.PI/Math.abs(b);const referenceAsymptote=(c+Math.PI/2)/b;const asymptotes=[];let x=referenceAsymptote;while(x>xRange[0]-period){if(x>xRange[0]&&x<xRange[1]){asymptotes.push(x);}x-=period;}x=referenceAsymptote+period;while(x<xRange[1]+period){if(x>xRange[0]&&x<xRange[1]){asymptotes.push(x);}x+=period;}return asymptotes.sort((a,b)=>a-b)}function getPlotSegments(asymptotes,xRange){const eps=.01;const segments=[];let start=xRange[0];for(const asymptote of asymptotes){segments.push([start,asymptote-eps]);start=asymptote+eps;}segments.push([start,xRange[1]]);return segments}function TangentAsymptotes(props){const{asymptotes,yRange,color}=props;const endpoints=asymptotes.flatMap(x=>[[x,yRange[0]],[x,yRange[1]]]);const pixels=useTransformVectorsToPixels(...endpoints);return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:asymptotes.map((x,i)=>jsxRuntimeExports.jsx(DashedAsymptoteLine,{start:pixels[i*2],end:pixels[i*2+1],color:color,testId:"tangent-asymptote__line"},`asymptote-${x}`))})}
|
|
2060
2061
|
|
|
2061
2062
|
const ARROW_SCALE=1.5;const arrowPath=pathBuilder().move(-5,5).line(0,0).line(-5,-5).scale(ARROW_SCALE).build();function buildRoundedTriangle(tipX,tipY,armX,armY,backX,backY,backR,tipR){return pathBuilder().move(tipX,tipY).line(armX,armY).circularArc(backR,backX,backY,{sweep:true}).line(backX,-5).circularArc(backR,armX,-7.8,{sweep:true}).line(tipX,-2.8).circularArc(tipR,tipX,tipY,{sweep:true}).scale(ARROW_SCALE).build()}const arrowPathHalo=buildRoundedTriangle(2.8,2.8,-2.2,7.8,-9,5,4,4);const chevronPathAttrs={d:arrowPath,fill:"none",strokeLinejoin:"round",strokeLinecap:"round"};const MovableArrowheadView=React.forwardRef(function MovableArrowheadViewWithRef(props,hitboxRef){const{showTooltips,interactiveColor,snapStep}=useGraphConfig();const{point,angle,dragging,hovered,cursor,showFocusRing,onClick=()=>{}}=props;const classes=classNames("movable-arrowhead",dragging&&"movable-arrowhead--dragging",showFocusRing&&"movable-arrowhead--focus",hovered&&"movable-arrowhead--hover");const[[x,y]]=useTransformVectorsToPixels(point);const xSigFigs=countSignificantDecimals(snapStep[X]);const ySigFigs=countSignificantDecimals(snapStep[Y]);const xTickLabel=point[X].toFixed(xSigFigs);const yTickLabel=point[Y].toFixed(ySigFigs);const tooltipContent=`(${xTickLabel}, ${yTickLabel})`;const svgForArrowhead=jsxRuntimeExports.jsx("g",{"aria-hidden":true,ref:hitboxRef,className:classes,style:{"--movable-arrowhead-color":interactiveColor,cursor},"data-testid":"movable-arrowhead",onClick:onClick,children:jsxRuntimeExports.jsxs("g",{transform:`translate(${x} ${y}) rotate(${angle})`,children:[jsxRuntimeExports.jsx("path",{d:arrowPathHalo,className:"movable-arrowhead-halo"}),jsxRuntimeExports.jsx("path",{...chevronPathAttrs,className:"movable-arrowhead-ring"}),jsxRuntimeExports.jsx("path",{...chevronPathAttrs,className:"movable-arrowhead-center"})]})});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:showTooltips?jsxRuntimeExports.jsx(Tooltip__default.default,{autoUpdate:true,opened:true,content:tooltipContent,variant:"strong",children:svgForArrowhead}):svgForArrowhead})});function classNames(...names){return names.filter(Boolean).join(" ")}
|
|
2062
2063
|
|
|
@@ -2140,7 +2141,7 @@ class Measurer extends React__namespace.Component{componentDidMount(){this.setup
|
|
|
2140
2141
|
|
|
2141
2142
|
const getPromptJSON$6=widgetData=>{const{userInput}=widgetData;return {type:"number-line",options:{range:widgetData.range,snapDivisions:widgetData.snapDivisions},userInput:{numLinePosition:userInput.numLinePosition,numDivisions:userInput.numDivisions,rel:userInput.rel}}};
|
|
2142
2143
|
|
|
2143
|
-
const MovablePoint=Graphie.MovablePoint;const Line=Graphie.Line;const{assert: assert$1}=InteractiveUtil;const bound=(x,gt,lt)=>Math.min(Math.max(x,gt),lt);const EN_DASH="–";const horizontalPadding=30;const reverseRel={eq:"eq",ge:"le",gt:"lt",le:"ge",lt:"gt"};const toggleStrictRel={eq:"eq",ge:"gt",gt:"ge",le:"lt",lt:"le"};function formatImproper(n,d){if(d===1){return ""+n}return `\\dfrac{${n}}{${d}}`}function formatMixed(n,d){if(n<0){return "-"+formatMixed(-n,d)}const w=Math.floor(n/d);if(w===0){return formatImproper(n,d)}if(n-w*d===0){return ""+w}return w+formatImproper(n-w*d,d)}function formatNonReduced(n,d,base){const factor=Math.floor(base/d);return formatImproper(n*factor,base)}const _label=(graphie,labelStyle,pos,value,base)=>{value=value||pos;if(labelStyle==="decimal"){return graphie.label([pos,-0.53],Math.round(value*100)/100,"center")}if(labelStyle==="improper"){const frac=kmath.KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatImproper(frac[0],frac[1]),"below")}if(labelStyle==="mixed"){const frac=kmath.KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatMixed(frac[0],frac[1]),"below")}if(labelStyle==="non-reduced"){const frac=kmath.KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatNonReduced(frac[0],frac[1],base),"below")}};const TickMarks=Graphie.createSimpleClass((graphie,props)=>{if(!___default.default.isFinite(props.tickStep)||props.tickStep<=0){return []}const results=[];const{range,labelRange,labelStyle,labelTicks,tickStep,numDivisions}=props;const leftLabel=labelRange[0]==null?range[0]:labelRange[0];const rightLabel=labelRange[1]==null?range[1]:labelRange[1];let base;if(labelStyle==="non-reduced"){const fractions=[leftLabel,rightLabel];for(let i=0;i<=numDivisions;i++){const x=range[0]+i*tickStep;fractions.push(x);}const getDenom=x=>kmath.number.toFraction(x)[1];const denoms=___default.default.map(fractions,getDenom);base=___default.default.reduce(denoms,(x,y)=>kmath.KhanMath.getLCM(x,y));}else {base=undefined;}const highlightedLineStyle={stroke:KhanColors.BLUE,strokeWidth:3.5};const highlightedTextStyle={color:KhanColors.BLUE};const initialTicks=[...Array(Math.round(numDivisions)).keys()].map(index=>range[0]+index*tickStep);const byNumericAscending=(a,b)=>a-b;const allTicks=[...new Set([...initialTicks,leftLabel,rightLabel,...range])].sort(byNumericAscending);allTicks.forEach(tick=>{const tickIsHighlighted=tick===leftLabel||tick===rightLabel;const lineStyle=tickIsHighlighted?highlightedLineStyle:null;const textStyle=tickIsHighlighted?highlightedTextStyle:null;graphie.style(lineStyle,()=>{results.push(graphie.line([tick,-0.2],[tick,.2]));});if(labelTicks||tickIsHighlighted){graphie.style(textStyle,()=>{results.push(_label(graphie,labelStyle,tick,tick,base));});}});return results});class NumberLine extends React__namespace.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"number-line",widgetId:this.props.widgetId}});}focus(){if(this.props.isTickCtrl){this.refs["tick-ctrl"].focus();return true}return false}getDOMNodeForPath(inputPath){if(inputPath?.length===1){return ReactDOM__namespace.default.findDOMNode(this.refs[inputPath[0]])}return null}_getInequalityEndpoint(props){const isGreater=___default.default(["ge","gt"]).contains(this.props.userInput.rel);const widthInPixels=400;const range=props.range;const scale=(range[1]-range[0])/widthInPixels;const buffer=horizontalPadding*scale;const left=range[0]-buffer;const right=range[1]+buffer;const end=isGreater?[right,0]:[left,0];return end}_renderInequality(props){if(props.isInequality){const end=this._getInequalityEndpoint(props);const style={arrows:"->",stroke:this.props.apiOptions.isMobile?KhanColors.GREEN:KhanColors.BLUE,strokeWidth:3.5};return jsxRuntimeExports.jsx(Line,{start:[props.userInput.numLinePosition,0],end:end,style:style})}return null}getPromptJSON(){return getPromptJSON$6(this.props)}getSerializedState(){const props=this.props;return {alignment:props.alignment,static:props.static,range:props.range,labelRange:props.labelRange,labelStyle:props.labelStyle,labelTicks:props.labelTicks,divisionRange:props.divisionRange,snapDivisions:props.snapDivisions,isInequality:props.isInequality,showTooltips:props.showTooltips,isTickCtrl:props.isTickCtrl,numDivisions:props.userInput.numDivisions,numLinePosition:props.userInput.numLinePosition,rel:"ge"}}render(){const{strings}=this.context;const divisionRange=this.props.divisionRange;const divRangeString=divisionRange[0]+EN_DASH+divisionRange[1];const invalidNumDivisions=this.props.userInput?.numDivisions<divisionRange[0]||this.props.userInput?.numDivisions>divisionRange[1];const inequalityControls=jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("input",{type:"button",className:"simple-button",value:strings.switchDirection,onClick:this.handleReverse}),jsxRuntimeExports.jsx("input",{type:"button",className:"simple-button",value:["le","ge"].includes(this.props.userInput?.rel)?strings.circleOpen:strings.circleFilled,onClick:this.handleToggleStrict})]});let tickCtrl;if(this.props.isTickCtrl){let Input;if(this.props.apiOptions.customKeypad){Input=SimpleKeypadInput;}else {Input=NumberInput;}tickCtrl=jsxRuntimeExports.jsxs("label",{children:[strings.numDivisions," ",jsxRuntimeExports.jsx(Input,{ref:"tick-ctrl",value:this.state.numDivisionsEmpty?null:this.props.userInput?.numDivisions||divisionRange[0],checkValidity:val=>val>=divisionRange[0]&&val<=divisionRange[1],onChange:this.onNumDivisionsChange,onFocus:this._handleTickCtrlFocus,onBlur:this._handleTickCtrlBlur,useArrowKeys:true,keypadElement:this.props.keypadElement})]});}return jsxRuntimeExports.jsxs("div",{className:"perseus-widget "+"perseus-widget-interactive-number-line",children:[tickCtrl,!this.isValid()?jsxRuntimeExports.jsx("div",{className:"perseus-error",children:"Invalid number line configuration."}):this.props.isTickCtrl&&invalidNumDivisions?jsxRuntimeExports.jsx("div",{className:"perseus-error",children:strings.divisions({divRangeString:divRangeString})}):this._renderGraphie(),!this.props.static&&this.props.isInequality&&inequalityControls]})}constructor(...args){super(...args),this.state={numDivisionsEmpty:false},this.isValid=()=>{const range=this.props.range;let initialX=this.props.userInput?.numLinePosition;const divisionRange=this.props.divisionRange;initialX=initialX==null?range[0]:initialX;return range[0]<range[1]&&kmath.number.sign(initialX-range[0])>=0&&kmath.number.sign(initialX-range[1])<=0&&divisionRange[0]<divisionRange[1]&&0<this.props.userInput?.numDivisions&&0<this.props.snapDivisions},this.onNumDivisionsChange=(numDivisions,cb)=>{const width=this.props.range[1]-this.props.range[0];numDivisions=Math.round(numDivisions);numDivisions=numDivisions<0?numDivisions*-1:numDivisions;if(numDivisions){const nextProps={...this.props,tickStep:width/numDivisions};const newNumLinePosition=this.snapNumLinePosition(nextProps,this.props.userInput.numLinePosition);this.setState({numDivisionsEmpty:false},()=>{this.props.handleUserInput({...this.props.userInput,numDivisions:numDivisions,numLinePosition:newNumLinePosition},cb);});}else {this.setState({numDivisionsEmpty:true},cb);}},this._handleTickCtrlFocus=()=>{this.props.onFocus(["tick-ctrl"]);},this._handleTickCtrlBlur=()=>{this.props.onBlur(["tick-ctrl"]);},this.focusInputPath=path=>{if(path.length===1){this.refs[path[0]].focus();}},this.blurInputPath=path=>{if(path.length===1){this.refs[path[0]].blur();}},this.getInputPaths=()=>{if(this.props.isTickCtrl){return [["tick-ctrl"]]}return []},this._renderGraphie=()=>{const range=this.props.range;const width=range[1]-range[0];const options={range:this.props.range,isTickCtrl:this.props.isTickCtrl};const props={...this.props,tickStep:width/this.props.userInput.numDivisions};return jsxRuntimeExports.jsxs(Graphie,{ref:"graphie",box:[this.props.apiOptions.isMobile?288:460,80],options:options,onMouseDown:coord=>{this.refs.graphie.movables.numberLinePoint.grab(coord);},setup:this._setupGraphie,isMobile:this.props.apiOptions.isMobile,children:[jsxRuntimeExports.jsx(TickMarks,{range:props.range,labelTicks:props.labelTicks,labelStyle:props.labelStyle,labelRange:props.labelRange,tickStep:props.tickStep,numDivisions:props.userInput.numDivisions,isMobile:props.apiOptions.isMobile}),this._renderInequality(props),this._renderNumberLinePoint(props)]},this.props.labelStyle)},this.snapNumLinePosition=(props,numLinePosition)=>{const left=props.range[0];const right=props.range[1];const snapX=props.tickStep/this.props.snapDivisions;let x=bound(numLinePosition,left,right);x=left+kmath.number.roundTo(x-left,snapX);assert$1(___default.default.isFinite(x));return x},this.movePosition=targetPosition=>{this.props.handleUserInput({...this.props.userInput,numLinePosition:targetPosition});this.props.trackInteraction();},this._renderNumberLinePoint=props=>{const isOpen=___default.default(["lt","gt"]).contains(props.userInput.rel);let fill;if(isOpen){fill=KhanColors._BACKGROUND;}else if(props.static){fill=KhanColors.BLUE;}else {fill=KhanColors.GREEN;}const normalStyle={fill:fill,stroke:props.static?KhanColors.BLUE:KhanColors.GREEN,"stroke-width":isOpen?3:1};const highlightStyle={fill:isOpen?KhanColors._BACKGROUND:KhanColors.GREEN,"stroke-width":isOpen?3:1};const mobileDotStyle=props.isInequality?{stroke:KhanColors.GREEN,"fill-opacity":isOpen?0:1}:{};return jsxRuntimeExports.jsx(MovablePoint,{ref:"numberLinePoint",pointSize:6,coord:[props.userInput.numLinePosition,0],constraints:[(coord,prevCoord)=>{return [coord[0],prevCoord[1]]},(coord,prevCoord)=>{const x=this.snapNumLinePosition(props,coord[0]);return [x,coord[1]]}],normalStyle:normalStyle,highlightStyle:highlightStyle,onMove:coord=>{this.movePosition(coord[0]);},isMobile:this.props.apiOptions.isMobile,mobileStyleOverride:mobileDotStyle,showTooltips:this.props.showTooltips??false,xOnlyTooltip:true})},this.handleReverse=()=>{const newRel=reverseRel[this.props.userInput.rel];this.props.handleUserInput({...this.props.userInput,rel:newRel});},this.handleToggleStrict=()=>{const newRel=toggleStrictRel[this.props.userInput.rel];this.props.handleUserInput({...this.props.userInput,rel:newRel});},this._setupGraphie=(graphie,options)=>{if(!this.isValid()){return}const widthInPixels=this.props.apiOptions.isMobile?288-horizontalPadding*2:400;const range=options.range;const scale=(range[1]-range[0])/widthInPixels;const buffer=horizontalPadding*scale;const left=range[0]-buffer;const right=range[1]+buffer;const hasFractionalLabels=this.props.labelStyle==="improper"||this.props.labelStyle==="mixed"||this.props.labelStyle==="non-reduced";const bottom=hasFractionalLabels?-1.5:-1;const top=1;graphie.init({range:[[left,right],[bottom,top]],scale:[1/scale,40],isMobile:this.props.apiOptions.isMobile});const center=(range[0]+range[1])/2;graphie.line([center,0],[right,0],{arrows:"->"});graphie.line([center,0],[left,0],{arrows:"->"});};}}NumberLine.contextType=PerseusI18nContext;function getUserInputFromSerializedState$4(serializedState){return {numDivisions:serializedState.numDivisions,numLinePosition:serializedState.numLinePosition,rel:"eq"}}function getStartNumDivisions(options){const width=options.range[1]-options.range[0];let numDivisions;if(options.numDivisions!=null){numDivisions=options.numDivisions;}else if(options.tickStep!=null){numDivisions=width/options.tickStep;}else {numDivisions=undefined;}return numDivisions}function getCorrectUserInput$1(options){const numLinePosition=options.correctX!=null?options.correctX:options.range[0];return {numDivisions:getStartNumDivisions(options),numLinePosition,rel:options.isInequality&&options.correctRel||"eq"}}function getStartUserInput$4(options){const numLinePosition=options.initialX!=null?options.initialX:options.range[0];return {numDivisions:getStartNumDivisions(options),numLinePosition,rel:options.isInequality?"ge":"eq"}}const WrappedNumberLine=withDependencies(NumberLine);var NumberLine$1 = {name:"number-line",displayName:"Number line",widget:WrappedNumberLine,getCorrectUserInput: getCorrectUserInput$1,getStartUserInput: getStartUserInput$4,getUserInputFromSerializedState: getUserInputFromSerializedState$4};
|
|
2144
|
+
const MovablePoint=Graphie.MovablePoint;const Line=Graphie.Line;const{assert: assert$1}=InteractiveUtil;const bound=(x,gt,lt)=>Math.min(Math.max(x,gt),lt);const EN_DASH="–";const horizontalPadding=30;const reverseRel={eq:"eq",ge:"le",gt:"lt",le:"ge",lt:"gt"};const toggleStrictRel={eq:"eq",ge:"gt",gt:"ge",le:"lt",lt:"le"};function formatImproper(n,d){if(d===1){return ""+n}return `\\dfrac{${n}}{${d}}`}function formatMixed(n,d){if(n<0){return "-"+formatMixed(-n,d)}const w=Math.floor(n/d);if(w===0){return formatImproper(n,d)}if(n-w*d===0){return ""+w}return w+formatImproper(n-w*d,d)}function formatNonReduced(n,d,base){const factor=Math.floor(base/d);return formatImproper(n*factor,base)}const _label=(graphie,labelStyle,pos,value,base)=>{value=value||pos;if(labelStyle==="decimal"){return graphie.label([pos,-0.53],Math.round(value*100)/100,"center")}if(labelStyle==="improper"){const frac=kmath.KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatImproper(frac[0],frac[1]),"below")}if(labelStyle==="mixed"){const frac=kmath.KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatMixed(frac[0],frac[1]),"below")}if(labelStyle==="non-reduced"){const frac=kmath.KhanMath.toFraction(value);return graphie.label([pos,-0.17],formatNonReduced(frac[0],frac[1],base),"below")}};const TickMarks=Graphie.createSimpleClass((graphie,props)=>{if(!___default.default.isFinite(props.tickStep)||props.tickStep<=0){return []}const results=[];const{range,labelRange,labelStyle,labelTicks,tickStep,numDivisions}=props;const leftLabel=labelRange[0]==null?range[0]:labelRange[0];const rightLabel=labelRange[1]==null?range[1]:labelRange[1];let base;if(labelStyle==="non-reduced"){const fractions=[leftLabel,rightLabel];for(let i=0;i<=numDivisions;i++){const x=range[0]+i*tickStep;fractions.push(x);}const getDenom=x=>kmath.number.toFraction(x)[1];const denoms=___default.default.map(fractions,getDenom);base=___default.default.reduce(denoms,(x,y)=>kmath.KhanMath.getLCM(x,y));}else {base=undefined;}const highlightedLineStyle={stroke:KhanColors.BLUE,strokeWidth:3.5};const highlightedTextStyle={color:KhanColors.BLUE};const initialTicks=[...Array(Math.round(numDivisions)).keys()].map(index=>range[0]+index*tickStep);const byNumericAscending=(a,b)=>a-b;const allTicks=[...new Set([...initialTicks,leftLabel,rightLabel,...range])].sort(byNumericAscending);allTicks.forEach(tick=>{const tickIsHighlighted=tick===leftLabel||tick===rightLabel;const lineStyle=tickIsHighlighted?highlightedLineStyle:null;const textStyle=tickIsHighlighted?highlightedTextStyle:null;graphie.style(lineStyle,()=>{results.push(graphie.line([tick,-0.2],[tick,.2]));});if(labelTicks||tickIsHighlighted){graphie.style(textStyle,()=>{results.push(_label(graphie,labelStyle,tick,tick,base));});}});return results});class NumberLine extends React__namespace.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"number-line",widgetId:this.props.widgetId}});}_getInequalityEndpoint(props){const isGreater=___default.default(["ge","gt"]).contains(this.props.userInput.rel);const widthInPixels=400;const range=props.range;const scale=(range[1]-range[0])/widthInPixels;const buffer=horizontalPadding*scale;const left=range[0]-buffer;const right=range[1]+buffer;const end=isGreater?[right,0]:[left,0];return end}_renderInequality(props){if(props.isInequality){const end=this._getInequalityEndpoint(props);const style={arrows:"->",stroke:this.props.apiOptions.isMobile?KhanColors.GREEN:KhanColors.BLUE,strokeWidth:3.5};return jsxRuntimeExports.jsx(Line,{start:[props.userInput.numLinePosition,0],end:end,style:style})}return null}focus(){if(this.props.isTickCtrl){this.refs["tick-ctrl"].focus();return true}return false}getDOMNodeForPath(inputPath){if(inputPath?.length===1){return ReactDOM__namespace.default.findDOMNode(this.refs[inputPath[0]])}return null}getSerializedState(){const props=this.props;return {alignment:props.alignment,static:props.static,range:props.range,labelRange:props.labelRange,labelStyle:props.labelStyle,labelTicks:props.labelTicks,divisionRange:props.divisionRange,snapDivisions:props.snapDivisions,isInequality:props.isInequality,showTooltips:props.showTooltips,isTickCtrl:props.isTickCtrl,numDivisions:props.userInput.numDivisions,numLinePosition:props.userInput.numLinePosition,rel:"ge"}}getPromptJSON(){return getPromptJSON$6(this.props)}render(){const{strings}=this.context;const divisionRange=this.props.divisionRange;const divRangeString=divisionRange[0]+EN_DASH+divisionRange[1];const invalidNumDivisions=this.props.userInput?.numDivisions<divisionRange[0]||this.props.userInput?.numDivisions>divisionRange[1];const inequalityControls=jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("input",{type:"button",className:"simple-button",value:strings.switchDirection,onClick:this.handleReverse}),jsxRuntimeExports.jsx("input",{type:"button",className:"simple-button",value:["le","ge"].includes(this.props.userInput?.rel)?strings.circleOpen:strings.circleFilled,onClick:this.handleToggleStrict})]});let tickCtrl;if(this.props.isTickCtrl){let Input;if(this.props.apiOptions.customKeypad){Input=SimpleKeypadInput;}else {Input=NumberInput;}tickCtrl=jsxRuntimeExports.jsxs("label",{children:[strings.numDivisions," ",jsxRuntimeExports.jsx(Input,{ref:"tick-ctrl",value:this.state.numDivisionsEmpty?null:this.props.userInput?.numDivisions||divisionRange[0],checkValidity:val=>val>=divisionRange[0]&&val<=divisionRange[1],onChange:this.onNumDivisionsChange,onFocus:this._handleTickCtrlFocus,onBlur:this._handleTickCtrlBlur,useArrowKeys:true,keypadElement:this.props.keypadElement})]});}return jsxRuntimeExports.jsxs("div",{className:"perseus-widget "+"perseus-widget-interactive-number-line",children:[tickCtrl,!this.isValid()?jsxRuntimeExports.jsx("div",{className:"perseus-error",children:"Invalid number line configuration."}):this.props.isTickCtrl&&invalidNumDivisions?jsxRuntimeExports.jsx("div",{className:"perseus-error",children:strings.divisions({divRangeString:divRangeString})}):this._renderGraphie(),!this.props.static&&this.props.isInequality&&inequalityControls]})}constructor(...args){super(...args),this.state={numDivisionsEmpty:false},this.isValid=()=>{const range=this.props.range;let initialX=this.props.userInput?.numLinePosition;const divisionRange=this.props.divisionRange;initialX=initialX==null?range[0]:initialX;return range[0]<range[1]&&kmath.number.sign(initialX-range[0])>=0&&kmath.number.sign(initialX-range[1])<=0&&divisionRange[0]<divisionRange[1]&&0<this.props.userInput?.numDivisions&&0<this.props.snapDivisions},this.snapNumLinePosition=(props,numLinePosition)=>{const left=props.range[0];const right=props.range[1];const snapX=props.tickStep/this.props.snapDivisions;let x=bound(numLinePosition,left,right);x=left+kmath.number.roundTo(x-left,snapX);assert$1(___default.default.isFinite(x));return x},this.onNumDivisionsChange=(numDivisions,cb)=>{const width=this.props.range[1]-this.props.range[0];numDivisions=Math.round(numDivisions);numDivisions=numDivisions<0?numDivisions*-1:numDivisions;if(numDivisions){const nextProps={...this.props,tickStep:width/numDivisions};const newNumLinePosition=this.snapNumLinePosition(nextProps,this.props.userInput.numLinePosition);this.setState({numDivisionsEmpty:false},()=>{this.props.handleUserInput({...this.props.userInput,numDivisions:numDivisions,numLinePosition:newNumLinePosition},cb);});}else {this.setState({numDivisionsEmpty:true},cb);}},this._handleTickCtrlFocus=()=>{this.props.onFocus(["tick-ctrl"]);},this._handleTickCtrlBlur=()=>{this.props.onBlur(["tick-ctrl"]);},this.movePosition=targetPosition=>{this.props.handleUserInput({...this.props.userInput,numLinePosition:targetPosition});this.props.trackInteraction();},this.handleReverse=()=>{const newRel=reverseRel[this.props.userInput.rel];this.props.handleUserInput({...this.props.userInput,rel:newRel});},this.handleToggleStrict=()=>{const newRel=toggleStrictRel[this.props.userInput.rel];this.props.handleUserInput({...this.props.userInput,rel:newRel});},this._setupGraphie=(graphie,options)=>{if(!this.isValid()){return}const widthInPixels=this.props.apiOptions.isMobile?288-horizontalPadding*2:400;const range=options.range;const scale=(range[1]-range[0])/widthInPixels;const buffer=horizontalPadding*scale;const left=range[0]-buffer;const right=range[1]+buffer;const hasFractionalLabels=this.props.labelStyle==="improper"||this.props.labelStyle==="mixed"||this.props.labelStyle==="non-reduced";const bottom=hasFractionalLabels?-1.5:-1;const top=1;graphie.init({range:[[left,right],[bottom,top]],scale:[1/scale,40],isMobile:this.props.apiOptions.isMobile});const center=(range[0]+range[1])/2;graphie.line([center,0],[right,0],{arrows:"->"});graphie.line([center,0],[left,0],{arrows:"->"});},this._renderNumberLinePoint=props=>{const isOpen=___default.default(["lt","gt"]).contains(props.userInput.rel);let fill;if(isOpen){fill=KhanColors._BACKGROUND;}else if(props.static){fill=KhanColors.BLUE;}else {fill=KhanColors.GREEN;}const normalStyle={fill:fill,stroke:props.static?KhanColors.BLUE:KhanColors.GREEN,"stroke-width":isOpen?3:1};const highlightStyle={fill:isOpen?KhanColors._BACKGROUND:KhanColors.GREEN,"stroke-width":isOpen?3:1};const mobileDotStyle=props.isInequality?{stroke:KhanColors.GREEN,"fill-opacity":isOpen?0:1}:{};return jsxRuntimeExports.jsx(MovablePoint,{ref:"numberLinePoint",pointSize:6,coord:[props.userInput.numLinePosition,0],constraints:[(coord,prevCoord)=>{return [coord[0],prevCoord[1]]},(coord,prevCoord)=>{const x=this.snapNumLinePosition(props,coord[0]);return [x,coord[1]]}],normalStyle:normalStyle,highlightStyle:highlightStyle,onMove:coord=>{this.movePosition(coord[0]);},isMobile:this.props.apiOptions.isMobile,mobileStyleOverride:mobileDotStyle,showTooltips:this.props.showTooltips??false,xOnlyTooltip:true})},this._renderGraphie=()=>{const range=this.props.range;const width=range[1]-range[0];const options={range:this.props.range,isTickCtrl:this.props.isTickCtrl};const props={...this.props,tickStep:width/this.props.userInput.numDivisions};return jsxRuntimeExports.jsxs(Graphie,{ref:"graphie",box:[this.props.apiOptions.isMobile?288:460,80],options:options,onMouseDown:coord=>{this.refs.graphie.movables.numberLinePoint.grab(coord);},setup:this._setupGraphie,isMobile:this.props.apiOptions.isMobile,children:[jsxRuntimeExports.jsx(TickMarks,{range:props.range,labelTicks:props.labelTicks,labelStyle:props.labelStyle,labelRange:props.labelRange,tickStep:props.tickStep,numDivisions:props.userInput.numDivisions,isMobile:props.apiOptions.isMobile}),this._renderInequality(props),this._renderNumberLinePoint(props)]},this.props.labelStyle)},this.focusInputPath=path=>{if(path.length===1){this.refs[path[0]].focus();}},this.blurInputPath=path=>{if(path.length===1){this.refs[path[0]].blur();}},this.getInputPaths=()=>{if(this.props.isTickCtrl){return [["tick-ctrl"]]}return []};}}NumberLine.contextType=PerseusI18nContext;function getUserInputFromSerializedState$4(serializedState){return {numDivisions:serializedState.numDivisions,numLinePosition:serializedState.numLinePosition,rel:"eq"}}function getStartNumDivisions(options){const width=options.range[1]-options.range[0];let numDivisions;if(options.numDivisions!=null){numDivisions=options.numDivisions;}else if(options.tickStep!=null){numDivisions=width/options.tickStep;}else {numDivisions=undefined;}return numDivisions}function getCorrectUserInput$1(options){const numLinePosition=options.correctX!=null?options.correctX:options.range[0];return {numDivisions:getStartNumDivisions(options),numLinePosition,rel:options.isInequality&&options.correctRel||"eq"}}function getStartUserInput$4(options){const numLinePosition=options.initialX!=null?options.initialX:options.range[0];return {numDivisions:getStartNumDivisions(options),numLinePosition,rel:options.isInequality?"ge":"eq"}}const WrappedNumberLine=withDependencies(NumberLine);var NumberLine$1 = {name:"number-line",displayName:"Number line",widget:WrappedNumberLine,getCorrectUserInput: getCorrectUserInput$1,getStartUserInput: getStartUserInput$4,getUserInputFromSerializedState: getUserInputFromSerializedState$4};
|
|
2144
2145
|
|
|
2145
2146
|
const getPromptJSON$5=widgetData=>{return {type:"orderer",options:{options:widgetData.options.map(option=>option.content)},userInput:{values:widgetData.userInput.current}}};
|
|
2146
2147
|
|
|
@@ -2176,7 +2177,7 @@ var extraWidgets = [CSProgram$1,Categorizer$1,Definition$1,DeprecatedStandin$1,D
|
|
|
2176
2177
|
|
|
2177
2178
|
const init=function(){registerWidgets(basicWidgets);registerWidgets(extraWidgets);replaceDeprecatedWidgets();};
|
|
2178
2179
|
|
|
2179
|
-
const libName="@khanacademy/perseus";const libVersion="82.0.
|
|
2180
|
+
const libName="@khanacademy/perseus";const libVersion="82.0.1";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
2180
2181
|
|
|
2181
2182
|
const apiVersion={major:12,minor:0};
|
|
2182
2183
|
|