!449 输入框四则运算

pull/449/MERGE
ChenX 5 years ago
parent bcde414f30
commit 1d454718c6

@ -1,16 +1,17 @@
import React = require("react"); import React = require("react");
import { Classes, Button, RadioGroup, Radio } from "@blueprintjs/core"; import { Button, Classes, Radio, RadioGroup } from "@blueprintjs/core";
import { app } from "../../ApplicationServices/Application";
import { CheckObjectType, CheckoutValid } from "../../Common/CheckoutVaildValue";
import { ToasterInput, AppToaster } from "../../UI/Components/Toaster";
import { observable } from "mobx"; import { observable } from "mobx";
import { DataAdapter } from "../../Common/DataAdapter";
import { Singleton } from "../../Common/Singleton";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { ModalState } from "../../UI/Components/Modal/ModalsManage";
import { begin } from "xaop"; import { begin } from "xaop";
import { app } from "../../ApplicationServices/Application";
import { CheckObjectType, CheckoutValid } from "../../Common/CheckoutVaildValue";
import { DataAdapter } from "../../Common/DataAdapter";
import { safeEval } from "../../Common/eval";
import { KeyBoard } from "../../Common/KeyEnum"; import { KeyBoard } from "../../Common/KeyEnum";
import { Singleton } from "../../Common/Singleton";
import { BoardType } from "../../DatabaseServices/Entity/Board"; import { BoardType } from "../../DatabaseServices/Entity/Board";
import { ModalState } from "../../UI/Components/Modal/ModalsManage";
import { AppToaster, ToasterInput } from "../../UI/Components/Toaster";
export enum CuttingOffset export enum CuttingOffset
{ {
@ -155,7 +156,7 @@ export class ReferenceCuttingModal extends React.Component<{ store: ReferenceCut
isDisabled={store.m_Option.CuttingPosSelected === CuttingOffset.Middle} isDisabled={store.m_Option.CuttingPosSelected === CuttingOffset.Middle}
option={store.m_Option} option={store.m_Option}
uiOption={this.uiOption} uiOption={this.uiOption}
onChange={(e) => { store.m_Option.offset = parseFloat(e.currentTarget.value); }} onChange={(e) => { store.m_Option.offset = safeEval(e.currentTarget.value); }}
/> />
</div> </div>
</div> </div>

@ -2,11 +2,12 @@ import { toJS } from "mobx";
import { app } from "../ApplicationServices/Application"; import { app } from "../ApplicationServices/Application";
import { arrayLast } from "../Common/ArrayExt"; import { arrayLast } from "../Common/ArrayExt";
import { EBoardKeyList } from "../Common/BoardKeyList"; import { EBoardKeyList } from "../Common/BoardKeyList";
import { safeEval } from "../Common/eval";
import { FixedNotZero } from "../Common/Utils"; import { FixedNotZero } from "../Common/Utils";
import { GangDrill, GangDrillType } from "../DatabaseServices/3DSolid/GangDrill"; import { GangDrill, GangDrillType } from "../DatabaseServices/3DSolid/GangDrill";
import { Board } from "../DatabaseServices/Entity/Board";
import { LineAngularDimension } from "../DatabaseServices/Dimension/2LineAngularDimension"; import { LineAngularDimension } from "../DatabaseServices/Dimension/2LineAngularDimension";
import { AlignedDimension } from "../DatabaseServices/Dimension/AlignedDimension"; import { AlignedDimension } from "../DatabaseServices/Dimension/AlignedDimension";
import { Board } from "../DatabaseServices/Entity/Board";
import { Command } from "../Editor/CommandMachine"; import { Command } from "../Editor/CommandMachine";
import { PromptStatus } from "../Editor/PromptResult"; import { PromptStatus } from "../Editor/PromptResult";
import { SelectSetBase } from "../Editor/SelectBase"; import { SelectSetBase } from "../Editor/SelectBase";
@ -126,20 +127,20 @@ export class BoardFindModify implements Command
{ {
case EBoardKeyList.Height: case EBoardKeyList.Height:
compareBrValue = br.Height; compareBrValue = br.Height;
compareValue = parseFloat(option.height) || 0; compareValue = safeEval(option.height) || 0;
torValue = parseFloat(option.tolerance.height) || 0; torValue = safeEval(option.tolerance.height) || 0;
isVail = this.FilterBrSize(compareBrValue, compareValue, torValue, option.compareType.height); isVail = this.FilterBrSize(compareBrValue, compareValue, torValue, option.compareType.height);
break; break;
case EBoardKeyList.Width: case EBoardKeyList.Width:
compareBrValue = br.Width; compareBrValue = br.Width;
compareValue = parseFloat(option.width) || 0; compareValue = safeEval(option.width) || 0;
torValue = parseFloat(option.tolerance.width) || 0; torValue = safeEval(option.tolerance.width) || 0;
isVail = this.FilterBrSize(compareBrValue, compareValue, torValue, option.compareType.width); isVail = this.FilterBrSize(compareBrValue, compareValue, torValue, option.compareType.width);
break; break;
case EBoardKeyList.Thick: case EBoardKeyList.Thick:
compareBrValue = br.Thickness; compareBrValue = br.Thickness;
compareValue = parseFloat(option.thickness) || 0; compareValue = safeEval(option.thickness) || 0;
torValue = parseFloat(option.tolerance.thickness) || 0; torValue = safeEval(option.tolerance.thickness) || 0;
isVail = this.FilterBrSize(compareBrValue, compareValue, torValue, option.compareType.thickness); isVail = this.FilterBrSize(compareBrValue, compareValue, torValue, option.compareType.thickness);
break; break;
case "uerDoor": case "uerDoor":
@ -240,17 +241,17 @@ export class BoardFindModify implements Command
switch (i as keyof EBoardKeyList) switch (i as keyof EBoardKeyList)
{ {
case EBoardKeyList.Height: case EBoardKeyList.Height:
let height = parseFloat(option.height); let height = safeEval(option.height);
if (height) if (height)
br.Height = height; br.Height = height;
break; break;
case EBoardKeyList.Width: case EBoardKeyList.Width:
let width = parseFloat(option.width); let width = safeEval(option.width);
if (width) if (width)
br.Width = width; br.Width = width;
break; break;
case EBoardKeyList.Thick: case EBoardKeyList.Thick:
let thickness = parseFloat(option.thickness); let thickness = safeEval(option.thickness);
if (thickness) if (thickness)
br.Thickness = thickness; br.Thickness = thickness;
break; break;

@ -1,11 +1,12 @@
import { Vector3 } from 'three'; import { Vector3 } from 'three';
import { app } from '../../ApplicationServices/Application'; import { app } from '../../ApplicationServices/Application';
import { safeEval } from '../../Common/eval';
import { Board, BoardType } from '../../DatabaseServices/Entity/Board'; import { Board, BoardType } from '../../DatabaseServices/Entity/Board';
import { JigUtils } from '../../Editor/JigUtils';
import { MoveMatrix } from '../../Geometry/GeUtils'; import { MoveMatrix } from '../../Geometry/GeUtils';
import { BehindBoardOption, BehindHeightPositon, BrRelativePos } from '../../UI/Store/BoardInterface'; import { BehindBoardOption, BehindHeightPositon, BrRelativePos } from '../../UI/Store/BoardInterface';
import { DrawBoardTool } from './DrawBoardTool';
import { BehindBoardStore } from '../../UI/Store/BoardStore'; import { BehindBoardStore } from '../../UI/Store/BoardStore';
import { JigUtils } from '../../Editor/JigUtils'; import { DrawBoardTool } from './DrawBoardTool';
export class DrawBehindBoard extends DrawBoardTool export class DrawBehindBoard extends DrawBoardTool
{ {
@ -59,10 +60,10 @@ export class DrawBehindBoard extends DrawBoardTool
const grooveOption = (this.store as BehindBoardStore).grooveOption; const grooveOption = (this.store as BehindBoardStore).grooveOption;
let board = Board.CreateBoard(height, size.x, thickness, BoardType.Behind); let board = Board.CreateBoard(height, size.x, thickness, BoardType.Behind);
board.KnifeRadius = parseFloat(grooveOption.knifeRadius); board.KnifeRadius = safeEval(grooveOption.knifeRadius);
board.GroovesAddDepth = parseFloat(grooveOption.grooveAddDepth); board.GroovesAddDepth = safeEval(grooveOption.grooveAddDepth);
board.GroovesAddWidth = parseFloat(grooveOption.grooveAddWidth); board.GroovesAddWidth = safeEval(grooveOption.grooveAddWidth);
board.GroovesAddLength = parseFloat(grooveOption.grooveAddLength); board.GroovesAddLength = safeEval(grooveOption.grooveAddLength);
board.BoardProcessOption = this.store.BoardProcessOption; board.BoardProcessOption = this.store.BoardProcessOption;
opt.height = height; opt.height = height;

@ -13,6 +13,7 @@ import { DoorOpenDir } from "../../UI/Store/DoorInterface";
import { DrillType } from "../../UI/Store/BoardInterface"; import { DrillType } from "../../UI/Store/BoardInterface";
import { EBoardKeyList } from "../../Common/BoardKeyList"; import { EBoardKeyList } from "../../Common/BoardKeyList";
import { NonAssociativeCutting } from "../BoardCutting/NonAssociativeCutting"; import { NonAssociativeCutting } from "../BoardCutting/NonAssociativeCutting";
import { safeEval } from "../../Common/eval";
export class DrawDoor implements Command export class DrawDoor implements Command
{ {
@ -29,9 +30,9 @@ export class DrawDoor implements Command
let store = DoorStore.GetInstance() as DoorStore; let store = DoorStore.GetInstance() as DoorStore;
const surroundOption = spaceParse.m_Boards[0].BoardProcessOption; const surroundOption = spaceParse.m_Boards[0].BoardProcessOption;
store.m_Option.boardName = surroundOption.cabinetName; store.m_Option.boardName = surroundOption.cabinetName;
store.totalHeight = parseFloat(ToFixed(size.z, 2)); store.totalHeight = safeEval(ToFixed(size.z, 2));
store.totalWidth = parseFloat(ToFixed(size.x, 2)); store.totalWidth = safeEval(ToFixed(size.x, 2));
store.totalDepth = parseFloat(ToFixed(size.y, 2)); store.totalDepth = safeEval(ToFixed(size.y, 2));
store.m_Option.depth = store.totalDepth; store.m_Option.depth = store.totalDepth;
app.Editor.ModalManage.RenderModal(DoorModal, ModalPosition.Center, { store }); app.Editor.ModalManage.RenderModal(DoorModal, ModalPosition.Center, { store });

@ -5,6 +5,7 @@ import { PointSelectSpaceClamp } from "../../Geometry/SpaceParse/PointSelectSpac
import { DoorModal } from "../../UI/Components/Board/Door/DoorModal"; import { DoorModal } from "../../UI/Components/Board/Door/DoorModal";
import { ModalPosition, ModalState } from "../../UI/Components/Modal/ModalsManage"; import { ModalPosition, ModalState } from "../../UI/Components/Modal/ModalsManage";
import { DrawerStore } from "../../UI/Store/DoorDrawerStore/DrawerStore"; import { DrawerStore } from "../../UI/Store/DoorDrawerStore/DrawerStore";
import { safeEval } from "../../Common/eval";
export class DrawDrawrer implements Command export class DrawDrawrer implements Command
{ {
@ -20,9 +21,9 @@ export class DrawDrawrer implements Command
let store = DrawerStore.GetInstance() as DrawerStore; let store = DrawerStore.GetInstance() as DrawerStore;
store.m_Option.boardName = spaceParse.m_Boards[0].BoardProcessOption.cabinetName; store.m_Option.boardName = spaceParse.m_Boards[0].BoardProcessOption.cabinetName;
store.totalHeight = parseFloat(FixedNotZero(size.z, 2)); store.totalHeight = safeEval(FixedNotZero(size.z, 2));
store.totalWidth = parseFloat(FixedNotZero(size.x, 2)); store.totalWidth = safeEval(FixedNotZero(size.x, 2));
store.totalDepth = parseFloat(FixedNotZero(size.y, 2)); store.totalDepth = safeEval(FixedNotZero(size.y, 2));
store.m_Option.depth = store.totalDepth; store.m_Option.depth = store.totalDepth;
app.Editor.ModalManage.RenderModal(DoorModal, ModalPosition.Center, { store }); app.Editor.ModalManage.RenderModal(DoorModal, ModalPosition.Center, { store });

@ -8,6 +8,7 @@ import { ModalPosition } from "../../UI/Components/Modal/ModalsManage";
import { SpecialShapeStore } from "../../UI/Store/BoardStore"; import { SpecialShapeStore } from "../../UI/Store/BoardStore";
import { ExtrudeApplyContour, SelectExtrudeContour } from "./DrawSpecialShapeBoardTool"; import { ExtrudeApplyContour, SelectExtrudeContour } from "./DrawSpecialShapeBoardTool";
import { Matrix4 } from "three"; import { Matrix4 } from "three";
import { safeEval } from "../../Common/eval";
export class DrawSpecialShapedBoard implements Command export class DrawSpecialShapedBoard implements Command
{ {
@ -22,8 +23,8 @@ export class DrawSpecialShapedBoard implements Command
let toCurve = new Matrix4().getInverse(applyMatrix4); let toCurve = new Matrix4().getInverse(applyMatrix4);
const store = SpecialShapeStore.GetInstance() as SpecialShapeStore; const store = SpecialShapeStore.GetInstance() as SpecialShapeStore;
store.m_Option.height = parseFloat(FixedNotZero(this.ext.Height, 2)); store.m_Option.height = safeEval(FixedNotZero(this.ext.Height, 2));
store.m_Option.width = parseFloat(FixedNotZero(this.ext.Width, 2)); store.m_Option.width = safeEval(FixedNotZero(this.ext.Width, 2));
app.Editor.ModalManage.RenderModeless(SpecialShapeBoardModal, ModalPosition.Center, { store }); app.Editor.ModalManage.RenderModeless(SpecialShapeBoardModal, ModalPosition.Center, { store });

@ -18,6 +18,7 @@ import { DrillingOption, SpacingType } from "../../UI/Store/drillInterface";
import { begin } from "xaop"; import { begin } from "xaop";
import { IsPointInPolyLine } from "../../DatabaseServices/PointInPolyline"; import { IsPointInPolyLine } from "../../DatabaseServices/PointInPolyline";
import { Polyline } from "../../DatabaseServices/Entity/Polyline"; import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { safeEval } from "../../Common/eval";
export class DrawDrillingTool extends Singleton export class DrawDrillingTool extends Singleton
@ -128,7 +129,7 @@ export class DrawDrillingTool extends Singleton
posHeight = eval(ljgPos); posHeight = eval(ljgPos);
} }
else else
posHeight = this.m_Face.m_Width - parseFloat(ljgPos); posHeight = this.m_Face.m_Width - safeEval(ljgPos);
if (!isNaN(posHeight)) if (!isNaN(posHeight))
d.ApplyMatrix(MoveMatrix(new Vector3(0, posHeight))); d.ApplyMatrix(MoveMatrix(new Vector3(0, posHeight)));

@ -1,5 +1,6 @@
import { end } from 'xaop'; import { end } from 'xaop';
import { app } from '../ApplicationServices/Application'; import { app } from '../ApplicationServices/Application';
import { safeEval } from '../Common/eval';
import { KeyWord } from '../Common/InputState'; import { KeyWord } from '../Common/InputState';
import { KeyCode } from '../Common/KeyEnum'; import { KeyCode } from '../Common/KeyEnum';
import { FixedNotZero } from '../Common/Utils'; import { FixedNotZero } from '../Common/Utils';
@ -108,7 +109,7 @@ export class CommandFillet implements Command
}); });
if (enRes2.Status === PromptStatus.String) if (enRes2.Status === PromptStatus.String)
{ {
let rad = parseFloat(enRes2.StringResult); let rad = safeEval(enRes2.StringResult);
if (rad !== 0 && !isNaN(rad)) if (rad !== 0 && !isNaN(rad))
this.UpdateFilletRadius(rad); this.UpdateFilletRadius(rad);
} }
@ -265,7 +266,7 @@ export class CommandFillet implements Command
}); });
if (enRes.Status === PromptStatus.String) if (enRes.Status === PromptStatus.String)
{ {
let rad = parseFloat(enRes.StringResult); let rad = safeEval(enRes.StringResult);
if (rad !== 0) if (rad !== 0)
{ {
this.m_FilletRadius = rad; this.m_FilletRadius = rad;

@ -1,12 +1,13 @@
import { Command } from "../Editor/CommandMachine";
import { app } from "../ApplicationServices/Application"; import { app } from "../ApplicationServices/Application";
import { ModalPosition } from "../UI/Components/Modal/ModalsManage"; import { EBoardKeyList } from "../Common/BoardKeyList";
import { LookOverBoardInfosModal } from "../UI/Components/Board/LookOverBoardInfos"; import { safeEval } from "../Common/eval";
import { LookOverBoardInfosStore } from "../UI/Store/LookOverBoardInfosStore";
import { Board } from "../DatabaseServices/Entity/Board"; import { Board } from "../DatabaseServices/Entity/Board";
import { Command } from "../Editor/CommandMachine";
import { PromptStatus } from "../Editor/PromptResult"; import { PromptStatus } from "../Editor/PromptResult";
import { LookOverBoardInfosModal } from "../UI/Components/Board/LookOverBoardInfos";
import { ModalPosition } from "../UI/Components/Modal/ModalsManage";
import { EFindType } from "../UI/Store/BoardFindInterface"; import { EFindType } from "../UI/Store/BoardFindInterface";
import { EBoardKeyList } from "../Common/BoardKeyList"; import { LookOverBoardInfosStore } from "../UI/Store/LookOverBoardInfosStore";
export class LookOverBoardInfos implements Command export class LookOverBoardInfos implements Command
{ {
@ -60,13 +61,13 @@ export class LookOverBoardInfos implements Command
switch (i) switch (i)
{ {
case EBoardKeyList.Height: case EBoardKeyList.Height:
br.Height = parseFloat(opts[i]); br.Height = safeEval(opts[i]);
break; break;
case EBoardKeyList.Width: case EBoardKeyList.Width:
br.Width = parseFloat(opts[i]); br.Width = safeEval(opts[i]);
break; break;
case EBoardKeyList.Thick: case EBoardKeyList.Thick:
br.Thickness = parseFloat(opts[i]); br.Thickness = safeEval(opts[i]);
break; break;
case "brName": case "brName":
br.Name = opts.brName; br.Name = opts.brName;

@ -1,5 +1,6 @@
import { operationExpReg } from "./Utils"; import { operationExpReg } from "./Utils";
import { EBoardKeyList } from "./BoardKeyList"; import { EBoardKeyList } from "./BoardKeyList";
import { safeEval } from "./eval";
export enum CheckObjectType export enum CheckObjectType
{ {
@ -116,7 +117,7 @@ export namespace CheckoutValid
case "sealedDown": case "sealedDown":
case "sealedLeft": case "sealedLeft":
case "sealedRight": case "sealedRight":
if (!isNaN(parseFloat(v)) && parseFloat(v) < 0) if (!isNaN(safeEval(v)) && safeEval(v) < 0)
return "数值不能小于0"; return "数值不能小于0";
return ""; return "";
case "height": case "height":
@ -125,7 +126,7 @@ export namespace CheckoutValid
case "divCount": case "divCount":
case "thickness": case "thickness":
case "footThickness": case "footThickness":
if (!isNaN(parseFloat(v)) && parseFloat(v) <= 0) if (!isNaN(safeEval(v)) && safeEval(v) <= 0)
return "数值必须大于0"; return "数值必须大于0";
default: default:
if (v === "" || isNaN(Number(v))) if (v === "" || isNaN(Number(v)))
@ -165,14 +166,14 @@ export namespace CheckoutValid
case "wdepth": case "wdepth":
case "originDist": case "originDist":
case "retDist": case "retDist":
if (!isNaN(parseFloat(v)) && parseFloat(v) === 0) if (!isNaN(safeEval(v)) && safeEval(v) === 0)
return "数值必须大于0"; return "数值必须大于0";
default: default:
if (v === "" || isNaN(Number(v))) if (v === "" || isNaN(Number(v)))
{ {
return "数值不能为空且必须为数字"; return "数值不能为空且必须为数字";
} }
if (!isNaN(parseFloat(v)) && parseFloat(v) < 0) if (!isNaN(safeEval(v)) && safeEval(v) < 0)
return "数值必须大于0"; return "数值必须大于0";
} }
return ""; return "";
@ -187,25 +188,25 @@ export namespace CheckoutValid
return ""; return "";
case "row": case "row":
case "col": case "col":
if (parseFloat(v) > 32767 || parseFloat(v) < 1 || parseFloat(v) % 1 !== 0) if (safeEval(v) > 32767 || safeEval(v) < 1 || safeEval(v) % 1 !== 0)
return "请输入1-32767间的整数"; return "请输入1-32767间的整数";
else if (v === "" || isNaN(Number(v)))//break不会经过default else if (v === "" || isNaN(Number(v)))//break不会经过default
return "数值不能为空且必须为数字"; return "数值不能为空且必须为数字";
return ""; return "";
case "itemTotal": case "itemTotal":
if (parseFloat(v) > 32767 || parseFloat(v) < 2 || parseFloat(v) % 1 !== 0) if (safeEval(v) > 32767 || safeEval(v) < 2 || safeEval(v) % 1 !== 0)
return "请输入2-32767间整数"; return "请输入2-32767间整数";
else if (v === "" || isNaN(Number(v))) else if (v === "" || isNaN(Number(v)))
return "数值不能为空且必须为数字"; return "数值不能为空且必须为数字";
return ""; return "";
case "betweenAngle": case "betweenAngle":
if (!isNaN(parseFloat(v)) && parseFloat(v) < 0) if (!isNaN(safeEval(v)) && safeEval(v) < 0)
return "数值不可小于0"; return "数值不可小于0";
case "fillAngle": case "fillAngle":
if (!isNaN(parseFloat(v)) && parseFloat(v) === 0) if (!isNaN(safeEval(v)) && safeEval(v) === 0)
return "数值不可等于0"; return "数值不可等于0";
case "arrayAngle": case "arrayAngle":
if (Math.abs(parseFloat(v)) > 360) if (Math.abs(safeEval(v)) > 360)
return "角度不可大于360"; return "角度不可大于360";
default: default:
if (v === "" || isNaN(Number(v))) if (v === "" || isNaN(Number(v)))
@ -314,7 +315,7 @@ export namespace CheckoutValid
case "boardThick": case "boardThick":
case "brThick2": case "brThick2":
case "gripWidth": case "gripWidth":
if (!isNaN(parseFloat(v)) && parseFloat(v) <= 0) if (!isNaN(safeEval(v)) && safeEval(v) <= 0)
return "数值必须大于0"; return "数值必须大于0";
default: default:
if (v === "" || isNaN(Number(v))) if (v === "" || isNaN(Number(v)))
@ -332,7 +333,7 @@ export namespace CheckoutValid
case "gripWidth": case "gripWidth":
case "gripDepth": case "gripDepth":
case "arcLen": case "arcLen":
if (!isNaN(parseFloat(v)) && parseFloat(v) <= 0) if (!isNaN(safeEval(v)) && safeEval(v) <= 0)
return "数值必须大于0"; return "数值必须大于0";
case "widthCount": case "widthCount":
case "depthCount": case "depthCount":
@ -343,7 +344,7 @@ export namespace CheckoutValid
case "knifeRad": case "knifeRad":
case "upCut": case "upCut":
case "downCut": case "downCut":
if (!isNaN(parseFloat(v)) && parseFloat(v) < 0) if (!isNaN(safeEval(v)) && safeEval(v) < 0)
return "数值不能小于0"; return "数值不能小于0";
default: default:
if (v === "" || isNaN(Number(v))) if (v === "" || isNaN(Number(v)))

@ -1,6 +1,7 @@
import { Object3D } from "three"; import { Object3D } from "three";
import { Entity } from "../DatabaseServices/Entity/Entity"; import { Entity } from "../DatabaseServices/Entity/Entity";
import { equaln } from "../Geometry/GeUtils"; import { equaln } from "../Geometry/GeUtils";
import { safeEval } from "./eval";
//四则运算表达式正则 //四则运算表达式正则
export const operationExpReg = /^(\d+([.]\d)?)+([+|\-|*|/](\d+([.]\d)?))*$/; export const operationExpReg = /^(\d+([.]\d)?)+([+|\-|*|/](\d+([.]\d)?))*$/;
@ -43,7 +44,7 @@ export function isLetter(s: string)
} }
export function isNum(s: string) export function isNum(s: string)
{ {
return !isNaN(parseFloat(s)); return !isNaN(safeEval(s));
} }
export function clamp(value: number, min: number, max: number) export function clamp(value: number, min: number, max: number)

@ -20,6 +20,7 @@ import { GetPointPrompt } from "./PromptOptions";
import { PromptPointResult, PromptStatus } from './PromptResult'; import { PromptPointResult, PromptStatus } from './PromptResult';
import { SnapMenuKW, SNAPMODE } from './ShowSnapMenu'; import { SnapMenuKW, SNAPMODE } from './ShowSnapMenu';
import { SnapServices } from './SnapServices'; import { SnapServices } from './SnapServices';
import { safeEval } from '../Common/eval';
/** /**
* ,Editor. * ,Editor.
@ -267,7 +268,7 @@ export class GetPointServices implements EditorService
let vlist = []; let vlist = [];
for (let str of strList) for (let str of strList)
{ {
let v = parseFloat(str); let v = safeEval(str);
if (!isNaN(v)) if (!isNaN(v))
vlist.push(v); vlist.push(v);
else else

@ -5,7 +5,7 @@ import { StoreageKeys } from "../Common/KeyEnum";
import { IWineRackOption } from "../UI/Store/WineRackInterface"; import { IWineRackOption } from "../UI/Store/WineRackInterface";
/** /**
* //TODO:保存用户的配置,先保存在sessionStroage * TODO:,sessionStroage
*/ */
export class UserConfig export class UserConfig
{ {

@ -10,6 +10,7 @@ import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore';
import { RightTabId } from '../RightPanel/RightPanel'; import { RightTabId } from '../RightPanel/RightPanel';
import { AppToaster, ToasterInput } from '../Toaster'; import { AppToaster, ToasterInput } from '../Toaster';
import { GetEntity } from '../../../Common/Utils'; import { GetEntity } from '../../../Common/Utils';
import { safeEval } from '../../../Common/eval';
type OptionType = BoardOption | DrillingOption; type OptionType = BoardOption | DrillingOption;
@ -308,7 +309,7 @@ export const BoardTypeComponent = observer((data: { opt?: BoardConfigOption, cla
} }
onChange={e => onChange={e =>
{ {
data.opt.type = parseFloat(e.target.value); data.opt.type = safeEval(e.target.value);
data.opt.name = e.target.options[e.target.selectedIndex].text; data.opt.name = e.target.options[e.target.selectedIndex].text;
}} }}
/> />

@ -1,7 +1,8 @@
import { Button, Checkbox, Classes, HTMLSelect } from '@blueprintjs/core';
import { observer } from 'mobx-react';
import * as React from 'react'; import * as React from 'react';
import { Checkbox, HTMLSelect, Classes, Button } from '@blueprintjs/core'; import { safeEval } from '../../../Common/eval';
import { IBoardFindOption } from '../../Store/BoardFindInterface'; import { IBoardFindOption } from '../../Store/BoardFindInterface';
import { observer } from 'mobx-react';
export interface IBoardProps export interface IBoardProps
{ {
@ -112,7 +113,7 @@ export class BoardFindSelectItem extends React.Component<IFindSelectItem, {}> {
onChange={e => onChange={e =>
{ {
if (typeof option[k] === "number") if (typeof option[k] === "number")
option[k] = parseFloat(e.target.value); option[k] = safeEval(e.target.value);
else else
option[k] = e.target.value; option[k] = e.target.value;
}} }}

@ -1,11 +1,12 @@
import React = require("react"); import React = require("react");
import { Board } from "../../../DatabaseServices/Entity/Board";
import { LookOverBoardInfosStore } from "../../Store/LookOverBoardInfosStore";
import { HTMLSelect, Icon } from "@blueprintjs/core"; import { HTMLSelect, Icon } from "@blueprintjs/core";
import { LinesType, ComposingType, FaceDirection } from "../../Store/BoardInterface";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { EBoardKeyList } from "../../../Common/BoardKeyList"; import { EBoardKeyList } from "../../../Common/BoardKeyList";
import { CheckObjectType } from "../../../Common/CheckoutVaildValue"; import { CheckObjectType } from "../../../Common/CheckoutVaildValue";
import { safeEval } from "../../../Common/eval";
import { Board } from "../../../DatabaseServices/Entity/Board";
import { ComposingType, FaceDirection, LinesType } from "../../Store/BoardInterface";
import { LookOverBoardInfosStore } from "../../Store/LookOverBoardInfosStore";
import { ToasterInput } from "../Toaster"; import { ToasterInput } from "../Toaster";
export interface IBoardInfoListProps export interface IBoardInfoListProps
@ -176,8 +177,8 @@ export class BoardInfoList extends React.Component<IBoardInfoListProps, IBoardIn
} }
onChange={e => onChange={e =>
{ {
this.setState({ [EBoardKeyList.Lines]: parseFloat(e.target.value) }); this.setState({ [EBoardKeyList.Lines]: safeEval(e.target.value) });
this.modifyDataMap(br, EBoardKeyList.Lines, parseFloat(e.target.value)); this.modifyDataMap(br, EBoardKeyList.Lines, safeEval(e.target.value));
}} }}
onClick={() => { store.selectedBr = br; store.findSameTypeBrDataKey = EBoardKeyList.Lines }} onClick={() => { store.selectedBr = br; store.findSameTypeBrDataKey = EBoardKeyList.Lines }}
/> />

@ -4,13 +4,13 @@ import * as React from 'react';
import { Math } from 'three'; import { Math } from 'three';
import { app } from '../../../ApplicationServices/Application'; import { app } from '../../../ApplicationServices/Application';
import { CheckObjectType, CheckoutValid } from '../../../Common/CheckoutVaildValue'; import { CheckObjectType, CheckoutValid } from '../../../Common/CheckoutVaildValue';
import { safeEval } from '../../../Common/eval';
import { FixedNotZero } from '../../../Common/Utils'; import { FixedNotZero } from '../../../Common/Utils';
import { Board } from '../../../DatabaseServices/Entity/Board'; import { Board } from '../../../DatabaseServices/Entity/Board';
import { commandMachine } from '../../../Editor/CommandMachine'; import { commandMachine } from '../../../Editor/CommandMachine';
import { CommandState } from '../../../Editor/CommandState';
import { userConfig } from '../../../Editor/UserConfig'; import { userConfig } from '../../../Editor/UserConfig';
import { equaln } from '../../../Geometry/GeUtils'; import { equaln } from '../../../Geometry/GeUtils';
import { BoardProcessOption, IGrooveOption, SingleBoardOption, DrillType } from '../../Store/BoardInterface'; import { BoardProcessOption, IGrooveOption, SingleBoardOption } from '../../Store/BoardInterface';
import { AppToaster } from '../Toaster'; import { AppToaster } from '../Toaster';
import { Notes } from './BoardCommon'; import { Notes } from './BoardCommon';
import { BoardConfigModal } from './BoardConfigModal'; import { BoardConfigModal } from './BoardConfigModal';
@ -127,10 +127,10 @@ export class BoardOptionModal extends React.Component<{ board: Board }, {}>
let newRoZ = Math.degToRad(this.m_ConfigOption.rotateZ); let newRoZ = Math.degToRad(this.m_ConfigOption.rotateZ);
//应用槽数据 //应用槽数据
board.KnifeRadius = parseFloat(this.m_GrooveOption.knifeRadius); board.KnifeRadius = safeEval(this.m_GrooveOption.knifeRadius);
board.GroovesAddLength = parseFloat(this.m_GrooveOption.grooveAddLength); board.GroovesAddLength = safeEval(this.m_GrooveOption.grooveAddLength);
board.GroovesAddWidth = parseFloat(this.m_GrooveOption.grooveAddWidth); board.GroovesAddWidth = safeEval(this.m_GrooveOption.grooveAddWidth);
board.GroovesAddDepth = parseFloat(this.m_GrooveOption.grooveAddDepth); board.GroovesAddDepth = safeEval(this.m_GrooveOption.grooveAddDepth);
if (!equaln(oldEuler.x, newRoX, 1e-2) if (!equaln(oldEuler.x, newRoX, 1e-2)
|| !equaln(oldEuler.y, newRoY, 1e-2) || !equaln(oldEuler.y, newRoY, 1e-2)

@ -1,20 +1,19 @@
import { Button, Classes, HTMLSelect, Checkbox } from '@blueprintjs/core'; import { Button, Checkbox, Classes, HTMLSelect } from '@blueprintjs/core';
import { IObservableValue, observable } from 'mobx'; import { IObservableValue, observable } from 'mobx';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import * as React from 'react'; import * as React from 'react';
import { app } from '../../../ApplicationServices/Application'; import { app } from '../../../ApplicationServices/Application';
import { EBoardKeyList } from '../../../Common/BoardKeyList';
import { CheckObjectType } from '../../../Common/CheckoutVaildValue'; import { CheckObjectType } from '../../../Common/CheckoutVaildValue';
import { safeEval } from '../../../Common/eval';
import { Board } from '../../../DatabaseServices/Entity/Board'; import { Board } from '../../../DatabaseServices/Entity/Board';
import { Circle } from '../../../DatabaseServices/Entity/Circle'; import { PromptStatus } from '../../../Editor/PromptResult';
import { userConfig } from '../../../Editor/UserConfig'; import { userConfig } from '../../../Editor/UserConfig';
import { BoardProcessOption, ComposingType, FaceDirection, LinesType, DrillType } from '../../Store/BoardInterface'; import { BoardProcessOption, ComposingType, FaceDirection, LinesType } from '../../Store/BoardInterface';
import { DrillingOption } from '../../Store/drillInterface'; import { DrillingOption } from '../../Store/drillInterface';
import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore'; import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore';
import { RightTabId } from '../RightPanel/RightPanel'; import { RightTabId } from '../RightPanel/RightPanel';
import { AppToaster } from '../Toaster';
import { DrillTypeSelectCom, Input5Or4Component, SetBoardDataBlock, SetBoardDataItem } from './BoardCommon'; import { DrillTypeSelectCom, Input5Or4Component, SetBoardDataBlock, SetBoardDataItem } from './BoardCommon';
import { PromptStatus } from '../../../Editor/PromptResult';
import { EBoardKeyList } from '../../../Common/BoardKeyList';
interface BoardProcessProps interface BoardProcessProps
{ {
@ -130,7 +129,7 @@ export class BoardProcessModal extends React.Component<BoardProcessProps, {}>{
} }
onChange={e => onChange={e =>
{ {
this.props.opt.lines = parseFloat(e.target.value); this.props.opt.lines = safeEval(e.target.value);
}} }}
/> />
</label> </label>
@ -152,7 +151,7 @@ export class BoardProcessModal extends React.Component<BoardProcessProps, {}>{
} }
onChange={e => onChange={e =>
{ {
this.props.opt.bigHoleDir = parseFloat(e.target.value); this.props.opt.bigHoleDir = safeEval(e.target.value);
}} }}
/> />
</label> </label>
@ -187,7 +186,7 @@ export class BoardProcessModal extends React.Component<BoardProcessProps, {}>{
} }
onChange={e => onChange={e =>
{ {
this.props.opt.composingFace = parseFloat(e.target.value); this.props.opt.composingFace = safeEval(e.target.value);
}} }}
/> />
</label> </label>

@ -7,6 +7,7 @@ import { DoorStore } from '../../../Store/DoorDrawerStore/DoorStore';
import { DoorPosType, HandleHorPos, HandleVePos } from '../../../Store/DoorInterface'; import { DoorPosType, HandleHorPos, HandleVePos } from '../../../Store/DoorInterface';
import { ToasterInput } from '../../Toaster'; import { ToasterInput } from '../../Toaster';
import { Input5Or4Component, SetBoardDataBlock, SetBoardDataItem } from '../BoardCommon'; import { Input5Or4Component, SetBoardDataBlock, SetBoardDataItem } from '../BoardCommon';
import { safeEval } from '../../../../Common/eval';
@observer @observer
export class DoorConfigModal extends React.Component<{ store?: DoorDrawerStore }> export class DoorConfigModal extends React.Component<{ store?: DoorDrawerStore }>
@ -16,7 +17,7 @@ export class DoorConfigModal extends React.Component<{ store?: DoorDrawerStore }
private handleChangeDoorPosType = (e) => private handleChangeDoorPosType = (e) =>
{ {
const store = this.props.store; const store = this.props.store;
store.m_Option.doorPosType = parseFloat(e.currentTarget.value) as DoorPosType; store.m_Option.doorPosType = safeEval(e.currentTarget.value) as DoorPosType;
if (store.m_Option.doorPosType === DoorPosType.In) if (store.m_Option.doorPosType === DoorPosType.In)
{ {
store.m_Option.offset = 18; store.m_Option.offset = 18;
@ -281,7 +282,7 @@ export class DoorConfigModal extends React.Component<{ store?: DoorDrawerStore }
selectedValue={store.m_Option.handleHorPos} selectedValue={store.m_Option.handleHorPos}
onChange={e => onChange={e =>
{ {
store.m_Option.handleHorPos = parseFloat(e.currentTarget.value) as HandleHorPos; store.m_Option.handleHorPos = safeEval(e.currentTarget.value) as HandleHorPos;
}} }}
> >
<Radio label="左距" value={HandleHorPos.Left} /> <Radio label="左距" value={HandleHorPos.Left} />
@ -303,7 +304,7 @@ export class DoorConfigModal extends React.Component<{ store?: DoorDrawerStore }
selectedValue={store.m_Option.handleVePos} selectedValue={store.m_Option.handleVePos}
onChange={e => onChange={e =>
{ {
store.m_Option.handleVePos = parseFloat(e.currentTarget.value) as HandleVePos; store.m_Option.handleVePos = safeEval(e.currentTarget.value) as HandleVePos;
}} }}
> >
<Radio label="上距" value={HandleVePos.Top} /> <Radio label="上距" value={HandleVePos.Top} />

@ -6,6 +6,7 @@ import { FixedNotZero } from '../../../../Common/Utils';
import { DoorDrawerStore } from '../../../Store/DoorDrawerStore/DoorDrawerStore'; import { DoorDrawerStore } from '../../../Store/DoorDrawerStore/DoorDrawerStore';
import { DoorStore, openDirTitle } from '../../../Store/DoorDrawerStore/DoorStore'; import { DoorStore, openDirTitle } from '../../../Store/DoorDrawerStore/DoorStore';
import { DoorOpenDir, IDoorInfo } from "../../../Store/DoorInterface"; import { DoorOpenDir, IDoorInfo } from "../../../Store/DoorInterface";
import { safeEval } from '../../../../Common/eval';
interface IDoorPreviewItemProps interface IDoorPreviewItemProps
{ {
@ -70,7 +71,7 @@ export class DoorPreviewLgItem extends React.Component<IDoorPreviewItemProps, {}
}} }}
onBlur={e => onBlur={e =>
{ {
let vaildVal = parseFloat(e.currentTarget.value); let vaildVal = safeEval(e.currentTarget.value);
if (!isNaN(vaildVal) && info.width !== vaildVal) if (!isNaN(vaildVal) && info.width !== vaildVal)
{ {
let oldWidth = info.width; let oldWidth = info.width;
@ -126,7 +127,7 @@ export class DoorPreviewLgItem extends React.Component<IDoorPreviewItemProps, {}
}} }}
onBlur={e => onBlur={e =>
{ {
let vaildVal = parseFloat(e.currentTarget.value); let vaildVal = safeEval(e.currentTarget.value);
if (!isNaN(vaildVal) && info.height !== vaildVal) if (!isNaN(vaildVal) && info.height !== vaildVal)
{ {
let oldHeight = info.height; let oldHeight = info.height;
@ -336,7 +337,7 @@ export class DoorPreviewItem extends React.Component<IDoorPreviewItemProps, {}>{
}} }}
onBlur={e => onBlur={e =>
{ {
let vaildVal = parseFloat(e.currentTarget.value); let vaildVal = safeEval(e.currentTarget.value);
if (!isNaN(vaildVal) && info.width !== vaildVal) if (!isNaN(vaildVal) && info.width !== vaildVal)
{ {
let oldWidth = info.width; let oldWidth = info.width;
@ -366,7 +367,7 @@ export class DoorPreviewItem extends React.Component<IDoorPreviewItemProps, {}>{
}} }}
onBlur={e => onBlur={e =>
{ {
let vaildVal = parseFloat(e.currentTarget.value); let vaildVal = safeEval(e.currentTarget.value);
if (!isNaN(vaildVal) && info.height !== vaildVal) if (!isNaN(vaildVal) && info.height !== vaildVal)
{ {
let oldHeight = info.height; let oldHeight = info.height;

@ -2,6 +2,7 @@ import { Button, Classes } from '@blueprintjs/core';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import * as React from 'react'; import * as React from 'react';
import { DrillStore } from '../../Store/DrillStore'; import { DrillStore } from '../../Store/DrillStore';
import { safeEval } from '../../../Common/eval';
@observer @observer
export class DrillRulesComponent extends React.Component<{ store?: DrillStore }, {}>{ export class DrillRulesComponent extends React.Component<{ store?: DrillStore }, {}>{
@ -18,8 +19,8 @@ export class DrillRulesComponent extends React.Component<{ store?: DrillStore },
onChange={e => onChange={e =>
{ {
store.UIOption["startDist"] = e.target.value; store.UIOption["startDist"] = e.target.value;
if (e.target.value !== "" && !isNaN(parseFloat(e.target.value))) if (e.target.value !== "" && !isNaN(safeEval(e.target.value)))
store.m_Option.startDist = parseFloat(e.target.value); store.m_Option.startDist = safeEval(e.target.value);
}} }}
/> />
<span> <span>
@ -31,8 +32,8 @@ export class DrillRulesComponent extends React.Component<{ store?: DrillStore },
onChange={e => onChange={e =>
{ {
store.UIOption["endDist"] = e.target.value; store.UIOption["endDist"] = e.target.value;
if (e.target.value !== "" && !isNaN(parseFloat(e.target.value))) if (e.target.value !== "" && !isNaN(safeEval(e.target.value)))
store.m_Option.endDist = parseFloat(e.target.value); store.m_Option.endDist = safeEval(e.target.value);
}} }}
/> />
<Button <Button

@ -16,6 +16,7 @@ import { DrillRulesComponent } from './DrillRules';
import { UserConfig } from './UserConfig'; import { UserConfig } from './UserConfig';
import { userConfigStore } from '../../Store/UserConfigStore'; import { userConfigStore } from '../../Store/UserConfigStore';
import { DrillTypeCom } from './DrillCommon'; import { DrillTypeCom } from './DrillCommon';
import { safeEval } from '../../../Common/eval';
@inject('store') @inject('store')
@observer @observer
@ -97,7 +98,7 @@ export class DrillModal extends React.Component<{ store?: DrillStore }, {}> {
title="数量" title="数量"
onChange={() => onChange={() =>
{ {
if (parseFloat(store.UIOption["count"]) <= 2 && store.UIOption["haveDist"]) if (safeEval(store.UIOption["count"]) <= 2 && store.UIOption["haveDist"])
{ {
store.m_Option.haveDist = false; store.m_Option.haveDist = false;
} }
@ -165,7 +166,7 @@ export class DrillModal extends React.Component<{ store?: DrillStore }, {}> {
disabled={ disabled={
store.m_Option.isForceDiv store.m_Option.isForceDiv
|| !store.m_Option.count || !store.m_Option.count
|| parseFloat(store.UIOption["count"]) <= 2 || safeEval(store.UIOption["count"]) <= 2
|| store.m_Option.spacing === SpacingType.EqualDist || store.m_Option.spacing === SpacingType.EqualDist
} }
checked={store.m_Option.haveDist} checked={store.m_Option.haveDist}
@ -182,7 +183,7 @@ export class DrillModal extends React.Component<{ store?: DrillStore }, {}> {
isDisabled={ isDisabled={
store.m_Option.isForceDiv store.m_Option.isForceDiv
|| store.UIOption["count"] === "" || store.UIOption["count"] === ""
|| parseFloat(store.UIOption["count"]) <= 2 || safeEval(store.UIOption["count"]) <= 2
} }
/> />
</div> </div>
@ -297,7 +298,7 @@ export class DrillModal extends React.Component<{ store?: DrillStore }, {}> {
onChange={e => onChange={e =>
{ {
store.UIOption["notGangDist"] = e.target.value; store.UIOption["notGangDist"] = e.target.value;
store.m_Option.notGangDist = parseFloat(e.target.value); store.m_Option.notGangDist = safeEval(e.target.value);
}} /> }} />
<span></span> <span></span>
</div> </div>

@ -15,6 +15,7 @@ import { AppToaster } from '../Toaster';
import { KeyBoard } from '../../../Common/KeyEnum'; import { KeyBoard } from '../../../Common/KeyEnum';
import { FixedNotZero } from '../../../Common/Utils'; import { FixedNotZero } from '../../../Common/Utils';
import { userConfig } from '../../../Editor/UserConfig'; import { userConfig } from '../../../Editor/UserConfig';
import { safeEval } from '../../../Common/eval';
@inject("store") @inject("store")
@observer @observer
@ -151,7 +152,7 @@ export class WineRackModal extends React.Component<{ store?: WineRackStore }, {}
let v = m_Option[k] % 0.5; let v = m_Option[k] % 0.5;
let v1 = FixedNotZero(m_Option[k] - v, 1) let v1 = FixedNotZero(m_Option[k] - v, 1)
UIOption[k] = v1; UIOption[k] = v1;
m_Option[k] = parseFloat(v1); m_Option[k] = safeEval(v1);
}} }}
/> />
) )
@ -174,7 +175,7 @@ export class WineRackModal extends React.Component<{ store?: WineRackStore }, {}
{ {
let v1 = FixedNotZero(m_Option[k], 2) let v1 = FixedNotZero(m_Option[k], 2)
UIOption[k] = v1; UIOption[k] = v1;
m_Option[k] = parseFloat(v1); m_Option[k] = safeEval(v1);
}} }}
/> />
) )

@ -10,6 +10,7 @@ import { ModalState } from "./Modal/ModalsManage";
import { UserConfig } from "./Board/UserConfig"; import { UserConfig } from "./Board/UserConfig";
import { BoardModalType } from "./Board/BoardModal"; import { BoardModalType } from "./Board/BoardModal";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { safeEval } from "../../Common/eval";
export interface IBoardBatchCurtailProps export interface IBoardBatchCurtailProps
{ {
@ -86,7 +87,7 @@ export class BoardBatchCurtailModal extends React.Component<IBoardBatchCurtailPr
private CheckFunc(optKey: string, value: string): string private CheckFunc(optKey: string, value: string): string
{ {
let store = this.props.store; let store = this.props.store;
let val = parseFloat(value); let val = safeEval(value);
if (isNaN(val)) return ""; if (isNaN(val)) return "";
store.m_Option[optKey] = val; store.m_Option[optKey] = val;

@ -8,6 +8,7 @@ import { ToasterInput, AppToaster } from "../Toaster";
import { KeyBoard } from "../../../Common/KeyEnum"; import { KeyBoard } from "../../../Common/KeyEnum";
import * as xaop from 'xaop'; import * as xaop from 'xaop';
import { isNumber } from "util"; import { isNumber } from "util";
import { safeEval } from "../../../Common/eval";
export interface ArrayModalProps export interface ArrayModalProps
{ {
@ -125,7 +126,7 @@ class RectanArray extends React.Component<{ store: ArrayStore }, {}>
else else
{ {
if (!isNumber(arOpt.arrayAngle)) if (!isNumber(arOpt.arrayAngle))
arOpt.arrayAngle = parseFloat(arOpt.arrayAngle); arOpt.arrayAngle = safeEval(arOpt.arrayAngle);
arOpt.arrayAngle = Math.round(arOpt.arrayAngle); arOpt.arrayAngle = Math.round(arOpt.arrayAngle);
if (Math.abs(arOpt.arrayAngle) === 360) if (Math.abs(arOpt.arrayAngle) === 360)
arOpt.arrayAngle = 0; arOpt.arrayAngle = 0;
@ -264,9 +265,9 @@ class CirArray extends React.Component<{ store: ArrayStore }, {}>
} }
else else
{ {
if (!isNumber(arOpt.itemTotal)) arOpt.itemTotal = Math.round(parseFloat(arOpt.itemTotal)); if (!isNumber(arOpt.itemTotal)) arOpt.itemTotal = Math.round(safeEval(arOpt.itemTotal));
if (!isNumber(arOpt.fillAngle)) arOpt.fillAngle = Math.round(parseFloat(arOpt.fillAngle)); if (!isNumber(arOpt.fillAngle)) arOpt.fillAngle = Math.round(safeEval(arOpt.fillAngle));
if (!isNumber(arOpt.betweenAngle)) arOpt.betweenAngle = Math.round(parseFloat(arOpt.betweenAngle)); if (!isNumber(arOpt.betweenAngle)) arOpt.betweenAngle = Math.round(safeEval(arOpt.betweenAngle));
// 方法一 计算项目间角 // 方法一 计算项目间角
if (arOpt.method === CirArrMethod.itemsAndAngle) if (arOpt.method === CirArrMethod.itemsAndAngle)
@ -355,7 +356,7 @@ class CirArray extends React.Component<{ store: ArrayStore }, {}>
onChange={e => onChange={e =>
{ {
let el = e.target; let el = e.target;
arOpt.method = parseFloat(el.value); arOpt.method = safeEval(el.value);
}} }}
value={arOpt.method} value={arOpt.method}
style={{ height: 22, fontSize: "15px", outline: "none" }} style={{ height: 22, fontSize: "15px", outline: "none" }}

@ -15,6 +15,7 @@ import { commandMachine } from '../../../Editor/CommandMachine';
import { RectAreaLight } from '../../../DatabaseServices/Lights/RectAreaLight'; import { RectAreaLight } from '../../../DatabaseServices/Lights/RectAreaLight';
import { FixedNotZero } from '../../../Common/Utils'; import { FixedNotZero } from '../../../Common/Utils';
import { HemisphereLight } from '../../../DatabaseServices/Lights/HemisphereLight'; import { HemisphereLight } from '../../../DatabaseServices/Lights/HemisphereLight';
import { safeEval } from '../../../Common/eval';
@ -232,7 +233,7 @@ export class LightDataCom extends React.Component<ILightComponentProps, {}> {
onChange={(e) => onChange={(e) =>
{ {
lightData[v] = e.target.value; lightData[v] = e.target.value;
let newVal = parseFloat(e.target.value); let newVal = safeEval(e.target.value);
if (!isNaN(newVal)) if (!isNaN(newVal))
{ {
let newPos = light.Position; let newPos = light.Position;

@ -3,6 +3,7 @@ import { observer } from 'mobx-react';
import * as React from 'react'; import * as React from 'react';
import { app } from '../../../../ApplicationServices/Application'; import { app } from '../../../../ApplicationServices/Application';
import { UserConfig } from '../../../../Editor/UserConfig'; import { UserConfig } from '../../../../Editor/UserConfig';
import { safeEval } from '../../../../Common/eval';
interface IConfigProps interface IConfigProps
{ {
@ -48,7 +49,7 @@ export class DrawConfigPanel extends React.Component<IConfigProps, {}> {
type="text" type="text"
className={Classes.INPUT} className={Classes.INPUT}
value={userConfig.maxHeight} value={userConfig.maxHeight}
onChange={e => userConfig.maxHeight = parseFloat(e.target.value)} onChange={e => userConfig.maxHeight = safeEval(e.target.value)}
/> />
</Label> </Label>
<Label className={Classes.INLINE}> <Label className={Classes.INLINE}>
@ -57,7 +58,7 @@ export class DrawConfigPanel extends React.Component<IConfigProps, {}> {
type="text" type="text"
className={Classes.INPUT} className={Classes.INPUT}
value={userConfig.maxWidth} value={userConfig.maxWidth}
onChange={e => userConfig.maxWidth = parseFloat(e.target.value)} onChange={e => userConfig.maxWidth = safeEval(e.target.value)}
/> />
</Label> </Label>
</Card> </Card>

@ -14,6 +14,7 @@ import { equaln } from "../../../Geometry/GeUtils";
import { observer, inject } from "mobx-react"; import { observer, inject } from "mobx-react";
import '../../../UI/Components/Modal/ModalStyle/Modal.less' import '../../../UI/Components/Modal/ModalStyle/Modal.less'
import { Button, Classes, H5 } from "@blueprintjs/core"; import { Button, Classes, H5 } from "@blueprintjs/core";
import { safeEval } from "../../../Common/eval";
@inject('board') @inject('board')
@ -43,12 +44,12 @@ export class BoardPropsComponent extends React.Component<{ board: Board }, {}>
let newConfig = { let newConfig = {
name: data.Name, name: data.Name,
type: data.BoardType, type: data.BoardType,
height: parseFloat(FixedNotZero(data.Height, 2)), height: safeEval(FixedNotZero(data.Height, 2)),
width: parseFloat(FixedNotZero(data.Width, 2)), width: safeEval(FixedNotZero(data.Width, 2)),
thickness: parseFloat(FixedNotZero(data.Thickness, 2)), thickness: safeEval(FixedNotZero(data.Thickness, 2)),
rotateX: parseFloat(FixedNotZero(Math.radToDeg(ro.x), 2)), rotateX: safeEval(FixedNotZero(Math.radToDeg(ro.x), 2)),
rotateY: parseFloat(FixedNotZero(Math.radToDeg(ro.y), 2)), rotateY: safeEval(FixedNotZero(Math.radToDeg(ro.y), 2)),
rotateZ: parseFloat(FixedNotZero(Math.radToDeg(ro.z), 2)), rotateZ: safeEval(FixedNotZero(Math.radToDeg(ro.z), 2)),
} }
if (this.m_ConfigOption) if (this.m_ConfigOption)
Object.assign(this.m_ConfigOption, newConfig); Object.assign(this.m_ConfigOption, newConfig);
@ -122,22 +123,22 @@ export class BoardPropsComponent extends React.Component<{ board: Board }, {}>
} }
board.Name = this.m_ConfigOption.name; board.Name = this.m_ConfigOption.name;
board.Height = parseFloat(this.m_ConfigOption.height.toString()); board.Height = safeEval(this.m_ConfigOption.height.toString());
board.Width = parseFloat(this.m_ConfigOption.width.toString()); board.Width = safeEval(this.m_ConfigOption.width.toString());
board.Thickness = parseFloat(this.m_ConfigOption.thickness.toString()); board.Thickness = safeEval(this.m_ConfigOption.thickness.toString());
board.BoardType = this.m_ConfigOption.type; board.BoardType = this.m_ConfigOption.type;
//应用旋转分量 //应用旋转分量
let oldEuler = board.Rotation; let oldEuler = board.Rotation;
let newRoX = Math.degToRad(parseFloat(this.m_ConfigOption.rotateX.toString())); let newRoX = Math.degToRad(safeEval(this.m_ConfigOption.rotateX.toString()));
let newRoY = Math.degToRad(parseFloat(this.m_ConfigOption.rotateY.toString())); let newRoY = Math.degToRad(safeEval(this.m_ConfigOption.rotateY.toString()));
let newRoZ = Math.degToRad(parseFloat(this.m_ConfigOption.rotateZ.toString())); let newRoZ = Math.degToRad(safeEval(this.m_ConfigOption.rotateZ.toString()));
//应用槽数据 //应用槽数据
board.KnifeRadius = parseFloat(this.m_GrooveOption.knifeRadius); board.KnifeRadius = safeEval(this.m_GrooveOption.knifeRadius);
board.GroovesAddLength = parseFloat(this.m_GrooveOption.grooveAddLength); board.GroovesAddLength = safeEval(this.m_GrooveOption.grooveAddLength);
board.GroovesAddWidth = parseFloat(this.m_GrooveOption.grooveAddWidth); board.GroovesAddWidth = safeEval(this.m_GrooveOption.grooveAddWidth);
board.GroovesAddDepth = parseFloat(this.m_GrooveOption.grooveAddDepth); board.GroovesAddDepth = safeEval(this.m_GrooveOption.grooveAddDepth);
if (!equaln(oldEuler.x, newRoX, 1e-2) if (!equaln(oldEuler.x, newRoX, 1e-2)
|| !equaln(oldEuler.y, newRoY, 1e-2) || !equaln(oldEuler.y, newRoY, 1e-2)

@ -6,6 +6,7 @@ import { FaceDirection } from '../../Store/BoardInterface';
import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore'; import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore';
import { UserConfig } from '../Board/UserConfig'; import { UserConfig } from '../Board/UserConfig';
import { BoardModalType } from '../Board/BoardModal'; import { BoardModalType } from '../Board/BoardModal';
import { safeEval } from '../../../Common/eval';
export interface IModelingItem export interface IModelingItem
{ {
@ -75,7 +76,7 @@ export class ModelingComponent extends React.Component<{ store?: RightPanelStore
onChange={e => onChange={e =>
{ {
item[k] = e.target.value; item[k] = e.target.value;
let v = parseFloat(e.target.value); let v = safeEval(e.target.value);
if (!isNaN(v)) if (!isNaN(v))
data[index][k] = v; data[index][k] = v;
}} }}

@ -8,6 +8,7 @@ import { FixedNotZero } from '../../../Common/Utils';
import { angle, equalv3 } from '../../../Geometry/GeUtils'; import { angle, equalv3 } from '../../../Geometry/GeUtils';
import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore'; import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore';
import { LightDataCom, LightModal } from '../Modal/LightModal'; import { LightDataCom, LightModal } from '../Modal/LightModal';
import { safeEval } from '../../../Common/eval';
enum ETime enum ETime
{ {
@ -80,12 +81,12 @@ export class ScenePanel extends React.Component<{ store?: RightPanelStore }, {}>
private handleChangeSunAngle = (num: number) => private handleChangeSunAngle = (num: number) =>
{ {
this.sunState.angle = num.toString(); this.sunState.angle = num.toString();
this.SetSunPostion(TMath.degToRad(num), TMath.degToRad(parseFloat(this.sunState.rotation))); this.SetSunPostion(TMath.degToRad(num), TMath.degToRad(safeEval(this.sunState.rotation)));
} }
private handleChangeSunRotation = (num: number) => private handleChangeSunRotation = (num: number) =>
{ {
this.sunState.rotation = num.toString(); this.sunState.rotation = num.toString();
this.SetSunPostion(TMath.degToRad(parseFloat(this.sunState.angle)), TMath.degToRad(num)); this.SetSunPostion(TMath.degToRad(safeEval(this.sunState.angle)), TMath.degToRad(num));
} }
componentWillMount() componentWillMount()
{ {

@ -3,6 +3,7 @@ import { inject, observer } from 'mobx-react';
import * as React from 'react'; import * as React from 'react';
import { ColorMaterial } from '../../../Common/ColorPalette'; import { ColorMaterial } from '../../../Common/ColorPalette';
import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore'; import { RightPanelStore } from '../../Store/RightPanelStore/RightPanelStore';
import { safeEval } from '../../../Common/eval';
@inject("store") @inject("store")
@ -47,7 +48,7 @@ export class SealingComponent extends React.Component<{ store?: RightPanelStore
}} }}
onBlur={e => onBlur={e =>
{ {
let val = parseFloat(e.target.value); let val = safeEval(e.target.value);
if (isNaN(val)) if (isNaN(val))
store.highSizes[i] = "0"; store.highSizes[i] = "0";
}} }}

@ -4,9 +4,9 @@ import { inject, observer } from 'mobx-react';
import * as React from 'react'; import * as React from 'react';
import { CURRENT_HOST } from '../../../Common/HostUrl'; import { CURRENT_HOST } from '../../../Common/HostUrl';
import { MouseKey } from '../../../Common/KeyEnum'; import { MouseKey } from '../../../Common/KeyEnum';
import { getFileSize } from '../../../Common/Utils';
import { FileServer } from '../../../DatabaseServices/FileServer'; import { FileServer } from '../../../DatabaseServices/FileServer';
import { TopPanelStore } from '../../Store/TopPanelStore'; import { TopPanelStore } from '../../Store/TopPanelStore';
import { getFileSize } from '../../../Common/Utils';
export interface IFileListProps export interface IFileListProps
{ {

@ -5,6 +5,7 @@ import { MaterialStore } from '../../Store/MaterialStore';
import { CURRENT_HOST } from '../../../Common/HostUrl'; import { CURRENT_HOST } from '../../../Common/HostUrl';
import { getFileSize } from '../../../Common/Utils'; import { getFileSize } from '../../../Common/Utils';
import { observable } from 'mobx'; import { observable } from 'mobx';
import { safeEval } from '../../../Common/eval';
export interface IImgListProps export interface IImgListProps
{ {
@ -108,7 +109,7 @@ export class ImgList extends React.Component<IImgListProps, {}> {
left: 5, left: 5,
bottom: 25, bottom: 25,
background: "#fff" background: "#fff"
}}>{getFileSize(parseFloat(pic.size))}</div> }}>{getFileSize(safeEval(pic.size))}</div>
} }
<p title={pic.name}>{pic.name}</p> <p title={pic.name}>{pic.name}</p>
{ {

@ -8,6 +8,7 @@ import { inflate, MaterialIn, MaterialInAndAppendAppData } from '../../../Common
import { MaterialUrls, CURRENT_HOST } from '../../../Common/HostUrl'; import { MaterialUrls, CURRENT_HOST } from '../../../Common/HostUrl';
import { observable } from 'mobx'; import { observable } from 'mobx';
import { getFileSize } from '../../../Common/Utils'; import { getFileSize } from '../../../Common/Utils';
import { safeEval } from '../../../Common/eval';
export interface IImgListProps export interface IImgListProps
{ {
@ -99,7 +100,7 @@ export class MaterialList extends React.Component<IImgListProps, {}> {
left: 5, left: 5,
bottom: 25, bottom: 25,
background: "#fff" background: "#fff"
}}>{getFileSize(parseFloat(mtl.size))}</div> }}>{getFileSize(safeEval(mtl.size))}</div>
} }
<p title={mtl.name}>{mtl.name}</p> <p title={mtl.name}>{mtl.name}</p>
<Popover <Popover

@ -2,6 +2,7 @@ import { observer } from 'mobx-react';
import * as React from 'react'; import * as React from 'react';
import { Label, Classes, Icon } from '@blueprintjs/core'; import { Label, Classes, Icon } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons'; import { IconNames } from '@blueprintjs/icons';
import { safeEval } from '../../../Common/eval';
interface IPaginationProps interface IPaginationProps
{ {
@ -70,7 +71,7 @@ export class Pagination extends React.Component<IPaginationProps, { startPage: n
const pages = Math.ceil(pageData.count / pageData.pageCount); const pages = Math.ceil(pageData.count / pageData.pageCount);
if (this._timeId) if (this._timeId)
clearTimeout(this._timeId); clearTimeout(this._timeId);
let currentPage = parseFloat(e.currentTarget.value); let currentPage = safeEval(e.currentTarget.value);
if (isNaN(currentPage) || currentPage > pages || currentPage < 1) return; if (isNaN(currentPage) || currentPage > pages || currentPage < 1) return;
this._timeId = setTimeout(() => this._timeId = setTimeout(() =>
{ {

@ -4,6 +4,7 @@ import { observer } from "mobx-react";
import { ISetItemOption } from "./Board/BoardCommon"; import { ISetItemOption } from "./Board/BoardCommon";
import { observable } from "mobx"; import { observable } from "mobx";
import { CheckoutValid, CheckObjectType } from "../../Common/CheckoutVaildValue"; import { CheckoutValid, CheckObjectType } from "../../Common/CheckoutVaildValue";
import { safeEval } from "../../Common/eval";
export const AppToaster = Toaster.create({ export const AppToaster = Toaster.create({
className: "recipe-toaster", className: "recipe-toaster",
position: Position.TOP, position: Position.TOP,
@ -53,7 +54,7 @@ export class ToasterInput extends React.Component<IToasterInputProps, {}>
if (this.hideErrorMsg && typeof this.props.option[this.props.optKey] === 'number') if (this.hideErrorMsg && typeof this.props.option[this.props.optKey] === 'number')
{ {
//值有效并且属性值为number //值有效并且属性值为number
this.props.option[this.props.optKey] = parseFloat(e.target.value); this.props.option[this.props.optKey] = safeEval(e.target.value);
} }
else if (this.hideErrorMsg) else if (this.hideErrorMsg)
{ {

@ -3,6 +3,7 @@ import { observer } from "mobx-react";
import * as React from "react"; import * as React from "react";
import { SketchPicker } from 'react-color'; import { SketchPicker } from 'react-color';
import { ClampToEdgeWrapping, MirroredRepeatWrapping, RepeatWrapping } from "three"; import { ClampToEdgeWrapping, MirroredRepeatWrapping, RepeatWrapping } from "three";
import { safeEval } from "../../Common/eval";
const LabelStyle: React.CSSProperties = { display: "flex", margin: 3 }; const LabelStyle: React.CSSProperties = { display: "flex", margin: 3 };
const PromptStyle: React.CSSProperties = { alignSelf: "center", width: 60 }; const PromptStyle: React.CSSProperties = { alignSelf: "center", width: 60 };
@ -51,7 +52,7 @@ export class Input extends React.Component<
value.set(e.target.value); value.set(e.target.value);
else else
{ {
let val = parseFloat(e.target.value); let val = safeEval(e.target.value);
if (!isNaN(val)) if (!isNaN(val))
value.set(val); value.set(val);
} }
@ -60,10 +61,10 @@ export class Input extends React.Component<
{ {
if (typeof value.get() === "number") if (typeof value.get() === "number")
{ {
if (isNaN(parseFloat(e.target.value))) if (isNaN(safeEval(e.target.value)))
{ {
this.inputEl.value = e.target.defaultValue; this.inputEl.value = e.target.defaultValue;
value.set(parseFloat(e.target.defaultValue)); value.set(safeEval(e.target.defaultValue));
} }
} }
else else

@ -5,6 +5,7 @@ import { ITextureEditorProps } from './TextureList';
import { observer, inject } from 'mobx-react'; import { observer, inject } from 'mobx-react';
import { TextureTableRecord } from '../../DatabaseServices/Texture'; import { TextureTableRecord } from '../../DatabaseServices/Texture';
import { MaterialStore } from '../Store/MaterialStore'; import { MaterialStore } from '../Store/MaterialStore';
import { safeEval } from '../../Common/eval';
interface IMaterialEditorContentProps interface IMaterialEditorContentProps
{ {
@ -47,7 +48,7 @@ export class MaterialEditorContent extends React.Component<IMaterialEditorConten
options={WrapSelects} options={WrapSelects}
onChange={e => onChange={e =>
{ {
let val = parseFloat(e.target.value); let val = safeEval(e.target.value);
texture.WrapS = val; texture.WrapS = val;
option.wrapS = val; option.wrapS = val;
}} }}
@ -60,7 +61,7 @@ export class MaterialEditorContent extends React.Component<IMaterialEditorConten
options={WrapSelects} options={WrapSelects}
onChange={e => onChange={e =>
{ {
let val = parseFloat(e.target.value); let val = safeEval(e.target.value);
texture.WrapT = val; texture.WrapT = val;
option.wrapT = val; option.wrapT = val;
}} }}
@ -76,7 +77,7 @@ export class MaterialEditorContent extends React.Component<IMaterialEditorConten
value={option.repeatX} value={option.repeatX}
onChange={e => onChange={e =>
{ {
let val = parseFloat(e.target.value); let val = safeEval(e.target.value);
option.repeatX = e.target.value; option.repeatX = e.target.value;
if (!isNaN(val)) if (!isNaN(val))
{ {
@ -92,7 +93,7 @@ export class MaterialEditorContent extends React.Component<IMaterialEditorConten
value={option.repeatY} value={option.repeatY}
onChange={e => onChange={e =>
{ {
let val = parseFloat(e.target.value); let val = safeEval(e.target.value);
option.repeatY = e.target.value option.repeatY = e.target.value
if (!isNaN(val)) if (!isNaN(val))
{ {

@ -1,10 +1,10 @@
import { observable, toJS } from "mobx"; import { observable, toJS } from "mobx";
import { Vector3 } from "three"; import { Vector3 } from "three";
import { IDoorAndDrawerConfigOption, IDrawerInfo, IDoorInfo } from "../DoorInterface"; import { CheckObjectType, CheckoutValid } from "../../../Common/CheckoutVaildValue";
import { BoardStore } from "../BoardStore";
import { FixedNotZero } from "../../../Common/Utils"; import { FixedNotZero } from "../../../Common/Utils";
import { IConfigOption } from "../../Components/Board/UserConfig"; import { IConfigOption } from "../../Components/Board/UserConfig";
import { CheckoutValid, CheckObjectType } from "../../../Common/CheckoutVaildValue"; import { BoardStore } from "../BoardStore";
import { IDoorAndDrawerConfigOption, IDrawerInfo } from "../DoorInterface";
export class DoorDrawerStore extends BoardStore export class DoorDrawerStore extends BoardStore

@ -1,7 +1,7 @@
import { DoorDrawerStore } from "./DoorDrawerStore";
import { HandleHorPos, HandleVePos, DoorPosType, IDoorConfigOption, IDoorInfo, DoorOpenDir } from "../DoorInterface";
import { observable } from "mobx"; import { observable } from "mobx";
import { FixedNotZero } from "../../../Common/Utils"; import { FixedNotZero } from "../../../Common/Utils";
import { DoorOpenDir, DoorPosType, HandleHorPos, HandleVePos, IDoorConfigOption, IDoorInfo } from "../DoorInterface";
import { DoorDrawerStore } from "./DoorDrawerStore";
export const openDirTitle = {}; //门板开门类型对应 export const openDirTitle = {}; //门板开门类型对应
openDirTitle[DoorOpenDir.Left] = "左"; openDirTitle[DoorOpenDir.Left] = "左";

@ -1,7 +1,7 @@
import { observable } from "mobx"; import { observable } from "mobx";
import { IDrawerInfo, IDrawerConfigOption, DoorPosType, HandleHorPos, HandleVePos } from "../DoorInterface";
import { DoorDrawerStore } from "./DoorDrawerStore";
import { FixedNotZero } from "../../../Common/Utils"; import { FixedNotZero } from "../../../Common/Utils";
import { DoorPosType, HandleHorPos, HandleVePos, IDrawerConfigOption, IDrawerInfo } from "../DoorInterface";
import { DoorDrawerStore } from "./DoorDrawerStore";
export class DrawerStore extends DoorDrawerStore export class DrawerStore extends DoorDrawerStore
{ {
title = "抽屉"; title = "抽屉";

@ -11,6 +11,7 @@ import { RightTabId } from "../../Components/RightPanel/RightPanel";
import { AppToaster } from "../../Components/Toaster"; import { AppToaster } from "../../Components/Toaster";
import { IHighSealedItem } from "../BoardInterface"; import { IHighSealedItem } from "../BoardInterface";
import { BoardEdgesEditor } from "./BoardEdgesEditor"; import { BoardEdgesEditor } from "./BoardEdgesEditor";
import { safeEval } from "../../../Common/eval";
export class SealingStore extends BoardEdgesEditor export class SealingStore extends BoardEdgesEditor
{ {
@ -90,7 +91,7 @@ export class SealingStore extends BoardEdgesEditor
else else
{ {
const size = this.highSizes[color - 1]; const size = this.highSizes[color - 1];
data.push({ size: parseFloat(size) }); data.push({ size: safeEval(size) });
} }
} }
this._dataMap.set(b, data); this._dataMap.set(b, data);

@ -1,9 +1,8 @@
import { autorun, observable } from "mobx"; import { autorun, observable } from "mobx";
import { MirroredRepeatWrapping, ClampToEdgeWrapping, Math } from "three"; import { ClampToEdgeWrapping, Math, MirroredRepeatWrapping } from "three";
import { FixedNotZero } from "../../Common/Utils";
import { ObjectId } from "../../DatabaseServices/ObjectId"; import { ObjectId } from "../../DatabaseServices/ObjectId";
import { TextureTableRecord } from "../../DatabaseServices/Texture"; import { TextureTableRecord } from "../../DatabaseServices/Texture";
import { FixedNotZero } from "../../Common/Utils";
export class TextureStore export class TextureStore
{ {

@ -1,9 +1,9 @@
import { autorun, observable } from "mobx"; import { autorun, observable } from "mobx";
import { FileUrls, SignUrl, CloudUrl } from "../../Common/HostUrl"; import { CloudUrl, FileUrls, SignUrl } from "../../Common/HostUrl";
import { StoreageKeys } from "../../Common/KeyEnum";
import { PostJson, RequestStatus } from "../../Common/Request"; import { PostJson, RequestStatus } from "../../Common/Request";
import { Singleton } from "../../Common/Singleton"; import { Singleton } from "../../Common/Singleton";
import { IFileInfo } from "../../DatabaseServices/FileServer"; import { IFileInfo } from "../../DatabaseServices/FileServer";
import { StoreageKeys } from "../../Common/KeyEnum";
export interface ICloudInfo export interface ICloudInfo
{ {

Loading…
Cancel
Save