@khanacademy/perseus-editor 34.0.0 → 34.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/index.js +13 -13
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +13 -13
- package/dist/index.js.map +1 -1
- package/dist/widgets/free-response-editor.d.ts +1 -2
- package/dist/widgets/plotter-editor.d.ts +2 -2
- package/package.json +7 -7
package/dist/es/index.js
CHANGED
|
@@ -63,7 +63,7 @@ import minusCircle from '@phosphor-icons/core/regular/minus-circle.svg';
|
|
|
63
63
|
import checkIcon from '@phosphor-icons/core/bold/check-bold.svg';
|
|
64
64
|
import minusCircleIcon from '@phosphor-icons/core/bold/minus-circle-bold.svg';
|
|
65
65
|
|
|
66
|
-
const libName="@khanacademy/perseus-editor";const libVersion="34.
|
|
66
|
+
const libName="@khanacademy/perseus-editor";const libVersion="34.1.1";addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
67
67
|
|
|
68
68
|
var jsxRuntime = {exports: {}};
|
|
69
69
|
|
|
@@ -1495,7 +1495,7 @@ class ItemDiff extends React.Component{render(){const{before,after}=this.props;c
|
|
|
1495
1495
|
|
|
1496
1496
|
const{InfoTip: InfoTip$o,InlineIcon: InlineIcon$2}=components;class HintEditor extends React.Component{serialize(){invariant(this.editor.current,"cannot serialize HintEditor with no Editor");return {...this.editor.current.serialize(),replace:this.props.replace??undefined}}render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-hint-editor "+this.props.className,children:[this.props.showTitle&&jsxRuntimeExports.jsx("div",{className:"pod-title",children:"Hint"}),jsxRuntimeExports.jsx(Editor,{ref:this.editor,apiOptions:this.props.apiOptions,widgets:this.props.widgets||undefined,content:this.props.content||undefined,images:this.props.images,placeholder:"Type your hint here...",imageUploader:this.props.imageUploader,onChange:this.props.onChange,widgetIsOpen:this.props.widgetIsOpen},this.props.itemId),jsxRuntimeExports.jsxs("div",{className:"hint-controls-container clearfix",children:[this.props.showMoveButtons&&jsxRuntimeExports.jsxs("span",{className:"reorder-hints",children:[jsxRuntimeExports.jsx("button",{type:"button",className:this.props.isLast?"hidden":"",onClick:_.partial(this.props.onMove,1),children:jsxRuntimeExports.jsx(InlineIcon$2,{...iconCircleArrowDown})})," ",jsxRuntimeExports.jsx("button",{type:"button",className:this.props.isFirst?"hidden":"",onClick:_.partial(this.props.onMove,-1),children:jsxRuntimeExports.jsx(InlineIcon$2,{...iconCircleArrowUp})})," ",this.props.isLast&&jsxRuntimeExports.jsx(InfoTip$o,{children:jsxRuntimeExports.jsx("p",{children:"The last hint is automatically bolded."})})]}),jsxRuntimeExports.jsx("input",{type:"checkbox",checked:this.props.replace,onChange:this.handleReplaceChanged}),"Replace previous hint",this.props.showRemoveButton&&jsxRuntimeExports.jsxs("button",{type:"button",className:"remove-hint simple-button orange",onClick:this.props.onRemove,children:[jsxRuntimeExports.jsx(InlineIcon$2,{...iconTrash}),"Remove this hint"," "]})]})]})}constructor(...args){super(...args),this.editor=React.createRef(),this.handleReplaceChanged=e=>{this.props.onChange({replace:e.target.checked});},this.focus=()=>{this.editor.current?.focus();},this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()};}}HintEditor.defaultProps={className:"",content:"",replace:false,showMoveButtons:true,showTitle:true,showRemoveButton:true};class CombinedHintEditor extends React.Component{componentDidMount(){this.updatePreview();}componentDidUpdate(){this.updatePreview();}serialize(){invariant(this.editor.current,"cannot serialize CombinedHintEditor with no HintEditor");return this.editor.current.serialize()}render(){const isMobile=this.props.deviceType==="phone"||this.props.deviceType==="tablet";return jsxRuntimeExports.jsxs("div",{className:"perseus-combined-hint-editor "+"perseus-editor-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-editor-left-cell",children:jsxRuntimeExports.jsx(HintEditor,{ref:this.editor,itemId:this.props.itemId,isFirst:this.props.isFirst,isLast:this.props.isLast,widgets:this.props.hint.widgets,content:this.props.hint.content,images:this.props.hint.images,replace:this.props.hint.replace,imageUploader:this.props.imageUploader,onChange:this.props.onChange,onRemove:this.props.onRemove,onMove:this.props.onMove,apiOptions:this.props.apiOptions,widgetIsOpen:this.props.widgetIsOpen})}),jsxRuntimeExports.jsx("div",{className:"perseus-editor-right-cell",children:jsxRuntimeExports.jsx(DeviceFramer,{deviceType:this.props.deviceType,nochrome:true,children:jsxRuntimeExports.jsx(IframeContentRenderer,{ref:this.frame,datasetKey:"mobile",datasetValue:isMobile,seamless:true,url:this.props.previewURL})})})]})}constructor(...args){super(...args),this.editor=React.createRef(),this.frame=React.createRef(),this.updatePreview=()=>{this.frame.current?.sendNewData({type:"hint",data:{hint:this.props.hint,pos:this.props.pos,apiOptions:this.props.apiOptions,linterContext:{contentType:"hint",highlightLint:this.props.highlightLint}}});},this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()},this.focus=()=>{this.editor.current?.focus();};}}CombinedHintEditor.defaultProps={highlightLint:false};class CombinedHintsEditor extends React.Component{handleHintChange(i,newProps){const hints=[...this.props.hints];hints[i]=_.extend({},this.serializeHint(i),newProps);this.props.onChange({hints:hints});}handleHintRemove(i){if(!confirm("Are you sure you want to delete this hint?")){return}const hints=[...this.props.hints];hints.splice(i,1);this.props.onChange({hints:hints});}handleHintMove(i,dir){const hints=[...this.props.hints];const hint=hints.splice(i,1)[0];hints.splice(i+dir,0,hint);this.props.onChange({hints:hints});}serialize(){return this.props.hints.map((_,i)=>this.serializeHint(i))}serializeHint(index){return this.refs["hintEditor"+index].serialize()}render(){const{itemId,hints}=this.props;const editingDisabled=this.props.apiOptions?.editingDisabled??false;const hintElems=_.map(hints,function(hint,i){return jsxRuntimeExports.jsx("fieldset",{disabled:editingDisabled,children:jsxRuntimeExports.jsx(CombinedHintEditor,{ref:"hintEditor"+i,isFirst:i===0,isLast:i+1===hints.length,itemId:itemId,hint:hint,pos:i,imageUploader:this.props.imageUploader,onChange:this.handleHintChange.bind(this,i),onRemove:this.handleHintRemove.bind(this,i),onMove:this.handleHintMove.bind(this,i),deviceType:this.props.deviceType,apiOptions:this.props.apiOptions,highlightLint:this.props.highlightLint,previewURL:this.props.previewURL,widgetIsOpen:this.props.widgetIsOpen})},"hintEditor"+i)},this);return jsxRuntimeExports.jsxs("div",{className:"perseus-hints-editor perseus-editor-table",children:[hintElems,jsxRuntimeExports.jsx("div",{className:"perseus-editor-row",children:jsxRuntimeExports.jsx("div",{className:"add-hint-container perseus-editor-left-cell",children:jsxRuntimeExports.jsxs("button",{type:"button",className:"add-hint simple-button orange",disabled:editingDisabled,onClick:this.addHint,children:[jsxRuntimeExports.jsx(InlineIcon$2,{...iconPlus})," Add a hint"]})})})]})}constructor(...args){super(...args),this.addHint=()=>{const hint={content:"",images:{},widgets:{}};const hints=[...this.props.hints,hint];this.props.onChange({hints:hints});},this.getSaveWarnings=()=>{return _.chain(this.props.hints).map((hint,i)=>{return _.map(this.refs["hintEditor"+i].getSaveWarnings(),issue=>"Hint "+(i+1)+": "+issue)}).flatten(true).value()};}}CombinedHintsEditor.HintEditor=HintEditor;CombinedHintsEditor.defaultProps={onChange:()=>{},hints:[],highlightLint:false};
|
|
1497
1497
|
|
|
1498
|
-
const calculatorVariants=[{label:"Scientific calculator",tip:"Provides the student with a scientific calculator.",variant:"scientific"},{label:"Graphing calculator",tip:"Provides the student with a graphing calculator.",variant:"graphing"},{label:"Four-function calculator",tip:"Provides the student with a four-function calculator.",variant:"four_function"}];const{InfoTip: InfoTip$n}=components;class ItemExtrasEditor extends React.Component{shouldShowCalculatorVariants(){return this.props.calculatorVariant!==
|
|
1498
|
+
const calculatorVariants=[{label:"Scientific calculator",tip:"Provides the student with a scientific calculator.",variant:"scientific"},{label:"Graphing calculator",tip:"Provides the student with a graphing calculator.",variant:"graphing"},{label:"Four-function calculator",tip:"Provides the student with a four-function calculator.",variant:"four_function"}];const{InfoTip: InfoTip$n}=components;class ItemExtrasEditor extends React.Component{shouldShowCalculatorVariants(){return this.props.calculatorVariant!==undefined}shouldShowFinancialCalculatorOptions(){return this.props.financialCalculatorMonthlyPayment||this.props.financialCalculatorTotalAmount||this.props.financialCalculatorTimeToPayOff}serialize(){const data={...ItemExtrasEditor.defaultProps};for(const key of ItemExtras){data[key]=!!this.props[key];}return data}render(){const{editingDisabled}=this.props;return jsxRuntimeExports.jsx("div",{className:"perseus-answer-editor",children:jsxRuntimeExports.jsxs("div",{className:"perseus-answer-options",children:[jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Show calculator",disabled:editingDisabled,infoTip:"Use the calculator when completing difficult calculations is NOT the intent of the question. DON’T use the calculator when testing the student’s ability to complete different types of computations.",checked:this.shouldShowCalculatorVariants(),onChange:newCheckedState=>{this.props.onChange({calculator:newCheckedState,calculatorVariant:newCheckedState?"scientific":undefined});}}),isFeatureOn(this.props,"desmos-calculator")&&this.shouldShowCalculatorVariants()&&calculatorVariants.map(calcVariant=>jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:calcVariant.label,disabled:editingDisabled,infoTip:calcVariant.tip,checked:this.props.calculatorVariant===calcVariant.variant,onChange:()=>{this.props.onChange({calculatorVariant:calcVariant.variant});},indent:true},calcVariant.variant)),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Show financial calculator",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a financial calculator, e.g., for answering financial questions. Once checked, requires at least one of the three options below to be checked.",checked:this.shouldShowFinancialCalculatorOptions(),onChange:newCheckedState=>{this.props.onChange({financialCalculatorMonthlyPayment:newCheckedState,financialCalculatorTotalAmount:newCheckedState,financialCalculatorTimeToPayOff:newCheckedState});}}),this.shouldShowFinancialCalculatorOptions()&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include monthly payment",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a monthly payment calculator; e.g., given a loan amount, interest rate, and term, what is the monthly payment?",checked:this.props.financialCalculatorMonthlyPayment,onChange:newCheckedState=>{this.props.onChange({financialCalculatorMonthlyPayment:newCheckedState});},indent:true}),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include total amount",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a total amount calculator; e.g., given a monthly payment, interest rate, and term, what is the total amount to be paid?",checked:this.props.financialCalculatorTotalAmount,onChange:newCheckedState=>{this.props.onChange({financialCalculatorTotalAmount:newCheckedState});},indent:true}),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include time-to-pay-off",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a time to pay off calculator; e.g., given a loan amount, interest rate, and monthly payment, how long will it take to pay off the loan?",checked:this.props.financialCalculatorTimeToPayOff,onChange:newCheckedState=>{this.props.onChange({financialCalculatorTimeToPayOff:newCheckedState});},indent:true})]}),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Show periodic table",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a periodic table of the elements, e.g., for answering chemistry questions.",checked:this.props.periodicTable,onChange:newCheckedState=>{this.props.onChange({periodicTable:newCheckedState,periodicTableWithKey:false});}}),this.props.periodicTable&&jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include key/legend with periodic table",disabled:editingDisabled,infoTip:"Include a key for HS courses; omit for AP chemistry.",checked:this.props.periodicTableWithKey,onChange:newCheckedState=>{this.props.onChange({periodicTableWithKey:newCheckedState});},indent:true})]})})}}ItemExtrasEditor.defaultProps=getDefaultAnswerArea();const ItemExtraCheckbox=props=>jsxRuntimeExports.jsx(View,{style:[styles$O.checkbox,props.indent?styles$O.indented:undefined],children:jsxRuntimeExports.jsx(Checkbox$1,{disabled:props.disabled,label:jsxRuntimeExports.jsxs(View,{style:{flexDirection:"row"},children:[props.label," ",jsxRuntimeExports.jsx(InfoTip$n,{children:props.infoTip})]}),checked:props.checked,onChange:newCheckedState=>props.onChange(newCheckedState)})});const styles$O=StyleSheet.create({indented:{marginInlineStart:spacing.large_24}});
|
|
1499
1499
|
|
|
1500
1500
|
var issuesList = {"axe-core":{"user-fixable":["aria-input-field-name","aria-meter-name","aria-toggle-field-name","image-alt","input-image-alt","label","link-name","list","role-img-alt","select-name","summary-name","svg-img-alt","video-caption"]}};
|
|
1501
1501
|
|
|
@@ -1538,7 +1538,7 @@ var styles$M = {"paddedX":"perseus_xyIPJvSm","paddedY":"perseus_6B-8VzAW","answe
|
|
|
1538
1538
|
const{ButtonGroup: ButtonGroup$7,InfoTip: InfoTip$k}=components;const buttonSetsList=["basic","trig","prealgebra","logarithms","scientific","basic relations","advanced relations"];class ExpressionEditor extends React.Component{serialize(){const{answerForms,buttonSets,functions,times,visibleLabel,ariaLabel}=this.props;return {answerForms,buttonSets,functions,times,visibleLabel,ariaLabel,extraKeys:deriveExtraKeys(this.props)}}updateAnswerForm(index,answerFormProps){const answerForms=this.props.answerForms.slice();answerForms[index]=answerFormProps;const{extraKeys:_,...restProps}=this.props;const extraKeys=deriveExtraKeys({...restProps,answerForms});this.props.onChange({answerForms,extraKeys});}changeSimplify(index,simplify){const answerForm={...this.props.answerForms[index],simplify};this.updateAnswerForm(index,answerForm);}changeForm(index,form){const answerForm={...this.props.answerForms[index],form};this.updateAnswerForm(index,answerForm);}changeConsidered(index,considered){const answerForm={...this.props.answerForms[index],considered};this.updateAnswerForm(index,answerForm);}changeTimes(times){this.props.onChange({times:times});}render(){const editingDisabled=this.props.apiOptions.editingDisabled??false;const answerOptions=this.props.answerForms.map((ans,index)=>{const expressionProps={times:this.props.times,functions:this.props.functions,buttonSets:this.props.buttonSets,buttonsVisible:"focused",userInput:ans.value,handleUserInput:input=>this.changeExpressionWidget(index,input),trackInteraction:()=>{},widgetId:this.props.widgetId+"-"+ans.key,visibleLabel:this.props.visibleLabel,ariaLabel:this.props.ariaLabel};return jsxRuntimeExports.jsx(AnswerOption,{considered:ans.considered,editingDisabled:editingDisabled,expressionProps:expressionProps,form:ans.form,simplify:ans.simplify,onDelete:()=>this.handleRemoveForm(index),onChangeSimplify:simplify=>this.changeSimplify(index,simplify),onChangeForm:form=>this.changeForm(index,form),onChangeConsidered:considered=>this.changeConsidered(index,considered)},ans.key)});const buttonSetChoices=buttonSetsList.map(name=>{const isBasic=name==="basic";const checked=this.props.buttonSets.includes(name)||isBasic;return jsxRuntimeExports.jsx(Checkbox$1,{label:name,checked:checked,disabled:isBasic,onChange:()=>this.handleButtonSet(name)},name)});buttonSetChoices.unshift(jsxRuntimeExports.jsx(Checkbox$1,{label:"show ÷ button",checked:this.props.buttonSets.includes("basic+div"),onChange:this.handleToggleDiv},"show ÷ button"));return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(Heading$1,{size:"medium",children:"Global Options"}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(LabeledTextField,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Visible label",jsxRuntimeExports.jsx(InfoTip$k,{children:"Optional visible text; strongly encouraged to help learners using dictation software, but can be omitted if the surrounding content provides enough context."})]}),value:this.props.visibleLabel||"",onChange:this.handleVisibleLabel})}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(LabeledTextField,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Aria label",jsxRuntimeExports.jsxs(InfoTip$k,{children:["Label text that's read by screen readers. Highly recommend adding a label here to ensure your exercise is accessible. For more information on writting accessible labels, please see"," ",jsxRuntimeExports.jsx("a",{href:"https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",target:"_blank",rel:"noreferrer",children:"this article."})]})]}),value:this.props.ariaLabel||"",onChange:this.handleAriaLabel})}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(LabeledTextField,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Function variables",jsxRuntimeExports.jsx(InfoTip$k,{children:'Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means "f of x" and not "f times x".'})]}),value:this.state.functionsInternal,onChange:this.handleFunctions})}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Use × instead of ⋅ for multiplication",jsxRuntimeExports.jsx(InfoTip$k,{children:"For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."})]}),checked:this.props.times,onChange:newCheckedState=>{this.changeTimes(newCheckedState);}})}),jsxRuntimeExports.jsxs("div",{className:styles$M.paddedY,children:[jsxRuntimeExports.jsx(Heading$1,{size:"small",className:styles$M.buttonSets,children:"Button Sets"}),buttonSetChoices]}),jsxRuntimeExports.jsx(Heading$1,{size:"medium",children:"Answers"}),jsxRuntimeExports.jsx(BodyText,{size:"small",className:styles$M.answersSubtitle,children:"student responses area matched against these from top to bottom"}),jsxRuntimeExports.jsxs(View,{className:styles$M.answersGroup,children:[jsxRuntimeExports.jsx(View,{className:styles$M.answersList,children:answerOptions}),jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.newAnswer,children:"Add new answer"})]})]})}constructor(props){super(props),this.getSaveWarnings=()=>{const issues=[];if(this.props.answerForms.length===0){issues.push("No answers specified");}else {const hasCorrect=this.props.answerForms.some(form=>{return form.considered==="correct"});if(!hasCorrect){issues.push("No correct answer specified");}_(this.props.answerForms).each((form,ix)=>{if(this.props.value===""){issues.push(`Answer ${ix+1} is empty`);}else {const expression=KAS.parse(form.value,{functions:this.props.functions});if(!expression.parsed){issues.push(`Couldn't parse ${form.value}`);}else if(form.simplify&&!expression.expr.isSimplified()){issues.push(`${form.value} isn't simplified, but is required" +
|
|
1539
1539
|
" to be`);}}});}return issues},this.newAnswer=()=>{const answerForms=this.props.answerForms.slice();const newKey=crypto.randomUUID();const newAnswerForm={considered:"correct",form:false,key:`${newKey}`,simplify:false,value:""};answerForms.push(newAnswerForm);this.props.onChange({answerForms});},this.handleRemoveForm=i=>{const updatedAnswerForms=this.props.answerForms.slice();updatedAnswerForms.splice(i,1);this.props.onChange({answerForms:updatedAnswerForms});},this.handleButtonSet=changingName=>{const buttonSetNames=buttonSetsList;const buttonSets=buttonSetNames.filter(set=>{return this.props.buttonSets.includes(set)!==(set===changingName)});this.props.onChange({buttonSets});},this.handleToggleDiv=()=>{let keep;let remove;if(this.props.buttonSets.includes("basic+div")){keep="basic";remove="basic+div";}else {keep="basic+div";remove="basic";}const buttonSets=this.props.buttonSets.filter(set=>set!==remove).concat(keep);this.props.onChange({buttonSets});},this.handleTexInsert=str=>{this.refs.expression.insert(str);},this.handleFunctions=value=>{this.setState({functionsInternal:value});const newProps={};newProps.functions=value.split(/[ ,]+/).filter(isTruthy);this.props.onChange(newProps);},this.handleVisibleLabel=visibleLabel=>{this.props.onChange({visibleLabel});},this.handleAriaLabel=ariaLabel=>{this.props.onChange({ariaLabel});},this.changeExpressionWidget=(index,input)=>{const answerForm={...this.props.answerForms[index],value:input};this.updateAnswerForm(index,answerForm);};this.state={functionsInternal:this.props.functions.join(" ")};}}ExpressionEditor.widgetName="expression";ExpressionEditor.defaultProps={...expressionLogic.defaultWidgetOptions,apiOptions:ApiOptions.defaults};const findNextIn=function(arr,val){let ix=arr.indexOf(val);ix=(ix+1)%arr.length;return arr[ix]};class AnswerOption extends React.Component{render(){const{editingDisabled}=this.props;const removeButton=this.state.deleteFocused?jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.handleImSure,actionType:"destructive",children:"I'm sure!"}),jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.handleCancelDelete,kind:"secondary",children:"Cancel"})]}):jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.handleDelete,actionType:"destructive",kind:"tertiary",className:styles$M.deleteButton,children:"Delete"});return jsxRuntimeExports.jsxs("div",{className:styles$M.answerOption,children:[jsxRuntimeExports.jsx(ButtonGroup$7,{onChange:this.toggleConsidered,allowEmpty:false,disabled:editingDisabled,value:this.props.considered,selectedButtonStyle:consideredButtonStyles[this.props.considered],buttons:PerseusExpressionAnswerFormConsidered.map(c=>({value:c,content:c,title:`This answer will be considered ${c}`}))}),jsxRuntimeExports.jsx(Expression,{...this.props.expressionProps}),jsxRuntimeExports.jsx("div",{className:`${styles$M.paddedY} ${styles$M.paddedX}`,children:jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Answer expression must have the same form.",jsxRuntimeExports.jsx(InfoTip$k,{children:"The student's answer must be in the same form. Commutativity and excess negative signs are ignored."})]}),checked:this.props.form,onChange:this.props.onChangeForm})}),jsxRuntimeExports.jsx("div",{className:`${styles$M.paddedY} ${styles$M.paddedX}`,children:jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Answer expression must be fully expanded and simplified.",jsxRuntimeExports.jsx(InfoTip$k,{children:'The student\'s answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response "Your answer is not fully expanded and simplified."'})]}),checked:this.props.simplify,onChange:this.props.onChangeSimplify})}),jsxRuntimeExports.jsx("div",{className:`${styles$M.buttonRow} ${styles$M.paddedY}`,children:removeButton})]})}constructor(...args){super(...args),this.state={deleteFocused:false},this.handleImSure=()=>{this.props.onDelete();this.handleCancelDelete();},this.handleCancelDelete=()=>{this.setState({deleteFocused:false});},this.handleDelete=()=>{this.setState({deleteFocused:true});},this.toggleConsidered=()=>{const newVal=findNextIn(PerseusExpressionAnswerFormConsidered,this.props.considered);this.props.onChangeConsidered(newVal);};}}const wbStyles$1=StyleSheet.create({answerStatusWrong:{backgroundColor:semanticColor.core.background.critical.subtle},answerStatusCorrect:{backgroundColor:semanticColor.core.background.success.subtle},answerStatusUngraded:{backgroundColor:semanticColor.core.background.instructive.subtle}});const consideredButtonStyles={wrong:wbStyles$1.answerStatusWrong,correct:wbStyles$1.answerStatusCorrect,ungraded:wbStyles$1.answerStatusUngraded};
|
|
1540
1540
|
|
|
1541
|
-
class FreeResponseEditor extends React.Component{render(){const editingDisabled=this.props.apiOptions.editingDisabled??false;return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(LabeledField,{label:"Question",field:jsxRuntimeExports.jsx(
|
|
1541
|
+
class FreeResponseEditor extends React.Component{render(){const editingDisabled=this.props.apiOptions.editingDisabled??false;return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(LabeledField,{label:"Question",field:jsxRuntimeExports.jsx(TextArea,{value:this.props.question,onChange:newValue=>this.props.onChange({question:newValue})}),styles:{root:styles$L.labeledInputField}}),jsxRuntimeExports.jsx(LabeledField,{label:"Placeholder",field:jsxRuntimeExports.jsx(TextArea,{value:this.props.placeholder,onChange:newValue=>this.props.onChange({placeholder:newValue})}),styles:{root:styles$L.labeledInputField}}),jsxRuntimeExports.jsx(LabeledField,{label:"Allow unlimited characters",field:jsxRuntimeExports.jsx(Checkbox$1,{checked:this.props.allowUnlimitedCharacters,onChange:val=>this.props.onChange({allowUnlimitedCharacters:val})}),styles:{root:styles$L.labeledInputField}}),!this.props.allowUnlimitedCharacters&&jsxRuntimeExports.jsx(LabeledField,{label:"Character limit",field:jsxRuntimeExports.jsx(TextField,{type:"number",min:1,value:String(this.props.characterLimit),onChange:this.handleUpdateCharacterLimit}),styles:{root:styles$L.labeledInputField}}),jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsxs(View,{style:styles$L.criteriaList,tag:"fieldset",children:[jsxRuntimeExports.jsx(BodyText,{tag:"legend",children:"Scoring criteria"}),this.renderCriteriaList(editingDisabled)]}),jsxRuntimeExports.jsx(View,{children:jsxRuntimeExports.jsx(Button,{onClick:this.handleAddCriterion,startIcon:plusCircle,disabled:editingDisabled,children:"Add an item"})})]})]})}constructor(...args){super(...args),this.serialize=()=>{return {allowUnlimitedCharacters:this.props.allowUnlimitedCharacters,characterLimit:this.props.characterLimit,placeholder:this.props.placeholder,question:this.props.question,scoringCriteria:this.props.scoringCriteria}},this.getSaveWarnings=()=>{const warnings=[];if(!this.props.question){warnings.push("The question is empty");}if(this.props.question.match(Util.rWidgetRule)!=null){warnings.push("The question contains a widget");}return warnings},this.handleUpdateCharacterLimit=newValue=>{const val=parseInt(newValue);if(isNaN(val)){return}this.props.onChange({characterLimit:Math.max(1,val)});},this.handleUpdateCriterion=(index,criterion)=>{const newCriteria=this.props.scoringCriteria.map((c,i)=>{if(i===index){return criterion}return c});this.props.onChange({scoringCriteria:newCriteria});},this.handleDeleteCriterion=index=>{this.props.onChange({scoringCriteria:this.props.scoringCriteria.filter((_,i)=>i!==index)});},this.handleAddCriterion=()=>{this.props.onChange({scoringCriteria:[...this.props.scoringCriteria,{text:""}]});},this.renderCriteriaList=editingDisabled=>{const isDeletable=this.props.scoringCriteria.length>1;return this.props.scoringCriteria.map((criterion,index)=>{return jsxRuntimeExports.jsx(CriterionEditor,{criterion:criterion,index:index,isDeletable:isDeletable,editingDisabled:editingDisabled,onChange:this.handleUpdateCriterion,onDelete:this.handleDeleteCriterion},index)})};}}FreeResponseEditor.defaultProps={...freeResponseLogic.defaultWidgetOptions,apiOptions:ApiOptions.defaults};FreeResponseEditor.widgetName="free-response";const CriterionEditor=function(props){return jsxRuntimeExports.jsxs(View,{style:styles$L.criterionContainer,children:[jsxRuntimeExports.jsx("textarea",{"aria-label":`Criterion ${props.index+1}`,onChange:e=>props.onChange(props.index,{text:e.target.value}),value:props.criterion.text}),props.isDeletable&&jsxRuntimeExports.jsx(View,{style:styles$L.deleteButtonContainer,children:jsxRuntimeExports.jsx(Button,{"aria-label":`Delete criterion ${props.index+1}`,actionType:"destructive",disabled:!props.isDeletable||props.editingDisabled,kind:"tertiary",onClick:()=>props.onDelete(props.index),size:"small",startIcon:trashIcon$1,children:"Delete"})})]})};const styles$L=StyleSheet.create({criteriaList:{gap:spacing.small_12},criterionContainer:{paddingTop:spacing.xSmall_8,paddingBottom:spacing.xSmall_8,borderBottom:`1px solid ${semanticColor.core.border.neutral.subtle}`,":last-child":{borderBottom:"none"}},deleteButtonContainer:{display:"flex",flexDirection:"row",justifyContent:"flex-end"},labeledInputField:{paddingBottom:spacing.large_24}});
|
|
1542
1542
|
|
|
1543
1543
|
var styles$K = {"title":"perseus_az1kQinp","input":"perseus_khxW0hEz","hintsTitle":"perseus_UPlDqNry","addHintButton":"perseus_2aajvB7Y"};
|
|
1544
1544
|
|
|
@@ -1594,27 +1594,27 @@ const{ButtonGroup: ButtonGroup$4}=components;class DashPicker extends React.Comp
|
|
|
1594
1594
|
|
|
1595
1595
|
function MathquillInput(props){const mathFieldWrapperRef=useRef(null);const mathFieldInstance=useRef();const{locale,strings}=useMathInputI18n();useEffect(()=>{if(mathFieldWrapperRef.current&&!mathFieldInstance.current){mathFieldInstance.current=createMathField(mathFieldWrapperRef.current,locale,strings,baseConfig=>({...baseConfig,handlers:{edit:mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(props.value!==value){props.onChange(value);}},upOutOf:mathField=>{mathField.typedText("^");}}}));}});return jsxRuntimeExports.jsx(View,{style:styles$E.outerWrapper,children:jsxRuntimeExports.jsx("span",{ref:mathFieldWrapperRef,className:"perseus-math-input mq-editable-field mq-math-mode"})})}const styles$E=StyleSheet.create({outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:1,borderColor:semanticColor.core.border.neutral.default,borderRadius:3,background:semanticColor.core.background.base.default}});
|
|
1596
1596
|
|
|
1597
|
-
const{NumberInput: NumberInput$b}=components;
|
|
1597
|
+
const{NumberInput: NumberInput$b}=components;class FunctionEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:this.props.funcName+"(x)="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.value,onChange:this.change("value")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Range: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMin,onChange:this.change("rangeMin")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMax,onChange:this.change("rangeMax")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$b,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}FunctionEditor.defaultProps={value:"x",rangeMin:"-10",rangeMax:"10",color:KhanColors.BLUE,strokeDasharray:"",strokeWidth:2};
|
|
1598
1598
|
|
|
1599
|
-
const{TextInput: TextInput$2}=components;
|
|
1599
|
+
const{TextInput: TextInput$2}=components;class LabelEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(TextInput$2,{value:this.props.label,onChange:this.change("label"),style:{width:"100%"}})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Location: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:this.change("coordX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordY,onChange:this.change("coordY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}LabelEditor.defaultProps={coordX:"0",coordY:"0",color:KhanColors.BLACK,label:"\\phi"};
|
|
1600
1600
|
|
|
1601
1601
|
const{ButtonGroup: ButtonGroup$3}=components;class ArrowPicker extends React.Component{render(){return jsxRuntimeExports.jsx(ButtonGroup$3,{value:this.props.value,allowEmpty:false,buttons:[{value:"",content:jsxRuntimeExports.jsx("span",{children:"—"})},{value:"->",content:jsxRuntimeExports.jsx("span",{children:"→"})}],onChange:this.props.onChange})}}ArrowPicker.defaultProps={value:""};
|
|
1602
1602
|
|
|
1603
|
-
const{NumberInput: NumberInput$a}=components;
|
|
1603
|
+
const{NumberInput: NumberInput$a}=components;class LineEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endX,onChange:this.change("endX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endY,onChange:this.change("endY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")})," ",jsxRuntimeExports.jsx(ArrowPicker,{value:this.props.arrows,onChange:this.change("arrows")})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$a,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}LineEditor.defaultProps={startX:"-5",startY:"5",endX:"5",endY:"5",color:KhanColors.BLACK,strokeDasharray:"",arrows:"",strokeWidth:2};
|
|
1604
1604
|
|
|
1605
1605
|
const{ButtonGroup: ButtonGroup$2,NumberInput: NumberInput$9}=components;class ConstraintEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Constraint:"," ",jsxRuntimeExports.jsx(ButtonGroup$2,{value:this.props.constraint,allowEmpty:false,buttons:[{value:"none",content:"None"},{value:"snap",content:"Snap"},{value:"x",content:"x="},{value:"y",content:"y="}],onChange:this.change("constraint")})]}),this.props.constraint==="snap"&&jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Snap:"," ",jsxRuntimeExports.jsx(NumberInput$9,{value:this.props.snap,placeholder:0,onChange:this.change("snap")})]}),this.props.constraint==="x"&&jsxRuntimeExports.jsx("div",{className:"graph-settings",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"x="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintFn,onChange:this.change("constraintFn")})]})}),this.props.constraint==="y"&&jsxRuntimeExports.jsx("div",{className:"graph-settings",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"y="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintFn,onChange:this.change("constraintFn")})]})}),"Ensure these are set so nothing can be dragged off the canvas:",jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"x \\in \\Large["})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintXMin,onChange:this.change("constraintXMin")}),jsxRuntimeExports.jsx(TeX,{children:", "})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintXMax,onChange:this.change("constraintXMax")})," ",jsxRuntimeExports.jsx(TeX,{children:"\\Large]"})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"y \\in \\Large["})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintYMin,onChange:this.change("constraintYMin")}),jsxRuntimeExports.jsx(TeX,{children:", "})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintYMax,onChange:this.change("constraintYMax")})," ",jsxRuntimeExports.jsx(TeX,{children:"\\Large]"})]})})]})}constructor(...args){super(...args),this.change=propName=>{return Changeable.change.call(this,propName)};}}ConstraintEditor.defaultProps={constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10"};
|
|
1606
1606
|
|
|
1607
|
-
const{NumberInput: NumberInput$8}=components;
|
|
1607
|
+
const{NumberInput: NumberInput$8}=components;class MovableLineEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:["Initial position:",jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endX,onChange:this.change("endX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endY,onChange:this.change("endY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start updates ",jsxRuntimeExports.jsx(TeX,{children:"(x_n, y_n)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"n ="}),jsxRuntimeExports.jsx(NumberInput$8,{value:this.props.startSubscript,placeholder:0,onChange:this.change("startSubscript")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End updates ",jsxRuntimeExports.jsx(TeX,{children:"(x_m, y_m)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"m ="}),jsxRuntimeExports.jsx(NumberInput$8,{value:this.props.endSubscript,placeholder:0,onChange:this.change("endSubscript")})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:"All constraints are applied to the start point."}),jsxRuntimeExports.jsx(ConstraintEditor,{...this.props})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MovableLineEditor.defaultProps={startX:"-5",startY:"5",endX:"5",endY:"5",constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10"};
|
|
1608
1608
|
|
|
1609
|
-
const{NumberInput: NumberInput$7}=components;
|
|
1609
|
+
const{NumberInput: NumberInput$7}=components;class MovablePointEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Update ",jsxRuntimeExports.jsx(TeX,{children:"(x_n, y_n)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"n ="})," ",jsxRuntimeExports.jsx(NumberInput$7,{value:this.props.varSubscript,placeholder:0,onChange:this.change("varSubscript")})]}),jsxRuntimeExports.jsx(ConstraintEditor,{...this.props})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MovablePointEditor.defaultProps={startX:"0",startY:"0",constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10"};
|
|
1610
1610
|
|
|
1611
|
-
const{NumberInput: NumberInput$6}=components;
|
|
1611
|
+
const{NumberInput: NumberInput$6}=components;class ParametricEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"X(t) ="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.x,onChange:this.change("x")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"Y(t) ="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.y,onChange:this.change("y")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Range: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMin,onChange:this.change("rangeMin")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMax,onChange:this.change("rangeMax")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$6,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}ParametricEditor.defaultProps={x:"cos(t)",y:"sin(t)",rangeMin:"0",rangeMax:"2\\pi",color:KhanColors.BLUE,strokeDasharray:"",strokeWidth:2};
|
|
1612
1612
|
|
|
1613
|
-
|
|
1613
|
+
class PointEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Coordinate: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:this.change("coordX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordY,onChange:this.change("coordY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}PointEditor.defaultProps={coordX:"0",coordY:"0",color:KhanColors.BLACK};
|
|
1614
1614
|
|
|
1615
|
-
|
|
1615
|
+
class RectangleEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Bottom left: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:this.change("coordX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordY,onChange:this.change("coordY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Width:"," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.width,onChange:this.change("width")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Height:"," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.height,onChange:this.change("height")})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,lightColors:true,onChange:this.change("color")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:"You want a border? Sorry, draw your own."})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}RectangleEditor.defaultProps={coordX:"-5",coordY:"5",width:"2",height:"3",color:KhanColors.LIGHT_BLUE};
|
|
1616
1616
|
|
|
1617
|
-
const{getDependencies}=Dependencies;const{unescapeMathMode}=Util;class InteractionEditor extends React.Component{UNSAFE_componentWillReceiveProps(nextProps){this.setState({usedVarSubscripts:this._getAllVarSubscripts(nextProps.elements),usedFunctionNames:this._getAllFunctionNames(nextProps.elements)});}_getAllVarSubscripts(elements){return _.map(_.where(elements,{type:"movable-point"}),element=>element.options.varSubscript).concat(_.map(_.where(elements,{type:"movable-line"}),element=>element.options.startSubscript)).concat(_.map(_.where(elements,{type:"movable-line"}),element=>element.options.endSubscript))}_getAllFunctionNames(elements){return _.map(_.where(elements,{type:"function"}),element=>element.options.funcName)}render(){const{TeX}=getDependencies();return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-interaction-editor",children:[jsxRuntimeExports.jsxs(ElementContainer,{title:"Grid settings",children:[jsxRuntimeExports.jsx(GraphSettings,{editableSettings:["canvas","graph"],box:this.props.graph.box,labels:this.props.graph.labels,range:this.props.graph.range,step:this.props.graph.tickStep,gridStep:this.props.graph.gridStep,markings:this.props.graph.markings,onChange:this._updateGraphProps}),jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:this.props.graph.valid!==true&&jsxRuntimeExports.jsx("div",{children:this.props.graph.valid})})]}),_.map(this.props.elements,function(element,n){if(element.type==="movable-point"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Movable point"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.varSubscript+"}, y_{"+element.options.varSubscript+"})"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(MovablePointEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="movable-line"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Movable line"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.startSubscript+"}, y_{"+element.options.startSubscript+"})"})," ","to"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.endSubscript+"}, y_{"+element.options.endSubscript+"})"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(MovableLineEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="point"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Point"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.coordX+", "+element.options.coordY+")"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(PointEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="line"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Line"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.startX+", "+element.options.startY+")"})," ","to"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.endX+", "+element.options.endY+")"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(LineEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="function"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Function"," ",jsxRuntimeExports.jsx(TeX,{children:element.options.funcName+"(x) = "+element.options.value})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(FunctionEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="parametric"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsx("span",{children:"Parametric"}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(ParametricEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="label"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Label"," ",jsxRuntimeExports.jsx(TeX,{children:unescapeMathMode(element.options.label)})," "]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(LabelEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="rectangle"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Rectangle"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.coordX+", "+element.options.coordY+")"})," — ",jsxRuntimeExports.jsx(TeX,{children:element.options.width+" \\times "+element.options.height})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(RectangleEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}},this),jsxRuntimeExports.jsx("div",{className:"perseus-widget-interaction-editor-select-element",children:jsxRuntimeExports.jsxs("select",{onChange:this._addNewElement,children:[jsxRuntimeExports.jsxs("option",{value:"",children:["Add an element","…"]}),jsxRuntimeExports.jsx("option",{disabled:true,children:"--"}),jsxRuntimeExports.jsx("option",{value:"point",children:"Point"}),jsxRuntimeExports.jsx("option",{value:"line",children:"Line segment"}),jsxRuntimeExports.jsx("option",{value:"function",children:"Function plot"}),jsxRuntimeExports.jsx("option",{value:"parametric",children:"Parametric plot"}),jsxRuntimeExports.jsx("option",{value:"label",children:"Label"}),jsxRuntimeExports.jsx("option",{value:"rectangle",children:"Rectangle"}),jsxRuntimeExports.jsx("option",{value:"movable-point",children:"★ Movable point"}),jsxRuntimeExports.jsx("option",{value:"movable-line",children:"★ Movable line segment"})]})})]})}constructor(...args){super(...args),this.state={usedVarSubscripts:this._getAllVarSubscripts(this.props.elements),usedFunctionNames:this._getAllFunctionNames(this.props.elements)},this._updateGraphProps=newProps=>{this.props.onChange({graph:{...this.props.graph,..._.omit(newProps,"step"),tickStep:newProps.step}});},this._addNewElement=e=>{const elementType=e.target.value;if(elementType===""){return}e.target.value="";const newElement={type:elementType,key:elementType+"-"+(Math.random()*0xffffff<<0).toString(16),options:elementType==="point"?_.clone(PointEditor.defaultProps):elementType==="line"?_.clone(LineEditor.defaultProps):elementType==="movable-point"?_.clone(MovablePointEditor.defaultProps):elementType==="movable-line"?_.clone(MovableLineEditor.defaultProps):elementType==="function"?_.clone(FunctionEditor.defaultProps):elementType==="parametric"?_.clone(ParametricEditor.defaultProps):elementType==="label"?_.clone(LabelEditor.defaultProps):elementType==="rectangle"?_.clone(RectangleEditor.defaultProps):{}};let nextSubscript;if(elementType==="movable-point"){nextSubscript=_.max([_.max(this.state.usedVarSubscripts),-1])+1;newElement.options.varSubscript=nextSubscript;}else if(elementType==="movable-line"){nextSubscript=_.max([_.max(this.state.usedVarSubscripts),-1])+1;newElement.options.startSubscript=nextSubscript;newElement.options.endSubscript=nextSubscript+1;}else if(elementType==="function"){const nextLetter=String.fromCharCode(_.max([_.max(_.map(this.state.usedFunctionNames,function(c){return c.charCodeAt(0)})),"e".charCodeAt(0)])+1);newElement.options.funcName=nextLetter;}this.props.onChange({elements:this.props.elements.concat(newElement)});},this._deleteElement=index=>{const element=this.props.elements[index];this.props.onChange({elements:_.without(this.props.elements,element)});},this._moveElementUp=index=>{const element=this.props.elements[index];const newElements=_.without(this.props.elements,element);newElements.splice(index-1,0,element);this.props.onChange({elements:newElements});},this._moveElementDown=index=>{const element=this.props.elements[index];const newElements=_.without(this.props.elements,element);newElements.splice(index+1,0,element);this.props.onChange({elements:newElements});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}InteractionEditor.widgetName="interaction";InteractionEditor.defaultProps=interactionLogic.defaultWidgetOptions;
|
|
1617
|
+
const{unescapeMathMode}=Util;class InteractionEditor extends React.Component{UNSAFE_componentWillReceiveProps(nextProps){this.setState({usedVarSubscripts:this._getAllVarSubscripts(nextProps.elements),usedFunctionNames:this._getAllFunctionNames(nextProps.elements)});}_getAllVarSubscripts(elements){return _.map(_.where(elements,{type:"movable-point"}),element=>element.options.varSubscript).concat(_.map(_.where(elements,{type:"movable-line"}),element=>element.options.startSubscript)).concat(_.map(_.where(elements,{type:"movable-line"}),element=>element.options.endSubscript))}_getAllFunctionNames(elements){return _.map(_.where(elements,{type:"function"}),element=>element.options.funcName)}render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-interaction-editor",children:[jsxRuntimeExports.jsxs(ElementContainer,{title:"Grid settings",children:[jsxRuntimeExports.jsx(GraphSettings,{editableSettings:["canvas","graph"],box:this.props.graph.box,labels:this.props.graph.labels,range:this.props.graph.range,step:this.props.graph.tickStep,gridStep:this.props.graph.gridStep,markings:this.props.graph.markings,onChange:this._updateGraphProps}),jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:this.props.graph.valid!==true&&jsxRuntimeExports.jsx("div",{children:this.props.graph.valid})})]}),_.map(this.props.elements,function(element,n){if(element.type==="movable-point"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Movable point"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.varSubscript+"}, y_{"+element.options.varSubscript+"})"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(MovablePointEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="movable-line"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Movable line"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.startSubscript+"}, y_{"+element.options.startSubscript+"})"})," ","to"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.endSubscript+"}, y_{"+element.options.endSubscript+"})"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(MovableLineEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="point"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Point"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.coordX+", "+element.options.coordY+")"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(PointEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="line"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Line"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.startX+", "+element.options.startY+")"})," ","to"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.endX+", "+element.options.endY+")"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(LineEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="function"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Function"," ",jsxRuntimeExports.jsx(TeX,{children:element.options.funcName+"(x) = "+element.options.value})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(FunctionEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="parametric"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsx("span",{children:"Parametric"}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(ParametricEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="label"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Label"," ",jsxRuntimeExports.jsx(TeX,{children:unescapeMathMode(element.options.label)})," "]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(LabelEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="rectangle"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Rectangle"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.coordX+", "+element.options.coordY+")"})," — ",jsxRuntimeExports.jsx(TeX,{children:element.options.width+" \\times "+element.options.height})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(RectangleEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}},this),jsxRuntimeExports.jsx("div",{className:"perseus-widget-interaction-editor-select-element",children:jsxRuntimeExports.jsxs("select",{onChange:this._addNewElement,children:[jsxRuntimeExports.jsxs("option",{value:"",children:["Add an element","…"]}),jsxRuntimeExports.jsx("option",{disabled:true,children:"--"}),jsxRuntimeExports.jsx("option",{value:"point",children:"Point"}),jsxRuntimeExports.jsx("option",{value:"line",children:"Line segment"}),jsxRuntimeExports.jsx("option",{value:"function",children:"Function plot"}),jsxRuntimeExports.jsx("option",{value:"parametric",children:"Parametric plot"}),jsxRuntimeExports.jsx("option",{value:"label",children:"Label"}),jsxRuntimeExports.jsx("option",{value:"rectangle",children:"Rectangle"}),jsxRuntimeExports.jsx("option",{value:"movable-point",children:"★ Movable point"}),jsxRuntimeExports.jsx("option",{value:"movable-line",children:"★ Movable line segment"})]})})]})}constructor(...args){super(...args),this.state={usedVarSubscripts:this._getAllVarSubscripts(this.props.elements),usedFunctionNames:this._getAllFunctionNames(this.props.elements)},this._updateGraphProps=newProps=>{this.props.onChange({graph:{...this.props.graph,..._.omit(newProps,"step"),tickStep:newProps.step}});},this._addNewElement=e=>{const elementType=e.target.value;if(elementType===""){return}e.target.value="";const newElement={type:elementType,key:elementType+"-"+(Math.random()*0xffffff<<0).toString(16),options:elementType==="point"?_.clone(PointEditor.defaultProps):elementType==="line"?_.clone(LineEditor.defaultProps):elementType==="movable-point"?_.clone(MovablePointEditor.defaultProps):elementType==="movable-line"?_.clone(MovableLineEditor.defaultProps):elementType==="function"?_.clone(FunctionEditor.defaultProps):elementType==="parametric"?_.clone(ParametricEditor.defaultProps):elementType==="label"?_.clone(LabelEditor.defaultProps):elementType==="rectangle"?_.clone(RectangleEditor.defaultProps):{}};let nextSubscript;if(elementType==="movable-point"){nextSubscript=_.max([_.max(this.state.usedVarSubscripts),-1])+1;newElement.options.varSubscript=nextSubscript;}else if(elementType==="movable-line"){nextSubscript=_.max([_.max(this.state.usedVarSubscripts),-1])+1;newElement.options.startSubscript=nextSubscript;newElement.options.endSubscript=nextSubscript+1;}else if(elementType==="function"){const nextLetter=String.fromCharCode(_.max([_.max(_.map(this.state.usedFunctionNames,function(c){return c.charCodeAt(0)})),"e".charCodeAt(0)])+1);newElement.options.funcName=nextLetter;}this.props.onChange({elements:this.props.elements.concat(newElement)});},this._deleteElement=index=>{const element=this.props.elements[index];this.props.onChange({elements:_.without(this.props.elements,element)});},this._moveElementUp=index=>{const element=this.props.elements[index];const newElements=_.without(this.props.elements,element);newElements.splice(index-1,0,element);this.props.onChange({elements:newElements});},this._moveElementDown=index=>{const element=this.props.elements[index];const newElements=_.without(this.props.elements,element);newElements.splice(index+1,0,element);this.props.onChange({elements:newElements});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}InteractionEditor.widgetName="interaction";InteractionEditor.defaultProps=interactionLogic.defaultWidgetOptions;
|
|
1618
1618
|
|
|
1619
1619
|
var styles$D = {"singleSelectShort":"perseus_wAZzFxEx","row":"perseus_6FquBkGo"};
|
|
1620
1620
|
|
|
@@ -1818,7 +1818,7 @@ const{InfoTip: InfoTip$3,TextListEditor: TextListEditor$2}=components;const NORM
|
|
|
1818
1818
|
|
|
1819
1819
|
class PhetSimulationEditor extends React.Component{serialize(){return {url:this.props.url,description:this.props.description}}render(){return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(LabeledTextField,{label:"URL",value:this.props.url,onChange:url=>this.props.onChange({url}),style:{marginBottom:spacing.large_24}}),jsxRuntimeExports.jsx(LabeledTextField,{label:"Description",value:this.props.description,onChange:description=>this.props.onChange({description})})]})}constructor(...args){super(...args),this.getSaveWarnings=()=>{if(makeSafeUrl(this.props.url,"en","https://phet.colorado.edu")===null){return ["Please enter a URL from the PhET domain."]}return []};}}PhetSimulationEditor.defaultProps=phetSimulationLogic.defaultWidgetOptions;PhetSimulationEditor.widgetName="phet-simulation";
|
|
1820
1820
|
|
|
1821
|
-
const{InfoTip: InfoTip$2,NumberInput: NumberInput$2,RangeInput,TextListEditor: TextListEditor$1}=components;const Plotter=PlotterWidget.widget;const STARTING="starting";const CORRECT="correct";const editingStates=[STARTING,CORRECT];function padArray(array,n,value){const copy=_.clone(array);copy.length=n;for(let i=array.length;i<n;i++){copy[i]=value;}return copy}const editorDefaults={scaleY:1,maxY:10,snapsPerLine:2};const formatNumber=num=>"$"+number.round(num,2)+"$";class PlotterEditor extends React.Component{UNSAFE_componentWillMount(){this.fetchPic(this.props.picUrl);}UNSAFE_componentWillReceiveProps(nextProps){this.fetchPic(nextProps.picUrl);if(nextProps.static){this.setState({editing:"starting"});}}render(){const setFromScale=_.contains(["line","histogram","dotplot"],this.props.type);const canChangeSnaps=!_.contains(["pic","dotplot"],this.props.type);const plotterProps={...this.props,trackInteraction:()=>{},starting:this.props[this.state.editing],onChange:this.handlePlotterChange,userInput:this.props.correct,handleUserInput:userInput=>{this.props.onChange({correct:userInput});}};return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-plotter-editor",children:[jsxRuntimeExports.jsxs("div",{children:["Chart type:"," ",plotterPlotTypes.map(type=>{return jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"radio",name:"chart-type",checked:this.props.type===type,onChange:_.partial(this.changeType,type)}),type]},type)},this)]}),jsxRuntimeExports.jsxs("div",{children:["Labels:"," ",["x","y"].map((axis,i)=>{return jsxRuntimeExports.jsxs("label",{children:[axis+":",jsxRuntimeExports.jsx("input",{type:"text",onChange:_.partial(this.changeLabel,i),defaultValue:this.props.labels[i]})]},axis)},this)]}),setFromScale&&jsxRuntimeExports.jsxs("div",{className:"set-from-scale-box",children:[jsxRuntimeExports.jsx("span",{className:"categories-title",children:"Set Categories From Scale"}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Tick Step:"," ",jsxRuntimeExports.jsx(NumberInput$2,{placeholder:1,useArrowKeys:true,value:this.state.tickStep,onChange:this.handleChangeTickStep})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:"The difference between adjacent ticks."})})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Range:"," ",jsxRuntimeExports.jsx(RangeInput,{placeholder:[0,10],useArrowKeys:true,value:[this.state.minX,this.state.maxX],onChange:this.handleChangeRange})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("button",{onClick:this.setCategoriesFromScale,children:["Set Categories"," "]})})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Label Interval:"," ",jsxRuntimeExports.jsx(NumberInput$2,{useArrowKeys:true,value:this.props.labelInterval,onChange:this.changeLabelInterval})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:'Which ticks to display the labels for. For instance, setting this to "4" will only show every 4th label (plus the last one)'})})]}),this.props.type==="pic"&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Picture:"," ",jsxRuntimeExports.jsx(BlurInput,{className:"pic-url",value:this.props.picUrl,onChange:this.changePicUrl}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:'Use the default picture of Earth, or insert the URL for a different picture using the "Add image" function.'})})]}),this.state.pic&&this.state.pic.width!==this.state.pic.height&&jsxRuntimeExports.jsxs("p",{className:"warning",children:[jsxRuntimeExports.jsx("b",{children:"Warning"}),": You are using a picture which is not square. This means the image will get distorted. You should probably crop it to be square."]})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Categories:"," ",jsxRuntimeExports.jsx(TextListEditor$1,{ref:"categories",layout:"horizontal",options:this.props.categories,onChange:this.changeCategories})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Scale (y):"," ",jsxRuntimeExports.jsx("input",{type:"text",onChange:this.changeScale,defaultValue:this.props.scaleY})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Max y:"," ",jsxRuntimeExports.jsx("input",{type:"text",ref:"maxY",onChange:this.changeMax,defaultValue:this.props.maxY})]})}),canChangeSnaps&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Snaps per line:"," ",jsxRuntimeExports.jsx("input",{type:"text",onChange:this.changeSnaps,defaultValue:this.props.snapsPerLine})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:"Creates the specified number of divisions between the horizontal lines. Fewer snaps between lines makes the graph easier for the student to create correctly."})})]}),jsxRuntimeExports.jsxs("div",{children:["Editing values:"," ",editingStates.map(editing=>jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"radio",disabled:editing===CORRECT&&this.props.static,checked:this.props.static?editing===STARTING:this.state.editing===editing,onChange:e=>this.changeEditing(editing)}),editing]},editing)),jsxRuntimeExports.jsxs(InfoTip$2,{children:[jsxRuntimeExports.jsx("p",{children:"Use this toggle to switch between editing the correct answer (what the student will be graded on) and the starting values (what the student will see plotted when they start the problem). Note: These cannot be the same."}),jsxRuntimeExports.jsx("p",{children:"In static mode, the starting values are rendered out to the displayed widget."})]})]}),jsxRuntimeExports.jsx(Plotter,{...plotterProps})]})}constructor(...args){super(...args),this.state={editing:this.props.static?STARTING:CORRECT,pic:null,loadedUrl:null,minX:null,maxX:null,tickStep:null},this.fetchPic=url=>{if(this.state.loadedUrl!==url){const pic=new Image;pic.src=url;pic.onload=()=>{this.setState({pic:pic,loadedUrl:url});};}},this.handleChangeTickStep=value=>{this.setState({tickStep:value});},this.handleChangeRange=newValue=>{this.setState({minX:newValue[0],maxX:newValue[1]});},this.changeLabelInterval=value=>{this.props.onChange({labelInterval:value});},this.handlePlotterChange=newProps=>{const props={};props[this.state.editing]=newProps.values;this.props.onChange(props);},this.changeType=type=>{let categories;if(type==="histogram"){categories=[formatNumber(0)].concat(this.props.categories);this.props.onChange({type:type,categories:categories});}else if(this.props.type==="histogram"){categories=this.props.categories.slice(1);this.props.onChange({type:type,categories:categories});}else {this.props.onChange({type:type});}if(categories){const node=ReactDOM.findDOMNode(this.refs.categories);node.value=categories.join(", ");}},this.changeLabel=(i,e)=>{const labels=_.clone(this.props.labels);labels[i]=e.target.value;this.props.onChange({labels:labels});},this.changePicUrl=value=>{const url=Util.getRealImageUrl(value);this.props.onChange({picUrl:url});},this.changeCategories=categories=>{let n=categories.length;if(this.props.type==="histogram"){n--;}const value=this.props.scaleY;this.props.onChange({categories:categories,correct:padArray(this.props.correct,n,value),starting:padArray(this.props.starting,n,value)});},this.changeScale=e=>{const oldScale=this.props.scaleY;const newScale=+e.target.value||editorDefaults.scaleY;const scale=function(value){return value*newScale/oldScale};const maxY=scale(this.props.maxY);this.props.onChange({scaleY:newScale,maxY:maxY,correct:_.map(this.props.correct,scale),starting:_.map(this.props.starting,scale)});ReactDOM.findDOMNode(this.refs.maxY).value=maxY;},this.changeMax=e=>{this.props.onChange({maxY:+e.target.value||editorDefaults.maxY});},this.changeSnaps=e=>{this.props.onChange({snapsPerLine:+e.target.value||editorDefaults.snapsPerLine});},this.changeEditing=editing=>{this.setState({editing:editing});},this.setCategoriesFromScale=()=>{const scale=this.state.tickStep||1;const min=this.state.minX||0;const max=this.state.maxX||0;const length=Math.floor((max-min)/scale)*scale;let categories;if(this.props.type==="histogram"||this.props.type==="dotplot"){categories=_.range(0,length+scale,scale);}else {categories=_.range(scale,length+scale,scale);}categories=_.map(categories,num=>num+min);categories=_.map(categories,formatNumber);this.changeCategories(categories);const node=ReactDOM.findDOMNode(this.refs.categories);node.value=categories.join(", ");},this.serialize=()=>{const json=_.pick(this.props,"correct","starting","type","labels","categories","scaleY","maxY","snapsPerLine","labelInterval");if(this.props.type==="pic"){json.picUrl=this.props.picUrl;}return json};}}PlotterEditor.widgetName="plotter";PlotterEditor.defaultProps=plotterLogic.defaultWidgetOptions;
|
|
1821
|
+
const{InfoTip: InfoTip$2,NumberInput: NumberInput$2,RangeInput,TextListEditor: TextListEditor$1}=components;const Plotter=PlotterWidget.widget;const STARTING="starting";const CORRECT="correct";const editingStates=[STARTING,CORRECT];function padArray(array,n,value){const copy=_.clone(array);copy.length=n;for(let i=array.length;i<n;i++){copy[i]=value;}return copy}const editorDefaults={scaleY:1,maxY:10,snapsPerLine:2};const formatNumber=num=>"$"+number.round(num,2)+"$";class PlotterEditor extends React.Component{UNSAFE_componentWillMount(){this.fetchPic(this.props.picUrl);}UNSAFE_componentWillReceiveProps(nextProps){this.fetchPic(nextProps.picUrl);if(nextProps.static){this.setState({editing:"starting"});}}render(){const setFromScale=_.contains(["line","histogram","dotplot"],this.props.type);const canChangeSnaps=!_.contains(["pic","dotplot"],this.props.type);const plotterProps={...this.props,trackInteraction:()=>{},starting:this.props[this.state.editing],onChange:this.handlePlotterChange,userInput:this.props.correct,handleUserInput:userInput=>{this.props.onChange({correct:userInput});}};return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-plotter-editor",children:[jsxRuntimeExports.jsxs("div",{children:["Chart type:"," ",plotterPlotTypes.map(type=>{return jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"radio",name:"chart-type",checked:this.props.type===type,onChange:_.partial(this.changeType,type)}),type]},type)},this)]}),jsxRuntimeExports.jsxs("div",{children:["Labels:"," ",["x","y"].map((axis,i)=>{return jsxRuntimeExports.jsxs("label",{children:[axis+":",jsxRuntimeExports.jsx("input",{type:"text",onChange:_.partial(this.changeLabel,i),defaultValue:this.props.labels[i]})]},axis)},this)]}),setFromScale&&jsxRuntimeExports.jsxs("div",{className:"set-from-scale-box",children:[jsxRuntimeExports.jsx("span",{className:"categories-title",children:"Set Categories From Scale"}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Tick Step:"," ",jsxRuntimeExports.jsx(NumberInput$2,{placeholder:1,useArrowKeys:true,value:this.state.tickStep,onChange:this.handleChangeTickStep})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:"The difference between adjacent ticks."})})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Range:"," ",jsxRuntimeExports.jsx(RangeInput,{placeholder:[0,10],useArrowKeys:true,value:[this.state.minX,this.state.maxX],onChange:this.handleChangeRange})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("button",{onClick:this.setCategoriesFromScale,children:["Set Categories"," "]})})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Label Interval:"," ",jsxRuntimeExports.jsx(NumberInput$2,{useArrowKeys:true,value:this.props.labelInterval,onChange:this.changeLabelInterval})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:'Which ticks to display the labels for. For instance, setting this to "4" will only show every 4th label (plus the last one)'})})]}),this.props.type==="pic"&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Picture:"," ",jsxRuntimeExports.jsx(BlurInput,{className:"pic-url",value:this.props.picUrl??"",onChange:this.changePicUrl}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:'Use the default picture of Earth, or insert the URL for a different picture using the "Add image" function.'})})]}),this.state.pic&&this.state.pic.width!==this.state.pic.height&&jsxRuntimeExports.jsxs("p",{className:"warning",children:[jsxRuntimeExports.jsx("b",{children:"Warning"}),": You are using a picture which is not square. This means the image will get distorted. You should probably crop it to be square."]})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Categories:"," ",jsxRuntimeExports.jsx(TextListEditor$1,{ref:"categories",layout:"horizontal",options:this.props.categories,onChange:this.changeCategories})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Scale (y):"," ",jsxRuntimeExports.jsx("input",{type:"text",onChange:this.changeScale,defaultValue:this.props.scaleY})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Max y:"," ",jsxRuntimeExports.jsx("input",{type:"text",ref:"maxY",onChange:this.changeMax,defaultValue:this.props.maxY})]})}),canChangeSnaps&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Snaps per line:"," ",jsxRuntimeExports.jsx("input",{type:"text",onChange:this.changeSnaps,defaultValue:this.props.snapsPerLine})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:"Creates the specified number of divisions between the horizontal lines. Fewer snaps between lines makes the graph easier for the student to create correctly."})})]}),jsxRuntimeExports.jsxs("div",{children:["Editing values:"," ",editingStates.map(editing=>jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"radio",disabled:editing===CORRECT&&this.props.static,checked:this.props.static?editing===STARTING:this.state.editing===editing,onChange:e=>this.changeEditing(editing)}),editing]},editing)),jsxRuntimeExports.jsxs(InfoTip$2,{children:[jsxRuntimeExports.jsx("p",{children:"Use this toggle to switch between editing the correct answer (what the student will be graded on) and the starting values (what the student will see plotted when they start the problem). Note: These cannot be the same."}),jsxRuntimeExports.jsx("p",{children:"In static mode, the starting values are rendered out to the displayed widget."})]})]}),jsxRuntimeExports.jsx(Plotter,{...plotterProps})]})}constructor(...args){super(...args),this.state={editing:this.props.static?STARTING:CORRECT,pic:null,loadedUrl:null,minX:null,maxX:null,tickStep:null},this.fetchPic=url=>{if(url==null){if(this.state.pic!==null){this.setState({pic:null,loadedUrl:null});}return}if(this.state.loadedUrl!==url){const pic=new Image;pic.src=url;pic.onload=()=>{this.setState({pic:pic,loadedUrl:url});};}},this.handleChangeTickStep=value=>{this.setState({tickStep:value});},this.handleChangeRange=newValue=>{this.setState({minX:newValue[0],maxX:newValue[1]});},this.changeLabelInterval=value=>{this.props.onChange({labelInterval:value});},this.handlePlotterChange=newProps=>{const props={};props[this.state.editing]=newProps.values;this.props.onChange(props);},this.changeType=type=>{let categories;if(type==="histogram"){categories=[formatNumber(0)].concat(this.props.categories);this.props.onChange({type:type,categories:categories});}else if(this.props.type==="histogram"){categories=this.props.categories.slice(1);this.props.onChange({type:type,categories:categories});}else {this.props.onChange({type:type});}if(categories){const node=ReactDOM.findDOMNode(this.refs.categories);node.value=categories.join(", ");}},this.changeLabel=(i,e)=>{const labels=_.clone(this.props.labels);labels[i]=e.target.value;this.props.onChange({labels:labels});},this.changePicUrl=value=>{const url=Util.getRealImageUrl(value);this.props.onChange({picUrl:url});},this.changeCategories=categories=>{let n=categories.length;if(this.props.type==="histogram"){n--;}const value=this.props.scaleY;this.props.onChange({categories:categories,correct:padArray(this.props.correct,n,value),starting:padArray(this.props.starting,n,value)});},this.changeScale=e=>{const oldScale=this.props.scaleY;const newScale=+e.target.value||editorDefaults.scaleY;const scale=function(value){return value*newScale/oldScale};const maxY=scale(this.props.maxY);this.props.onChange({scaleY:newScale,maxY:maxY,correct:_.map(this.props.correct,scale),starting:_.map(this.props.starting,scale)});ReactDOM.findDOMNode(this.refs.maxY).value=maxY;},this.changeMax=e=>{this.props.onChange({maxY:+e.target.value||editorDefaults.maxY});},this.changeSnaps=e=>{this.props.onChange({snapsPerLine:+e.target.value||editorDefaults.snapsPerLine});},this.changeEditing=editing=>{this.setState({editing:editing});},this.setCategoriesFromScale=()=>{const scale=this.state.tickStep||1;const min=this.state.minX||0;const max=this.state.maxX||0;const length=Math.floor((max-min)/scale)*scale;let categories;if(this.props.type==="histogram"||this.props.type==="dotplot"){categories=_.range(0,length+scale,scale);}else {categories=_.range(scale,length+scale,scale);}categories=_.map(categories,num=>num+min);categories=_.map(categories,formatNumber);this.changeCategories(categories);const node=ReactDOM.findDOMNode(this.refs.categories);node.value=categories.join(", ");},this.serialize=()=>{const json=_.pick(this.props,"correct","starting","type","labels","categories","scaleY","maxY","snapsPerLine","labelInterval");if(this.props.type==="pic"){json.picUrl=this.props.picUrl;}return json};}}PlotterEditor.widgetName="plotter";PlotterEditor.defaultProps=plotterLogic.defaultWidgetOptions;
|
|
1822
1822
|
|
|
1823
1823
|
const{NumberInput: NumberInput$1,TextInput}=components;function validateOptions(height,programID){const errors=[];if(programID===""){errors.push("The program ID is required.");}if(!Number.isInteger(height)||height<1){errors.push("The height must be a positive integer.");}return errors}class PythonProgramEditor extends React.Component{serialize(){return {programID:this.props.programID,height:this.props.height}}render(){return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["User Program ID:"," ",jsxRuntimeExports.jsx(TextInput,{value:this.props.programID,onChange:this.change("programID"),placeholder:"123"})]}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsxs("label",{children:["Height:"," ",jsxRuntimeExports.jsx(NumberInput$1,{value:this.props.height,onChange:this.change("height"),placeholder:"400"})]})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.getSaveWarnings=()=>{return validateOptions(this.props.height,this.props.programID)};}}PythonProgramEditor.widgetName="python-program";PythonProgramEditor.defaultProps=pythonProgramLogic.defaultWidgetOptions;
|
|
1824
1824
|
|