fix climb vs conventional for 95% of cases with normal endmills

This commit is contained in:
Stewart Allen 2020-03-14 20:26:00 -04:00
commit 01485dc38e
4 changed files with 93 additions and 71 deletions

View file

@ -437,7 +437,7 @@ var gs_kiri_conf = exports;
camStockZ: 0, camStockZ: 0,
camStockOffset: true, camStockOffset: true,
outputClockwise: true, outputClockwise: false,
// --- shared FDM/Laser/CAM --- // --- shared FDM/Laser/CAM ---

View file

@ -832,7 +832,6 @@ var gs_kiri_cam = exports;
function slice(settings, widget, onupdate, ondone) { function slice(settings, widget, onupdate, ondone) {
let conf = settings, let conf = settings,
proc = conf.process, proc = conf.process,
outp = conf.process,
sliceAll = widget.slices = [], sliceAll = widget.slices = [],
unitsName = settings.controller.units, unitsName = settings.controller.units,
units = unitsName === 'in' ? 25.4 : 1, units = unitsName === 'in' ? 25.4 : 1,
@ -847,9 +846,9 @@ var gs_kiri_cam = exports;
procFacing = proc.roughingOn && proc.camZTopOffset, procFacing = proc.roughingOn && proc.camZTopOffset,
procDrill = proc.drillingOn && proc.drillDown && proc.drillDownSpeed, procDrill = proc.drillingOn && proc.drillDown && proc.drillDownSpeed,
sliceDepth = MAX(0.1, MIN(proc.roughingDown, proc.finishingDown) / 3) * units, sliceDepth = MAX(0.1, MIN(proc.roughingDown, proc.finishingDown) / 3) * units,
// pocketOnly = outp.camPocketOnly, // pocketOnly = proc.camPocketOnly,
pocketOnlyRough = outp.camPocketOnlyRough, pocketOnlyRough = proc.camPocketOnlyRough,
pocketOnlyFinish = outp.camPocketOnlyFinish, pocketOnlyFinish = proc.camPocketOnlyFinish,
// addTabs = proc.camTabsOn && !pocketOnly, // addTabs = proc.camTabsOn && !pocketOnly,
addTabsRough = procRough && proc.camTabsOn && !pocketOnlyRough, addTabsRough = procRough && proc.camTabsOn && !pocketOnlyRough,
addTabsFinish = procFinish && proc.camTabsOn && !pocketOnlyFinish, addTabsFinish = procFinish && proc.camTabsOn && !pocketOnlyFinish,
@ -857,7 +856,7 @@ var gs_kiri_cam = exports;
tabHeight = proc.camTabsHeight * units, tabHeight = proc.camTabsHeight * units,
mesh = widget.mesh, mesh = widget.mesh,
bounds = widget.getBoundingBox(), bounds = widget.getBoundingBox(),
zMin = MAX(bounds.min.z, outp.camZBottom) * units, zMin = MAX(bounds.min.z, proc.camZBottom) * units,
shellRough, shellRough,
shellFinish, shellFinish,
facePolys; facePolys;
@ -952,7 +951,7 @@ var gs_kiri_cam = exports;
// hollow area from top of stock to top of part // hollow area from top of stock to top of part
if (procFacing) { if (procFacing) {
let ztop = bounds.max.z, let ztop = bounds.max.z,
zpos = ztop + (outp.camZTopOffset * units), zpos = ztop + (proc.camZTopOffset * units),
zstep = proc.roughingDown * units; zstep = proc.roughingDown * units;
while (zpos >= ztop) { while (zpos >= ztop) {
@ -1029,7 +1028,7 @@ var gs_kiri_cam = exports;
} }
// horizontal slices for rough/finish // horizontal slices for rough/finish
doSlicing(widget, {height: sliceDepth, cam:true, zmin:outp.camZBottom}, camSlicesDone, function(update) { doSlicing(widget, {height: sliceDepth, cam:true, zmin:proc.camZBottom}, camSlicesDone, function(update) {
onupdate(0.0 + update * 0.25, "slicing"); onupdate(0.0 + update * 0.25, "slicing");
}); });
@ -1370,7 +1369,7 @@ var gs_kiri_cam = exports;
} }
}); });
// set winding specified in output // set winding specified in output
POLY.setWinding(polys, process.outputClockwise, true); POLY.setWinding(polys, process.outputClockwise, false);
printPoint = poly2polyEmit(polys, printPoint, function(poly, index, count) { printPoint = poly2polyEmit(polys, printPoint, function(poly, index, count) {
poly.forEachPoint(function(point, pidx, points, offset) { poly.forEachPoint(function(point, pidx, points, offset) {
camOut(point.clone(), offset !== 0); camOut(point.clone(), offset !== 0);
@ -1381,6 +1380,7 @@ var gs_kiri_cam = exports;
break; break;
case modes.ROUGH: case modes.ROUGH:
case modes.FINISH: case modes.FINISH:
let dir = process.outputClockwise;
if (slice.camMode === modes.ROUGH) { if (slice.camMode === modes.ROUGH) {
setTool(process.roughingTool, process.roughingSpeed, process.roughingPlunge); setTool(process.roughingTool, process.roughingSpeed, process.roughingPlunge);
spindle = Math.min(spindleMax, process.roughingSpindle); spindle = Math.min(spindleMax, process.roughingSpindle);
@ -1389,19 +1389,26 @@ var gs_kiri_cam = exports;
setTool(process.finishingTool, process.finishingSpeed, process.finishingPlunge); setTool(process.finishingTool, process.finishingSpeed, process.finishingPlunge);
spindle = Math.min(spindleMax, process.finishingSpindle); spindle = Math.min(spindleMax, process.finishingSpindle);
depthData.finishDiam = toolDiam; depthData.finishDiam = toolDiam;
if (!process.camPocketOnlyFinish) {
dir = !dir;
}
} }
// todo find closest next trace/trace-point // todo find closest next trace/trace-point
slice.tops.forEach(function(top) { slice.tops.forEach(function(top) {
if (!top.poly) return; if (!top.poly) return;
if (!top.traces) return; if (!top.traces) return;
let polys = []; let polys = [], t = [], c = [];
POLY.flatten(top.traces, top.inner || []).forEach(function (poly) { POLY.flatten(top.traces, top.inner || []).forEach(function (poly) {
let child = poly.parent;
if (depthFirst) poly = poly.clone(true); if (depthFirst) poly = poly.clone(true);
if (child) c.push(poly); else t.push(poly);
poly.layer = depthData.layer; poly.layer = depthData.layer;
polys.push(poly); polys.push(poly);
}); });
// set winding specified in output // set cut direction on outer polys
POLY.setWinding(polys, process.outputClockwise, true); POLY.setWinding(t, dir);
// set cut direction on inner polys
POLY.setWinding(c, !dir);
if (depthFirst) { if (depthFirst) {
(slice.camMode === modes.ROUGH ? depthData.rough : depthData.finish).append(polys); (slice.camMode === modes.ROUGH ? depthData.rough : depthData.finish).append(polys);
} else { } else {

View file

@ -401,7 +401,7 @@ var gs_kiri_init = exports;
camZClearance: UC.newInput("z clearance", {title:"travel offset from z top\nin workspace units", convert:UC.toFloat, bound:UC.bound(0.01,100), modes:CAM}), camZClearance: UC.newInput("z clearance", {title:"travel offset from z top\nin workspace units", convert:UC.toFloat, bound:UC.bound(0.01,100), modes:CAM}),
// camPocketOnly: UC.newBoolean("pocket only", onBooleanClick, {title:"constrain to\npart boundaries", modes:CAM}), // camPocketOnly: UC.newBoolean("pocket only", onBooleanClick, {title:"constrain to\npart boundaries", modes:CAM}),
camDepthFirst: UC.newBoolean("depth first", onBooleanClick, {title:"optimize pocket cuts\nwith depth priority", modes:CAM}), camDepthFirst: UC.newBoolean("depth first", onBooleanClick, {title:"optimize pocket cuts\nwith depth priority", modes:CAM}),
outputClockwise: UC.newBoolean("clockwise", onBooleanClick, {title:"waterline milling direction", modes:CAM}), outputClockwise: UC.newBoolean("conventional", onBooleanClick, {title:"milling direction\nuncheck for 'climb'", modes:CAM}),
camStock: UC.newGroup("stock", null, {modes:CAM}), camStock: UC.newGroup("stock", null, {modes:CAM}),
camStockX: UC.newInput("width", {title:"width (x) in workspace units\n0 defaults to part size", convert:UC.toFloat, bound:UC.bound(0,9999), modes:CAM}), camStockX: UC.newInput("width", {title:"width (x) in workspace units\n0 defaults to part size", convert:UC.toFloat, bound:UC.bound(0,9999), modes:CAM}),

View file

@ -2,17 +2,17 @@
"use strict"; "use strict";
var gs_kiri_print = exports; let gs_kiri_print = exports;
(function() { (function() {
if (!self.kiri) self.kiri = {}; if (!self.kiri) self.kiri = {};
var KIRI = self.kiri, let KIRI = self.kiri,
DRIVERS = KIRI.driver, DRIVERS = KIRI.driver,
LASER = DRIVERS.LASER,
CAM = DRIVERS.CAM, CAM = DRIVERS.CAM,
FDM = DRIVERS.FDM, FDM = DRIVERS.FDM,
LASER = DRIVERS.LASER,
BASE = self.base, BASE = self.base,
UTIL = BASE.util, UTIL = BASE.util,
DBUG = BASE.debug, DBUG = BASE.debug,
@ -92,7 +92,7 @@ var gs_kiri_print = exports;
}; };
PRO.parseGCode = function(gcode, offset) { PRO.parseGCode = function(gcode, offset) {
var lines = gcode let lines = gcode
.toUpperCase() .toUpperCase()
.replace("X", " X") .replace("X", " X")
.replace("Y", " Y") .replace("Y", " Y")
@ -102,7 +102,7 @@ var gs_kiri_print = exports;
.replace(" ", " ") .replace(" ", " ")
.split("\n"); .split("\n");
var scope = this, let scope = this,
output = scope.output = [], output = scope.output = [],
bounds = scope.bounds = { bounds = scope.bounds = {
max: { x:-Infinity, y:-Infinity, z:-Infinity}, max: { x:-Infinity, y:-Infinity, z:-Infinity},
@ -185,7 +185,7 @@ var gs_kiri_print = exports;
}; };
PRO.setup = function(remote, onupdate, ondone) { PRO.setup = function(remote, onupdate, ondone) {
var scope = this, let scope = this,
settings = scope.settings, settings = scope.settings,
mode = settings.mode; mode = settings.mode;
@ -207,7 +207,7 @@ var gs_kiri_print = exports;
} else { } else {
// executed from kiri-worker.js // executed from kiri-worker.js
var driver = KIRI.driver[mode]; let driver = KIRI.driver[mode];
if (driver) driver.printSetup(scope, onupdate); if (driver) driver.printSetup(scope, onupdate);
else console.log({missing_print_driver: mode}); else console.log({missing_print_driver: mode});
ondone(); ondone();
@ -216,7 +216,7 @@ var gs_kiri_print = exports;
}; };
PRO.exportGCode = function(remote, ondone, online) { PRO.exportGCode = function(remote, ondone, online) {
var scope = this, let scope = this,
settings = scope.settings, settings = scope.settings,
mode = settings.mode; mode = settings.mode;
@ -239,7 +239,7 @@ var gs_kiri_print = exports;
} else { } else {
// executed from kiri-worker.js // executed from kiri-worker.js
var driver = KIRI.driver[mode]; let driver = KIRI.driver[mode];
if (driver && driver.printExport) { if (driver && driver.printExport) {
ondone(driver.printExport(scope, online)); ondone(driver.printExport(scope, online));
} else { } else {
@ -263,7 +263,7 @@ var gs_kiri_print = exports;
}; };
PRO.encodeOutput = function() { PRO.encodeOutput = function() {
var newout = [], newlayer; let newout = [], newlayer;
this.output.forEach(function(layerout) { this.output.forEach(function(layerout) {
newlayer = []; newlayer = [];
@ -286,7 +286,7 @@ var gs_kiri_print = exports;
}; };
PRO.render = function() { PRO.render = function() {
var scope = this, let scope = this,
mode = scope.settings.mode; mode = scope.settings.mode;
switch (mode) { switch (mode) {
@ -306,13 +306,13 @@ var gs_kiri_print = exports;
// hsv values all = 0 to 1 // hsv values all = 0 to 1
function hsv2rgb(hsv) { function hsv2rgb(hsv) {
var seg = Math.floor(hsv.h * 6); let seg = Math.floor(hsv.h * 6);
var rem = hsv.h - (seg * (1/6)); let rem = hsv.h - (seg * (1/6));
var out = {}; let out = {};
var p = hsv.v * (1.0 - (hsv.s) ); let p = hsv.v * (1.0 - (hsv.s) );
var q = hsv.v * (1.0 - (hsv.s * rem) ); let q = hsv.v * (1.0 - (hsv.s * rem) );
var t = hsv.v * (1.0 - (hsv.s * (1.0 - rem))); let t = hsv.v * (1.0 - (hsv.s * (1.0 - rem)));
switch (seg) { switch (seg) {
case 0: case 0:
@ -351,31 +351,46 @@ var gs_kiri_print = exports;
} }
PRO.renderMoves = function(showMoves, moveColor) { PRO.renderMoves = function(showMoves, moveColor) {
var scope = this, last, emits, moves; let debug = KIRI.api.const.LOCAL;
let scope = this, last, emits, moves;
// render layered output // render layered output
scope.lines = 0; scope.lines = 0;
scope.output.forEach(function(layerout) { scope.output.forEach(function(layerout) {
var move = [], print = {}, z; let move = [], print = {}, z;
layerout.forEach(function(out, index) { layerout.forEach(function(out, index) {
let point = out.point;
if (last) { if (last) {
if (UTIL.distSq(last, out.point) < 0.001 && out.point.z === last.z) { if (UTIL.distSq(last, point) < 0.001 && point.z === last.z) {
return; return;
} }
if (out.emit > 0) { if (out.emit > 0) {
var spd = out.speed || 4000; let spd = out.speed || 4000;
var arr = print[spd] || []; let arr = print[spd] || [];
print[spd] = arr; print[spd] = arr;
arr.push(last); arr.push(last);
arr.push(out.point); arr.push(point);
if (debug && showMoves) {
let rs = BASE.newSlope(
{x: point.x, y: point.y},
{x: last.x, y: last.y}
);
let ao1 = BASE.newSlopeFromAngle(rs.angle + 25);
let ao2 = BASE.newSlopeFromAngle(rs.angle - 25);
let sp = BASE.newPoint(point.x, point.y, point.z);
move.push(sp);
move.push(sp.projectOnSlope(ao1, 0.5));
move.push(sp);
move.push(sp.projectOnSlope(ao2, 0.5));
}
} else { } else {
move.push(last); move.push(last);
move.push(out.point); move.push(point);
} }
} else { } else {
if (out.emit) DBUG.log("first point is emit"); if (out.emit) DBUG.log("first point is emit");
z = out.point.z; z = point.z;
} }
last = out.point; last = point;
}); });
emits = KIRI.newLayer(scope.group); emits = KIRI.newLayer(scope.group);
scope.printView.push(emits); scope.printView.push(emits);
@ -385,9 +400,9 @@ var gs_kiri_print = exports;
scope.movesView.push(moves); scope.movesView.push(moves);
moves.render(); moves.render();
} }
for (var speed in print) { for (let speed in print) {
var sint = Math.min(6000, parseInt(speed)); let sint = Math.min(6000, parseInt(speed));
var rgb = hsv2rgb({h:sint/6000, s:1, v:0.6}); let rgb = hsv2rgb({h:sint/6000, s:1, v:0.6});
emits.lines(print[speed], emits.lines(print[speed],
((rgb.r * 0xff) << 16) | ((rgb.r * 0xff) << 16) |
((rgb.g * 0xff) << 8) | ((rgb.g * 0xff) << 8) |
@ -448,10 +463,10 @@ var gs_kiri_print = exports;
} }
function segmentOutput(output, p1, p2, s1, s2, steps, mult) { function segmentOutput(output, p1, p2, s1, s2, steps, mult) {
var sd = (s2 - s1) / (steps + 1); let sd = (s2 - s1) / (steps + 1);
var dd = p1.distTo2D(p2) / steps; let dd = p1.distTo2D(p2) / steps;
var dist = dd; let dist = dd;
var spd = s1; let spd = s1;
while (steps-- > 0) { while (steps-- > 0) {
spd += sd; spd += sd;
p1 = p1.offsetPointTo(p2, dd); p1 = p1.offsetPointTo(p2, dd);
@ -469,10 +484,10 @@ var gs_kiri_print = exports;
* @param {Function} [onfirst] optional fn to call on first point * @param {Function} [onfirst] optional fn to call on first point
* @return {Point} last output point * @return {Point} last output point
*/ */
PRO.polyPrintPath = function(poly, startPoint, output, options) { PRO.polyPrintPath = function(poly, startPoint, output, opt) {
poly.setClockwise(); poly.setClockwise();
var options = options || {}, let options = opt || {},
process = this.settings.process, process = this.settings.process,
shortDist = process.outputShortDistance, shortDist = process.outputShortDistance,
shellMult = pref(options.extrude, process.outputShellMult), shellMult = pref(options.extrude, process.outputShellMult),
@ -500,11 +515,11 @@ var gs_kiri_print = exports;
addOutput(output, point, 0, moveSpeed); addOutput(output, point, 0, moveSpeed);
first = false; first = false;
} else { } else {
var seglen = last.distTo2D(point); let seglen = last.distTo2D(point);
if (coastDist && shellMult && perimeter - seglen <= coastDist) { if (coastDist && shellMult && perimeter - seglen <= coastDist) {
var delta = perimeter - coastDist; let delta = perimeter - coastDist;
var offset = seglen - delta; let offset = seglen - delta;
var offPoint = last.offsetPointFrom(point, offset) let offPoint = last.offsetPointFrom(point, offset)
addOutput(output, offPoint, shellMult, printSpeed); addOutput(output, offPoint, shellMult, printSpeed);
shellMult = 0; shellMult = 0;
} }
@ -528,7 +543,7 @@ var gs_kiri_print = exports;
* @return {Point} last output point * @return {Point} last output point
*/ */
PRO.slicePrintPath = function(slice, startPoint, offset, output, options) { PRO.slicePrintPath = function(slice, startPoint, offset, output, options) {
var i, let i,
opt = options || {}, opt = options || {},
preout = [], preout = [],
scope = this, scope = this,
@ -567,7 +582,7 @@ var gs_kiri_print = exports;
} }
function intersectsTop(p1, p2) { function intersectsTop(p1, p2) {
var int = false; let int = false;
POLY.flatten(slice.gatherTopPolys([])).forEach(function(poly) { POLY.flatten(slice.gatherTopPolys([])).forEach(function(poly) {
if (!int) poly.forEachSegment(function(s1, s2) { if (!int) poly.forEachSegment(function(s1, s2) {
if (UTIL.intersect(p1,p2,s1,s2,BASE.key.SEGINT)) { if (UTIL.intersect(p1,p2,s1,s2,BASE.key.SEGINT)) {
@ -586,7 +601,7 @@ var gs_kiri_print = exports;
outputTraces(next, extrude); outputTraces(next, extrude);
}, null); }, null);
} else { } else {
var finishShell = poly.depth === 0 && !firstLayer; let finishShell = poly.depth === 0 && !firstLayer;
startPoint = scope.polyPrintPath(poly, startPoint, preout, { startPoint = scope.polyPrintPath(poly, startPoint, preout, {
rate: finishShell ? finishSpeed : printSpeed, rate: finishShell ? finishSpeed : printSpeed,
accel: finishShell, accel: finishShell,
@ -607,12 +622,12 @@ var gs_kiri_print = exports;
*/ */
function outputSparse(polys, extrude, speed) { function outputSparse(polys, extrude, speed) {
if (!polys) return; if (!polys) return;
var proxy = polys.map(function(poly) { let proxy = polys.map(function(poly) {
return {poly: poly, first: poly.first(), last: poly.last()}; return {poly: poly, first: poly.first(), last: poly.last()};
}); });
var lp = startPoint; let lp = startPoint;
startPoint = tip2tipEmit(proxy, startPoint, function(el, point, count) { startPoint = tip2tipEmit(proxy, startPoint, function(el, point, count) {
var poly = el.poly; let poly = el.poly;
if (poly.last() === point) { if (poly.last() === point) {
poly.reverse(); poly.reverse();
} }
@ -629,7 +644,7 @@ var gs_kiri_print = exports;
} }
function outputFills(lines, options) { function outputFills(lines, options) {
var p, p1, p2, dist, len, found, group, mindist, t1, t2, let p, p1, p2, dist, len, found, group, mindist, t1, t2,
marked = 0, marked = 0,
start = 0, start = 0,
skip = false, skip = false,
@ -744,7 +759,7 @@ var gs_kiri_print = exports;
return fn(array[0]); return fn(array[0]);
} }
array = array.slice(); array = array.slice();
var closest, find, next, order, poly, lastDepth = 0; let closest, find, next, order, poly, lastDepth = 0;
for (;;) { for (;;) {
order = []; order = [];
closest = null; closest = null;
@ -771,8 +786,8 @@ var gs_kiri_print = exports;
} }
} }
var all = [].appendAll(slice.supports || []).appendAll(slice.tops || []); let all = [].appendAll(slice.supports || []).appendAll(slice.tops || []);
var lastTop = null; let lastTop = null;
outputOrderClosest(all || [], function(next) { outputOrderClosest(all || [], function(next) {
if (next instanceof Polygon) { if (next instanceof Polygon) {
// support polygon // support polygon
@ -784,7 +799,7 @@ var gs_kiri_print = exports;
} }
} else { } else {
// top object // top object
var bounds = POLY.flatten(next.gatherOuter([])); let bounds = POLY.flatten(next.gatherOuter([]));
let dir = -1; // 1 == inside out, -1 == outside-in let dir = -1; // 1 == inside out, -1 == outside-in
@ -853,7 +868,7 @@ var gs_kiri_print = exports;
* the next closest endpoint. * the next closest endpoint.
*/ */
function tip2tipEmit(array, startPoint, emitter) { function tip2tipEmit(array, startPoint, emitter) {
var mindist, dist, found, count = 0; let mindist, dist, found, count = 0;
for (;;) { for (;;) {
found = null; found = null;
mindist = Infinity; mindist = Infinity;
@ -889,7 +904,7 @@ var gs_kiri_print = exports;
* depth in determining distance * depth in determining distance
*/ */
function poly2polyEmit(array, startPoint, emitter, mark) { function poly2polyEmit(array, startPoint, emitter, mark) {
var mindist, dist, found, count = 0, marker = mark || 'delete'; let mindist, dist, found, count = 0, marker = mark || 'delete';
for (;;) { for (;;) {
found = null; found = null;
mindist = Infinity; mindist = Infinity;
@ -943,7 +958,7 @@ var gs_kiri_print = exports;
* used for CAM depth first layer output * used for CAM depth first layer output
*/ */
function poly2polyDepthFirstEmit(array, startPoint, emitter, offset) { function poly2polyDepthFirstEmit(array, startPoint, emitter, offset) {
var layers = [], let layers = [],
pools; pools;
array.forEach(function(layerPolys, layerIndex) { array.forEach(function(layerPolys, layerIndex) {
@ -968,7 +983,7 @@ var gs_kiri_print = exports;
poly.poolsDown = []; poly.poolsDown = [];
} else { } else {
// otherwise walk up the parent tree to find a pool to join // otherwise walk up the parent tree to find a pool to join
var search = poly.parent; let search = poly.parent;
// walk up until pool found // walk up until pool found
while (search && !search.pool) { while (search && !search.pool) {
search = search.parent; search = search.parent;
@ -993,7 +1008,7 @@ var gs_kiri_print = exports;
if (layerIndex > 0) if (layerIndex > 0)
pools.forEach(function(pool) { pools.forEach(function(pool) {
for (var i=0; i<poolsAbove.length; i++) { for (let i=0; i<poolsAbove.length; i++) {
const above = poolsAbove[i]; const above = poolsAbove[i];
// can only add open polys to open polys // can only add open polys to open polys
if (above.isOpen() && pool.isClosed()) { if (above.isOpen() && pool.isClosed()) {
@ -1059,7 +1074,7 @@ var gs_kiri_print = exports;
} }
function polygonMinOffset(poly1, poly2, offset) { function polygonMinOffset(poly1, poly2, offset) {
var mindist = Infinity; let mindist = Infinity;
poly1.forEachPoint(function(p) { poly1.forEachPoint(function(p) {
const nextdist = p.distToPolySegments(poly2, offset); const nextdist = p.distToPolySegments(poly2, offset);
mindist = Math.min(mindist, nextdist); mindist = Math.min(mindist, nextdist);
@ -1082,7 +1097,7 @@ var gs_kiri_print = exports;
} }
function constOp(tok, consts, opch, op) { function constOp(tok, consts, opch, op) {
var pos, v1, v2; let pos, v1, v2;
if ((pos = tok.indexOf(opch)) > 0) { if ((pos = tok.indexOf(opch)) > 0) {
v1 = consts[tok.substring(0,pos)] || 0; v1 = consts[tok.substring(0,pos)] || 0;
v2 = parseInt(tok.substring(pos+1)) || 0; v2 = parseInt(tok.substring(pos+1)) || 0;
@ -1093,7 +1108,7 @@ var gs_kiri_print = exports;
} }
function constReplace(str, consts, start) { function constReplace(str, consts, start) {
var cs = str.indexOf("{", start || 0), let cs = str.indexOf("{", start || 0),
ce = str.indexOf("}", cs), ce = str.indexOf("}", cs),
tok, nutok, nustr; tok, nutok, nustr;
if (cs >=0 && ce > cs) { if (cs >=0 && ce > cs) {