@khanacademy/perseus-editor 28.14.4 → 28.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,30 +1,29 @@
1
1
  import * as React from "react";
2
- type Props = {
2
+ import type { Result } from "@khanacademy/perseus-core";
3
+ type Props<TData> = {
3
4
  multiLine: boolean;
4
- value: any;
5
- onChange: (newJson: any) => void;
5
+ value: TData;
6
+ onChange: (newJson: TData) => void;
7
+ parser: (json: string) => Result<TData, unknown>;
6
8
  editingDisabled: boolean;
7
9
  };
8
- type DefaultProps = {
9
- value: Props["value"];
10
- };
11
10
  type State = {
12
11
  currentValue: string | undefined;
13
12
  valid: boolean | undefined;
14
13
  };
15
- declare class JsonEditor extends React.Component<Props, State> {
14
+ declare class JsonEditor<TData> extends React.Component<Props<TData>, State> {
16
15
  static displayName: "JsonEditor";
17
- static defaultProps: DefaultProps;
18
16
  constructor(props: any);
19
17
  getInitialState(): {
20
18
  currentValue: string;
21
19
  valid: boolean;
22
20
  };
23
- componentDidUpdate(prevProps: Props): void;
24
- getCurrentValueAsJson(): any;
21
+ componentDidUpdate(prevProps: Props<TData>): void;
22
+ getCurrentValueAsJson(): TData | {} | null;
25
23
  handleKeyDown(e: any): void;
26
24
  handleChange(e: any): void;
27
25
  handleBlur(e: any): void;
26
+ private typesafeParseOrThrow;
28
27
  render(): React.JSX.Element;
29
28
  }
30
29
  export default JsonEditor;
package/dist/es/index.js CHANGED
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import React__default, { useState, useId, createElement, useRef, useEffect } from 'react';
4
4
  import { PerseusMarkdown, Util, components, Widgets, excludeDenylistKeys, ApiOptions, Log, preprocessTex, Dependencies, iconTrash, ClassNames, usePerseusI18n, UserInputManager, Renderer, Categorizer as Categorizer$1, Changeable, EditorJsonify, Expression, interactiveSizes, GrapherWidget, GrapherUtil, containerSizeClass, getInteractiveBoxFromSizeClass, iconChevronDown, KhanColors, mathOnlyParser, getAngleCoords, getPolygonCoords, getPointCoords, getQuadraticCoords, getSinusoidCoords, getCircleCoords, getLinearSystemCoords, getSegmentCoords, getLineCoords, InteractiveGraphWidget, bodyXsmallBold, MatrixWidget, PlotterWidget, TableWidget, widgets } from '@khanacademy/perseus';
5
5
  export { widgets } from '@khanacademy/perseus';
6
- import { generateImageWidget, generateImageOptions, isFeatureOn, CoreWidgetRegistry, applyDefaultsToWidget, PerseusError, Errors, ItemExtras, categorizerLogic, csProgramLogic, definitionLogic, dropdownLogic, explanationLogic, expressionLogic, deriveExtraKeys, PerseusExpressionAnswerFormConsidered, freeResponseLogic, gradedGroupLogic, gradedGroupSetLogic, grapherLogic, GrapherUtil as GrapherUtil$1, groupLogic, iframeLogic, imageLogic, inputNumberLogic, interactionLogic, lockedFigureColors, lockedFigureFillStyles, getDefaultFigureForType, interactiveGraphLogic, labelImageLogic, matcherLogic, matrixLogic, getMatrixSize, measurerLogic, numberLineLogic, numericInputLogic, ordererLogic, phetSimulationLogic, makeSafeUrl, plotterLogic, plotterPlotTypes, pythonProgramLogic, radioLogic, deriveNumCorrect, sorterLogic, tableLogic, videoLogic } from '@khanacademy/perseus-core';
6
+ import { generateImageWidget, generateImageOptions, isSuccess, CoreWidgetRegistry, applyDefaultsToWidget, PerseusError, Errors, parseAndMigratePerseusArticle, ItemExtras, parseAndMigratePerseusItem, categorizerLogic, csProgramLogic, definitionLogic, dropdownLogic, explanationLogic, expressionLogic, deriveExtraKeys, PerseusExpressionAnswerFormConsidered, freeResponseLogic, gradedGroupLogic, gradedGroupSetLogic, grapherLogic, GrapherUtil as GrapherUtil$1, groupLogic, iframeLogic, isFeatureOn, imageLogic, inputNumberLogic, interactionLogic, lockedFigureColors, lockedFigureFillStyles, getDefaultFigureForType, interactiveGraphLogic, labelImageLogic, matcherLogic, matrixLogic, getMatrixSize, measurerLogic, numberLineLogic, numericInputLogic, ordererLogic, phetSimulationLogic, makeSafeUrl, plotterLogic, plotterPlotTypes, pythonProgramLogic, radioLogic, deriveNumCorrect, sorterLogic, tableLogic, videoLogic } from '@khanacademy/perseus-core';
7
7
  import * as PerseusLinter from '@khanacademy/perseus-linter';
8
8
  import Button from '@khanacademy/wonder-blocks-button';
9
9
  import arrowCircleDownIcon from '@phosphor-icons/core/bold/arrow-circle-down-bold.svg';
@@ -39,12 +39,12 @@ import { LabeledField } from '@khanacademy/wonder-blocks-labeled-field';
39
39
  import plusCircle from '@phosphor-icons/core/regular/plus-circle.svg';
40
40
  import trashIcon$1 from '@phosphor-icons/core/regular/trash.svg';
41
41
  import { KhanMath, angles, vector, number } from '@khanacademy/kmath';
42
+ import Banner from '@khanacademy/wonder-blocks-banner';
42
43
  import arrowCounterClockwise from '@phosphor-icons/core/bold/arrow-counter-clockwise-bold.svg';
43
44
  import { inputNumberAnswerTypes } from '@khanacademy/perseus-score';
44
45
  import invariant from 'tiny-invariant';
45
46
  import { SingleSelect, OptionItem, ActionMenu, ActionItem } from '@khanacademy/wonder-blocks-dropdown';
46
47
  import Clickable from '@khanacademy/wonder-blocks-clickable';
47
- import Banner from '@khanacademy/wonder-blocks-banner';
48
48
  import Pill from '@khanacademy/wonder-blocks-pill';
49
49
  import pencilCircle from '@phosphor-icons/core/regular/pencil-circle.svg';
50
50
  import caretDoubleDownIcon from '@phosphor-icons/core/bold/caret-double-down-bold.svg';
@@ -65,7 +65,7 @@ import xIcon from '@phosphor-icons/core/regular/x.svg';
65
65
  import checkIcon from '@phosphor-icons/core/bold/check-bold.svg';
66
66
  import minusCircleIcon from '@phosphor-icons/core/bold/minus-circle-bold.svg';
67
67
 
68
- const libName="@khanacademy/perseus-editor";const libVersion="28.14.4";addLibraryVersionToPerseusDebug(libName,libVersion);
68
+ const libName="@khanacademy/perseus-editor";const libVersion="28.16.0";addLibraryVersionToPerseusDebug(libName,libVersion);
69
69
 
70
70
  var jsxRuntime = {exports: {}};
71
71
 
@@ -1433,7 +1433,7 @@ function ToggleableCaret(props){const iconStyle=props.isExpanded?styles$R.expand
1433
1433
 
1434
1434
  const IssuesPanel=props=>{const{issues=[]}=props;const a11yCheck=props.a11yCheck||{callback:()=>{},isChecked:false};const[showPanel,setShowPanel]=useState(false);const hasWarnings=issues.length>0;const hasErrors=issues.some(issue=>issue.impact==="high");const issuesCount=`${issues.length} issue${issues.length===1?"":"s"}`;const icon=hasErrors?iconAlert:hasWarnings?iconWarning:iconPass;const iconColor=hasErrors?semanticColor.feedback.critical.strong.icon:hasWarnings?semanticColor.feedback.warning.strong.icon:semanticColor.feedback.success.strong.icon;const impactOrder={high:3,medium:2,low:1};const sortedIssues=issues.sort((a,b)=>{if(impactOrder[b.impact]!==impactOrder[a.impact]){return impactOrder[b.impact]-impactOrder[a.impact]}return a.id.localeCompare(b.id)});return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-editor",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-editor-title",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-editor-title-id",children:jsxRuntimeExports.jsxs(View,{style:{display:"flex",flexDirection:"row",alignItems:"center",gap:"0.25em"},onClick:()=>setShowPanel(!showPanel),children:[jsxRuntimeExports.jsx(ToggleableCaret,{isExpanded:showPanel}),jsxRuntimeExports.jsx("span",{children:"Issues"})]})}),jsxRuntimeExports.jsx(PhosphorIcon,{icon:icon,size:"medium",color:iconColor,testId:`issues-icon-${icon}`,style:{marginRight:"0.25em"}}),issuesCount]}),showPanel&&jsxRuntimeExports.jsx("div",{className:"perseus-widget-editor-panel",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-editor-content",children:[sortedIssues.map(issue=>jsxRuntimeExports.jsx(IssueDetails,{issue:issue},issue.id)),issues.length===0&&jsxRuntimeExports.jsx("div",{children:"No issues found"}),jsxRuntimeExports.jsx(LabeledSwitch$1,{label:"Include axe-core scan",checked:a11yCheck.isChecked,onChange:()=>{a11yCheck.callback();},style:{marginBlockStart:"1rem"}})]})})]})};
