@khanacademy/perseus-core 37.0.0 → 38.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/data-schema.d.ts +9 -5
  2. package/dist/es/index.item-splitting.js +4 -0
  3. package/dist/es/index.item-splitting.js.map +1 -1
  4. package/dist/es/index.js +11 -7
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.d.ts +7 -61
  7. package/dist/index.item-splitting.js +4 -0
  8. package/dist/index.item-splitting.js.map +1 -1
  9. package/dist/index.js +14 -6
  10. package/dist/index.js.map +1 -1
  11. package/dist/utils/generators/table-widget-generator.d.ts +10 -0
  12. package/dist/validation.types.d.ts +8 -228
  13. package/dist/widgets/categorizer/index.d.ts +0 -1
  14. package/dist/widgets/cs-program/index.d.ts +0 -1
  15. package/dist/widgets/definition/index.d.ts +0 -2
  16. package/dist/widgets/dropdown/index.d.ts +0 -1
  17. package/dist/widgets/explanation/index.d.ts +0 -2
  18. package/dist/widgets/expression/index.d.ts +0 -1
  19. package/dist/widgets/free-response/index.d.ts +0 -1
  20. package/dist/widgets/graded-group/index.d.ts +0 -2
  21. package/dist/widgets/graded-group-set/index.d.ts +0 -2
  22. package/dist/widgets/grapher/index.d.ts +0 -1
  23. package/dist/widgets/group/index.d.ts +0 -1
  24. package/dist/widgets/iframe/index.d.ts +0 -1
  25. package/dist/widgets/image/index.d.ts +0 -1
  26. package/dist/widgets/input-number/index.d.ts +0 -1
  27. package/dist/widgets/interaction/index.d.ts +0 -2
  28. package/dist/widgets/interactive-graph/index.d.ts +0 -1
  29. package/dist/widgets/label-image/index.d.ts +0 -1
  30. package/dist/widgets/matcher/index.d.ts +0 -1
  31. package/dist/widgets/matrix/index.d.ts +0 -1
  32. package/dist/widgets/measurer/index.d.ts +0 -2
  33. package/dist/widgets/number-line/index.d.ts +0 -1
  34. package/dist/widgets/numeric-input/index.d.ts +0 -1
  35. package/dist/widgets/orderer/index.d.ts +0 -1
  36. package/dist/widgets/orderer/orderer-util.d.ts +11 -1
  37. package/dist/widgets/phet-simulation/index.d.ts +0 -2
  38. package/dist/widgets/plotter/index.d.ts +0 -1
  39. package/dist/widgets/python-program/index.d.ts +0 -2
  40. package/dist/widgets/radio/index.d.ts +0 -1
  41. package/dist/widgets/sorter/index.d.ts +0 -1
  42. package/dist/widgets/sorter/sorter-util.d.ts +12 -1
  43. package/dist/widgets/table/index.d.ts +0 -1
  44. package/dist/widgets/video/index.d.ts +0 -2
  45. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -256,7 +256,7 @@ const parseUserInputMap=(rawValue,ctx)=>{if(!isPlainObject(rawValue)){return ctx
256
256
 
257
257
  function parseAndMigratePerseusItem(data){const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parsePerseusItem);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}function parseAndMigratePerseusArticle(data){const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parsePerseusArticle);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}function parseAndMigrateUserInputMap(data){const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parseUserInputMap);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}function parseAndMigratePerseusRenderer(data){const object=typeof data==="string"?JSON.parse(data):data;const result=parse(object,parsePerseusRenderer);if(isFailure(result)){return failure({message:result.detail,invalidObject:object})}return result}
258
258
 
259
- const libName="@khanacademy/perseus-core";const libVersion="37.0.0";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
259
+ const libName="@khanacademy/perseus-core";const libVersion="38.0.1";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
260
260
 
261
261
  const Errors=Object.freeze({Unknown:"Unknown",Internal:"Internal",InvalidInput:"InvalidInput",NotAllowed:"NotAllowed",TransientService:"TransientService",Service:"Service"});
262
262
 
@@ -310,7 +310,7 @@ function getIFramePublicWidgetOptions(options){return options}
310
310
 
311
311
  const defaultWidgetOptions$j={url:"",settings:[{name:"",value:""}],width:"400",height:"400",allowFullScreen:false,allowTopNavigation:false};const iframeWidgetLogic={name:"iframe",defaultWidgetOptions: defaultWidgetOptions$j,getPublicWidgetOptions:getIFramePublicWidgetOptions,accessible:false};
