@khanacademy/perseus 90.0.2 → 90.1.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/{chunk-register-all-widgets-for-testing-CgikCidU.js → chunk-register-all-widgets-for-testing-B94oNv6V.js} +18 -9
- package/dist/chunk-register-all-widgets-for-testing-B94oNv6V.js.map +1 -0
- package/dist/icon-paths.d.ts +0 -20
- package/dist/index.css +2 -2
- package/dist/index.css.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/strings.d.ts +2 -0
- package/dist/strings.js +1 -1
- package/dist/strings.js.map +1 -1
- package/dist/testing.js +4 -1
- package/dist/testing.js.map +1 -1
- package/dist/widgets/graded-group/graded-group-answer-bar.d.ts +6 -9
- package/dist/widgets/radio/radio-component.d.ts +2 -1
- package/package.json +4 -4
- package/dist/chunk-register-all-widgets-for-testing-CgikCidU.js.map +0 -1
|
@@ -19,7 +19,7 @@ import { PerseusError, Errors, isLabeledSVG, getDataUrl, getSvgUrl, getBaseUrl,
|
|
|
19
19
|
import { TextField, TextArea } from '@khanacademy/wonder-blocks-form';
|
|
20
20
|
import { KhanAnswerTypes, emptyWidgetsFunctional, scoreWidgetsFunctional, flattenScores, scoreLabelImageMarker } from '@khanacademy/perseus-score';
|
|
21
21
|
import * as ReactDOM from 'react-dom';
|
|
22
|
-
import ReactDOM__default, { createPortal } from 'react-dom';
|
|
22
|
+
import ReactDOM__default, { flushSync, createPortal } from 'react-dom';
|
|
23
23
|
import _, { debounce as debounce$1 } from 'underscore';
|
|
24
24
|
import { CircularSpinner } from '@khanacademy/wonder-blocks-progress-spinner';
|
|
25
25
|
import { point, KhanMath, number, vector as vector$3, geometry, angles, coefficients, line } from '@khanacademy/kmath';
|
|
@@ -48,6 +48,9 @@ import caretDown from '@phosphor-icons/core/regular/caret-down.svg';
|
|
|
48
48
|
import caretUp from '@phosphor-icons/core/regular/caret-up.svg';
|
|
49
49
|
import { LabeledField } from '@khanacademy/wonder-blocks-labeled-field';
|
|
50
50
|
import warningCircleIcon$1 from '@phosphor-icons/core/regular/warning-circle.svg';
|
|
51
|
+
import arrowCounterIcon from '@phosphor-icons/core/bold/arrow-counter-clockwise-bold.svg';
|
|
52
|
+
import warningIcon from '@phosphor-icons/core/bold/warning-bold.svg';
|
|
53
|
+
import starIcon from '@phosphor-icons/core/fill/star-fill.svg';
|
|
51
54
|
import invariant from 'tiny-invariant';
|
|
52
55
|
import { vec, Coordinates, Ellipse, Plot as Plot$2, Line as Line$4, Point as Point$2, Polygon, useTransformContext, Text as Text$1, Polyline, Mafs } from 'mafs';
|
|
53
56
|
import * as KAS from '@khanacademy/kas';
|
|
@@ -1579,7 +1582,7 @@ const assert$4=InteractiveUtil.assert;const normalizeOptions$1=InteractiveUtil.n
|
|
|
1579
1582
|
|
|
1580
1583
|
const InlineIcon=({path,width,height,style={},title})=>jsxRuntimeExports.jsxs("svg",{role:"img","aria-hidden":!title,style:{verticalAlign:"middle",...style},width:`${width/height}em`,height:"1em",viewBox:`0 0 ${width} ${height}`,children:[!!title&&jsxRuntimeExports.jsx("title",{children:title}),jsxRuntimeExports.jsx("path",{d:path,fill:"currentColor"})]});
|
|
1581
1584
|
|
|
1582
|
-
const iconCheck={path:`M8.70710678,12.2928932 C8.31658249,11.9023689 7.68341751,11.9023689 7.29289322,12.2928932 C6.90236893,12.6834175 6.90236893,13.3165825 7.29289322,13.7071068 L9.82842712,16.2426407 C10.2207367,16.6349502 10.8574274,16.6328935 11.2471942,16.2380576 L16.7116603,10.7025237 C17.0996535,10.3094846 17.0955629,9.67633279 16.7025237,9.28833966 C16.3094846,8.90034653 15.6763328,8.90443714 15.2883397,9.29747629 L10.5309507,14.1167372 L8.70710678,12.2928932 Z`,width:24,height:24};const iconChevronDown={path:"M99.669 13.048q0 3.36-2.352 5.712l-41.664 41.664q-2.408 2.408-5.88 2.408t-5.712-2.408l-41.664-41.664q-2.408-2.24-2.408-5.712t2.408-5.88l4.76-4.816q2.52-2.352 5.88-2.352t5.656 2.352l31.136 31.136 31.08-31.136q2.352-2.352 5.712-2.352t5.88 2.352l4.816 4.816q2.352 2.52 2.352 5.88z",width:100,height:63.034};const iconCircle={path:"M100.035 50.046q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",width:100,height:100};const iconCircleThin={path:"M50.046 8.322q-8.493 0-16.188 3.306-15.561 6.669-22.173 22.23-3.363 7.695-3.363 16.188t3.306 16.188 8.949 13.281q5.586 5.586 13.281 8.892t16.188 3.306 16.188-3.306 13.281-8.892 8.892-13.281 3.306-16.188-3.306-16.188-8.892-13.281-13.281-8.949q-7.695-3.306-16.188-3.306zm0 91.713q-13.623 0-25.137-6.726t-18.183-18.183q-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.126q-11.514 6.726-25.08 6.726z",width:100,height:99.944};const
|
|
1585
|
+
const iconCheck={path:`M8.70710678,12.2928932 C8.31658249,11.9023689 7.68341751,11.9023689 7.29289322,12.2928932 C6.90236893,12.6834175 6.90236893,13.3165825 7.29289322,13.7071068 L9.82842712,16.2426407 C10.2207367,16.6349502 10.8574274,16.6328935 11.2471942,16.2380576 L16.7116603,10.7025237 C17.0996535,10.3094846 17.0955629,9.67633279 16.7025237,9.28833966 C16.3094846,8.90034653 15.6763328,8.90443714 15.2883397,9.29747629 L10.5309507,14.1167372 L8.70710678,12.2928932 Z`,width:24,height:24};const iconChevronDown={path:"M99.669 13.048q0 3.36-2.352 5.712l-41.664 41.664q-2.408 2.408-5.88 2.408t-5.712-2.408l-41.664-41.664q-2.408-2.24-2.408-5.712t2.408-5.88l4.76-4.816q2.52-2.352 5.88-2.352t5.656 2.352l31.136 31.136 31.08-31.136q2.352-2.352 5.712-2.352t5.88 2.352l4.816 4.816q2.352 2.52 2.352 5.88z",width:100,height:63.034};const iconCircle={path:"M100.035 50.046q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",width:100,height:100};const iconCircleThin={path:"M50.046 8.322q-8.493 0-16.188 3.306-15.561 6.669-22.173 22.23-3.363 7.695-3.363 16.188t3.306 16.188 8.949 13.281q5.586 5.586 13.281 8.892t16.188 3.306 16.188-3.306 13.281-8.892 8.892-13.281 3.306-16.188-3.306-16.188-8.892-13.281-13.281-8.949q-7.695-3.306-16.188-3.306zm0 91.713q-13.623 0-25.137-6.726t-18.183-18.183q-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.126q-11.514 6.726-25.08 6.726z",width:100,height:99.944};const iconTrash={path:"M31.293 37.506q2.052 0 2.052 2.109l0 37.506q0 1.995-2.052 2.109l-4.218 0q-.912-.057-1.482-.627t-.57-1.482l0-37.506q0-2.109 2.052-2.109l4.218 0zm18.753 2.109l0 37.506q0 .912-.57 1.482t-1.539.627l-4.161 0q-1.995 0-2.109-2.109l0-37.506q.057-.912.627-1.482t1.482-.627l4.161 0q.969.057 1.539.627t.57 1.482zm14.592-2.109q2.052 0 2.052 2.109l0 37.506q0 1.995-2.052 2.109l-4.161 0q-.969-.057-1.539-.627t-.57-1.482l0-37.506q0-2.109 2.109-2.109l4.161 0zm10.431 49.248l0-61.731l-58.368 0l0 61.731q.057 2.679.969 3.819t1.083 1.14l54.207 0q.171 0 1.14-1.083t.969-3.876zm-43.776-70.11l29.184 0l-3.135-7.581q-.456-.57-1.14-.741l-20.634 0q-.627.114-1.083.741zm-31.293 2.109q0-1.995 2.109-2.109l20.121 0l4.56-10.83q.969-2.394 3.477-4.104 2.565-1.71 5.187-1.71l20.805 0q2.622 0 5.187 1.71t3.477 4.104l4.56 10.83l20.178 0q.912.057 1.482.627t.57 1.482l0 4.161q0 1.995-2.052 2.109l-6.27 0l0 61.731q0 5.415-3.078 9.348t-7.353 3.933l-54.207 0q-4.275 0-7.353-3.819t-3.078-9.177l0-62.016l-6.213 0q-.969 0-1.539-.57t-.57-1.539l0-4.161z",width:91.681,height:100};const iconMinus={path:`M8,13 L16,13 C16.5522847,13 17,12.5522847 17,12 C17,11.4477153 16.5522847,11 16,11 L8,11 C7.44771525,11 7,11.4477153 7,12 C7,12.5522847 7.44771525,13 8,13 Z`,width:24,height:24};
|
|
1583
1586
|
|
|
1584
1587
|
const add={constrain:function(){this.constrain();}};add.standard=[add.constrain];const modify={draw:function(){this.draw();}};modify.standard=[modify.draw];const draw={basic:function(state,prevState){const graphie=this.graphie;if(!this.state.visibleShape){const radii=[this.pointSize()/graphie.scale[0],this.pointSize()/graphie.scale[1]];const options={maxScale:Math.max(this.highlightStyle().scale,this.normalStyle().scale),padding:10,shadow:state.shadow};this.state.visibleShape=new WrappedEllipse(graphie,this.coord(),radii,options);this.state.visibleShape.attr(_.omit(this.normalStyle(),"scale"));this.state.visibleShape.toFront();if(this.mouseTarget()){this.mouseTarget().toFront();}}if(state.shadow!==prevState.shadow){this.state.visibleShape.setShadow(state.shadow);}if(state.normalStyle!==prevState.normalStyle&&!_.isEqual(state.normalStyle,prevState.normalStyle)){this.state.visibleShape.attr(this.normalStyle());}this.state.visibleShape.moveTo(this.coord());if(this.mouseTarget()){this.mouseTarget().moveTo(this.coord());}},highlight:function(state,prevState){if(state.isHovering&&!prevState.isHovering){state.visibleShape.animate(this.highlightStyle(),50);}else if(!state.isHovering&&prevState.isHovering){state.visibleShape.animate(this.normalStyle(),50);}}};draw.standard=[draw.basic,draw.highlight];const remove={basic:function(){if(this.state.visibleShape){this.state.visibleShape.remove();this.state.visibleShape=null;}}};remove.standard=remove.basic;const constraints={fixed:function(){return function(){return false}},snap:function(snap){return function(coord){if(snap===null){return true}return point.roundTo(coord,snap||this.graphie.snap)}},bound:function(range,snap,optionalPaddingPx){const paddingPx=(()=>{if(optionalPaddingPx===undefined){if(range===undefined){return 10}else {return 0}}else {return optionalPaddingPx}})();return function(coord,prev,options){const graphie=this.graphie;range=range||graphie.range;if(snap===undefined){snap=graphie.snap;}let lower=graphie.unscalePoint([paddingPx,graphie.ypixels-paddingPx]);let upper=graphie.unscalePoint([graphie.xpixels-paddingPx,paddingPx]);if(snap){lower=point.ceilTo(lower,snap);upper=point.floorTo(upper,snap);}if(!!options&&!!options.onOutOfBounds){if(coord[0]>upper[0]||coord[0]<lower[0]||coord[1]>upper[1]||coord[1]<lower[1]){options.onSkipRemaining();options.onOutOfBounds();}return coord}const coordX=Math.max(lower[0],Math.min(upper[0],coord[0]));const coordY=Math.max(lower[1],Math.min(upper[1],coord[1]));return [coordX,coordY]}}};constraints.standard=null;var MovablePointOptions = {add:add,modify:modify,draw:draw,remove:remove,onMoveStart:{standard:null},constraints:constraints,onMove:{standard:null},onMoveEnd:{standard:null},onClick:{standard:null}};
|
|
1585
1588
|
|
|
@@ -1661,7 +1664,7 @@ var widgets$1 = /*#__PURE__*/Object.freeze({
|
|
|
1661
1664
|
|
|
1662
1665
|
class WidgetContainer extends React.Component{componentDidMount(){if(this.props.widgetProps.apiOptions.isMobile){const containerWidth=ReactDOM__default.findDOMNode(this).offsetWidth;this.setState({sizeClass:getClassFromWidth(containerWidth)});}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.type!==nextProps.type){throw new Error("WidgetContainer can't change widget type; set a different "+"key instead to recreate the container.")}}render(){let className=classNames$2({"perseus-widget-container":true,"perseus-widget__definition":this.props.type==="definition"});const type=this.props.type;const userAgent=navigator.userAgent;const WidgetType=getWidget(type);if(WidgetType==null){console.warn(`Widget type '${type}' not found!`);return jsxRuntimeExports.jsx("div",{className:className})}const subType=getWidgetSubType(type,this.props.widgetProps.options)??"null";let alignment=this.props.widgetProps.alignment;if(alignment==null||alignment==="default"){alignment=CoreWidgetRegistry.getDefaultAlignment(type);}className+=CoreWidgetRegistry.getAlignmentClassName(type,alignment);const Container=CoreWidgetRegistry.isInlineWidget(type,alignment)?"span":"div";const apiOptions=this.props.widgetProps.apiOptions;const isStatic=this.props.widgetProps.static||apiOptions.readOnly;const staticContainerStyles={position:"relative",overflow:"visible"};const staticOverlayStyles={width:"100%",height:"100%",position:"absolute",top:0,left:0,zIndex:3};const linterContext=isLintable(type)?this.props.widgetProps.linterContext:{...this.props.widgetProps.linterContext,highlightLint:false};return jsxRuntimeExports.jsx(Container,{className:className,style:isStatic?staticContainerStyles:{},children:jsxRuntimeExports.jsx(DependenciesContext.Consumer,{children:({analytics})=>jsxRuntimeExports.jsxs(ErrorBoundary,{metadata:{widget_type:type,widget_id:this.props.id},onError:error=>{analytics.onAnalyticsEvent({type:"perseus:widget-rendering-error:ti",payload:{widgetSubType:subType,widgetType:type,widgetId:this.props.id,message:error.message,stack:error.stack??"No stack trace available",userAgent:userAgent}});},children:[jsxRuntimeExports.jsx(WidgetType,{...this.props.widgetProps,linterContext:linterContext,containerSizeClass:this.state.sizeClass,ref:this.widgetRef}),isStatic&&jsxRuntimeExports.jsx("div",{style:staticOverlayStyles})]})})})}constructor(...args){super(...args),this.widgetRef=React.createRef(),this.state={sizeClass:containerSizeClass.MEDIUM},this.getWidget=()=>{return this.widgetRef.current};}}
|
|
1663
1666
|
|
|
1664
|
-
const rContainsNonWhitespace$1=/\S/;const rImageURL$1=/(web\+graphie|https):\/\/[^\s]*/;const noopOnRender$1=()=>{};const makeContainerId$1=id=>"container:"+id;const isIdPathPrefix$1=function(prefixArray,wholeArray){if(prefixArray===null||wholeArray===null){return prefixArray===wholeArray}return _.every(prefixArray,(elem,i)=>{if(wholeArray!=null){return _.isEqual(elem,wholeArray[i])}})};function isDifferentQuestion$1(propsA,propsB){function makeItem(props){return splitPerseusItem({question:{content:props.content,widgets:props.widgets,images:{}},hints:[],answerArea:getDefaultAnswerArea()})}return propsA.problemNum!==propsB.problemNum||!_.isEqual(makeItem(propsA),makeItem(propsB))}let Renderer$2 = class Renderer extends React.Component{componentDidMount(){this._isMounted=true;this.handleRender({});this._currentFocus=null;this.props.initializeUserInput?.(this.props.widgets,this.props.problemNum??0);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}UNSAFE_componentWillReceiveProps(nextProps){if(isDifferentQuestion$1(this.props,nextProps)){this.props.initializeUserInput?.(nextProps.widgets,nextProps.problemNum??0);this.setState(this._getInitialWidgetState(nextProps));}}shouldComponentUpdate(nextProps,nextState){if(this.props.alwaysUpdate){return true}const stateChanged=!_.isEqual(this.state,nextState);const propsChanged=!_.isEqual(this.props,nextProps);return propsChanged||stateChanged}componentDidUpdate(prevProps,prevState){this.handleRender(prevProps);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput&&!_.isEqual(this.props.userInput,prevProps.userInput)){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}componentWillUnmount(){this.widgetIds=[];if(this.translationIndex!=null){getDependencies().rendererTranslationComponents.removeComponentAtIndex(this.translationIndex);}this._isMounted=false;}_isAnswerable(){if(this.props.userInput){return this.emptyWidgets().length===0}return false}_getWidgetIndexById(id){const widgetIndex=this.widgetIds.indexOf(id);if(widgetIndex<0){Log.error("Unable to get widget index in _getWidgetIndexById",Errors.Internal,{loggedMetadata:{widgets:JSON.stringify(this.props.widgets),widgetId:JSON.stringify(id)}});return 0}return widgetIndex}getWidgetProps(widgetId){const apiOptions=this.getApiOptions();const widgetOptions=this.props.widgets[widgetId].options;const widgetInfo=this.state.widgetInfo[widgetId];if(!this._interactionTrackers){this._interactionTrackers={};}let interactionTracker=this._interactionTrackers[widgetId];if(!interactionTracker){interactionTracker=this._interactionTrackers[widgetId]=new InteractionTracker(apiOptions.trackInteraction,widgetInfo&&widgetInfo.type,widgetId,getTracking(widgetInfo&&widgetInfo.type));}return {options:widgetOptions,userInput:this.props.userInput?.[widgetId],widgetId:widgetId,widgetIndex:this._getWidgetIndexById(widgetId),alignment:widgetInfo&&widgetInfo.alignment,static:widgetInfo?.static,graded:widgetInfo?.graded,problemNum:this.props.problemNum,apiOptions:this.getApiOptions(),keypadElement:this.props.keypadElement,showSolutions:this.props.showSolutions,onFocus:_.partial(this._onWidgetFocus,widgetId),onBlur:_.partial(this._onWidgetBlur,widgetId),findWidgets:this.findWidgets,reviewMode:this.props.reviewMode??false,isScorable:this.props.isScorable??false,containerSizeClass:containerSizeClass.MEDIUM,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"widget"),handleUserInput:newUserInput=>{const updatedUserInput={...this.props.userInput,[widgetId]:newUserInput};const emptyWidgetIds=emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,updatedUserInput,this.context.locale);const widgetsEmpty=emptyWidgetIds.length>0;this.props.handleUserInput?.(widgetId,newUserInput,widgetsEmpty);this.props.apiOptions?.interactionCallback?.(updatedUserInput);},trackInteraction:interactionTracker.track}}getSerializedState(){return mapObject(this.props.widgets,(widgetData,widgetId)=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getSerializedState){return excludeDenylistKeys(widget.getSerializedState())}return widgetData.options})}replaceJiptContent(content,paragraphIndex){if(paragraphIndex==null){this.setState({jiptContent:content});}else {const codeFenceRegex=/^\s*(`{3,}|~{3,})\s*(\S+)?\s*\n([\s\S]+?)\s*\1\s*$/;if(codeFenceRegex.test(content));else if(/\S\n\s*\n\S/.test(content)){content="$\\large{\\red{\\text{Please translate each "+"paragraph to a single paragraph.}}}$";}else if(/^\s*$/.test(content)){content="$\\large{\\red{\\text{Translated paragraph is "+"currently empty}}}$";}const allContent=this.getContent(this.props,this.state);const paragraphs=JiptParagraphs.parseToArray(allContent);paragraphs[paragraphIndex]=content;this.setState({jiptContent:JiptParagraphs.joinFromArray(paragraphs)});}}emptyWidgets(){if(!this.props.userInput){throw new Error(`emptyWidgets called without providing userInput to Renderer`)}return emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale)}getUserInputMap(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInputMap called without providing userInput to Renderer`)}return userInput}getPromptJSON(){const{content}=this.props;const widgetJSON={};this.widgetIds.forEach(id=>{const widget=this.getWidgetInstance(id);widgetJSON[id]=widget?.getPromptJSON?.()||{};});return {content,widgets:widgetJSON}}score(){if(!this.props.userInput){throw new Error(`score called without providing userInput to Renderer`)}const scores=scoreWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale);const combinedScore=flattenScores(scores);return combinedScore}render(){const apiOptions=this.getApiOptions();const content=this.getContent(this.props,this.state);this.widgetIds=[];if(this.shouldRenderJiptPlaceholder(this.props,this.state)){if(!this.translationIndex){this.translationIndex=getDependencies().rendererTranslationComponents.addComponent(this);}if(!apiOptions.isArticle){return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{"data-perseus-component-index":this.translationIndex,children:content})})}}this._isTwoColumn=false;let parsedMarkdown=this.props.inline?PerseusMarkdown$1.parseInline(content,{isJipt:this.translationIndex!=null}):PerseusMarkdown$1.parse(content,{isJipt:this.translationIndex!=null});parsedMarkdown=Util.splitBlockWidgetsFromParagraphs(parsedMarkdown);if(this.props.linterContext.highlightLint){const fullLinterContext={content:this.props.content,widgets:this.props.widgets,...this.props.linterContext};PerseusLinter.runLinter(parsedMarkdown,fullLinterContext,true);this._translationLinter.applyLintErrors(parsedMarkdown,[...this.state.translationLintErrors,...this.props.legacyPerseusLint||[]]);}const markdownContents=this.outputMarkdown(Util.joinAdjacentTextNodes(parsedMarkdown),{baseElements:apiOptions.baseElements});const className=classNames$2({[ClassNames.RENDERER]:true,[ClassNames.RESPONSIVE_RENDERER]:true,[ClassNames.TWO_COLUMN_RENDERER]:this._isTwoColumn});return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{className:className,children:markdownContents})})}constructor(props){super(props),this._widgetContainers=new Map,this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions}},this._getInitialWidgetState=props=>{const allWidgetInfo=applyDefaultsToWidgets(props.widgets);return {widgetInfo:allWidgetInfo}},this._getDefaultWidgetInfo=widgetId=>{const widgetIdParts=Util.rTypeFromWidgetId.exec(widgetId);if(widgetIdParts==null){return {}}return {type:widgetIdParts[1],graded:true,options:{}}},this._getWidgetInfo=widgetId=>{return this.state.widgetInfo[widgetId]||this._getDefaultWidgetInfo(widgetId)},this.renderWidget=(impliedType,id,state)=>{const widgetInfo=this.state.widgetInfo[id];if(widgetInfo&&widgetInfo.alignment==="full-width"){state.foundFullWidth=true;}if(widgetInfo){const type=widgetInfo&&widgetInfo.type||impliedType;return jsxRuntimeExports.jsx(WidgetContainer,{id:id,ref:node=>{const containerId=makeContainerId$1(id);if(node!=null){this._widgetContainers.set(containerId,node);}else {this._widgetContainers.delete(containerId);}},type:type,widgetProps:this.getWidgetProps(id)},makeContainerId$1(id))}return null},this.findInternalWidgets=filterCriterion=>{let filterFunc;if(typeof filterCriterion==="string"){if(filterCriterion.indexOf(" ")!==-1){const widgetId=filterCriterion;filterFunc=(id,widgetInfo,widget)=>id===widgetId;}else {const widgetType=filterCriterion;filterFunc=(id,widgetInfo,widget)=>{return widgetInfo.type===widgetType};}}else {filterFunc=filterCriterion;}const results=this.widgetIds.filter(id=>{const widgetInfo=this._getWidgetInfo(id);const widget=this.getWidgetInstance(id);return filterFunc(id,widgetInfo,widget)}).map(this.getWidgetInstance);return results},this.findWidgets=filterCriterion=>{return [...this.findInternalWidgets(filterCriterion),...this.props.findExternalWidgets(filterCriterion)]},this.getWidgetInstance=id=>{const ref=this._widgetContainers.get(makeContainerId$1(id));if(!ref){return null}return ref.getWidget()},this._onWidgetFocus=(id,focusPath=[])=>{if(!Array.isArray(focusPath)){throw new PerseusError("widget props.onFocus focusPath must be an Array, "+"but was"+JSON.stringify(focusPath),Errors.Internal)}this._setCurrentFocus([id].concat(focusPath));},this._onWidgetBlur=(id,blurPath)=>{const blurringFocusPath=this._currentFocus;const fullPath=[id].concat(blurPath);if(!_.isEqual(fullPath,blurringFocusPath)){return}_.defer(()=>{if(_.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.getContent=(props,state)=>{return state.jiptContent||props.content},this.shouldRenderJiptPlaceholder=(props,state)=>{return getDependencies().JIPT.useJIPT&&state.jiptContent==null&&props.content.indexOf("crwdns")!==-1},this.outputMarkdown=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;state.paragraphIndex=i;const nodeOut=this.outputMarkdown(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}this._foundTextNodes=false;state.foundFullWidth=false;const output=this.outputNested(ast,state);let className;if(this.translationIndex!=null){className=null;}else {className=classNames$2({"perseus-paragraph-centered":!this._foundTextNodes,"perseus-paragraph-full-width":state.foundFullWidth&&ast.content?.length===1});}return jsxRuntimeExports.jsx(QuestionParagraph$1,{className:className,translationIndex:this.translationIndex,paragraphIndex:state.paragraphIndex,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:output})},state.key)},this.outputNested=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;const nodeOut=this.outputNested(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}return this.outputNode(ast,this.outputNested,state)},this.outputNode=(node,nestedOutput,state)=>{const apiOptions=this.getApiOptions();const imagePlaceholder=apiOptions.imagePlaceholder;if(node.type==="widget"){const widgetPlaceholder=apiOptions.widgetPlaceholder;if(widgetPlaceholder){return widgetPlaceholder}this._foundTextNodes=true;if(this.widgetIds.includes(node.id)){return jsxRuntimeExports.jsx("span",{className:"renderer-widget-error",children:["Widget [[","☃"," ",node.id,"]] already exists."].join("")},state.key)}this.widgetIds.push(node.id);return this.renderWidget(node.widgetType,node.id,state)}if(node.type==="blockMath"){const content=preprocessTex(node.content);const innerStyle={overflowX:"auto",overflowY:"hidden",paddingTop:10,paddingBottom:10,marginTop:-10,marginBottom:-10};if(apiOptions.isMobile){const margin=16;const outerStyle={marginLeft:-16,marginRight:-16};const horizontalPadding={paddingLeft:margin,paddingRight:margin};const mobileInnerStyle={...innerStyle,...styles$u.mobileZoomableParentFix};return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",style:outerStyle,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:{...mobileInnerStyle,...horizontalPadding},children:jsxRuntimeExports.jsx(ZoomableTeX,{children:content})})})},state.key)}return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:innerStyle,children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{setAssetStatus:setAssetStatus,children:content})})})})},state.key)}if(node.type==="math"){const tex=node.content;return jsxRuntimeExports.jsx("span",{style:{whiteSpace:"nowrap"},children:jsxRuntimeExports.jsxs(ErrorBoundary,{children:[jsxRuntimeExports.jsx("span",{}),jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.props.onRender,setAssetStatus:setAssetStatus,children:tex})}),jsxRuntimeExports.jsx("span",{})]})},state.key)}if(node.type==="image"){if(imagePlaceholder){return imagePlaceholder}const extraAttrs=_.has(this.props.images,node.target)?this.props.images[node.target]:null;const responsive=!state.inTable;return jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{allowZoom:true,setAssetStatus:setAssetStatus,src:PerseusMarkdown$1.sanitizeUrl(node.target),alt:node.alt,title:node.title,responsive:responsive,onUpdate:this.props.onRender,...extraAttrs})})},state.key)}if(node.type==="columns"){this._isTwoColumn=true;return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown$1.ruleOutput(node,nestedOutput,state)},state.key)}if(node.type==="text"){if(rContainsNonWhitespace$1.test(node.content)){this._foundTextNodes=true;}if(imagePlaceholder&&rImageURL$1.test(node.content)){return imagePlaceholder}return node.content}if(node.type==="table"||node.type==="titledTable"){const output=PerseusMarkdown$1.ruleOutput(node,nestedOutput,{...state,isMobile:apiOptions.isMobile,inTable:true});if(!apiOptions.isMobile){return output}const outerStyle={marginLeft:-16,marginRight:-16};const innerStyle={paddingLeft:0,paddingRight:0};const mobileInnerStyle={...innerStyle,...styles$u.mobileZoomableParentFix};const wrappedOutput=jsxRuntimeExports.jsx("div",{style:{...mobileInnerStyle,overflowX:"auto"},children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(Zoomable$1,{animateHeight:true,children:output})})});return jsxRuntimeExports.jsx("div",{style:outerStyle,children:wrappedOutput})}return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown$1.ruleOutput(node,nestedOutput,state)},state.key)},this.handleRender=prevProps=>{const onRender=this.props.onRender;const oldOnRender=prevProps.onRender;if(onRender!==noopOnRender$1||oldOnRender!==noopOnRender$1){const node=ReactDOM__default.findDOMNode(this);if(node instanceof Element){node.querySelectorAll("img").forEach(image=>{if(oldOnRender!==noopOnRender$1){image.removeEventListener("load",oldOnRender);}if(onRender!==noopOnRender$1){image.addEventListener("load",onRender);}});}}onRender();},this._setCurrentFocus=path=>{const apiOptions=this.getApiOptions();if(!isIdPathPrefix$1(path,this._currentFocus)){const prevFocus=this._currentFocus;if(prevFocus){this.blurPath(prevFocus);}this._currentFocus=path;apiOptions.onFocusChange(this._currentFocus,prevFocus);}},this.focus=()=>{let id;let focusResult;for(let i=0;i<this.widgetIds.length;i++){const widgetId=this.widgetIds[i];const widget=this.getWidgetInstance(widgetId);const widgetFocusResult=widget?.focus?.();if(widgetFocusResult){id=widgetId;focusResult=widgetFocusResult;break}}if(id){let path;if(typeof focusResult==="object"){path=[id].concat(focusResult.path||[]);Log.error("Renderer received a focus result of type 'object' "+"instead of the expected type 'boolean'",Errors.Internal,{loggedMetadata:{focusResult:JSON.stringify(focusResult)}});}else {path=[id];}this._setCurrentFocus(path);return true}},this.getDOMNodeForPath=path=>{const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget?.getDOMNodeForPath){return widget.getDOMNodeForPath(interWidgetPath)}if(interWidgetPath.length===0){const container=this._widgetContainers.get(makeContainerId$1(widgetId));if(container){return ReactDOM__default.findDOMNode(container)}return ReactDOM__default.findDOMNode(widget)}},this.getInputPaths=()=>{const inputPaths=[];this.widgetIds.forEach(widgetId=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getInputPaths){const widgetInputPaths=widget.getInputPaths();widgetInputPaths.forEach(inputPath=>{const relativeInputPath=[widgetId].concat(inputPath);inputPaths.push(relativeInputPath);});}});return inputPaths},this.focusPath=path=>{if(_.isEqual(this._currentFocus,path)){return}if(this._currentFocus){this.blurPath(this._currentFocus);}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const focusWidget=this.getWidgetInstance(widgetId);focusWidget?.focusInputPath?.(interWidgetPath);},this.blurPath=path=>{if(!_.isEqual(this._currentFocus,path)){return}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget){const blurWidget=this.getWidgetInstance(widgetId);blurWidget?.blurInputPath?.(interWidgetPath);}},this.blur=()=>{if(this._currentFocus){this.blurPath(this._currentFocus);}},this.getWidgetIds=()=>{return this.widgetIds},this.handletranslationLintErrors=lintErrors=>{if(!this._isMounted){return}this.setState({translationLintErrors:lintErrors});};this._translationLinter=new TranslationLinter;this.state={jiptContent:null,translationLintErrors:[],...this._getInitialWidgetState(props)};}};Renderer$2.contextType=PerseusI18nContext;Renderer$2.defaultProps={content:"",widgets:{},images:{},showSolutions:"none",onRender:noopOnRender$1,findExternalWidgets:()=>[],alwaysUpdate:false,reviewMode:false,isScorable:false,linterContext:PerseusLinter.linterContextDefault};const styles$u={mobileZoomableParentFix:{transform:"translate3d(0,0,0)"}};
|
|
1667
|
+
const rContainsNonWhitespace$1=/\S/;const rImageURL$1=/(web\+graphie|https):\/\/[^\s]*/;const noopOnRender$1=()=>{};const makeContainerId$1=id=>"container:"+id;const isIdPathPrefix$1=function(prefixArray,wholeArray){if(prefixArray===null||wholeArray===null){return prefixArray===wholeArray}return _.every(prefixArray,(elem,i)=>{if(wholeArray!=null){return _.isEqual(elem,wholeArray[i])}})};function isDifferentQuestion$1(propsA,propsB){function makeItem(props){return splitPerseusItem({question:{content:props.content,widgets:props.widgets,images:{}},hints:[],answerArea:getDefaultAnswerArea()})}return propsA.problemNum!==propsB.problemNum||!_.isEqual(makeItem(propsA),makeItem(propsB))}let Renderer$2 = class Renderer extends React.Component{componentDidMount(){this._isMounted=true;this.handleRender({});this._currentFocus=null;this.props.initializeUserInput?.(this.props.widgets,this.props.problemNum??0);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}UNSAFE_componentWillReceiveProps(nextProps){if(isDifferentQuestion$1(this.props,nextProps)){this.props.initializeUserInput?.(nextProps.widgets,nextProps.problemNum??0);this.setState(this._getInitialWidgetState(nextProps));}}shouldComponentUpdate(nextProps,nextState){if(this.props.alwaysUpdate){return true}const stateChanged=!_.isEqual(this.state,nextState);const propsChanged=!_.isEqual(this.props,nextProps);return propsChanged||stateChanged}componentDidUpdate(prevProps,prevState){this.handleRender(prevProps);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput&&!_.isEqual(this.props.userInput,prevProps.userInput)){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}componentWillUnmount(){this.widgetIds=[];if(this.translationIndex!=null){getDependencies().rendererTranslationComponents.removeComponentAtIndex(this.translationIndex);}this._isMounted=false;}_isAnswerable(){if(this.props.userInput){return this.emptyWidgets().length===0}return false}_getWidgetIndexById(id){const widgetIndex=this.widgetIds.indexOf(id);if(widgetIndex<0){Log.error("Unable to get widget index in _getWidgetIndexById",Errors.Internal,{loggedMetadata:{widgets:JSON.stringify(this.props.widgets),widgetId:JSON.stringify(id)}});return 0}return widgetIndex}getWidgetProps(widgetId){const apiOptions=this.getApiOptions();const widgetOptions=this.props.widgets[widgetId].options;const widgetInfo=this.state.widgetInfo[widgetId];if(!this._interactionTrackers){this._interactionTrackers={};}let interactionTracker=this._interactionTrackers[widgetId];if(!interactionTracker){interactionTracker=this._interactionTrackers[widgetId]=new InteractionTracker(apiOptions.trackInteraction,widgetInfo&&widgetInfo.type,widgetId,getTracking(widgetInfo&&widgetInfo.type));}return {options:widgetOptions,userInput:this.props.userInput?.[widgetId],widgetId:widgetId,widgetIndex:this._getWidgetIndexById(widgetId),alignment:widgetInfo&&widgetInfo.alignment,static:widgetInfo?.static,graded:widgetInfo?.graded,problemNum:this.props.problemNum,apiOptions:this.getApiOptions(),keypadElement:this.props.keypadElement,showSolutions:this.props.showSolutions,onFocus:_.partial(this._onWidgetFocus,widgetId),onBlur:_.partial(this._onWidgetBlur,widgetId),findWidgets:this.findWidgets,reviewMode:this.props.reviewMode??false,isScorable:this.props.isScorable??false,containerSizeClass:containerSizeClass.MEDIUM,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"widget"),handleUserInput:newUserInput=>{const updatedUserInput={...this.props.userInput,[widgetId]:newUserInput};const emptyWidgetIds=emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,updatedUserInput,this.context.locale);const widgetsEmpty=emptyWidgetIds.length>0;this.props.handleUserInput?.(widgetId,newUserInput,widgetsEmpty);this.props.apiOptions?.interactionCallback?.(updatedUserInput);},trackInteraction:interactionTracker.track}}getSerializedState(){return mapObject(this.props.widgets,(widgetData,widgetId)=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getSerializedState){return excludeDenylistKeys(widget.getSerializedState())}return widgetData.options})}replaceJiptContent(content,paragraphIndex){if(paragraphIndex==null){this.setState({jiptContent:content});}else {const codeFenceRegex=/^\s*(`{3,}|~{3,})\s*(\S+)?\s*\n([\s\S]+?)\s*\1\s*$/;if(codeFenceRegex.test(content));else if(/\S\n\s*\n\S/.test(content)){content="$\\large{\\red{\\text{Please translate each "+"paragraph to a single paragraph.}}}$";}else if(/^\s*$/.test(content)){content="$\\large{\\red{\\text{Translated paragraph is "+"currently empty}}}$";}const allContent=this.getContent(this.props,this.state);const paragraphs=JiptParagraphs.parseToArray(allContent);paragraphs[paragraphIndex]=content;this.setState({jiptContent:JiptParagraphs.joinFromArray(paragraphs)});}}emptyWidgets(){if(!this.props.userInput){throw new Error(`emptyWidgets called without providing userInput to Renderer`)}return emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale)}getUserInputMap(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInputMap called without providing userInput to Renderer`)}return userInput}getPromptJSON(){const{content}=this.props;const widgetJSON={};this.widgetIds.forEach(id=>{const widget=this.getWidgetInstance(id);widgetJSON[id]=widget?.getPromptJSON?.()||{};});return {content,widgets:widgetJSON}}score(){if(!this.props.userInput){throw new Error(`score called without providing userInput to Renderer`)}const scores=scoreWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale);const combinedScore=flattenScores(scores);return combinedScore}render(){const apiOptions=this.getApiOptions();const content=this.getContent(this.props,this.state);this.widgetIds=[];if(this.shouldRenderJiptPlaceholder(this.props,this.state)){if(!this.translationIndex){this.translationIndex=getDependencies().rendererTranslationComponents.addComponent(this);}if(!apiOptions.isArticle){return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{"data-perseus-component-index":this.translationIndex,children:content})})}}this._isTwoColumn=false;let parsedMarkdown=this.props.inline?PerseusMarkdown$1.parseInline(content,{isJipt:this.translationIndex!=null}):PerseusMarkdown$1.parse(content,{isJipt:this.translationIndex!=null});parsedMarkdown=Util.splitBlockWidgetsFromParagraphs(parsedMarkdown);if(this.props.linterContext.highlightLint){const fullLinterContext={content:this.props.content,widgets:this.props.widgets,...this.props.linterContext};PerseusLinter.runLinter(parsedMarkdown,fullLinterContext,true);this._translationLinter.applyLintErrors(parsedMarkdown,[...this.state.translationLintErrors,...this.props.legacyPerseusLint||[]]);}const markdownContents=this.outputMarkdown(Util.joinAdjacentTextNodes(parsedMarkdown),{baseElements:apiOptions.baseElements});const className=classNames$2({[ClassNames.RENDERER]:true,[ClassNames.RESPONSIVE_RENDERER]:true,[ClassNames.TWO_COLUMN_RENDERER]:this._isTwoColumn});return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{className:className,children:markdownContents})})}constructor(props){super(props),this._widgetContainers=new Map,this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions}},this._getInitialWidgetState=props=>{const allWidgetInfo=applyDefaultsToWidgets(props.widgets);return {widgetInfo:allWidgetInfo}},this._getDefaultWidgetInfo=widgetId=>{const widgetIdParts=Util.rTypeFromWidgetId.exec(widgetId);if(widgetIdParts==null){return {}}return {type:widgetIdParts[1],graded:true,options:{}}},this._getWidgetInfo=widgetId=>{return this.state.widgetInfo[widgetId]||this._getDefaultWidgetInfo(widgetId)},this.renderWidget=(impliedType,id,state)=>{const widgetInfo=this.state.widgetInfo[id];if(widgetInfo&&widgetInfo.alignment==="full-width"){state.foundFullWidth=true;}if(widgetInfo){const type=widgetInfo&&widgetInfo.type||impliedType;return jsxRuntimeExports.jsx(WidgetContainer,{id:id,ref:node=>{const containerId=makeContainerId$1(id);if(node!=null){this._widgetContainers.set(containerId,node);}else {this._widgetContainers.delete(containerId);}},type:type,widgetProps:this.getWidgetProps(id)},makeContainerId$1(id))}return null},this.findInternalWidgets=filterCriterion=>{let filterFunc;if(typeof filterCriterion==="string"){if(filterCriterion.indexOf(" ")!==-1){const widgetId=filterCriterion;filterFunc=(id,widgetInfo,widget)=>id===widgetId;}else {const widgetType=filterCriterion;filterFunc=(id,widgetInfo,widget)=>{return widgetInfo.type===widgetType};}}else {filterFunc=filterCriterion;}const results=this.widgetIds.filter(id=>{const widgetInfo=this._getWidgetInfo(id);const widget=this.getWidgetInstance(id);return filterFunc(id,widgetInfo,widget)}).map(this.getWidgetInstance);return results},this.findWidgets=filterCriterion=>{return [...this.findInternalWidgets(filterCriterion),...this.props.findExternalWidgets(filterCriterion)]},this.getWidgetInstance=id=>{const ref=this._widgetContainers.get(makeContainerId$1(id));if(!ref){return null}return ref.getWidget()},this._onWidgetFocus=(id,focusPath=[])=>{if(!Array.isArray(focusPath)){throw new PerseusError("widget props.onFocus focusPath must be an Array, "+"but was"+JSON.stringify(focusPath),Errors.Internal)}this._setCurrentFocus([id].concat(focusPath));},this._onWidgetBlur=(id,blurPath)=>{const blurringFocusPath=this._currentFocus;const fullPath=[id].concat(blurPath);if(!_.isEqual(fullPath,blurringFocusPath)){return}_.defer(()=>{if(_.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.getContent=(props,state)=>{return state.jiptContent||props.content},this.shouldRenderJiptPlaceholder=(props,state)=>{return getDependencies().JIPT.useJIPT&&state.jiptContent==null&&props.content.indexOf("crwdns")!==-1},this.outputMarkdown=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;state.paragraphIndex=i;const nodeOut=this.outputMarkdown(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}this._foundTextNodes=false;state.foundFullWidth=false;const output=this.outputNested(ast,state);let className;if(this.translationIndex!=null){className=null;}else {className=classNames$2({"perseus-paragraph-centered":!this._foundTextNodes&&!this.props.inline,"perseus-paragraph-full-width":state.foundFullWidth&&ast.content?.length===1});}return jsxRuntimeExports.jsx(QuestionParagraph$1,{className:className,translationIndex:this.translationIndex,paragraphIndex:state.paragraphIndex,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:output})},state.key)},this.outputNested=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;const nodeOut=this.outputNested(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}return this.outputNode(ast,this.outputNested,state)},this.outputNode=(node,nestedOutput,state)=>{const apiOptions=this.getApiOptions();const imagePlaceholder=apiOptions.imagePlaceholder;if(node.type==="widget"){const widgetPlaceholder=apiOptions.widgetPlaceholder;if(widgetPlaceholder){return widgetPlaceholder}this._foundTextNodes=true;if(this.widgetIds.includes(node.id)){return jsxRuntimeExports.jsx("span",{className:"renderer-widget-error",children:["Widget [[","☃"," ",node.id,"]] already exists."].join("")},state.key)}this.widgetIds.push(node.id);return this.renderWidget(node.widgetType,node.id,state)}if(node.type==="blockMath"){const content=preprocessTex(node.content);const innerStyle={overflowX:"auto",overflowY:"hidden",paddingTop:10,paddingBottom:10,marginTop:-10,marginBottom:-10};if(apiOptions.isMobile){const margin=16;const outerStyle={marginLeft:-16,marginRight:-16};const horizontalPadding={paddingLeft:margin,paddingRight:margin};const mobileInnerStyle={...innerStyle,...styles$u.mobileZoomableParentFix};return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",style:outerStyle,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:{...mobileInnerStyle,...horizontalPadding},children:jsxRuntimeExports.jsx(ZoomableTeX,{children:content})})})},state.key)}return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:innerStyle,children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{setAssetStatus:setAssetStatus,children:content})})})})},state.key)}if(node.type==="math"){const tex=node.content;return jsxRuntimeExports.jsx("span",{style:{whiteSpace:"nowrap"},children:jsxRuntimeExports.jsxs(ErrorBoundary,{children:[jsxRuntimeExports.jsx("span",{}),jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.props.onRender,setAssetStatus:setAssetStatus,children:tex})}),jsxRuntimeExports.jsx("span",{})]})},state.key)}if(node.type==="image"){if(imagePlaceholder){return imagePlaceholder}const extraAttrs=_.has(this.props.images,node.target)?this.props.images[node.target]:null;const responsive=!state.inTable;return jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{allowZoom:true,setAssetStatus:setAssetStatus,src:PerseusMarkdown$1.sanitizeUrl(node.target),alt:node.alt,title:node.title,responsive:responsive,onUpdate:this.props.onRender,...extraAttrs})})},state.key)}if(node.type==="columns"){this._isTwoColumn=true;return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown$1.ruleOutput(node,nestedOutput,state)},state.key)}if(node.type==="text"){if(rContainsNonWhitespace$1.test(node.content)){this._foundTextNodes=true;}if(imagePlaceholder&&rImageURL$1.test(node.content)){return imagePlaceholder}return node.content}if(node.type==="table"||node.type==="titledTable"){const output=PerseusMarkdown$1.ruleOutput(node,nestedOutput,{...state,isMobile:apiOptions.isMobile,inTable:true});if(!apiOptions.isMobile){return output}const outerStyle={marginLeft:-16,marginRight:-16};const innerStyle={paddingLeft:0,paddingRight:0};const mobileInnerStyle={...innerStyle,...styles$u.mobileZoomableParentFix};const wrappedOutput=jsxRuntimeExports.jsx("div",{style:{...mobileInnerStyle,overflowX:"auto"},children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(Zoomable$1,{animateHeight:true,children:output})})});return jsxRuntimeExports.jsx("div",{style:outerStyle,children:wrappedOutput})}return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown$1.ruleOutput(node,nestedOutput,state)},state.key)},this.handleRender=prevProps=>{const onRender=this.props.onRender;const oldOnRender=prevProps.onRender;if(onRender!==noopOnRender$1||oldOnRender!==noopOnRender$1){const node=ReactDOM__default.findDOMNode(this);if(node instanceof Element){node.querySelectorAll("img").forEach(image=>{if(oldOnRender!==noopOnRender$1){image.removeEventListener("load",oldOnRender);}if(onRender!==noopOnRender$1){image.addEventListener("load",onRender);}});}}onRender();},this._setCurrentFocus=path=>{const apiOptions=this.getApiOptions();if(!isIdPathPrefix$1(path,this._currentFocus)){const prevFocus=this._currentFocus;if(prevFocus){this.blurPath(prevFocus);}this._currentFocus=path;apiOptions.onFocusChange(this._currentFocus,prevFocus);}},this.focus=()=>{let id;let focusResult;for(let i=0;i<this.widgetIds.length;i++){const widgetId=this.widgetIds[i];const widget=this.getWidgetInstance(widgetId);const widgetFocusResult=widget?.focus?.();if(widgetFocusResult){id=widgetId;focusResult=widgetFocusResult;break}}if(id){let path;if(typeof focusResult==="object"){path=[id].concat(focusResult.path||[]);Log.error("Renderer received a focus result of type 'object' "+"instead of the expected type 'boolean'",Errors.Internal,{loggedMetadata:{focusResult:JSON.stringify(focusResult)}});}else {path=[id];}this._setCurrentFocus(path);return true}},this.getDOMNodeForPath=path=>{const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget?.getDOMNodeForPath){return widget.getDOMNodeForPath(interWidgetPath)}if(interWidgetPath.length===0){const container=this._widgetContainers.get(makeContainerId$1(widgetId));if(container){return ReactDOM__default.findDOMNode(container)}return ReactDOM__default.findDOMNode(widget)}},this.getInputPaths=()=>{const inputPaths=[];this.widgetIds.forEach(widgetId=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getInputPaths){const widgetInputPaths=widget.getInputPaths();widgetInputPaths.forEach(inputPath=>{const relativeInputPath=[widgetId].concat(inputPath);inputPaths.push(relativeInputPath);});}});return inputPaths},this.focusPath=path=>{if(_.isEqual(this._currentFocus,path)){return}if(this._currentFocus){this.blurPath(this._currentFocus);}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const focusWidget=this.getWidgetInstance(widgetId);focusWidget?.focusInputPath?.(interWidgetPath);},this.blurPath=path=>{if(!_.isEqual(this._currentFocus,path)){return}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget){const blurWidget=this.getWidgetInstance(widgetId);blurWidget?.blurInputPath?.(interWidgetPath);}},this.blur=()=>{if(this._currentFocus){this.blurPath(this._currentFocus);}},this.getWidgetIds=()=>{return this.widgetIds},this.handletranslationLintErrors=lintErrors=>{if(!this._isMounted){return}this.setState({translationLintErrors:lintErrors});};this._translationLinter=new TranslationLinter;this.state={jiptContent:null,translationLintErrors:[],...this._getInitialWidgetState(props)};}};Renderer$2.contextType=PerseusI18nContext;Renderer$2.defaultProps={content:"",widgets:{},images:{},showSolutions:"none",onRender:noopOnRender$1,findExternalWidgets:()=>[],alwaysUpdate:false,reviewMode:false,isScorable:false,linterContext:PerseusLinter.linterContextDefault};const styles$u={mobileZoomableParentFix:{transform:"translate3d(0,0,0)"}};
|
|
1665
1668
|
|
|
1666
1669
|
const rules={...pureMarkdownRules,columns:{...pureMarkdownRules.columns,react:(node,output,state)=>{return jsxRuntimeExports.jsxs("div",{className:"perseus-two-columns",children:[jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col1,state)})}),jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col2,state)})})]},state.key)}},crowdinId:{...pureMarkdownRules.crowdinId,react:(node,output,state)=>node.id},table:{...pureMarkdownRules.table,react:function(node,output,state){const table=SimpleMarkdown.defaultRules.table.react(node,output,state);if(!state.isMobile){return table}return React.cloneElement(table,{tabIndex:0})}},titledTable:{...pureMarkdownRules.titledTable,react:(node,output,state)=>{let contents;if(!node.table){contents="//invalid table//";}else if(node.table.type==="lint"){if(node.table.content?.type==="table"){contents=rules.lint.react({...node.table,content:{...node,table:node.table.content}},output,{...state,unwrapTitledTableContents:true});}else {contents=rules.lint.react(node.table,output,state);}}else {const tableOutput=SimpleMarkdown.defaultRules.table.react(node.table,output,state);const caption=jsxRuntimeExports.jsx("caption",{className:"perseus-table-title",children:output(node.title,state)},"caption");contents=React.cloneElement(tableOutput,null,[caption,...tableOutput.props.children]);}if(state.unwrapTitledTableContents){return contents}return jsxRuntimeExports.jsx("div",{className:"perseus-titled-table",children:contents},state.key)}},widget:{...pureMarkdownRules.widget,react:(node,output,state)=>{return jsxRuntimeExports.jsx("em",{children:`[Widget: ${node.id}]`},state.key)}},blockMath:{...pureMarkdownRules.blockMath,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},math:{...pureMarkdownRules.math,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},unescapedDollar:{...pureMarkdownRules.unescapedDollar,react:(node,output,state)=>{return "$"}},link:{...pureMarkdownRules.link,react:function(node,output,state){const link=SimpleMarkdown.defaultRules.link.react(node,output,state);const href=link.props.href;let rel=null;const isKAUrl=href?href.match(/https?:\/\/[^/]*khanacademy.org|^\//):false;if(!isKAUrl){rel="noopener noreferrer";}const newProps={...link.props,target:"_blank",href,rel};if(state.baseElements&&state.baseElements.Link){return state.baseElements.Link(newProps)}return React.cloneElement(link,newProps)}},codeBlock:{...pureMarkdownRules.codeBlock,react:(node,output,state)=>{if(node.lang==="alt"){return jsxRuntimeExports.jsx("div",{className:"perseus-markdown-alt perseus-sr-only",children:output(node.content,state)},state.key)}return SimpleMarkdown.defaultRules.codeBlock.react(node,output,state)}},lint:{...pureMarkdownRules.lint,react:(node,output,state)=>{return jsxRuntimeExports.jsx(Lint,{message:node.message,ruleName:node.ruleName,inline:isInline(node.content),blockHighlight:node.blockHighlight,insideTable:node.insideTable,severity:node.severity,children:output(node.content,state)})}}};function isInline(node){if(node?.type==="widget"){return CoreWidgetRegistry.isInlineWidget(node.widgetType)}return !!(node&&node.type&&inlineNodeTypes.hasOwnProperty(node.type))}const inlineNodeTypes={text:true,math:true,unescapedDollar:true,link:true,img:true,strong:true,u:true,em:true,del:true,code:true};const builtParser=SimpleMarkdown.parserFor(rules);const parse=(source,state)=>{const paragraphedSource=source+"\n\n";return builtParser(paragraphedSource,{...state,inline:false})};const inlineParser=(source,state)=>{return builtParser(source,{...state,inline:true})};const getContent=ast=>{if(Array.isArray(ast)){return _.flatten(ast.map(getContent))}if(ast.content&&typeof ast.content==="string"){if(ast.type.toLowerCase().indexOf("code")!==-1){return ["",ast.content,""]}return [ast.content.replace(/\s+/g," ")]}const children=_.chain(ast).values().flatten().filter(object=>object!=null&&_.has(object,"type")).value();if(!children.length){return []}const nestedContent=getContent(children);if(ast.type==="paragraph"&&nestedContent.length){nestedContent[0]=nestedContent[0].replace(/^\s+/,"");const last=nestedContent.length-1;nestedContent[last]=nestedContent[last].replace(/\s+$/,"");}return nestedContent};const characterCount=source=>{const ast=parse(source);const content=getContent(ast).join("");return content.length};var PerseusMarkdown = {characterCount:characterCount,traverseContent:traverseContent,parse:parse,parseInline:inlineParser,reactFor:SimpleMarkdown.reactFor,ruleOutput:SimpleMarkdown.ruleOutput(rules,"react"),basicOutput:SimpleMarkdown.reactFor(SimpleMarkdown.ruleOutput(rules,"react")),sanitizeUrl:SimpleMarkdown.sanitizeUrl};
|
|
1667
1670
|
|
|
@@ -1695,6 +1698,8 @@ var styles$q = {"scrollButtonsContainer":"perseus_kjDHiWdD"};
|
|
|
1695
1698
|
|
|
1696
1699
|
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=useRef(null);const[isScrollable,setIsScrollable]=useState(false);const[isScrolling,setIsScrolling]=useState(false);const generatedId=React.useId();const id=providedId||generatedId;const scrollableThreshold=React.useMemo(()=>{return window.innerWidth<=767?8:5},[]);const scroll=React.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.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]);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]=useState(null);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$q.scrollButtonsContainer,"aria-live":"polite",role:"group","aria-label":description,children:[jsxRuntimeExports.jsx(IconButton,{icon:caretLeftIcon,actionType:"neutral",kind:"secondary",size:"small",onClick:()=>scrollState.scroll("start"),"aria-label":strings.scrollStart,disabled:!scrollState.canScrollStart}),jsxRuntimeExports.jsx(IconButton,{icon:caretRightIcon,actionType:"neutral",kind:"secondary",size:"small",onClick:()=>scrollState.scroll("end"),"aria-label":strings.scrollEnd,disabled:!scrollState.canScrollEnd}),jsxRuntimeExports.jsx(BodyText,{size:"small",children:description})]})}const ScrollableView=ScrollableArea;ScrollableView.Controls=ScrollControls;
|
|
1697
1700
|
|
|
1701
|
+
var a11yStyles = {"srOnly":"perseus_BBUb6qxc"};
|
|
1702
|
+
|
|
1698
1703
|
var styles$p = {"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"};
|
|
1699
1704
|
|
|
1700
1705
|
const Indicator=props=>{const{checked,content,showCorrectness}=props;const indicatorId=useId();const ariaLabelledby=content.labelledBy?`${indicatorId} ${content.labelledBy}`:undefined;const ariaDisabled=showCorrectness?"true":"false";const iconImage=checked&&showCorrectness==="correct"?checkIcon:checked&&showCorrectness==="wrong"?minusIcon:undefined;const icon=iconImage?jsxRuntimeExports.jsx(PhosphorIcon,{"aria-hidden":true,className:styles$p.icon,icon:iconImage}):undefined;const classes=[styles$p.base,styles$p[props.shape+"-shape"]];if(showCorrectness){classes.push(styles$p["is-"+showCorrectness]);}const handleClick=showCorrectness?undefined:event=>{event.stopPropagation();props.updateChecked(!checked);};return jsxRuntimeExports.jsxs("button",{"aria-describedby":content.describedBy,"aria-disabled":ariaDisabled,"aria-pressed":checked,"aria-label":content.screenReader,"aria-labelledby":ariaLabelledby,className:classes.join(" "),id:indicatorId,type:"button",ref:props.buttonRef,onClick:handleClick,children:[icon,jsxRuntimeExports.jsx("span",{children:content.visible})]})};
|
|
@@ -1709,11 +1714,11 @@ function getChoiceLetter(pos,strings){const lettersString=strings.letters;const
|
|
|
1709
1714
|
|
|
1710
1715
|
const getInstructionsText=({multipleSelect,countChoices,numCorrect,strings})=>{if(multipleSelect){if(usesNumCorrect(multipleSelect,!!countChoices,numCorrect)){return strings.chooseNumAnswers({numCorrect:String(numCorrect)})}return strings.chooseAllAnswers}return strings.chooseOneAnswer};
|
|
1711
1716
|
|
|
1712
|
-
const RadioComponent=({choices,countChoices,multipleSelect=false,numCorrect,onChoiceChange,reviewMode})=>{const{strings}=usePerseusI18n();const legendId=useId();const containerRef=useRef(null);const[backgroundColor,setBackgroundColor]=useState("transparent");useEffect(()=>{const container=containerRef.current;if(container){setBackgroundColor(getBackgroundColor(container));}},[]);useTimeout(()=>{const container=containerRef.current;if(container){setBackgroundColor(getBackgroundColor(container));}},100);const instructions=getInstructionsText({multipleSelect,countChoices,numCorrect,strings});const choiceListClasses=reviewMode?`${styles$n.choiceList} ${styles$n.reviewAnswers}`:styles$n.choiceList;const cssVariableDeclaration=backgroundColor!=="transparent"?{"--perseus-widget-background-color":backgroundColor}:undefined;const scrollId=useId()+"-scroll";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs("fieldset",{className:styles$n.container,ref:containerRef,style:cssVariableDeclaration,children:[jsxRuntimeExports.
|
|
1717
|
+
const RadioComponent=({choices,countChoices,multipleSelect=false,numCorrect,onChoiceChange,reviewMode,isRequired=false})=>{const{strings}=usePerseusI18n();const legendId=useId();const containerRef=useRef(null);const[backgroundColor,setBackgroundColor]=useState("transparent");useEffect(()=>{const container=containerRef.current;if(container){setBackgroundColor(getBackgroundColor(container));}},[]);useTimeout(()=>{const container=containerRef.current;if(container){setBackgroundColor(getBackgroundColor(container));}},100);const instructions=getInstructionsText({multipleSelect,countChoices,numCorrect,strings});const choiceListClasses=reviewMode?`${styles$n.choiceList} ${styles$n.reviewAnswers}`:styles$n.choiceList;const cssVariableDeclaration=backgroundColor!=="transparent"?{"--perseus-widget-background-color":backgroundColor}:undefined;const scrollId=useId()+"-scroll";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs("fieldset",{className:styles$n.container,ref:containerRef,style:cssVariableDeclaration,children:[jsxRuntimeExports.jsxs("legend",{id:legendId,"aria-hidden":"true",className:styles$n.instructions,children:[instructions,isRequired&&jsxRuntimeExports.jsxs("span",{className:a11yStyles.srOnly,children:[" ",strings.required]})]}),jsxRuntimeExports.jsx(ScrollableView,{id:scrollId,overflowX:"auto",children:jsxRuntimeExports.jsx("ul",{"data-widget":"radio","aria-labelledby":legendId,className:choiceListClasses,role:"list",children:jsxRuntimeExports.jsx(ChoiceListItems,{choices:choices,i18nStrings:strings,onChoiceChange:onChoiceChange,reviewMode:reviewMode,multipleSelect:multipleSelect})})})]}),jsxRuntimeExports.jsx(ScrollableView.Controls,{target:scrollId})]})};const ChoiceListItems=props=>{const{choices,i18nStrings,multipleSelect,onChoiceChange,reviewMode}=props;const listId=useId();const items=choices.map((choice,i)=>{const updateChecked=isChecked=>{onChoiceChange(choice.id,isChecked);};const contentId=`${listId}-choice-${i+1}`;const choiceLetter=getChoiceLetter(i,i18nStrings);const srContent=reviewMode&&choice.correct?i18nStrings.choiceCorrect:i18nStrings.choice;const indicatorContent={visible:choiceLetter,screenReader:srContent({letter:choiceLetter}),labelledBy:contentId};const showCorrectness=reviewMode?choice.correct?"correct":"wrong":undefined;const content=choice.isNoneOfTheAbove?i18nStrings.noneOfTheAbove:choice.content;let rationale;if(reviewMode&&choice.hasRationale){const rationaleId=`${contentId}-rationale`;indicatorContent.describedBy=rationaleId;const rationaleClasses=showCorrectness==="correct"?`${styles$n.rationale} ${styles$n.isCorrect}`:styles$n.rationale;rationale=jsxRuntimeExports.jsx("div",{id:rationaleId,className:rationaleClasses,children:choice.rationale});}return jsxRuntimeExports.jsx(Choice,{checked:choice.checked,indicatorContent:indicatorContent,isMultiSelect:multipleSelect,showCorrectness:showCorrectness,updateChecked:updateChecked,children:jsxRuntimeExports.jsxs("div",{className:styles$n.content,children:[jsxRuntimeExports.jsx("div",{id:contentId,children:content}),rationale]})},choice.id)});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:items})};
|
|
1713
1718
|
|
|
1714
1719
|
const getChoiceStates=({choices,showSolutions,choiceStates,reviewMode})=>{if(showSolutions==="all"||reviewMode){return choices.map(choice=>({selected:!!choice.correct}))}if(choiceStates){return choiceStates}return choices.map(()=>({selected:false}))};
|
|
1715
1720
|
|
|
1716
|
-
const RadioWidget=forwardRef(function RadioWidget(props,ref){const{options}=props;const{multipleSelect=false,countChoices=false}=options;const{showSolutions="none",apiOptions,handleUserInput,trackInteraction,findWidgets,reviewMode,widgetId}=props;const{strings}=usePerseusI18n();const{analytics}=useDependencies();const randomSeed=(props.problemNum??0)+(props.widgetIndex??0);const choices=useMemo(()=>{return [...choiceTransform(options.choices,options.randomize,strings,randomSeed)]},[options.choices,options.randomize,strings,randomSeed]);useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:multipleSelect?"multiple-select":"single-select",widgetType:"radio",widgetId:widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON:()=>{return getPromptJSON$o({...props,options:{...props.options,choices}},props.userInput)},getSerializedState(){const{userInput,static:_1,options,...otherProps}=props;const{randomize,...otherOptions}=options;return {...otherOptions,...otherProps,numCorrect:options.numCorrect??0,choices,hasNoneOfTheAbove:options.hasNoneOfTheAbove??false,choiceStates:choices.map(choice=>{const selected=props.userInput?.selectedChoiceIds.includes(choice?.id)??false;return {selected,highlighted:false,readOnly:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}})}}}),[choices,props]);const renderContent=(content="")=>{const linterContext={contentType:"radio",highlightLint:false,stack:[]};return jsxRuntimeExports.jsx(MathRenderingContext.Provider,{value:{shouldAddAriaLabels:true},children:jsxRuntimeExports.jsx(Renderer,{apiOptions:apiOptions,content:content,findExternalWidgets:findWidgets,alwaysUpdate:true,linterContext:linterContext,strings:strings},"choiceContentRenderer")})};const handleChoiceChange=(choiceId,newCheckedState)=>{const checkedChoiceIds=[];const choiceStates=choices.map(choice=>{return {selected:props.userInput?.selectedChoiceIds.includes(choice.id)??false,id:choice.id}});const currentSelectedIds=choiceStates.filter(choice=>choice.selected).map(choice=>choice.id);if(newCheckedState&&!multipleSelect){checkedChoiceIds.push(choiceId);}else if(newCheckedState&&multipleSelect){checkedChoiceIds.push(...currentSelectedIds,choiceId);}else {checkedChoiceIds.push(...currentSelectedIds.filter(id=>id!==choiceId));}handleUserInput({selectedChoiceIds:checkedChoiceIds});trackInteraction();announceChoiceChange(checkedChoiceIds.length);};const announceChoiceChange=newCheckedCount=>{let screenReaderMessage="";if(!multipleSelect){screenReaderMessage=newCheckedCount===0?strings.notSelected:"";}else {screenReaderMessage=strings.choicesSelected({num:newCheckedCount});}announceMessage({message:screenReaderMessage});if(multipleSelect){setTimeout(()=>{announceMessage({message:""});},300);}};const buildChoiceProps=choiceStates=>{return choices.map((choice,i)=>{const content=choice.isNoneOfTheAbove&&!choice.content?strings.noneOfTheAbove:choice.content;const{selected=false}=choiceStates[i]??{};return {id:choice.id,content:renderContent(content),checked:selected,correct:!!choice.correct,hasRationale:!!choice.rationale,rationale:renderContent(choice.rationale),isNoneOfTheAbove:!!choice.isNoneOfTheAbove}})};const prepareChoicesProps=()=>{const choiceStates=choices.map(choice=>{return {selected:props.userInput?.selectedChoiceIds.includes(choice.id)??false}});const processedChoiceStates=getChoiceStates({choices,showSolutions,choiceStates,reviewMode});return buildChoiceProps(processedChoiceStates)};const choicesProps=prepareChoicesProps();const numCorrect=options.numCorrect;const isReviewMode=reviewMode||showSolutions==="all";const onChoiceChange=apiOptions.readOnly||isReviewMode?()=>{}:handleChoiceChange;return jsxRuntimeExports.jsx(RadioComponent,{reviewMode:isReviewMode,multipleSelect:multipleSelect,countChoices:countChoices,numCorrect:numCorrect,choices:choicesProps,onChoiceChange:onChoiceChange})});let Radio$1 = class Radio extends React.Component{getSerializedState(){if(!this.radioRef.current){throw new Error("Radio widget is not mounted; getSerializedState is unavailable.")}return this.radioRef.current.getSerializedState()}getPromptJSON(){if(!this.radioRef.current){throw new Error("Radio widget is not mounted; getPromptJSON is unavailable.")}return this.radioRef.current.getPromptJSON()}render(){return jsxRuntimeExports.jsx(RadioWidget,{ref:this.radioRef,...this.props})}constructor(...args){super(...args),this.radioRef=React.createRef();}};
|
|
1721
|
+
const RadioWidget=forwardRef(function RadioWidget(props,ref){const{options}=props;const{multipleSelect=false,countChoices=false}=options;const{showSolutions="none",apiOptions,handleUserInput,trackInteraction,findWidgets,reviewMode,widgetId}=props;const{strings}=usePerseusI18n();const{analytics}=useDependencies();const randomSeed=(props.problemNum??0)+(props.widgetIndex??0);const choices=useMemo(()=>{return [...choiceTransform(options.choices,options.randomize,strings,randomSeed)]},[options.choices,options.randomize,strings,randomSeed]);useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:multipleSelect?"multiple-select":"single-select",widgetType:"radio",widgetId:widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON:()=>{return getPromptJSON$o({...props,options:{...props.options,choices}},props.userInput)},getSerializedState(){const{userInput,static:_1,options,...otherProps}=props;const{randomize,...otherOptions}=options;return {...otherOptions,...otherProps,numCorrect:options.numCorrect??0,choices,hasNoneOfTheAbove:options.hasNoneOfTheAbove??false,choiceStates:choices.map(choice=>{const selected=props.userInput?.selectedChoiceIds.includes(choice?.id)??false;return {selected,highlighted:false,readOnly:false,rationaleShown:false,correctnessShown:false,previouslyAnswered:false}})}}}),[choices,props]);const renderContent=(content="")=>{const linterContext={contentType:"radio",highlightLint:false,stack:[]};return jsxRuntimeExports.jsx(MathRenderingContext.Provider,{value:{shouldAddAriaLabels:true},children:jsxRuntimeExports.jsx(Renderer,{apiOptions:apiOptions,content:content,findExternalWidgets:findWidgets,alwaysUpdate:true,linterContext:linterContext,strings:strings},"choiceContentRenderer")})};const handleChoiceChange=(choiceId,newCheckedState)=>{const checkedChoiceIds=[];const choiceStates=choices.map(choice=>{return {selected:props.userInput?.selectedChoiceIds.includes(choice.id)??false,id:choice.id}});const currentSelectedIds=choiceStates.filter(choice=>choice.selected).map(choice=>choice.id);if(newCheckedState&&!multipleSelect){checkedChoiceIds.push(choiceId);}else if(newCheckedState&&multipleSelect){checkedChoiceIds.push(...currentSelectedIds,choiceId);}else {checkedChoiceIds.push(...currentSelectedIds.filter(id=>id!==choiceId));}handleUserInput({selectedChoiceIds:checkedChoiceIds});trackInteraction();announceChoiceChange(checkedChoiceIds.length);};const announceChoiceChange=newCheckedCount=>{let screenReaderMessage="";if(!multipleSelect){screenReaderMessage=newCheckedCount===0?strings.notSelected:"";}else {screenReaderMessage=strings.choicesSelected({num:newCheckedCount});}announceMessage({message:screenReaderMessage});if(multipleSelect){setTimeout(()=>{announceMessage({message:""});},300);}};const buildChoiceProps=choiceStates=>{return choices.map((choice,i)=>{const content=choice.isNoneOfTheAbove&&!choice.content?strings.noneOfTheAbove:choice.content;const{selected=false}=choiceStates[i]??{};return {id:choice.id,content:renderContent(content),checked:selected,correct:!!choice.correct,hasRationale:!!choice.rationale,rationale:renderContent(choice.rationale),isNoneOfTheAbove:!!choice.isNoneOfTheAbove}})};const prepareChoicesProps=()=>{const choiceStates=choices.map(choice=>{return {selected:props.userInput?.selectedChoiceIds.includes(choice.id)??false}});const processedChoiceStates=getChoiceStates({choices,showSolutions,choiceStates,reviewMode});return buildChoiceProps(processedChoiceStates)};const choicesProps=prepareChoicesProps();const numCorrect=options.numCorrect;const isReviewMode=reviewMode||showSolutions==="all";const onChoiceChange=apiOptions.readOnly||isReviewMode?()=>{}:handleChoiceChange;const isRequired=props.isScorable&&!isReviewMode&&!props.static&&!apiOptions.readOnly;return jsxRuntimeExports.jsx(RadioComponent,{reviewMode:isReviewMode,isRequired:isRequired,multipleSelect:multipleSelect,countChoices:countChoices,numCorrect:numCorrect,choices:choicesProps,onChoiceChange:onChoiceChange})});let Radio$1 = class Radio extends React.Component{getSerializedState(){if(!this.radioRef.current){throw new Error("Radio widget is not mounted; getSerializedState is unavailable.")}return this.radioRef.current.getSerializedState()}getPromptJSON(){if(!this.radioRef.current){throw new Error("Radio widget is not mounted; getPromptJSON is unavailable.")}return this.radioRef.current.getPromptJSON()}render(){return jsxRuntimeExports.jsx(RadioWidget,{ref:this.radioRef,...this.props})}constructor(...args){super(...args),this.radioRef=React.createRef();}};
|
|
1717
1722
|
|
|
1718
1723
|
function getStartUserInput$g(){return {selectedChoiceIds:[]}}var Radio = {name:"radio",displayName:"Radio / Multiple choice",widget:Radio$1,getStartUserInput: getStartUserInput$g,isLintable:true,getUserInputFromSerializedState:serializedState=>{return getUserInputFromSerializedState$f(serializedState)}};
|
|
1719
1724
|
|
|
@@ -1775,13 +1780,17 @@ const FreeResponse=forwardRef(function FreeResponse({options,userInput,handleUse
|
|
|
1775
1780
|
|
|
1776
1781
|
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}};
|
|
1777
1782
|
|
|
1778
|
-
|
|
1783
|
+
var styles$e = {"result":"perseus_8dtO1IvS","answerBarContainer":"perseus_TQP1iS6G","answerBar":"perseus_FxBNEIyI","message":"perseus_PHIIz6-3"};
|
|
1784
|
+
|
|
1785
|
+
function GradedGroupAnswerBar({apiOptions,answerBarState,invalidMessage,onCheckAnswer,onNextQuestion}){const{strings}=usePerseusI18n();const{keepTrying,check,correctExcited,nextQuestion}=strings;const resultRef=React.useRef(null);const handleCheckAnswer=()=>{flushSync(onCheckAnswer);resultRef.current?.focus();};const stateInfoMap={correct:{icon:starIcon,iconColor:semanticColor.core.foreground.success.default,text:correctExcited},incorrect:{icon:arrowCounterIcon,iconColor:semanticColor.core.foreground.neutral.subtle,text:keepTrying},invalid:{icon:warningIcon,iconColor:semanticColor.core.border.warning.strong,text:invalidMessage},active:null};const stateInfo=stateInfoMap[answerBarState];const action=answerBarState==="correct"?onNextQuestion&&{label:nextQuestion,onClick:onNextQuestion,disabled:false}:{label:check,onClick:handleCheckAnswer,disabled:apiOptions.readOnly};return jsxRuntimeExports.jsx("div",{className:styles$e.answerBarContainer,children:jsxRuntimeExports.jsxs("div",{className:styles$e.answerBar,children:[jsxRuntimeExports.jsx("span",{className:styles$e.message,children:stateInfo&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PhosphorIcon,{icon:stateInfo.icon,color:stateInfo.iconColor}),jsxRuntimeExports.jsx("output",{ref:resultRef,tabIndex:-1,className:styles$e.result,children:jsxRuntimeExports.jsx(Renderer,{content:stateInfo.text,strings:strings,apiOptions:apiOptions})})]})}),action&&jsxRuntimeExports.jsx(Button,{disabled:action.disabled,onClick:action.onClick,children:action.label})]})})}
|
|
1786
|
+
|
|
1787
|
+
var cssModuleStyles = {"hint":"perseus_Tm6z7bco","hintCollapsed":"perseus_BaL4tWtd","hintExpanded":"perseus_Q4V7j8eC","hintWrapper":"perseus_AjlaWAbb"};
|
|
1779
1788
|
|
|
1780
|
-
const
|
|
1789
|
+
const GradedGroup=forwardRef(function GradedGroup(props,ref){const{strings}=usePerseusI18n();const dependencies=useDependencies();const[showHint,setShowHint]=useState(false);const[message,setMessage]=useState("");const[answerBarState,setAnswerBarState]=useState("active");const rendererRef=useRef(null);const hintRendererRef=useRef(null);const hintId=useId();useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group",widgetSubType:"null",widgetId:props.widgetId}});});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 handleAnswerChange(){setMessage("");setAnswerBarState(state=>state==="correct"?state:"active");}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?"correct":"incorrect":"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}`;setMessage(message);setAnswerBarState(status);props.trackInteraction({status:status});}const apiOptions=_.extend({},ApiOptions.defaults,props.apiOptions,{onFocusChange:(newFocus,oldFocus)=>{if(oldFocus){props.onBlur(oldFocus);}if(newFocus){props.onFocus(newFocus);}}});const classes=classNames$2("perseus-graded-group",props.inGradedGroupSet?css(styles$d.gradedGroupInSet):css(styles$d.gradedGroup));const isCorrect=answerBarState==="correct";const readOnly=apiOptions.readOnly||isCorrect;const showSolutions=isCorrect?"all":"none";return jsxRuntimeExports.jsxs("div",{className:classes,children:[!!props.options.title&&jsxRuntimeExports.jsx("div",{className:css(styles$d.title),children:props.options.title}),jsxRuntimeExports.jsx(UserInputManager,{widgets:props.options.widgets,handleUserInput:handleAnswerChange,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,isScorable:true})}),answerBarState!=="invalid"&&jsxRuntimeExports.jsx("div",{role:"status","aria-live":"polite",children:jsxRuntimeExports.jsx(Renderer,{content:message,strings:strings,apiOptions:apiOptions})}),props.options.answerArea&&apiOptions.renderExtras?.(props.options.answerArea,props.widgetId),props.options.hint?.content&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("button",{"aria-expanded":showHint,"aria-controls":hintId,className:css(styles$d.explainToggle),onClick:()=>setShowHint(!showHint),children:showHint?strings.hideExplanation:strings.explain}),jsxRuntimeExports.jsx("div",{id:hintId,className:classNames$2(cssModuleStyles.hint,showHint?cssModuleStyles.hintExpanded:cssModuleStyles.hintCollapsed),children:jsxRuntimeExports.jsx("div",{className:cssModuleStyles.hintWrapper,children: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(GradedGroupAnswerBar,{apiOptions:apiOptions,invalidMessage:message,answerBarState:answerBarState,onCheckAnswer:checkAnswer,onNextQuestion:props.onNextQuestion})]})});const styles$d=StyleSheet.create({gradedGroupInSet:{marginInlineStart:0,paddingInlineStart:0},gradedGroup:{borderBlockStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,backgroundColor:semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"},explainToggle:{backgroundColor:"unset",fontSize:font.body.size.small,padding:0,border:"none",marginBlockStart:20,color:semanticColor.core.foreground.instructive.default,cursor:"pointer",display:"block",clear:"both"},title:{fontSize:font.heading.size.small,color: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};
|
|
1781
1790
|
|
|
1782
1791
|
const getPromptJSON$h=(widgetData,activeGroupJSON)=>{return {type:"graded-group-set",options:{groupCount:widgetData.options.gradedGroups.length,currentGroup:activeGroupJSON}}};
|
|
1783
1792
|
|
|
1784
|
-
function Indicators(props){function handleKeyDown(e,i){if(e.key==="Enter"||e.key===" "){props.onChangeGroupIndex(i);}}return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames$2(css(styles$c.indicatorContainer),"indicatorContainer"),children:props.gradedGroups.map(({title},i)=>{const isCurrent=i===props.currentGroupIndex;return jsxRuntimeExports.jsx("li",{className:css(styles$c.indicator),children:jsxRuntimeExports.jsx(Clickable,{role:"button","aria-label":title,"aria-current":isCurrent,style:styles$c.indicatorButton,onClick:()=>props.onChangeGroupIndex(i),onKeyDown:e=>handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(View,{style:[styles$c.indicatorDot,isCurrent&&styles$c.indicatorDotActive,(hovered||focused||pressed)&&styles$c.indicatorDotFocused]})})},i)})})}const GradedGroupSet=forwardRef(function GradedGroupSet(props,ref){const dependencies=useDependencies();const childGroup=useRef(null);const[currentGroupIndex,setCurrentGroupIndex]=useState(0);useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group-set",widgetSubType:"null",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getInputPaths(){return childGroup.current?.getInputPaths?.()??[]},getPromptJSON(){invariant(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:css(styles$c.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:css(styles$c.container),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$c.top),children:[jsxRuntimeExports.jsx("div",{className:css(styles$c.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:css(styles$c.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$c=StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:font.heading.size.small,color:semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyleType:"none",margin:"unset",paddingInlineStart:"unset",flexWrap:"wrap"},indicator:{width:24,height:24},indicatorButton:{width:"100%",height:"100%",display:"flex",flexWrap:"wrap",placeContent:"center",cursor:"pointer",":focus":{outline:"none"}},indicatorDot:{boxSizing:"content-box",width:10,height:10,borderRadius:border$1.radius.radius_full,borderWidth:border$1.width.medium,borderColor:semanticColor.core.border.instructive.default,borderStyle:"solid"},indicatorDotFocused:{outlineColor:semanticColor.focus.outer,outlineStyle:"solid",outlineWidth:border$1.width.medium,outlineOffset:border$1.width.medium,boxShadow:`0 0 0 ${border$1.width.medium} ${semanticColor.focus.inner}`},indicatorDotActive:{backgroundColor:semanticColor.core.foreground.instructive.default,borderColor:semanticColor.core.transparent},container:{borderBlockStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,backgroundColor:semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"}});
|
|
1793
|
+
function Indicators(props){function handleKeyDown(e,i){if(e.key==="Enter"||e.key===" "){props.onChangeGroupIndex(i);}}return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames$2(css(styles$c.indicatorContainer),"indicatorContainer"),children:props.gradedGroups.map(({title},i)=>{const isCurrent=i===props.currentGroupIndex;return jsxRuntimeExports.jsx("li",{className:css(styles$c.indicator),children:jsxRuntimeExports.jsx(Clickable,{ref:isCurrent?props.currentPipRef:undefined,role:"button","aria-label":title,"aria-current":isCurrent,style:styles$c.indicatorButton,onClick:()=>props.onChangeGroupIndex(i),onKeyDown:e=>handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(View,{style:[styles$c.indicatorDot,isCurrent&&styles$c.indicatorDotActive,(hovered||focused||pressed)&&styles$c.indicatorDotFocused]})})},i)})})}const GradedGroupSet=forwardRef(function GradedGroupSet(props,ref){const dependencies=useDependencies();const childGroup=useRef(null);const currentPipRef=useRef(null);const[currentGroupIndex,setCurrentGroupIndex]=useState(0);useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group-set",widgetSubType:"null",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getInputPaths(){return childGroup.current?.getInputPaths?.()??[]},getPromptJSON(){invariant(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:css(styles$c.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:()=>{flushSync(()=>setCurrentGroupIndex(currentGroupIndex+1));currentPipRef.current?.focus();};return jsxRuntimeExports.jsxs("div",{className:css(styles$c.container),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$c.top),children:[jsxRuntimeExports.jsx("div",{className:css(styles$c.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:css(styles$c.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroupIndex:currentGroupIndex,gradedGroups:gradedGroups,onChangeGroupIndex:setCurrentGroupIndex,currentPipRef:currentPipRef})]}),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$c=StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:font.heading.size.small,color:semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyleType:"none",margin:"unset",paddingInlineStart:"unset",flexWrap:"wrap"},indicator:{width:24,height:24},indicatorButton:{width:"100%",height:"100%",display:"flex",flexWrap:"wrap",placeContent:"center",cursor:"pointer",":focus":{outline:"none"}},indicatorDot:{boxSizing:"content-box",width:10,height:10,borderRadius:border$1.radius.radius_full,borderWidth:border$1.width.medium,borderColor:semanticColor.core.border.instructive.default,borderStyle:"solid"},indicatorDotFocused:{outlineColor:semanticColor.focus.outer,outlineStyle:"solid",outlineWidth:border$1.width.medium,outlineOffset:border$1.width.medium,boxShadow:`0 0 0 ${border$1.width.medium} ${semanticColor.focus.inner}`},indicatorDotActive:{backgroundColor:semanticColor.core.foreground.instructive.default,borderColor:semanticColor.core.transparent},container:{borderBlockStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,backgroundColor:semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"}});
|
|
1785
1794
|
|
|
1786
1795
|
class ButtonGroup extends React.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: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=StyleSheet.create({buttonStyle:{backgroundColor:semanticColor.core.background.base.default,border:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderInlineStart:"0",color:semanticColor.core.foreground.neutral.strong,cursor:"pointer",margin:"0",paddingBlock:"5px",paddingInline:"10px",position:"relative",":first-child":{borderInlineStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderStartStartRadius:border$1.radius.radius_040,borderEndStartRadius:border$1.radius.radius_040},":last-child":{borderInlineEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderStartEndRadius:border$1.radius.radius_040,borderEndEndRadius:border$1.radius.radius_040},":hover":{backgroundColor:semanticColor.core.background.instructive.subtle},":focus":{zIndex:2}},selectedStyle:{backgroundColor:semanticColor.core.background.instructive.subtle,boxShadow:`inset 0 calc(-1 * ${border$1.width.thick}) 0 ${semanticColor.core.border.instructive.default}`},disabledStyle:{cursor:"not-allowed",backgroundColor:semanticColor.core.background.disabled.default,color:semanticColor.core.foreground.disabled.strong,":hover":{backgroundColor:semanticColor.core.background.disabled.default}}});
|
|
1787
1796
|
|
|
@@ -2110,4 +2119,4 @@ var allWidgets = [...basicWidgets,...extraWidgets];
|
|
|
2110
2119
|
const registerAllWidgetsForTesting=()=>{registerWidgets(allWidgets);replaceDeprecatedWidgets();};
|
|
2111
2120
|
|
|
2112
2121
|
export { dependencies as $, ApiOptions as A, ButtonGroup as B, ClassNames as C, DependenciesContext as D, Expression as E, NumericInput$1 as F, Graphie as G, HUD as H, Icon as I, JiptParagraphs as J, Radio as K, Categorizer$1 as L, MathInput as M, NumberInput as N, InteractiveGraph$1 as O, PerseusI18nContext as P, Matrix$1 as Q, RangeInput as R, SvgImage as S, TextInput as T, UserInputManager as U, Table$1 as V, Plotter$1 as W, Grapher$1 as X, iconChevronDown as Y, iconTrash as Z, bodyXsmallBold as _, InlineIcon as a, Log as a0, MathRenderingContext as a1, interactiveSizes$1 as a2, PerseusI18nContextProvider as a3, usePerseusI18n as a4, KhanColors as a5, preprocessTex as a6, registerAllWidgetsForTesting as a7, containerSizeClass as a8, getInteractiveBoxFromSizeClass as a9, mathOnlyParser as aa, getWidgetSubTypeByWidgetId as ab, contentHasWidgetType as ac, getWidgetFromWidgetMap as ad, getWidgetsFromWidgetMap as ae, getAbsoluteValueCoords as af, getCircleCoords as ag, getExponentialCoords as ah, getLogarithmCoords as ai, getLineCoords as aj, getLinearSystemCoords as ak, getPointCoords as al, getPolygonCoords as am, getSegmentCoords as an, getSinusoidCoords as ao, getTangentCoords as ap, getVectorCoords as aq, getQuadraticCoords as ar, getAngleCoords as as, deriveUserInputFromSerializedState as at, parseDataFromJSONP as au, MultiButtonGroup as b, basicWidgets as c, replaceDeprecatedWidgets as d, extraWidgets as e, Renderer as f, Util as g, getDependencies as h, hintPaddingInlineStart as i, jsxRuntimeExports as j, hintBorderWidth as k, context as l, mediaQueries as m, getWidgetTypeByWidgetId as n, getWidgetExport as o, PerseusMarkdown as p, getEquationString as q, registerWidgets as r, sharedStyles as s, typeToButton as t, defaultPlotProps as u, chooseType as v, DEFAULT_GRAPHER_PROPS as w, widgets$1 as x, allWidgets as y, InputNumber as z };
|
|
2113
|
-
//# sourceMappingURL=chunk-register-all-widgets-for-testing-
|
|
2122
|
+
//# sourceMappingURL=chunk-register-all-widgets-for-testing-B94oNv6V.js.map
|