1435
1435
 
1436
- class JsonEditor extends React.Component{getInitialState(){return {currentValue:JSON.stringify(this.props.value,null,4),valid:true}}componentDidUpdate(prevProps){if(!_.isEqual(prevProps.value,this.props.value)){const shouldReplaceContent=!this.state.valid||!_.isEqual(this.props.value,this.getCurrentValueAsJson());if(shouldReplaceContent){this.setState({currentValue:JSON.stringify(this.props.value,null,4),valid:true});}}}getCurrentValueAsJson(){try{return this.state.currentValue?JSON.parse(this.state.currentValue):{}}catch{return null}}handleKeyDown(e){if(e.key==="Tab"){const cursorPos=e.target.selectionStart;const v=e.target.value;const textBefore=v.substring(0,cursorPos);const textAfter=v.substring(cursorPos,v.length);e.target.value=textBefore+" "+textAfter;e.target.selectionStart=textBefore.length+4;e.target.selectionEnd=textBefore.length+4;e.preventDefault();this.handleChange(e);}}handleChange(e){const nextString=e.target.value;try{let json=JSON.parse(nextString);if(_.isString(json)){json=JSON.parse(json);}this.setState({currentValue:nextString,valid:true},function(){this.props.onChange(json);});}catch{this.setState({currentValue:nextString,valid:false});}}handleBlur(e){const nextString=e.target.value;try{let json=JSON.parse(nextString);if(_.isString(json)){json=JSON.parse(json);}this.setState({currentValue:JSON.stringify(json,null,4),valid:true},function(){this.props.onChange(json);});}catch{this.setState({currentValue:JSON.stringify(this.props.value,null,4),valid:true});}}render(){const classes="perseus-json-editor "+(this.state.valid?"valid":"invalid");return jsxRuntimeExports.jsx("textarea",{className:classes,value:this.state.currentValue,onChange:this.handleChange,onKeyDown:this.handleKeyDown,onBlur:this.handleBlur,disabled:this.props.editingDisabled})}constructor(props){super(props);this.state=this.getInitialState();this.handleBlur=this.handleBlur.bind(this);this.handleChange=this.handleChange.bind(this);this.handleKeyDown=this.handleKeyDown.bind(this);}}JsonEditor.defaultProps={value:{}};
1436
+ class JsonEditor extends React.Component{getInitialState(){return {currentValue:JSON.stringify(this.props.value,null,4),valid:true}}componentDidUpdate(prevProps){if(!_.isEqual(prevProps.value,this.props.value)){const shouldReplaceContent=!this.state.valid||!_.isEqual(this.props.value,this.getCurrentValueAsJson());if(shouldReplaceContent){this.setState({currentValue:JSON.stringify(this.props.value,null,4),valid:true});}}}getCurrentValueAsJson(){try{return this.state.currentValue?this.typesafeParseOrThrow(this.state.currentValue):{}}catch{return null}}handleKeyDown(e){if(e.key==="Tab"){const cursorPos=e.target.selectionStart;const v=e.target.value;const textBefore=v.substring(0,cursorPos);const textAfter=v.substring(cursorPos,v.length);e.target.value=textBefore+" "+textAfter;e.target.selectionStart=textBefore.length+4;e.target.selectionEnd=textBefore.length+4;e.preventDefault();this.handleChange(e);}}handleChange(e){const nextString=e.target.value;try{const json=this.typesafeParseOrThrow(nextString);this.setState({currentValue:nextString,valid:true},function(){this.props.onChange(json);});}catch{this.setState({currentValue:nextString,valid:false});}}handleBlur(e){const nextString=e.target.value;try{const json=this.typesafeParseOrThrow(nextString);this.setState({currentValue:JSON.stringify(json,null,4),valid:true},function(){this.props.onChange(json);});}catch{this.setState({currentValue:JSON.stringify(this.props.value,null,4),valid:true});}}typesafeParseOrThrow(json){const parsed=this.props.parser(json);if(isSuccess(parsed)){return parsed.value}const parsedFromQuotedString=this.props.parser(JSON.parse(json));if(isSuccess(parsedFromQuotedString)){return parsedFromQuotedString.value}throw new TypeError("JsonEditor: parse failure")}render(){const classes="perseus-json-editor "+(this.state.valid?"valid":"invalid");return jsxRuntimeExports.jsx("textarea",{className:classes,value:this.state.currentValue,onChange:this.handleChange,onKeyDown:this.handleKeyDown,onBlur:this.handleBlur,disabled:this.props.editingDisabled})}constructor(props){super(props);this.state=this.getInitialState();this.handleBlur=this.handleBlur.bind(this);this.handleChange=this.handleChange.bind(this);this.handleKeyDown=this.handleKeyDown.bind(this);}}
1437
1437
 
1438
1438
  const SectionControlButton=({icon,onClick,title,disabled})=>{return jsxRuntimeExports.jsx(IconButton,{icon:icon,disabled:disabled,"aria-label":title,style:styles$Q.button,size:"xsmall",onClick:onClick})};const styles$Q=StyleSheet.create({button:{marginLeft:5}});
1439
1439
 
@@ -1443,7 +1443,7 @@ function focusWithChromeStickyFocusBugWorkaround(element){element.focus({prevent
1443
1443
 
1444
1444
  const{InfoTip: InfoTip$o}=components;function AlignmentSelect({supportedAlignments,widgetInfo,isEditingDisabled,onChange}){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(InfoTip$o,{children:jsxRuntimeExports.jsx("ul",{children:supportedAlignments.map((alignment,index)=>jsxRuntimeExports.jsx("li",{style:{marginBlockEnd:index<supportedAlignments.length-1?sizing.size_240:0},children:alignmentInfoMap[alignment]},alignment))})}),jsxRuntimeExports.jsx("select",{className:"alignment",value:widgetInfo.alignment,disabled:isEditingDisabled,onChange:onChange,style:{marginLeft:sizing.size_060},children:supportedAlignments.map(alignment=>jsxRuntimeExports.jsx("option",{children:alignment},alignment))})]})}
1445
1445
 