312
312
 
313
- const defaultWidgetOptions$i={title:"",range:[[0,10],[0,10]],box:[400,400],backgroundImage:{url:null,width:0,height:0},scale:1,labels:[],alt:"",caption:""};const imageWidgetLogic={name:"image",defaultWidgetOptions: defaultWidgetOptions$i,supportedAlignments:["block","wrap-left","wrap-right","full-width"],defaultAlignment:"block",accessible:widgetOptions=>{const bgImage=widgetOptions.backgroundImage;const hasBackgroundImage=bgImage.url!=null;const hasAltText=!!widgetOptions.alt;const isDecorative=widgetOptions.decorative;return hasBackgroundImage&&(hasAltText||isDecorative)}};
313
+ const defaultWidgetOptions$i={title:"",range:[[0,10],[0,10]],box:[400,400],backgroundImage:{url:null,width:0,height:0},scale:1,labels:[],alt:"",caption:"",longDescription:"",decorative:false};const imageWidgetLogic={name:"image",defaultWidgetOptions: defaultWidgetOptions$i,supportedAlignments:["block","wrap-left","wrap-right","full-width"],defaultAlignment:"block",accessible:widgetOptions=>{const bgImage=widgetOptions.backgroundImage;const hasBackgroundImage=bgImage.url!=null;const hasAltText=!!widgetOptions.alt;const isDecorative=widgetOptions.decorative;return hasBackgroundImage&&(hasAltText||isDecorative)}};
314
314
 
315
315
  function getNumericInputAnswerPublicData(answer){return {status:answer.status,answerForms:answer.answerForms,simplify:answer.simplify,value:null,strict:false,message:""}}function getNumericInputPublicWidgetOptions(options){const{answers,...publicWidgetOptions}=options;return {...publicWidgetOptions,answers:answers.map(getNumericInputAnswerPublicData)}}
316
316
 