1446
- const _upgradeWidgetInfo=props=>{const filteredProps=excludeDenylistKeys(props);return applyDefaultsToWidget(filteredProps)};class WidgetEditor extends React.Component{UNSAFE_componentWillReceiveProps(nextProps){this.setState({widgetInfo:_upgradeWidgetInfo(nextProps)});if(nextProps.widgetIsOpen!=null&&nextProps.widgetIsOpen!==this.props.widgetIsOpen){this.setState({showWidget:nextProps.widgetIsOpen});}}render(){const widgetInfo=this.state.widgetInfo;const isEditingDisabled=this.props.apiOptions.editingDisabled??false;const Ed=Widgets.getEditor(widgetInfo.type);let supportedAlignments;const imageUpgradeAlignmentFF=isFeatureOn(this.props,"image-widget-upgrade-alignment");if(this.props.apiOptions.showAlignmentOptions){if(widgetInfo.type==="image"&&!imageUpgradeAlignmentFF){supportedAlignments=["block","full-width"];}else {supportedAlignments=CoreWidgetRegistry.getSupportedAlignments(widgetInfo.type);}}else {supportedAlignments=["default"];}const supportsStaticMode=Widgets.supportsStaticMode(widgetInfo.type);return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-editor",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-editor-title "+(this.state.showWidget?"open":"closed"),children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-editor-title-id",children:jsxRuntimeExports.jsxs(View,{style:{display:"flex",flexDirection:"row",alignItems:"center",gap:"0.25em"},onClick:this._toggleWidget,children:[jsxRuntimeExports.jsx(ToggleableCaret,{isExpanded:this.state.showWidget}),jsxRuntimeExports.jsx("span",{children:this.props.id})]})}),supportsStaticMode&&jsxRuntimeExports.jsx(LabeledSwitch,{label:"Static",checked:!!widgetInfo.static,disabled:isEditingDisabled,onChange:this._setStatic}),supportedAlignments.length>1&&jsxRuntimeExports.jsx(AlignmentSelect,{supportedAlignments:supportedAlignments,widgetInfo:widgetInfo,isEditingDisabled:isEditingDisabled,onChange:this._handleAlignmentChange}),jsxRuntimeExports.jsx(SectionControlButton,{icon:trashIcon,disabled:isEditingDisabled,onClick:()=>{this.props.onRemove();},title:"Remove image widget"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-editor-content "+(this.state.showWidget?"enter":"leave"),children:Ed&&jsxRuntimeExports.jsx(Ed,{ref:this.widget,onChange:this._handleWidgetChange,static:widgetInfo.static,apiOptions:this.props.apiOptions,...widgetInfo.options})})]})}constructor(props){super(props),this._toggleWidget=e=>{e.preventDefault();this.setState({showWidget:!this.state.showWidget});},this._handleWidgetChange=(newProps,cb,silent)=>{const newWidgetInfo={...this.state.widgetInfo,options:{...this.state.widgetInfo.options,...this.widget.current?.serialize()??{},...newProps}};this.props.onChange(newWidgetInfo,cb,silent);},this._setStatic=value=>{const newWidgetInfo={...this.state.widgetInfo,static:value};this.props.onChange(newWidgetInfo);},this._handleAlignmentChange=e=>{const newAlignment=e.currentTarget.value;const newWidgetInfo=Object.assign({},this.state.widgetInfo);newWidgetInfo.alignment=newAlignment;this.props.onChange(newWidgetInfo);},this.getSaveWarnings=()=>{const issuesFunc=this.widget.current?.getSaveWarnings;return issuesFunc?issuesFunc():[]},this.serialize=()=>{const widgetInfo=this.state.widgetInfo;return {type:widgetInfo.type,alignment:widgetInfo.alignment,static:widgetInfo.static,graded:widgetInfo.graded,options:this.widget.current.serialize(),version:widgetInfo.version}};this.state={showWidget:props.widgetIsOpen??true,widgetInfo:_upgradeWidgetInfo(props)};this.widget=React.createRef();}}function LabeledSwitch(props){const{label,disabled,...switchProps}=props;const id=useId();return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("label",{htmlFor:id,children:label}),jsxRuntimeExports.jsx(Strut,{size:spacing.xxSmall_6}),jsxRuntimeExports.jsx(Switch,{id:id,...switchProps,disabled:disabled})]})}
1446
+ const _upgradeWidgetInfo=props=>{const filteredProps=excludeDenylistKeys(props);return applyDefaultsToWidget(filteredProps)};class WidgetEditor extends React.Component{UNSAFE_componentWillReceiveProps(nextProps){this.setState({widgetInfo:_upgradeWidgetInfo(nextProps)});if(nextProps.widgetIsOpen!=null&&nextProps.widgetIsOpen!==this.props.widgetIsOpen){this.setState({showWidget:nextProps.widgetIsOpen});}}render(){const widgetInfo=this.state.widgetInfo;const isEditingDisabled=this.props.apiOptions.editingDisabled??false;const Ed=Widgets.getEditor(widgetInfo.type);let supportedAlignments;if(this.props.apiOptions.showAlignmentOptions){supportedAlignments=CoreWidgetRegistry.getSupportedAlignments(widgetInfo.type);}else {supportedAlignments=["default"];}const supportsStaticMode=Widgets.supportsStaticMode(widgetInfo.type);return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-editor",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-editor-title "+(this.state.showWidget?"open":"closed"),children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-editor-title-id",children:jsxRuntimeExports.jsxs(View,{style:{display:"flex",flexDirection:"row",alignItems:"center",gap:"0.25em"},onClick:this._toggleWidget,children:[jsxRuntimeExports.jsx(ToggleableCaret,{isExpanded:this.state.showWidget}),jsxRuntimeExports.jsx("span",{children:this.props.id})]})}),supportsStaticMode&&jsxRuntimeExports.jsx(LabeledSwitch,{label:"Static",checked:!!widgetInfo.static,disabled:isEditingDisabled,onChange:this._setStatic}),supportedAlignments.length>1&&jsxRuntimeExports.jsx(AlignmentSelect,{supportedAlignments:supportedAlignments,widgetInfo:widgetInfo,isEditingDisabled:isEditingDisabled,onChange:this._handleAlignmentChange}),jsxRuntimeExports.jsx(SectionControlButton,{icon:trashIcon,disabled:isEditingDisabled,onClick:()=>{this.props.onRemove();},title:"Remove image widget"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-editor-content "+(this.state.showWidget?"enter":"leave"),children:Ed&&jsxRuntimeExports.jsx(Ed,{ref:this.widget,onChange:this._handleWidgetChange,static:widgetInfo.static,apiOptions:this.props.apiOptions,...widgetInfo.options})})]})}constructor(props){super(props),this._toggleWidget=e=>{e.preventDefault();this.setState({showWidget:!this.state.showWidget});},this._handleWidgetChange=(newProps,cb,silent)=>{const newWidgetInfo={...this.state.widgetInfo,options:{...this.state.widgetInfo.options,...this.widget.current?.serialize()??{},...newProps}};this.props.onChange(newWidgetInfo,cb,silent);},this._setStatic=value=>{const newWidgetInfo={...this.state.widgetInfo,static:value};this.props.onChange(newWidgetInfo);},this._handleAlignmentChange=e=>{const newAlignment=e.currentTarget.value;const newWidgetInfo=Object.assign({},this.state.widgetInfo);newWidgetInfo.alignment=newAlignment;this.props.onChange(newWidgetInfo);},this.getSaveWarnings=()=>{const issuesFunc=this.widget.current?.getSaveWarnings;return issuesFunc?issuesFunc():[]},this.serialize=()=>{const widgetInfo=this.state.widgetInfo;return {type:widgetInfo.type,alignment:widgetInfo.alignment,static:widgetInfo.static,graded:widgetInfo.graded,options:this.widget.current.serialize(),version:widgetInfo.version}};this.state={showWidget:props.widgetIsOpen??true,widgetInfo:_upgradeWidgetInfo(props)};this.widget=React.createRef();}}function LabeledSwitch(props){const{label,disabled,...switchProps}=props;const id=useId();return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("label",{htmlFor:id,children:label}),jsxRuntimeExports.jsx(Strut,{size:spacing.xxSmall_6}),jsxRuntimeExports.jsx(Switch,{id:id,...switchProps,disabled:disabled})]})}
1447
1447
 
1448
1448
  class WidgetSelect extends React.Component{shouldComponentUpdate(){return false}render(){const widgets=Widgets.getPublicWidgets();const orderedWidgetNames=_.sortBy(_.keys(widgets),name=>{return widgets[name].displayName});const addWidgetString="Add a widget…";return jsxRuntimeExports.jsxs("select",{value:"",onChange:this.handleChange,"data-testid":"editor__widget-select",children:[jsxRuntimeExports.jsx("option",{value:"",children:addWidgetString}),jsxRuntimeExports.jsx("option",{disabled:true,children:"--"}),orderedWidgetNames.map(name=>{return jsxRuntimeExports.jsx("option",{value:name,children:widgets[name].displayName},name)})]})}constructor(...args){super(...args),this.handleChange=e=>{const widgetType=e.currentTarget.value;if(widgetType===""){return}if(this.props.onChange){this.props.onChange(widgetType);}};}}
1449
1449
 
@@ -1461,7 +1461,7 @@ katex.__defineMacro("\\ce",function(context){return chemParse(context.consumeArg
1461
1461
 
1462
1462
  function detectTexErrors(content){const errors=[];const ast=PerseusMarkdown.parse(content,{});PerseusMarkdown.traverseContent(ast,node=>{if(node.type==="math"||node.type==="blockMath"){const texContent=preprocessTex(node.content);try{katex.renderToString(texContent,{colorIsTextColor:true});}catch(e){errors.push({math:texContent,message:e.message});}}});return errors}
1463
1463
 
1464
- const{HUD: HUD$1}=components;class ArticleEditor extends React.Component{componentDidMount(){this._updateIssues();this._updatePreviewFrames();}componentDidUpdate(prevProps){if(prevProps.json!==this.props.json||prevProps.issues!==this.props.issues){this._updateIssues();}this._updatePreviewFrames();}_updateIssues(){const sections=this.props.json instanceof Array?this.props.json:[this.props.json];const allLinterIssues=[];sections.forEach(section=>{const parsed=PerseusMarkdown.parse(section.content??"",{});const linterContext={content:section.content,widgets:section.widgets,stack:[]};const sectionIssues=PerseusLinter.runLinter(parsed,linterContext,false)?.map(linterWarning=>{if(linterWarning.rule==="inaccessible-widget"){return WARNINGS.inaccessibleWidget(linterWarning.metadata?.widgetType??"unknown",linterWarning.metadata?.widgetId??"unknown")}return WARNINGS.genericLinterWarning(linterWarning.rule,linterWarning.message,linterWarning.severity)})??[];allLinterIssues.push(...sectionIssues);const texErrors=detectTexErrors(section.content??"");const texIssues=texErrors.map((error,index)=>WARNINGS.texError(error.math,error.message,index));allLinterIssues.push(...texIssues);});this.setState({issues:[...this.props.issues??[],...allLinterIssues]});}_updatePreviewFrames(){if(this.props.mode==="preview"){this.refs["frame-all"].sendNewData({type:"article-all",data:this._sections().map((section,i)=>{return this._apiOptionsForSection(section,i)})});}else if(this.props.mode==="edit"){this._sections().forEach((section,i)=>{this.refs["frame-"+i].sendNewData({type:"article",data:this._apiOptionsForSection(section,i)});});}}_apiOptionsForSection(section,sectionIndex){const editor=this.refs[`editor${sectionIndex}`];return {apiOptions:{...ApiOptions.defaults,...this.props.apiOptions,showAlignmentOptions:true,isArticle:true},json:section,useNewStyles:this.props.useNewStyles,linterContext:{contentType:"article",highlightLint:this.state.highlightLint,paths:this.props.contentPaths},legacyPerseusLint:editor?editor.getSaveWarnings():[]}}_sections(){const json=this.props.json;return json instanceof Array?json:[json]}_renderEditor(){const{imageUploader,sectionImageUploadGenerator}=this.props;const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,showAlignmentOptions:true,isArticle:true};const sections=this._sections();const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs("div",{className:"perseus-editor-table",children:[sections.map((section,i)=>{return [jsxRuntimeExports.jsx("div",{className:"perseus-editor-row",children:jsxRuntimeExports.jsxs("fieldset",{disabled:editingDisabled,children:[jsxRuntimeExports.jsxs("div",{className:"perseus-editor-left-cell",children:[jsxRuntimeExports.jsx(IssuesPanel,{issues:this.state.issues}),jsxRuntimeExports.jsxs("div",{className:"pod-title",children:["Section ",i+1,jsxRuntimeExports.jsxs("div",{style:{display:"inline-block",float:"right"},children:[sectionImageUploadGenerator(i),jsxRuntimeExports.jsx(SectionControlButton,{icon:plusIcon,disabled:editingDisabled,onClick:()=>{this._handleAddSectionAfter(i);},title:"Add a new section after this one"}),i+1<sections.length&&jsxRuntimeExports.jsx(SectionControlButton,{icon:arrowCircleDownIcon,disabled:editingDisabled,onClick:()=>{this._handleMoveSectionLater(i);},title:"Move this section down"}),i>0&&jsxRuntimeExports.jsx(SectionControlButton,{icon:arrowCircleUpIcon,disabled:editingDisabled,onClick:()=>{this._handleMoveSectionEarlier(i);},title:"Move this section up"}),jsxRuntimeExports.jsx(SectionControlButton,{icon:trashIcon,disabled:editingDisabled,onClick:()=>{const msg="Are you sure you "+"want to delete section "+(i+1)+"?";if(confirm(msg)){this._handleRemoveSection(i);}},title:"Delete this section"})]})]}),jsxRuntimeExports.jsx(Editor,{...section,apiOptions:apiOptions,imageUploader:imageUploader,onChange:newProps=>this._handleEditorChange(i,newProps),placeholder:"Type your section text here...",ref:"editor"+i})]}),jsxRuntimeExports.jsx("div",{className:"editor-preview",children:this._renderIframePreview(i,true)})]})},i)]}),this._renderAddSection(editingDisabled),this._renderLinterHUD()]})}_renderAddSection(editingDisabled){return jsxRuntimeExports.jsx("div",{className:"perseus-editor-row",children:jsxRuntimeExports.jsx("div",{className:"perseus-editor-left-cell",children:jsxRuntimeExports.jsx(Button,{startIcon:plusIcon,disabled:editingDisabled,kind:"tertiary","aria-label":"Add a section",onClick:()=>{this._handleAddSectionAfter(this._sections().length-1);},children:"Add a section"})})})}_renderLinterHUD(){return jsxRuntimeExports.jsx(HUD$1,{message:"Style warnings",enabled:this.state.highlightLint,onClick:()=>{this.setState({highlightLint:!this.state.highlightLint});}})}_renderIframePreview(i,nochrome){const isMobile=this.props.screen==="phone"||this.props.screen==="tablet";return jsxRuntimeExports.jsx(DeviceFramer,{deviceType:this.props.screen,nochrome:nochrome,children:jsxRuntimeExports.jsx(IframeContentRenderer,{ref:"frame-"+i,datasetKey:"mobile",datasetValue:isMobile,seamless:nochrome,url:this.props.previewURL},this.props.screen)})}_renderPreviewMode(){return jsxRuntimeExports.jsx("div",{className:"standalone-preview",children:this._renderIframePreview("all",false)})}_handleMoveSectionEarlier(i){if(i===0){return}const sections=[...this._sections()];const section=sections[i];sections.splice(i,1);sections.splice(i-1,0,section);this.props.onChange({json:sections});}_handleMoveSectionLater(i){const sections=[...this._sections()];if(i+1===sections.length){return}const section=sections[i];sections.splice(i,1);sections.splice(i+1,0,section);this.props.onChange({json:sections});}_handleAddSectionAfter(i){const sections=_.clone(this.serialize());const newSection=i>=0?{widgets:sections[i].widgets}:{};sections.splice(i+1,0,newSection);this.props.onChange({json:sections});}_handleRemoveSection(i){const sections=[...this._sections()];sections.splice(i,1);this.props.onChange({json:sections});}serialize(){if(this.props.mode==="edit"){return this._sections().map((section,i)=>{return this.refs["editor"+i].serialize()})}if(this.props.mode==="preview"||this.props.mode==="json"){return this.props.json}throw new PerseusError("Could not serialize; mode "+this.props.mode+" not found",Errors.Internal)}getSaveWarnings(){if(this.props.mode!=="edit"){throw new PerseusError("Can only get save warnings in edit mode.",Errors.NotAllowed)}return this._sections().map((section,i)=>{return this.refs["editor"+i].getSaveWarnings()})}render(){const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsx(Dependencies.DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{className:"framework-perseus perseus-article-editor",children:[this.props.mode==="edit"&&this._renderEditor(),this.props.mode==="preview"&&this._renderPreviewMode(),this.props.mode==="json"&&jsxRuntimeExports.jsxs("div",{className:"json-editor",children:[jsxRuntimeExports.jsx("div",{className:"json-editor-warning",children:jsxRuntimeExports.jsx("span",{children:"Warning: Editing in this mode can lead to broken articles!"})}),jsxRuntimeExports.jsx(JsonEditor,{multiLine:true,onChange:this._handleJsonChange,value:this.props.json,editingDisabled:editingDisabled})]})]})})}constructor(...args){super(...args),this.state={highlightLint:true,issues:[]},this._handleJsonChange=newJson=>{this.props.onChange({json:newJson});},this._handleEditorChange=(i,newProps)=>{const sections=[...this._sections()];sections[i]={...sections[i],...newProps};this.props.onChange({json:sections});};}}ArticleEditor.defaultProps={contentPaths:[],json:[{}],mode:"edit",screen:"desktop",sectionImageUploadGenerator:()=>jsxRuntimeExports.jsx("span",{}),useNewStyles:false};
1464
+ const{HUD: HUD$1}=components;class ArticleEditor extends React.Component{componentDidMount(){this._updateIssues();this._updatePreviewFrames();}componentDidUpdate(prevProps){if(prevProps.json!==this.props.json||prevProps.issues!==this.props.issues){this._updateIssues();}this._updatePreviewFrames();}_updateIssues(){const sections=this.props.json instanceof Array?this.props.json:[this.props.json];const allLinterIssues=[];sections.forEach(section=>{const parsed=PerseusMarkdown.parse(section.content??"",{});const linterContext={content:section.content,widgets:section.widgets,stack:[]};const sectionIssues=PerseusLinter.runLinter(parsed,linterContext,false)?.map(linterWarning=>{if(linterWarning.rule==="inaccessible-widget"){return WARNINGS.inaccessibleWidget(linterWarning.metadata?.widgetType??"unknown",linterWarning.metadata?.widgetId??"unknown")}return WARNINGS.genericLinterWarning(linterWarning.rule,linterWarning.message,linterWarning.severity)})??[];allLinterIssues.push(...sectionIssues);const texErrors=detectTexErrors(section.content??"");const texIssues=texErrors.map((error,index)=>WARNINGS.texError(error.math,error.message,index));allLinterIssues.push(...texIssues);});this.setState({issues:[...this.props.issues??[],...allLinterIssues]});}_updatePreviewFrames(){if(this.props.mode==="preview"){this.refs["frame-all"].sendNewData({type:"article-all",data:this._sections().map((section,i)=>{return this._apiOptionsForSection(section,i)})});}else if(this.props.mode==="edit"){this._sections().forEach((section,i)=>{this.refs["frame-"+i].sendNewData({type:"article",data:this._apiOptionsForSection(section,i)});});}}_apiOptionsForSection(section,sectionIndex){const editor=this.refs[`editor${sectionIndex}`];return {apiOptions:{...ApiOptions.defaults,...this.props.apiOptions,showAlignmentOptions:true,isArticle:true},json:section,useNewStyles:this.props.useNewStyles,linterContext:{contentType:"article",highlightLint:this.state.highlightLint,paths:this.props.contentPaths},legacyPerseusLint:editor?editor.getSaveWarnings():[]}}_sections(){const json=this.props.json;return json instanceof Array?json:[json]}_renderEditor(){const{imageUploader,sectionImageUploadGenerator}=this.props;const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,showAlignmentOptions:true,isArticle:true};const sections=this._sections();const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs("div",{className:"perseus-editor-table",children:[sections.map((section,i)=>{return [jsxRuntimeExports.jsx("div",{className:"perseus-editor-row",children:jsxRuntimeExports.jsxs("fieldset",{disabled:editingDisabled,children:[jsxRuntimeExports.jsxs("div",{className:"perseus-editor-left-cell",children:[jsxRuntimeExports.jsx(IssuesPanel,{issues:this.state.issues}),jsxRuntimeExports.jsxs("div",{className:"pod-title",children:["Section ",i+1,jsxRuntimeExports.jsxs("div",{style:{display:"inline-block",float:"right"},children:[sectionImageUploadGenerator(i),jsxRuntimeExports.jsx(SectionControlButton,{icon:plusIcon,disabled:editingDisabled,onClick:()=>{this._handleAddSectionAfter(i);},title:"Add a new section after this one"}),i+1<sections.length&&jsxRuntimeExports.jsx(SectionControlButton,{icon:arrowCircleDownIcon,disabled:editingDisabled,onClick:()=>{this._handleMoveSectionLater(i);},title:"Move this section down"}),i>0&&jsxRuntimeExports.jsx(SectionControlButton,{icon:arrowCircleUpIcon,disabled:editingDisabled,onClick:()=>{this._handleMoveSectionEarlier(i);},title:"Move this section up"}),jsxRuntimeExports.jsx(SectionControlButton,{icon:trashIcon,disabled:editingDisabled,onClick:()=>{const msg="Are you sure you "+"want to delete section "+(i+1)+"?";if(confirm(msg)){this._handleRemoveSection(i);}},title:"Delete this section"})]})]}),jsxRuntimeExports.jsx(Editor,{...section,apiOptions:apiOptions,imageUploader:imageUploader,onChange:newProps=>this._handleEditorChange(i,newProps),placeholder:"Type your section text here...",ref:"editor"+i})]}),jsxRuntimeExports.jsx("div",{className:"editor-preview",children:this._renderIframePreview(i,true)})]})},i)]}),this._renderAddSection(editingDisabled),this._renderLinterHUD()]})}_renderAddSection(editingDisabled){return jsxRuntimeExports.jsx("div",{className:"perseus-editor-row",children:jsxRuntimeExports.jsx("div",{className:"perseus-editor-left-cell",children:jsxRuntimeExports.jsx(Button,{startIcon:plusIcon,disabled:editingDisabled,kind:"tertiary","aria-label":"Add a section",onClick:()=>{this._handleAddSectionAfter(this._sections().length-1);},children:"Add a section"})})})}_renderLinterHUD(){return jsxRuntimeExports.jsx(HUD$1,{message:"Style warnings",enabled:this.state.highlightLint,onClick:()=>{this.setState({highlightLint:!this.state.highlightLint});}})}_renderIframePreview(i,nochrome){const isMobile=this.props.screen==="phone"||this.props.screen==="tablet";return jsxRuntimeExports.jsx(DeviceFramer,{deviceType:this.props.screen,nochrome:nochrome,children:jsxRuntimeExports.jsx(IframeContentRenderer,{ref:"frame-"+i,datasetKey:"mobile",datasetValue:isMobile,seamless:nochrome,url:this.props.previewURL},this.props.screen)})}_renderPreviewMode(){return jsxRuntimeExports.jsx("div",{className:"standalone-preview",children:this._renderIframePreview("all",false)})}_handleMoveSectionEarlier(i){if(i===0){return}const sections=[...this._sections()];const section=sections[i];sections.splice(i,1);sections.splice(i-1,0,section);this.props.onChange({json:sections});}_handleMoveSectionLater(i){const sections=[...this._sections()];if(i+1===sections.length){return}const section=sections[i];sections.splice(i,1);sections.splice(i+1,0,section);this.props.onChange({json:sections});}_handleAddSectionAfter(i){const sections=_.clone(this.serialize());const newSection=i>=0?{widgets:sections[i].widgets}:{};sections.splice(i+1,0,newSection);this.props.onChange({json:sections});}_handleRemoveSection(i){const sections=[...this._sections()];sections.splice(i,1);this.props.onChange({json:sections});}serialize(){if(this.props.mode==="edit"){return this._sections().map((section,i)=>{return this.refs["editor"+i].serialize()})}if(this.props.mode==="preview"||this.props.mode==="json"){return this.props.json}throw new PerseusError("Could not serialize; mode "+this.props.mode+" not found",Errors.Internal)}getSaveWarnings(){if(this.props.mode!=="edit"){throw new PerseusError("Can only get save warnings in edit mode.",Errors.NotAllowed)}return this._sections().map((section,i)=>{return this.refs["editor"+i].getSaveWarnings()})}render(){const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsx(Dependencies.DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{className:"framework-perseus perseus-article-editor",children:[this.props.mode==="edit"&&this._renderEditor(),this.props.mode==="preview"&&this._renderPreviewMode(),this.props.mode==="json"&&jsxRuntimeExports.jsxs("div",{className:"json-editor",children:[jsxRuntimeExports.jsx("div",{className:"json-editor-warning",children:jsxRuntimeExports.jsx("span",{children:"Warning: Editing in this mode can lead to broken articles!"})}),jsxRuntimeExports.jsx(JsonEditor,{multiLine:true,onChange:this._handleJsonChange,value:this.props.json,parser:parseAndMigratePerseusArticle,editingDisabled:editingDisabled})]})]})})}constructor(...args){super(...args),this.state={highlightLint:true,issues:[]},this._handleJsonChange=newJson=>{this.props.onChange({json:newJson});},this._handleEditorChange=(i,newProps)=>{const sections=[...this._sections()];sections[i]={...sections[i],...newProps};this.props.onChange({json:sections});};}}ArticleEditor.defaultProps={contentPaths:[],json:[{}],mode:"edit",screen:"desktop",sectionImageUploadGenerator:()=>jsxRuntimeExports.jsx("span",{}),useNewStyles:false};
1465
1465
 