@@ -346,13 +346,13 @@ const defaultWidgetOptions$b={box:[480,480],image:{},showProtractor:true,showRul
346
346
 
347
347
  function getNumberLinePublicWidgetOptions(options){const{correctX,correctRel,...publicOptions}=options;return publicOptions}
348
348
 
349
- const defaultWidgetOptions$a={range:[0,10],labelRange:[null,null],labelStyle:"decimal",labelTicks:true,divisionRange:[1,12],numDivisions:5,snapDivisions:2,tickStep:null,correctRel:"eq",correctX:null,initialX:null,showTooltips:false};const numberLineWidgetLogic={name:"number-line",defaultWidgetOptions: defaultWidgetOptions$a,getPublicWidgetOptions:getNumberLinePublicWidgetOptions,accessible:false};
349
+ const defaultWidgetOptions$a={range:[0,10],labelRange:[null,null],labelStyle:"decimal",labelTicks:true,isTickCtrl:false,isInequality:false,divisionRange:[1,12],numDivisions:5,snapDivisions:2,tickStep:null,correctRel:"eq",correctX:null,initialX:null,showTooltips:false};const numberLineWidgetLogic={name:"number-line",defaultWidgetOptions: defaultWidgetOptions$a,getPublicWidgetOptions:getNumberLinePublicWidgetOptions,accessible:false};
350
350
 
351
351
  const defaultWidgetOptions$9={answers:[{value:null,status:"correct",message:"",simplify:"required",answerForms:[],strict:false,maxError:null}],size:"normal",coefficient:false,labelText:"",textAlign:"left"};const numericInputWidgetLogic={name:"numeric-input",version:{major:1,minor:0},defaultWidgetOptions: defaultWidgetOptions$9,defaultAlignment:"inline-block",getPublicWidgetOptions:getNumericInputPublicWidgetOptions,accessible:true};
352
352
 
353
- function getOrdererPublicWidgetOptions(fullOptions){const{options,height,layout}=fullOptions;return {options,height,layout}}
353
+ function getOrdererPublicWidgetOptions(fullOptions){const{options,height,layout}=fullOptions;return {options,height,layout}}function toCard(content){return {content,widgets:{},images:{}}}function getCategoryScore(content){if(/\d/.test(content)){return 0}if(/^\$?[a-zA-Z]+\$?$/.test(content)){return 2}return 1}function mergeCards(correctOptions,otherOptions){const allCards=[...correctOptions,...otherOptions];return [...new Set(allCards.map(card=>card.content))].filter(content=>content!=="").sort().sort((a,b)=>getCategoryScore(a)-getCategoryScore(b)).map(toCard)}
354
354
 
355
- const defaultWidgetOptions$8={correctOptions:[{content:"$x$"}],otherOptions:[{content:"$y$"}],height:"normal",layout:"horizontal"};const ordererWidgetLogic={name:"orderer",defaultWidgetOptions: defaultWidgetOptions$8,getPublicWidgetOptions:getOrdererPublicWidgetOptions,accessible:false};
355
+ const defaultCorrectOptions=[toCard("$x$")];const defaultOtherOptions=[toCard("$y$")];const defaultWidgetOptions$8={correctOptions:defaultCorrectOptions,otherOptions:defaultOtherOptions,options:mergeCards(defaultCorrectOptions,defaultOtherOptions),height:"normal",layout:"horizontal"};const ordererWidgetLogic={name:"orderer",defaultWidgetOptions: defaultWidgetOptions$8,getPublicWidgetOptions:getOrdererPublicWidgetOptions,accessible:false};
356
356
 
357
357
  const defaultWidgetOptions$7={url:"",description:""};const phetSimulationWidgetLogic={name:"phet-simulation",defaultWidgetOptions: defaultWidgetOptions$7,accessible:true};
358
358
 
@@ -366,7 +366,7 @@ function getRadioChoicePublicData(choice){const{id,content,isNoneOfTheAbove}=cho
366
366
 
367
367
  const currentVersion={major:3,minor:0};const defaultWidgetOptions$4={choices:[{content:"",id:"radio-choice-0"},{content:"",id:"radio-choice-1"},{content:"",id:"radio-choice-2"},{content:"",id:"radio-choice-3"}],randomize:false,hasNoneOfTheAbove:false,multipleSelect:false,countChoices:false,deselectEnabled:false};const radioWidgetLogic={name:"radio",version:currentVersion,defaultWidgetOptions:defaultWidgetOptions$4,getPublicWidgetOptions:getRadioPublicWidgetOptions,accessible:true};
368
368
 
369
- function getSorterPublicWidgetOptions(options){return {...options,correct:sortAllButFirst(options.correct)}}function shuffleSorter(options,problemNum){const{correct}=options;const rng=seededRNG(problemNum??0);return shuffleDisplacingFirst(correct,rng)}function sortAllButFirst([first,...rest]){return [first,...rest.sort()]}function shuffleDisplacingFirst(array,rng){function isFirstElementDisplaced(shuffled){return shuffled[0]!==array[0]}return constrainedShuffle(array,rng,isFirstElementDisplaced)}
369
+ function getSorterPublicWidgetOptions(options){return {...options,correct:sortAllButFirst(options.correct)}}function shuffleSorter(options,problemNum){const{correct}=options;const rng=seededRNG(problemNum??0);return shuffleDisplacingFirst(correct,rng)}function sortAllButFirst(cards){if(cards.length===0){return []}const[first,...rest]=cards;return [first,...rest.sort()]}function shuffleDisplacingFirst(array,rng){function isFirstElementDisplaced(shuffled){return shuffled[0]!==array[0]}return constrainedShuffle(array,rng,isFirstElementDisplaced)}
370
370
 
371
371
  const defaultWidgetOptions$3={correct:["$x$","$y$","$z$"],layout:"horizontal",padding:true};const sorterWidgetLogic={name:"sorter",defaultWidgetOptions: defaultWidgetOptions$3,getPublicWidgetOptions:getSorterPublicWidgetOptions,accessible:false};
372
372
 
@@ -465,6 +465,10 @@ function generateVideoWidget(videoWidgetProperties){return {type:"video",graded:
465
465
 
466
466
  function generateSorterOptions(options){return {...sorterWidgetLogic.defaultWidgetOptions,...options}}function generateSorterWidget(sorterWidgetProperties){return {type:"sorter",graded:true,version:{major:0,minor:0},static:false,alignment:"default",options:generateSorterOptions(),...sorterWidgetProperties}}
467
467
 
468
+ function generateTableOptions(options){const merged={...tableWidgetLogic.defaultWidgetOptions,...options};const columns=options?.columns??merged.answers[0]?.length??tableWidgetLogic.defaultWidgetOptions.columns;return {...merged,rows:options?.rows??merged.answers.length,columns,headers:options?.headers??new Array(columns).fill("")}}
469
+
470
+ function generateGrapherWidgetOptions(options={}){return {...grapherWidgetLogic.defaultWidgetOptions,...options}}
471
+
468
472
  const joinOptionContents=options=>options.map(({content})=>content).join("\n");const toOptionLetter=index=>String.fromCharCode("A".charCodeAt(0)+index);function getAnswersFromWidgets(widgets){const answers=[];wonderStuffCore.keys(widgets).forEach(widgetID=>{const widget=widgets[widgetID];if(!widget.options){return}switch(widget.type){case "radio":const radio=widget;const options=radio.options;if(options?.choices?.length){for(const choice of options.choices){if(choice?.correct){answers.push(choice.content);}}}break;case "categorizer":const categorizer=widget;if(categorizer.options?.categories&&categorizer.options?.items&&categorizer.options?.values){const categories=categorizer.options?.categories;const items=categorizer.options?.items;const values=categorizer.options?.values;answers.push(...values.map((value,index)=>`${items[index]}: ${categories[value]}`));}break;case "dropdown":const dropdown=widget;if(dropdown.options?.choices){for(const choice of dropdown.options.choices){if(choice.correct){answers.push(choice.content);}}}break;case "input-number":case "numeric-input":const numericInput=widget;if(numericInput.options?.answers){for(const ans of numericInput.options.answers){if(ans.status==="correct"&&ans.value!=null){answers.push(ans.value.toString());}}}break;case "expression":const expression=widget;if(expression.options?.answerForms){answers.push(...expression.options.answerForms.map(answer=>answer.value));}break;case "group":case "graded-group":const gradedGroup=widget;if(gradedGroup.options?.widgets){answers.push(...getAnswersFromWidgets(gradedGroup.options.widgets));}break;case "plotter":const plotter=widget;if(plotter.options?.categories&&plotter.options?.correct&&plotter.options.categories.length===plotter.options.correct.length){const{categories,correct}=plotter.options;answers.push(`{${categories.map((category,index)=>`${category}: ${correct[index]}`).join(", ")}}`);}break;case "interactive-graph":case "grapher":const grapher=widget;if(grapher.options?.correct?.coords){answers.push(`There should be point(s) on [${grapher.options.correct?.coords.join("], [")}]`);}break;case "orderer":const orderer=widget;if(orderer.options?.correctOptions){answers.push(joinOptionContents(orderer.options.correctOptions));}break;case "sorter":const sorter=widget;if(sorter.options?.correct){answers.push(sorter.options.correct.join(", "));}break;case "label-image":const labelImage=widget;if(labelImage.options?.markers){answers.push(...labelImage.options.markers.map(m=>`{label: "${m.label}", position: {${m.x},${m.y}}, answer: "${m.answers.join(", ")}"}`));}break;case "number-line":const numberLine=widget;if(numberLine.options?.correctX!=null){answers.push(numberLine.options.correctX.toString());}break;case "matrix":const matrix=widget;if(matrix.options?.answers){answers.push(`[${matrix.options.answers.join("], [")}]`);}break;case "matcher":const matcher=widget;if(matcher.options?.left&&matcher.options?.right){const{left,right}=matcher.options;const[leftHeader,rightHeader]=matcher.options.labels;const tableHeader=`| ${leftHeader} | ${rightHeader} |
469
473
  | --- | --- |`;const tableRows=left.map((leftItem,index)=>{return `| ${leftItem} | ${right[index]} |`});const table=[tableHeader,...tableRows].join("\n");answers.push(table);}break}});return answers}function injectWidgets(content,widgets,widgetProps){if(!content){return ""}if(!widgets){return content}let context=content;wonderStuffCore.keys(widgets).forEach(widgetID=>{const widget=widgets[widgetID];if(!widget.options){return}switch(widget.type){case "radio":const radio=widget;const radioProps=widgetProps?.[widgetID];if(radio.options?.choices?.length){let radioContext=joinOptionContents(radioProps?radioProps.choices.map(({content},i)=>({content:`Option ${toOptionLetter(i)}: ${content}`})):radio.options.choices);if(!radioProps&&radio.options?.randomize){radioContext+="\nThose options are displayed in a different order to the user. If the user says the letter, number, or ordinal number, always ask them clarify which option they are referring to.\n";}context=context.replace(`[[☃ ${widgetID}]]`,radioContext);}break;case "image":const image=widget;if(image.options?.alt){context=context.replace(`[[☃ ${widgetID}]]`,`<img id="${widgetID}" alt="${image.options.alt}">`);}break;case "label-image":const labelImage=widget;if(labelImage.options?.imageAlt){context=context.replace(`[[☃ ${widgetID}]]`,`[An image with dots that user needs to label. Label choices: [${labelImage.options.choices.join(", ")}]. Image alt text: ${labelImage.options?.imageAlt??""}]`);}break;case "explanation":const explanation=widget;if(explanation.options?.explanation){context=context.replace(`[[☃ ${widgetID}]]`,injectWidgets(explanation.options.explanation,explanation.options.widgets));}break;case "group":case "graded-group":const group=widget;if(group.options?.widgets&&group.options.content){context=context.replace(`[[☃ ${widgetID}]]`,injectWidgets(group.options.content,group.options.widgets));}break;case "graded-group-set":const gradedGroup=widget;if(gradedGroup.options?.gradedGroups){const gradedGroups=gradedGroup.options.gradedGroups;const gradedGroupsContent=gradedGroups.reduce((acc,group)=>{if(group.widgets&&group.content){acc+=injectWidgets(group.content,group.widgets)+"\n";}return acc},"");context=context.replace(`[[☃ ${widgetID}]]`,gradedGroupsContent);}break;case "categorizer":const categorizer=widget;if(categorizer.options?.categories&&categorizer.options.items){const categories=categorizer.options.categories;const items=categorizer.options.items;context=context.replace(`[[☃ ${widgetID}]]`,`For each item, select the correct category. Categories: ${categories.join(", ")}.
470
474
  Items:
@@ -524,6 +528,7 @@ exports.generateFreeResponseWidget = generateFreeResponseWidget;
524
528
  exports.generateGradedGroupOptions = generateGradedGroupOptions;
525
529
  exports.generateGradedGroupSetWidget = generateGradedGroupSetWidget;
526
530
  exports.generateGradedGroupWidget = generateGradedGroupWidget;
531
+ exports.generateGrapherWidgetOptions = generateGrapherWidgetOptions;
527
532
  exports.generateGroupOptions = generateGroupOptions;
528
533
  exports.generateGroupWidget = generateGroupWidget;
529
534
  exports.generateIGAbsoluteValueGraph = generateIGAbsoluteValueGraph;
@@ -584,6 +589,7 @@ exports.generateSimpleRadioItem = generateSimpleRadioItem;
584
589
  exports.generateSimpleRadioQuestion = generateSimpleRadioQuestion;
585
590
  exports.generateSorterOptions = generateSorterOptions;
586
591
  exports.generateSorterWidget = generateSorterWidget;
592
+ exports.generateTableOptions = generateTableOptions;
587
593
  exports.generateTestPerseusItem = generateTestPerseusItem;
588
594
  exports.generateTestPerseusRenderer = generateTestPerseusRenderer;
589
595
  exports.generateVideoWidget = generateVideoWidget;
@@ -648,6 +654,7 @@ exports.mapObject = mapObject;
648
654
  exports.matcherLogic = matcherWidgetLogic;
649
655
  exports.matrixLogic = matrixWidgetLogic;
650
656
  exports.measurerLogic = measurerWidgetLogic;
657
+ exports.mergeCards = mergeCards;
651
658
  exports.numberLineLogic = numberLineWidgetLogic;
652
659
  exports.numericInputLogic = numericInputWidgetLogic;
653
660
  exports.ordererLogic = ordererWidgetLogic;
@@ -671,6 +678,7 @@ exports.sorterLogic = sorterWidgetLogic;
671
678
  exports.splitPerseusItem = splitPerseusItem;
672
679
  exports.splitPerseusItemJSON = splitPerseusItemJSON;
673
680
  exports.tableLogic = tableWidgetLogic;
681
+ exports.toCard = toCard;
674
682
  exports.traverse = traverse;
675
683
  exports.usesNumCorrect = usesNumCorrect;
676
684
  exports.videoLogic = videoWidgetLogic;