1466
1466
  const iconChevronRight={path:"M62.808 49.728q0 3.36-2.352 5.88l-41.72 41.664q-2.352 2.408-5.768 2.408t-5.768-2.408l-4.872-4.76q-2.352-2.52-2.352-5.88t2.352-5.712l31.08-31.136-31.08-31.024q-2.352-2.52-2.352-5.88t2.352-5.712l4.872-4.76q2.296-2.408 5.768-2.408t5.768 2.408l41.72 41.664q2.352 2.296 2.352 5.656z",width:63.034,height:100};const iconCircleArrowDown={path:"M50.046 83.676q1.767 0 2.907-1.14l29.526-29.526q1.197-1.197 1.197-2.907t-1.197-2.964l-5.928-5.928q-1.197-1.14-2.964-1.14t-2.907 1.14l-12.312 12.312l0-32.661q0-1.71-1.254-2.964t-2.907-1.254l-8.322 0q-1.71 0-2.964 1.254t-1.254 2.964l0 32.661l-12.312-12.312q-1.197-1.254-2.907-1.254t-2.907 1.254l-5.928 5.928q-1.197 1.197-1.197 2.964t1.197 2.907l29.469 29.526q1.197 1.14 2.964 1.14zm49.989-33.63q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",width:100,height:100};const iconCircleArrowUp={path:"M54.207 83.391q1.653 0 2.907-1.254t1.254-2.907l0-32.718l12.312 12.312q1.254 1.254 2.964 1.254t2.907-1.254l5.928-5.928q1.197-1.197 1.14-2.964 0-1.767-1.14-2.907l-29.526-29.526q-1.197-1.14-2.907-1.14t-2.964 1.14l-29.469 29.526q-1.197 1.254-1.197 2.964t1.197 2.907l5.928 5.928q1.197 1.197 2.907 1.197t2.907-1.197l12.312-12.312l0 32.718q0 1.653 1.254 2.907t2.964 1.254l8.322 0zm45.828-33.345q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",width:100,height:100};const iconDesktop={path:"M94.208 52.119l0-43.746q0-.69-.506-1.15t-1.196-.506l-84.088 0q-.69 0-1.196.506t-.506 1.15l0 43.746q0 .69.506 1.196t1.196.506l84.088 0q.69 0 1.196-.506t.506-1.196zm6.716-43.746l0 57.224q0 3.45-2.484 5.934t-5.934 2.484l-28.566 0q0 3.128 2.53 7.774.828 1.61.828 2.622t-1.012 2.07q-1.012 1.012-2.346.966l-26.91 0q-1.38 0-2.392-1.012t-1.012-2.024q0-1.058 1.656-4.14t1.748-6.256l-28.612 0q-3.45 0-5.934-2.484t-2.484-5.934l0-57.224q0-3.45 2.484-5.934t5.934-2.438l84.088 0q3.45 0 5.98 2.438 2.438 2.484 2.438 5.934z",width:100,height:86.648};const iconMobilePhone={path:"M36.04 89.557q0-2.584-1.836-4.42t-4.42-1.836-4.352 1.836q-1.836 1.836-1.836 4.42t1.836 4.352 4.42 1.836q2.652-.068 4.42-1.836t1.768-4.352zm16.184-12.444l0-54.74q0-1.088-.748-1.768t-1.768-.68l-39.78 0q-1.088 0-1.768.748t-.68 1.7l0 54.74q0 1.02.748 1.768t1.7.68l39.78 0q1.02-.068 1.768-.748t.748-1.7zm-14.892-65.892q0-1.224-1.292-1.292l-12.444 0q-1.224.068-1.224 1.292t1.224 1.224l12.444 0q1.292 0 1.292-1.224zm22.372-1.292l0 79.628q0 3.944-2.992 6.936t-7.004 2.992l-39.78 0q-4.012 0-7.004-2.924-2.924-2.924-2.924-7.004l0-79.628q0-4.012 2.924-6.936t7.004-2.992l39.78 0q4.012-.068 7.004 2.924t2.992 7.004z",width:60.013,height:100};const iconPlus={path:"M99.758 43.09l0 13.578q0 2.852-1.984 4.836t-4.836 1.984l-29.45 0l0 29.45q0 2.852-1.984 4.836t-4.836 1.984l-13.578 0q-2.852 0-4.836-1.984t-1.984-4.836l0-29.45l-29.45 0q-2.852 0-4.836-1.984t-1.984-4.836l0-13.578q0-2.852 1.984-4.836t4.836-1.984l29.45 0l0-29.45q0-2.852 1.984-4.836t4.836-1.984l13.578 0q2.852 0 4.836 1.984t1.984 4.836l0 29.45l29.45 0q2.852 0 4.836 1.984t1.984 4.836z",width:100,height:100};const iconTablet={path:"M45.322 90.706q0-1.86-1.302-3.224-1.364-1.364-3.224-1.364t-3.224 1.364-1.302 3.224q0 1.86 1.364 3.224 1.302 1.364 3.162 1.302 1.86.062 3.224-1.302t1.302-3.224zm27.218-11.346l0-68.014q0-.93-.682-1.612t-1.55-.682l-58.962 0q-.93 0-1.612.682t-.682 1.612l0 68.014q0 .93.682 1.612t1.612.62l58.962 0q.992-.062 1.612-.682t.62-1.55zm9.114-68.014l0 77.066q0 4.65-3.348 7.998t-7.998 3.348l-58.962 0q-4.65 0-7.998-3.348t-3.348-7.998l0-77.066q0-4.65 3.348-7.998t7.998-3.348l58.962 0q4.65 0 7.998 3.348t3.348 7.998z",width:81.852,height:100};
1467
1467
 
@@ -1501,7 +1501,7 @@ const assistanceNeededMessage="Developer assistance needed - Please send this ex
1501
1501
 
1502
1502
  class ItemEditor extends React.Component{componentDidUpdate(prevProps){if(this.props.question?.content===prevProps.question?.content&&this.props.question?.widgets===prevProps.question?.widgets){return}const parsed=PerseusMarkdown.parse(this.props.question?.content??"",{});const linterContext={content:this.props.question?.content,widgets:this.props.question?.widgets,stack:[]};const texErrors=detectTexErrors(this.props.question?.content??"");const texIssues=texErrors.map((error,index)=>WARNINGS.texError(error.math,error.message,index));this.a11yCheckerTimeoutId=runAxeCoreOnUpdate(this.a11yCheckerTimeoutId,issues=>{this.setState({axeCoreIssues:issues});});const gatherIssues=()=>{return [...this.props.issues??[],...PerseusLinter.runLinter(parsed,linterContext,false)?.map(linterWarning=>{if(linterWarning.rule==="inaccessible-widget"){return WARNINGS.inaccessibleWidget(linterWarning.metadata?.widgetType??"unknown",linterWarning.metadata?.widgetId??"unknown")}return WARNINGS.genericLinterWarning(linterWarning.rule,linterWarning.message,linterWarning.severity)})??[],...texIssues]};this.setState({issues:gatherIssues()});}render(){const isMobile=this.props.deviceType==="phone"||this.props.deviceType==="tablet";const editingDisabled=this.props.apiOptions?.editingDisabled??false;const allIssues=this.state.issues.concat(this.state.showAxeCoreIssues?this.state.axeCoreIssues:[]);const a11yCheck={callback:()=>{this.setState({showAxeCoreIssues:!this.state.showAxeCoreIssues});},isChecked:this.state.showAxeCoreIssues};return jsxRuntimeExports.jsx(ItemEditorContext.Provider,{value:{question:this.props.question,onEditorChange:this.handleEditorChange},children:jsxRuntimeExports.jsxs("div",{className:"perseus-editor-table",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-editor-row perseus-question-container",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-editor-left-cell",children:[jsxRuntimeExports.jsx(IssuesPanel,{issues:allIssues,a11yCheck:a11yCheck}),jsxRuntimeExports.jsx("div",{className:"pod-title",children:"Question"}),jsxRuntimeExports.jsx("fieldset",{disabled:editingDisabled,children:jsxRuntimeExports.jsx(Editor,{ref:this.questionEditor,placeholder:"Type your question here...",className:"perseus-question-editor",imageUploader:this.props.imageUploader,onChange:this.handleEditorChange,apiOptions:this.props.apiOptions,showWordCount:true,widgetIsOpen:this.props.widgetIsOpen,additionalTemplates:this.props.additionalTemplates,...this.props.question},this.props.itemId)})]}),jsxRuntimeExports.jsx("div",{className:"perseus-editor-right-cell",children:jsxRuntimeExports.jsx("div",{id:"problemarea",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},this.props.deviceType)})})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-editor-row perseus-answer-container",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-editor-left-cell",children:[jsxRuntimeExports.jsx("div",{className:"pod-title",children:"Question extras"}),jsxRuntimeExports.jsx(ItemExtrasEditor,{ref:this.itemExtrasEditor,onChange:this.handleItemExtrasChange,editingDisabled:editingDisabled,...this.props.answerArea})]}),jsxRuntimeExports.jsx("div",{className:"perseus-editor-right-cell"})]})]})})}constructor(...args){super(...args),this.frame=React.createRef(),this.questionEditor=React.createRef(),this.itemExtrasEditor=React.createRef(),this.state={issues:[],axeCoreIssues:[],showAxeCoreIssues:false},this.updateProps=(newProps,cb,silent)=>{const props=_(this.props).pick("question","answerArea");this.props.onChange(_(props).extend(newProps),cb,silent);},this.triggerPreviewUpdate=newData=>{this.frame.current?.sendNewData(newData);},this.handleEditorChange=(newProps,cb,silent)=>{const question=_.extend({},this.props.question,newProps);this.updateProps({question},cb,silent);},this.handleItemExtrasChange=newProps=>{const answerArea=_.extend({},this.props.answerArea,newProps);this.updateProps({answerArea},()=>{},true);},this.getSaveWarnings=()=>{return this.questionEditor.current?.getSaveWarnings()},this.serialize=options=>{return {question:this.questionEditor.current?.serialize(options),answerArea:this.itemExtrasEditor.current?.serialize()}};}}ItemEditor.defaultProps={onChange:()=>{},question:{},answerArea:{}};
1503
1503
 
1504
- const{HUD}=components;class EditorPage extends React.Component{componentDidMount(){this._isMounted=true;this.updateRenderer();}getSnapshotBeforeUpdate(prevProps,prevState){if(!prevProps.jsonMode&&this.props.jsonMode){return {...this.itemEditor.current?.serialize({keepDeletedWidgets:true})??{},hints:this.hintsEditor.current?.serialize({keepDeletedWidgets:true})}}return null}componentDidUpdate(previousProps,prevState,snapshot){setTimeout(()=>{this.updateRenderer();});if(snapshot){this.setState({json:snapshot});return}if(!_.isEqual(previousProps.question,this.props.question)||!_.isEqual(previousProps.answerArea,this.props.answerArea)||!_.isEqual(previousProps.hints,this.props.hints)){this.syncJsonStateFromProps();}}componentWillUnmount(){this._isMounted=false;}syncJsonStateFromProps(){if(!this.props.question){return}this.setState({json:{question:this.props.question,answerArea:this.props.answerArea,hints:this.props.hints}});}updateRenderer(){const hasEditor=!this.props.developerMode||!this.props.jsonMode;if(!this._isMounted||!hasEditor){return}const touch=this.props.previewDevice==="phone"||this.props.previewDevice==="tablet";const deviceBasedApiOptions={...this.getApiOptions(),customKeypad:touch,isMobile:touch};this.itemEditor.current?.triggerPreviewUpdate({type:"question",data:_({item:this.serialize(),apiOptions:deviceBasedApiOptions,initialHintsVisible:0,device:this.props.previewDevice,linterContext:{contentType:"exercise",highlightLint:this.state.highlightLint,paths:this.props.contentPaths||[]},reviewMode:true,legacyPerseusLint:this.itemEditor.current?.getSaveWarnings()}).extend(_(this.props).pick("problemNum"))});}getApiOptions(){return {...ApiOptions.defaults,...this.props.apiOptions}}getSaveWarnings(){const issues1=this.itemEditor.current?.getSaveWarnings();const issues2=this.hintsEditor.current?.getSaveWarnings();return issues1.concat(issues2)}serialize(options){if(this.props.jsonMode){return this.state.json}return _.extend(this.itemEditor.current?.serialize(options),{hints:this.hintsEditor.current?.serialize(options)})}render(){let className="framework-perseus";const editingDisabled=this.props.apiOptions?.editingDisabled??false;const touch=this.props.previewDevice==="phone"||this.props.previewDevice==="tablet";const deviceBasedApiOptions={...this.getApiOptions(),customKeypad:touch,isMobile:touch};if(deviceBasedApiOptions.isMobile){className+=" "+ClassNames.MOBILE;}return jsxRuntimeExports.jsx(Dependencies.DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{id:"perseus",className:className,children:[jsxRuntimeExports.jsxs("div",{style:{marginBottom:10},children:[this.props.developerMode&&jsxRuntimeExports.jsxs("span",{children:[jsxRuntimeExports.jsxs("label",{children:[" ","Developer JSON Mode:"," ",jsxRuntimeExports.jsx("input",{type:"checkbox",checked:this.props.jsonMode,disabled:this.props.apiOptions?.editingDisabled,onChange:this.toggleJsonMode})]})," "]}),!this.props.jsonMode&&jsxRuntimeExports.jsx(ViewportResizer,{deviceType:this.props.previewDevice,onViewportSizeChanged:this.props.onPreviewDeviceChange}),!this.props.jsonMode&&jsxRuntimeExports.jsx(HUD,{message:"Style warnings",enabled:this.state.highlightLint,onClick:()=>{this.setState({highlightLint:!this.state.highlightLint});}})]}),this.props.developerMode&&this.props.jsonMode&&jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsx(JsonEditor,{multiLine:true,value:this.state.json,onChange:this.changeJSON,editingDisabled:editingDisabled})}),(!this.props.developerMode||!this.props.jsonMode)&&jsxRuntimeExports.jsx(ItemEditor,{ref:this.itemEditor,itemId:this.props.itemId,question:this.props.question,answerArea:this.props.answerArea,imageUploader:this.props.imageUploader,onChange:this.handleChange,deviceType:this.props.previewDevice,widgetIsOpen:this.state.widgetsAreOpen,apiOptions:deviceBasedApiOptions,previewURL:this.props.previewURL,issues:this.props.issues,additionalTemplates:this.props.additionalTemplates}),(!this.props.developerMode||!this.props.jsonMode)&&jsxRuntimeExports.jsx(CombinedHintsEditor,{ref:this.hintsEditor,itemId:this.props.itemId,hints:this.props.hints,imageUploader:this.props.imageUploader,onChange:this.handleChange,deviceType:this.props.previewDevice,apiOptions:deviceBasedApiOptions,previewURL:this.props.previewURL,highlightLint:this.state.highlightLint,widgetIsOpen:this.state.widgetsAreOpen})]})})}constructor(props){super(props),this.itemEditor=React.createRef(),this.hintsEditor=React.createRef(),this.toggleJsonMode=()=>{this.setState({json:this.serialize({keepDeletedWidgets:true})},()=>{this.props.onChange({jsonMode:!this.props.jsonMode});});},this.handleChange=(toChange,cb,silent)=>{const newProps=_(this.props).pick("question","hints","answerArea");_(newProps).extend(toChange);this.props.onChange(newProps,cb,silent);},this.changeJSON=newJson=>{this.setState({json:newJson});this.props.onChange(newJson);};this.state={json:_.pick(this.props,"question","answerArea","hints"),gradeMessage:"",wasAnswered:false,highlightLint:true,widgetsAreOpen:this.props.widgetsAreOpen??true};this._isMounted=false;}}EditorPage.defaultProps={developerMode:false,jsonMode:false,onChange:()=>{}};
1504
+ const{HUD}=components;class EditorPage extends React.Component{componentDidMount(){this._isMounted=true;this.updateRenderer();}getSnapshotBeforeUpdate(prevProps,prevState){if(!prevProps.jsonMode&&this.props.jsonMode){return {...this.itemEditor.current?.serialize({keepDeletedWidgets:true})??{},hints:this.hintsEditor.current?.serialize({keepDeletedWidgets:true})}}return null}componentDidUpdate(previousProps,prevState,snapshot){setTimeout(()=>{this.updateRenderer();});if(snapshot){this.setState({json:snapshot});return}if(!_.isEqual(previousProps.question,this.props.question)||!_.isEqual(previousProps.answerArea,this.props.answerArea)||!_.isEqual(previousProps.hints,this.props.hints)){this.syncJsonStateFromProps();}}componentWillUnmount(){this._isMounted=false;}syncJsonStateFromProps(){if(!this.props.question){return}this.setState({json:{question:this.props.question,answerArea:this.props.answerArea,hints:this.props.hints}});}updateRenderer(){const hasEditor=!this.props.developerMode||!this.props.jsonMode;if(!this._isMounted||!hasEditor){return}const touch=this.props.previewDevice==="phone"||this.props.previewDevice==="tablet";const deviceBasedApiOptions={...this.getApiOptions(),customKeypad:touch,isMobile:touch};this.itemEditor.current?.triggerPreviewUpdate({type:"question",data:_({item:this.serialize(),apiOptions:deviceBasedApiOptions,initialHintsVisible:0,device:this.props.previewDevice,linterContext:{contentType:"exercise",highlightLint:this.state.highlightLint,paths:this.props.contentPaths||[]},reviewMode:true,legacyPerseusLint:this.itemEditor.current?.getSaveWarnings()}).extend(_(this.props).pick("problemNum"))});}getApiOptions(){return {...ApiOptions.defaults,...this.props.apiOptions}}getSaveWarnings(){const issues1=this.itemEditor.current?.getSaveWarnings();const issues2=this.hintsEditor.current?.getSaveWarnings();return issues1.concat(issues2)}serialize(options){if(this.props.jsonMode){return this.state.json}return _.extend(this.itemEditor.current?.serialize(options),{hints:this.hintsEditor.current?.serialize(options)})}render(){let className="framework-perseus";const editingDisabled=this.props.apiOptions?.editingDisabled??false;const touch=this.props.previewDevice==="phone"||this.props.previewDevice==="tablet";const deviceBasedApiOptions={...this.getApiOptions(),customKeypad:touch,isMobile:touch};if(deviceBasedApiOptions.isMobile){className+=" "+ClassNames.MOBILE;}return jsxRuntimeExports.jsx(Dependencies.DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{id:"perseus",className:className,children:[jsxRuntimeExports.jsxs("div",{style:{marginBottom:10},children:[this.props.developerMode&&jsxRuntimeExports.jsxs("span",{children:[jsxRuntimeExports.jsxs("label",{children:[" ","Developer JSON Mode:"," ",jsxRuntimeExports.jsx("input",{type:"checkbox",checked:this.props.jsonMode,disabled:this.props.apiOptions?.editingDisabled,onChange:this.toggleJsonMode})]})," "]}),!this.props.jsonMode&&jsxRuntimeExports.jsx(ViewportResizer,{deviceType:this.props.previewDevice,onViewportSizeChanged:this.props.onPreviewDeviceChange}),!this.props.jsonMode&&jsxRuntimeExports.jsx(HUD,{message:"Style warnings",enabled:this.state.highlightLint,onClick:()=>{this.setState({highlightLint:!this.state.highlightLint});}})]}),this.props.developerMode&&this.props.jsonMode&&jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsx(JsonEditor,{multiLine:true,value:this.state.json,parser:parseAndMigratePerseusItem,onChange:this.changeJSON,editingDisabled:editingDisabled})}),(!this.props.developerMode||!this.props.jsonMode)&&jsxRuntimeExports.jsx(ItemEditor,{ref:this.itemEditor,itemId:this.props.itemId,question:this.props.question,answerArea:this.props.answerArea,imageUploader:this.props.imageUploader,onChange:this.handleChange,deviceType:this.props.previewDevice,widgetIsOpen:this.state.widgetsAreOpen,apiOptions:deviceBasedApiOptions,previewURL:this.props.previewURL,issues:this.props.issues,additionalTemplates:this.props.additionalTemplates}),(!this.props.developerMode||!this.props.jsonMode)&&jsxRuntimeExports.jsx(CombinedHintsEditor,{ref:this.hintsEditor,itemId:this.props.itemId,hints:this.props.hints,imageUploader:this.props.imageUploader,onChange:this.handleChange,deviceType:this.props.previewDevice,apiOptions:deviceBasedApiOptions,previewURL:this.props.previewURL,highlightLint:this.state.highlightLint,widgetIsOpen:this.state.widgetsAreOpen})]})})}constructor(props){super(props),this.itemEditor=React.createRef(),this.hintsEditor=React.createRef(),this.toggleJsonMode=()=>{this.setState({json:this.serialize({keepDeletedWidgets:true})},()=>{this.props.onChange({jsonMode:!this.props.jsonMode});});},this.handleChange=(toChange,cb,silent)=>{const newProps=_(this.props).pick("question","hints","answerArea");_(newProps).extend(toChange);this.props.onChange(newProps,cb,silent);},this.changeJSON=newJson=>{this.setState({json:newJson});this.props.onChange(newJson);};this.state={json:_.pick(this.props,"question","answerArea","hints"),gradeMessage:"",wasAnswered:false,highlightLint:true,widgetsAreOpen:this.props.widgetsAreOpen??true};this._isMounted=false;}}EditorPage.defaultProps={developerMode:false,jsonMode:false,onChange:()=>{}};
1505
1505
 
1506
1506
  function ContentPreview({question,apiOptions,seamless,linterContext,legacyPerseusLint,previewDevice,reviewMode}){const i18n=usePerseusI18n();const isMobile=previewDevice!=="desktop";const className=isMobile?"perseus-mobile":"";return jsxRuntimeExports.jsx(View,{className:`framework-perseus ${className}`,style:[styles$O.container,!seamless?styles$O.gutter:undefined],children:jsxRuntimeExports.jsx(StatefulKeypadContextProvider,{children:jsxRuntimeExports.jsx(KeypadContext.Consumer,{children:({setKeypadActive,keypadElement,setKeypadElement})=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(UserInputManager,{widgets:question?.widgets||{},problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>jsxRuntimeExports.jsx(Renderer,{strings:i18n.strings,apiOptions:{...apiOptions,isMobile},keypadElement:keypadElement,linterContext:linterContext,legacyPerseusLint:legacyPerseusLint,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,reviewMode:reviewMode,...question})}),jsxRuntimeExports.jsx(MobileKeypad,{onAnalyticsEvent:()=>Promise.resolve(),onDismiss:()=>setKeypadActive(false),onElementMounted:setKeypadElement})]})})})})}const styles$O=StyleSheet.create({container:{padding:spacing.xxxSmall_4,containerType:"inline-size",containerName:"perseus-root"},gutter:{marginRight:lintGutterWidth}});
1507
1507
 
@@ -1548,7 +1548,7 @@ const ScrolllessNumberTextField=props=>{const{value,onChange,...restOfProps}=pro
1548
1548
 
1549
1549
  var styles$J = {"dimensionsContainer":"perseus_4qo24hC2","dimensionsFieldContainer":"perseus_BMTr3h5s","xSpan":"perseus_4OCWnpA9","horizontalLine":"perseus_SKDkfpcb"};
1550
1550
 
1551
- function ImageDimensionsInput({backgroundImage,onChange}){function handleWidthChange(newWidth){const newHeight=getOtherSideLengthWithPreservedAspectRatio(backgroundImage.width,backgroundImage.height,Number(newWidth));if(isNaN(newHeight)){return}const newWidthNumber=Number(newWidth);if(newWidthNumber===backgroundImage.width&&newHeight===backgroundImage.height){return}onChange({backgroundImage:{...backgroundImage,width:newWidthNumber,height:newHeight}});}function handleHeightChange(newHeight){const newWidth=getOtherSideLengthWithPreservedAspectRatio(backgroundImage.height,backgroundImage.width,Number(newHeight));if(isNaN(newWidth)){return}const newHeightNumber=Number(newHeight);if(newWidth===backgroundImage.width&&newHeightNumber===backgroundImage.height){return}onChange({backgroundImage:{...backgroundImage,height:newHeightNumber,width:newWidth}});}async function handleResetToOriginalSize(){const naturalSize=await Util.getImageSizeModern(backgroundImage.url);const[naturalWidth,naturalHeight]=naturalSize;if(naturalWidth===backgroundImage.width&&naturalHeight===backgroundImage.height){return}onChange({backgroundImage:{...backgroundImage,width:naturalWidth,height:naturalHeight}});}return jsxRuntimeExports.jsxs("div",{className:styles$J.dimensionsContainer,children:[jsxRuntimeExports.jsxs("div",{className:styles$J.dimensionsFieldContainer,children:[jsxRuntimeExports.jsx(LabeledField,{label:"Width",field:jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:backgroundImage.width?.toString()??"",onChange:handleWidthChange}),styles:wbFieldStyles}),jsxRuntimeExports.jsx("span",{className:styles$J.xSpan,children:"x"}),jsxRuntimeExports.jsx(LabeledField,{label:"Height",field:jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:backgroundImage.height?.toString()??"",onChange:handleHeightChange}),styles:wbFieldStyles})]}),jsxRuntimeExports.jsx(Button,{kind:"tertiary",size:"small",startIcon:arrowCounterClockwise,onClick:handleResetToOriginalSize,children:"Reset to original size"})]})}
1551
+ function ImageDimensionsInput({backgroundImage,onChange}){function handleWidthChange(newWidth){const newHeight=getOtherSideLengthWithPreservedAspectRatio(backgroundImage.width,backgroundImage.height,Number(newWidth));if(isNaN(newHeight)){return}const newWidthNumber=Number(newWidth);if(newWidthNumber===backgroundImage.width&&newHeight===backgroundImage.height){return}onChange({backgroundImage:{...backgroundImage,width:newWidthNumber,height:newHeight}});}function handleHeightChange(newHeight){const newWidth=getOtherSideLengthWithPreservedAspectRatio(backgroundImage.height,backgroundImage.width,Number(newHeight));if(isNaN(newWidth)){return}const newHeightNumber=Number(newHeight);if(newWidth===backgroundImage.width&&newHeightNumber===backgroundImage.height){return}onChange({backgroundImage:{...backgroundImage,height:newHeightNumber,width:newWidth}});}async function handleResetToOriginalSize(){const naturalSize=await Util.getImageSizeModern(backgroundImage.url);const[naturalWidth,naturalHeight]=naturalSize;if(naturalWidth===backgroundImage.width&&naturalHeight===backgroundImage.height){return}onChange({backgroundImage:{...backgroundImage,width:naturalWidth,height:naturalHeight}});}return jsxRuntimeExports.jsxs("div",{className:styles$J.dimensionsContainer,children:[jsxRuntimeExports.jsx(Banner,{kind:"warning",text:"Sizing is temporarily disabled due to detected issues.",styles:{root:{marginBottom:sizing.size_080}}}),jsxRuntimeExports.jsxs("div",{className:styles$J.dimensionsFieldContainer,children:[jsxRuntimeExports.jsx(LabeledField,{label:"Width",field:jsxRuntimeExports.jsx(ScrolllessNumberTextField,{disabled:true,value:backgroundImage.width?.toString()??"",onChange:handleWidthChange}),styles:wbFieldStyles}),jsxRuntimeExports.jsx("span",{className:styles$J.xSpan,children:"x"}),jsxRuntimeExports.jsx(LabeledField,{label:"Height",field:jsxRuntimeExports.jsx(ScrolllessNumberTextField,{disabled:true,value:backgroundImage.height?.toString()??"",onChange:handleHeightChange}),styles:wbFieldStyles})]}),jsxRuntimeExports.jsx(Button,{kind:"tertiary",size:"small",startIcon:arrowCounterClockwise,onClick:handleResetToOriginalSize,children:"Reset to original size"})]})}
1552
1552
 
1553
1553
  function ImageScaleInput({backgroundImage,scale,onChange}){const width=backgroundImage.width??0;const height=backgroundImage.height??0;function handleScaleChange(newScale){const scaleNum=Number(newScale);if(isNaN(scaleNum)||scaleNum<=0){return}onChange({scale:scaleNum});}function handleScaledWidthChange(newScaledWidth){const newScaledWidthNum=Number(newScaledWidth);if(isNaN(newScaledWidthNum)||newScaledWidthNum<=0){return}const newScale=newScaledWidthNum/width;onChange({scale:newScale});}function handleScaledHeightChange(newScaledHeight){const newScaledHeightNum=Number(newScaledHeight);if(isNaN(newScaledHeightNum)||newScaledHeightNum<=0){return}const newScale=newScaledHeightNum/height;onChange({scale:newScale});}async function handleResetToOriginalSize(){if(!backgroundImage.url){return}const naturalSize=await Util.getImageSizeModern(backgroundImage.url);const[naturalWidth,naturalHeight]=naturalSize;if(naturalWidth===backgroundImage.width&&naturalHeight===backgroundImage.height){return}onChange({backgroundImage:{...backgroundImage,width:naturalWidth,height:naturalHeight}});}return jsxRuntimeExports.jsxs("div",{className:styles$J.dimensionsContainer,children:[jsxRuntimeExports.jsxs(BodyMonospace,{children:["Dimensions: ",width," x ",height]}),jsxRuntimeExports.jsx(Button,{kind:"tertiary",size:"small",startIcon:arrowCounterClockwise,onClick:handleResetToOriginalSize,children:"Recalculate original size"}),jsxRuntimeExports.jsx("div",{className:styles$J.horizontalLine}),jsxRuntimeExports.jsx(LabeledField,{label:"Scale",description:"Use 1 to display image at original size.",field:jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:scale.toString(),min:0,onChange:handleScaleChange}),styles:wbFieldStyles}),jsxRuntimeExports.jsxs("div",{className:styles$J.dimensionsFieldContainer,children:[jsxRuntimeExports.jsx(LabeledField,{label:"Scaled Width",field:jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:(width*scale).toString(),min:0,onChange:handleScaledWidthChange}),styles:wbFieldStyles}),jsxRuntimeExports.jsx("span",{className:styles$J.xSpan,children:"x"}),jsxRuntimeExports.jsx(LabeledField,{label:"Scaled Height",field:jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:(height*scale).toString(),min:0,onChange:handleScaledHeightChange}),styles:wbFieldStyles})]})]})}
1554
1554