@xom11/whiteboard 0.29.0 → 0.31.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.
- package/dist/ai.d.mts +259 -33
- package/dist/ai.d.ts +259 -33
- package/dist/ai.js +5424 -470
- package/dist/ai.js.map +1 -1
- package/dist/ai.mjs +4971 -351
- package/dist/ai.mjs.map +1 -1
- package/dist/catalog.json +5 -5
- package/dist/{chunk-V3YJ6JFL.mjs → chunk-44JY2AKC.mjs} +3 -3
- package/dist/{chunk-V3YJ6JFL.mjs.map → chunk-44JY2AKC.mjs.map} +1 -1
- package/dist/{chunk-GEC2D2EQ.mjs → chunk-BMYC2ILT.mjs} +4 -4
- package/dist/{chunk-GEC2D2EQ.mjs.map → chunk-BMYC2ILT.mjs.map} +1 -1
- package/dist/{chunk-PPKHCRRE.mjs → chunk-C76SOFXF.mjs} +3 -3
- package/dist/{chunk-PPKHCRRE.mjs.map → chunk-C76SOFXF.mjs.map} +1 -1
- package/dist/{chunk-IHUFOV7L.mjs → chunk-CH6SFONH.mjs} +15 -3
- package/dist/chunk-CH6SFONH.mjs.map +1 -0
- package/dist/{chunk-E6EDOPGT.mjs → chunk-DWIEVCGK.mjs} +254 -16
- package/dist/chunk-DWIEVCGK.mjs.map +1 -0
- package/dist/{chunk-SZDAS7LK.mjs → chunk-IE2GGHNF.mjs} +131 -81
- package/dist/chunk-IE2GGHNF.mjs.map +1 -0
- package/dist/{chunk-ZTQBUKLJ.mjs → chunk-JJ4FPCBE.mjs} +142 -22
- package/dist/chunk-JJ4FPCBE.mjs.map +1 -0
- package/dist/{chunk-QRUAEXLR.mjs → chunk-K5BS2H56.mjs} +5 -5
- package/dist/{chunk-QRUAEXLR.mjs.map → chunk-K5BS2H56.mjs.map} +1 -1
- package/dist/{chunk-BNBOIDO5.mjs → chunk-K7VJU7LQ.mjs} +3 -3
- package/dist/{chunk-BNBOIDO5.mjs.map → chunk-K7VJU7LQ.mjs.map} +1 -1
- package/dist/{chunk-H22OZYTW.mjs → chunk-KOXOC2FI.mjs} +48 -39
- package/dist/chunk-KOXOC2FI.mjs.map +1 -0
- package/dist/{chunk-CXHNVYMD.mjs → chunk-KWDBVLST.mjs} +5 -5
- package/dist/{chunk-CXHNVYMD.mjs.map → chunk-KWDBVLST.mjs.map} +1 -1
- package/dist/{chunk-OQIQNKPQ.mjs → chunk-LTLLQUMN.mjs} +4 -4
- package/dist/{chunk-OQIQNKPQ.mjs.map → chunk-LTLLQUMN.mjs.map} +1 -1
- package/dist/chunk-QK6OVDLC.mjs +103 -0
- package/dist/chunk-QK6OVDLC.mjs.map +1 -0
- package/dist/{chunk-QGNU34T7.mjs → chunk-QLQ4MJNO.mjs} +10 -4
- package/dist/chunk-QLQ4MJNO.mjs.map +1 -0
- package/dist/{chunk-BU5KLO3P.mjs → chunk-T3N4BSJV.mjs} +4 -4
- package/dist/{chunk-BU5KLO3P.mjs.map → chunk-T3N4BSJV.mjs.map} +1 -1
- package/dist/{chunk-5JM35CXV.mjs → chunk-TMRFSOM7.mjs} +4 -4
- package/dist/{chunk-5JM35CXV.mjs.map → chunk-TMRFSOM7.mjs.map} +1 -1
- package/dist/geometry-2d.d.mts +1 -1
- package/dist/geometry-2d.d.ts +1 -1
- package/dist/geometry-2d.js +841 -204
- package/dist/geometry-2d.js.map +1 -1
- package/dist/geometry-2d.mjs +5 -5
- package/dist/geometry-3d.d.mts +1 -1
- package/dist/geometry-3d.d.ts +1 -1
- package/dist/geometry-3d.js +172 -22
- package/dist/geometry-3d.js.map +1 -1
- package/dist/geometry-3d.mjs +4 -4
- package/dist/graph-2d.d.mts +1 -1
- package/dist/graph-2d.d.ts +1 -1
- package/dist/graph-2d.js +307 -100
- package/dist/graph-2d.js.map +1 -1
- package/dist/graph-2d.mjs +7 -7
- package/dist/handleExtractProblem-BrDY9ifM.d.mts +58 -0
- package/dist/handleExtractProblem-BrDY9ifM.d.ts +58 -0
- package/dist/{host-HOSJHQ5H.mjs → host-4FIUNIDQ.mjs} +13 -12
- package/dist/host-4FIUNIDQ.mjs.map +1 -0
- package/dist/{host-2ISGVO7O.mjs → host-4ZB4XD4S.mjs} +9 -8
- package/dist/host-4ZB4XD4S.mjs.map +1 -0
- package/dist/{host-ZQCDAT6O.mjs → host-H2IGOKJU.mjs} +3 -3
- package/dist/{host-ZQCDAT6O.mjs.map → host-H2IGOKJU.mjs.map} +1 -1
- package/dist/{host-HKMZSCIT.mjs → host-KMWP7KBT.mjs} +286 -74
- package/dist/host-KMWP7KBT.mjs.map +1 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +849 -206
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -21
- package/dist/index.mjs.map +1 -1
- package/dist/latex.d.mts +1 -1
- package/dist/latex.d.ts +1 -1
- package/dist/latex.js +8 -2
- package/dist/latex.js.map +1 -1
- package/dist/latex.mjs +1 -1
- package/dist/render-NMS7OAV6.mjs +10 -0
- package/dist/{render-ZX2O2IK7.mjs.map → render-NMS7OAV6.mjs.map} +1 -1
- package/dist/serialize-PGHQZEPV.mjs +9 -0
- package/dist/{serialize-N4G6RFBB.mjs.map → serialize-PGHQZEPV.mjs.map} +1 -1
- package/dist/{types-C3FjpoUi.d.ts → types-tePd94vW.d.mts} +8 -0
- package/dist/{types-C3FjpoUi.d.mts → types-tePd94vW.d.ts} +8 -0
- package/package.json +2 -1
- package/dist/chunk-E6EDOPGT.mjs.map +0 -1
- package/dist/chunk-H22OZYTW.mjs.map +0 -1
- package/dist/chunk-IHUFOV7L.mjs.map +0 -1
- package/dist/chunk-QGNU34T7.mjs.map +0 -1
- package/dist/chunk-SZDAS7LK.mjs.map +0 -1
- package/dist/chunk-ZTQBUKLJ.mjs.map +0 -1
- package/dist/host-2ISGVO7O.mjs.map +0 -1
- package/dist/host-HKMZSCIT.mjs.map +0 -1
- package/dist/host-HOSJHQ5H.mjs.map +0 -1
- package/dist/render-ZX2O2IK7.mjs +0 -10
- package/dist/serialize-N4G6RFBB.mjs +0 -9
package/dist/geometry-2d.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
export { geometryStamp } from './chunk-
|
|
3
|
-
import './chunk-
|
|
2
|
+
export { geometryStamp } from './chunk-BMYC2ILT.mjs';
|
|
3
|
+
import './chunk-KOXOC2FI.mjs';
|
|
4
4
|
import './chunk-R5FL6S7L.mjs';
|
|
5
|
-
import './chunk-
|
|
5
|
+
import './chunk-IE2GGHNF.mjs';
|
|
6
6
|
import './chunk-ICR4CVOE.mjs';
|
|
7
|
-
import './chunk-
|
|
8
|
-
import './chunk-
|
|
7
|
+
import './chunk-JJ4FPCBE.mjs';
|
|
8
|
+
import './chunk-CH6SFONH.mjs';
|
|
9
9
|
import './chunk-73Q7ADVL.mjs';
|
|
10
10
|
import './chunk-B4NJJZFR.mjs';
|
|
11
11
|
import './chunk-5UTGXHLJ.mjs';
|
package/dist/geometry-3d.d.mts
CHANGED
package/dist/geometry-3d.d.ts
CHANGED
package/dist/geometry-3d.js
CHANGED
|
@@ -939,8 +939,12 @@ function constraintRefs2D(c) {
|
|
|
939
939
|
return [c.line, c.circle, c.other];
|
|
940
940
|
case "tangencyPoint":
|
|
941
941
|
return [c.circle, c.onLine];
|
|
942
|
-
case "arcMidpoint":
|
|
943
|
-
|
|
942
|
+
case "arcMidpoint": {
|
|
943
|
+
const containment = c.notContaining ?? c.containing;
|
|
944
|
+
return containment ? [c.circle, c.a, c.b, containment] : [c.circle, c.a, c.b];
|
|
945
|
+
}
|
|
946
|
+
case "mixtilinearPoint":
|
|
947
|
+
return [c.vertices[0], c.vertices[1], c.vertices[2]];
|
|
944
948
|
case "pointAtDistance": {
|
|
945
949
|
const d = c.distance;
|
|
946
950
|
const extra = d.kind === "circleRadius" ? [d.circle] : d.kind === "segmentLength" ? [d.p1, d.p2] : [];
|
|
@@ -1227,7 +1231,7 @@ function dist(p, q) {
|
|
|
1227
1231
|
function sideOf(a, b, p) {
|
|
1228
1232
|
return (b[0] - a[0]) * (p[1] - a[1]) - (b[1] - a[1]) * (p[0] - a[0]);
|
|
1229
1233
|
}
|
|
1230
|
-
function arcMidpoint(center, radius, a, b,
|
|
1234
|
+
function arcMidpoint(center, radius, a, b, reference, sameSide = false) {
|
|
1231
1235
|
const mcx = (a[0] + b[0]) / 2;
|
|
1232
1236
|
const mcy = (a[1] + b[1]) / 2;
|
|
1233
1237
|
let ux = mcx - center[0];
|
|
@@ -1242,12 +1246,18 @@ function arcMidpoint(center, radius, a, b, notContaining) {
|
|
|
1242
1246
|
uy /= len;
|
|
1243
1247
|
const cand1 = [center[0] + radius * ux, center[1] + radius * uy];
|
|
1244
1248
|
const cand2 = [center[0] - radius * ux, center[1] - radius * uy];
|
|
1249
|
+
if (!reference) return cand1[1] >= cand2[1] ? cand1 : cand2;
|
|
1250
|
+
const notContaining = reference;
|
|
1245
1251
|
const sN = sideOf(a, b, notContaining);
|
|
1246
1252
|
if (Math.abs(sN) < 1e-9) {
|
|
1247
|
-
|
|
1253
|
+
const far = dist(cand1, notContaining) >= dist(cand2, notContaining) ? cand1 : cand2;
|
|
1254
|
+
const near = far === cand1 ? cand2 : cand1;
|
|
1255
|
+
return sameSide ? near : far;
|
|
1248
1256
|
}
|
|
1249
1257
|
const s1 = sideOf(a, b, cand1);
|
|
1250
|
-
|
|
1258
|
+
const opp = s1 * sN < 0 ? cand1 : cand2;
|
|
1259
|
+
const same = opp === cand1 ? cand2 : cand1;
|
|
1260
|
+
return sameSide ? same : opp;
|
|
1251
1261
|
}
|
|
1252
1262
|
function excenter(vertices, oppositeIndex) {
|
|
1253
1263
|
const [A, B, C] = vertices;
|
|
@@ -1263,6 +1273,35 @@ function excenter(vertices, oppositeIndex) {
|
|
|
1263
1273
|
(w[0] * A[1] + w[1] * B[1] + w[2] * C[1]) / sum
|
|
1264
1274
|
];
|
|
1265
1275
|
}
|
|
1276
|
+
function circumcenterXY(a, b, c) {
|
|
1277
|
+
const ax = a[0], ay = a[1], bx = b[0], by = b[1], cx = c[0], cy = c[1];
|
|
1278
|
+
const d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by));
|
|
1279
|
+
if (Math.abs(d) < 1e-12) return [(ax + bx + cx) / 3, (ay + by + cy) / 3];
|
|
1280
|
+
const ux = ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) * (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / d;
|
|
1281
|
+
const uy = ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) * (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / d;
|
|
1282
|
+
return [ux, uy];
|
|
1283
|
+
}
|
|
1284
|
+
function mixtilinearPoint(a, b, c, which) {
|
|
1285
|
+
const O = circumcenterXY(a, b, c);
|
|
1286
|
+
const R = Math.hypot(O[0] - a[0], O[1] - a[1]);
|
|
1287
|
+
const ux1 = (b[0] - a[0]) / (Math.hypot(b[0] - a[0], b[1] - a[1]) || 1);
|
|
1288
|
+
const uy1 = (b[1] - a[1]) / (Math.hypot(b[0] - a[0], b[1] - a[1]) || 1);
|
|
1289
|
+
const ux2 = (c[0] - a[0]) / (Math.hypot(c[0] - a[0], c[1] - a[1]) || 1);
|
|
1290
|
+
const uy2 = (c[1] - a[1]) / (Math.hypot(c[0] - a[0], c[1] - a[1]) || 1);
|
|
1291
|
+
let bx = ux1 + ux2, by = uy1 + uy2;
|
|
1292
|
+
const bl = Math.hypot(bx, by) || 1;
|
|
1293
|
+
bx /= bl;
|
|
1294
|
+
by /= bl;
|
|
1295
|
+
const cosA = ux1 * ux2 + uy1 * uy2;
|
|
1296
|
+
const sinHalf = Math.sqrt(Math.max(0, (1 - cosA) / 2));
|
|
1297
|
+
const cos2Half = Math.max(1e-9, (1 + cosA) / 2);
|
|
1298
|
+
const dotAO = bx * (O[0] - a[0]) + by * (O[1] - a[1]);
|
|
1299
|
+
const d = 2 * (dotAO - R * sinHalf) / cos2Half;
|
|
1300
|
+
const K = [a[0] + d * bx, a[1] + d * by];
|
|
1301
|
+
if (which === "center") return K;
|
|
1302
|
+
const kl = Math.hypot(K[0] - O[0], K[1] - O[1]) || 1;
|
|
1303
|
+
return [O[0] + R * (K[0] - O[0]) / kl, O[1] + R * (K[1] - O[1]) / kl];
|
|
1304
|
+
}
|
|
1266
1305
|
function pointAtDistanceCoord(from, through, d) {
|
|
1267
1306
|
const dx = through[0] - from[0];
|
|
1268
1307
|
const dy = through[1] - from[1];
|
|
@@ -1290,29 +1329,38 @@ var init_arcMidpoint = __esm({
|
|
|
1290
1329
|
arcMidpointConstraint = definePointConstraint({
|
|
1291
1330
|
kind: "arcMidpoint",
|
|
1292
1331
|
validate: (c) => {
|
|
1293
|
-
if (!c.circle || !c.a || !c.b
|
|
1294
|
-
throw new Error("point.arcMidpoint: circle, a, b
|
|
1332
|
+
if (!c.circle || !c.a || !c.b) {
|
|
1333
|
+
throw new Error("point.arcMidpoint: circle, a, b b\u1EAFt bu\u1ED9c");
|
|
1334
|
+
}
|
|
1335
|
+
if (c.notContaining && c.containing) {
|
|
1336
|
+
throw new Error("point.arcMidpoint: kh\xF4ng th\u1EC3 v\u1EEBa notContaining v\u1EEBa containing");
|
|
1295
1337
|
}
|
|
1296
1338
|
},
|
|
1297
1339
|
describe: (obj, state, c) => {
|
|
1298
1340
|
const al = state?.objects[c.a]?.label ?? c.a;
|
|
1299
1341
|
const bl = state?.objects[c.b]?.label ?? c.b;
|
|
1300
|
-
const
|
|
1301
|
-
return `${obj.label} = trung \u0111i\u1EC3m cung ${al}${bl}
|
|
1342
|
+
const ref = c.containing ?? c.notContaining;
|
|
1343
|
+
if (!ref) return `${obj.label} = trung \u0111i\u1EC3m cung ${al}${bl}`;
|
|
1344
|
+
const rl = state?.objects[ref]?.label ?? ref;
|
|
1345
|
+
const rel = c.containing ? "ch\u1EE9a" : "kh\xF4ng ch\u1EE9a";
|
|
1346
|
+
return `${obj.label} = trung \u0111i\u1EC3m cung ${al}${bl} (${rel} ${rl})`;
|
|
1302
1347
|
},
|
|
1303
1348
|
render: (obj, ctx, c, opts) => {
|
|
1304
1349
|
const board = ctx.jxg;
|
|
1305
1350
|
const circle = ctx.resolveRef(c.circle);
|
|
1306
1351
|
const A = ctx.resolveRef(c.a);
|
|
1307
1352
|
const B = ctx.resolveRef(c.b);
|
|
1308
|
-
const
|
|
1353
|
+
const refName = c.containing ?? c.notContaining;
|
|
1354
|
+
const ref = refName ? ctx.resolveRef(refName) : void 0;
|
|
1355
|
+
const sameSide = !!c.containing;
|
|
1309
1356
|
const O = circle?.center ?? circle?.midpoint ?? circle;
|
|
1310
1357
|
const am = () => arcMidpoint(
|
|
1311
1358
|
[O.X(), O.Y()],
|
|
1312
1359
|
circle.Radius(),
|
|
1313
1360
|
[A.X(), A.Y()],
|
|
1314
1361
|
[B.X(), B.Y()],
|
|
1315
|
-
[
|
|
1362
|
+
ref ? [ref.X(), ref.Y()] : void 0,
|
|
1363
|
+
sameSide
|
|
1316
1364
|
);
|
|
1317
1365
|
return board.create("point", [() => am()[0], () => am()[1]], opts);
|
|
1318
1366
|
}
|
|
@@ -1362,6 +1410,53 @@ var init_excenter = __esm({
|
|
|
1362
1410
|
}
|
|
1363
1411
|
});
|
|
1364
1412
|
|
|
1413
|
+
// src/core/scene/kinds/point-constraints/mixtilinearPoint.ts
|
|
1414
|
+
var mixtilinearPointConstraint;
|
|
1415
|
+
var init_mixtilinearPoint = __esm({
|
|
1416
|
+
"src/core/scene/kinds/point-constraints/mixtilinearPoint.ts"() {
|
|
1417
|
+
init_pointConstructions();
|
|
1418
|
+
init_types2();
|
|
1419
|
+
mixtilinearPointConstraint = definePointConstraint({
|
|
1420
|
+
kind: "mixtilinearPoint",
|
|
1421
|
+
validate: (c) => {
|
|
1422
|
+
if (!Array.isArray(c.vertices) || c.vertices.length !== 3 || !c.vertices.every(Boolean)) {
|
|
1423
|
+
throw new Error("point.mixtilinearPoint: vertices ph\u1EA3i l\xE0 tuple 3 id non-empty");
|
|
1424
|
+
}
|
|
1425
|
+
if (c.which !== "center" && c.which !== "touch") {
|
|
1426
|
+
throw new Error("point.mixtilinearPoint: which ph\u1EA3i 'center' | 'touch'");
|
|
1427
|
+
}
|
|
1428
|
+
},
|
|
1429
|
+
describe: (obj, state, c) => {
|
|
1430
|
+
const labels = c.vertices.map((id) => state?.objects[id]?.label ?? id).join("");
|
|
1431
|
+
return c.which === "center" ? `${obj.label} = t\xE2m \u0111\u01B0\u1EDDng tr\xF2n mixtilinear \u0394${labels}` : `${obj.label} = ti\u1EBFp \u0111i\u1EC3m mixtilinear \u0394${labels} v\u1EDBi (O)`;
|
|
1432
|
+
},
|
|
1433
|
+
render: (obj, ctx, c, opts) => {
|
|
1434
|
+
const board = ctx.jxg;
|
|
1435
|
+
const a = ctx.resolveRef(c.vertices[0]);
|
|
1436
|
+
const b = ctx.resolveRef(c.vertices[1]);
|
|
1437
|
+
const d = ctx.resolveRef(c.vertices[2]);
|
|
1438
|
+
const mp = () => mixtilinearPoint(
|
|
1439
|
+
[a.X(), a.Y()],
|
|
1440
|
+
[b.X(), b.Y()],
|
|
1441
|
+
[d.X(), d.Y()],
|
|
1442
|
+
c.which
|
|
1443
|
+
);
|
|
1444
|
+
return board.create("point", [() => mp()[0], () => mp()[1]], opts);
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1448
|
+
});
|
|
1449
|
+
|
|
1450
|
+
// src/core/scene/kinds/_label.ts
|
|
1451
|
+
function labelOpts(labelOffset, dflt) {
|
|
1452
|
+
const offset = labelOffset ?? dflt;
|
|
1453
|
+
return { label: { fixed: false, ...offset ? { offset } : {} } };
|
|
1454
|
+
}
|
|
1455
|
+
var init_label = __esm({
|
|
1456
|
+
"src/core/scene/kinds/_label.ts"() {
|
|
1457
|
+
}
|
|
1458
|
+
});
|
|
1459
|
+
|
|
1365
1460
|
// src/core/scene/kinds/point-constraints/shared.ts
|
|
1366
1461
|
function buildJxgTransforms(board, ctx, t) {
|
|
1367
1462
|
switch (t.kind) {
|
|
@@ -1413,11 +1508,13 @@ function buildPointOpts(obj) {
|
|
|
1413
1508
|
strokeColor: obj.attrs.color ?? "#1e40af",
|
|
1414
1509
|
fillColor: obj.attrs.color ?? "#1e40af",
|
|
1415
1510
|
face: obj.attrs.face ?? "o",
|
|
1416
|
-
size: obj.attrs.size ?? 4
|
|
1511
|
+
size: obj.attrs.size ?? 4,
|
|
1512
|
+
...labelOpts(obj.attrs.labelOffset, [10, 10])
|
|
1417
1513
|
};
|
|
1418
1514
|
}
|
|
1419
1515
|
var init_shared = __esm({
|
|
1420
1516
|
"src/core/scene/kinds/point-constraints/shared.ts"() {
|
|
1517
|
+
init_label();
|
|
1421
1518
|
}
|
|
1422
1519
|
});
|
|
1423
1520
|
|
|
@@ -1726,6 +1823,7 @@ var init_registry2 = __esm({
|
|
|
1726
1823
|
init_centroid();
|
|
1727
1824
|
init_arcMidpoint();
|
|
1728
1825
|
init_excenter();
|
|
1826
|
+
init_mixtilinearPoint();
|
|
1729
1827
|
init_pointAtDistance();
|
|
1730
1828
|
init_circleIntersection();
|
|
1731
1829
|
init_circleSecondIntersection();
|
|
@@ -1751,6 +1849,7 @@ var init_registry2 = __esm({
|
|
|
1751
1849
|
centroidConstraint,
|
|
1752
1850
|
arcMidpointConstraint,
|
|
1753
1851
|
excenterConstraint,
|
|
1852
|
+
mixtilinearPointConstraint,
|
|
1754
1853
|
pointAtDistanceConstraint,
|
|
1755
1854
|
circleIntersectionConstraint,
|
|
1756
1855
|
circleSecondIntersectionConstraint,
|
|
@@ -1775,6 +1874,7 @@ var init_point = __esm({
|
|
|
1775
1874
|
init_d_constraint2();
|
|
1776
1875
|
init_registry2();
|
|
1777
1876
|
init_shared();
|
|
1877
|
+
init_label();
|
|
1778
1878
|
def3 = {
|
|
1779
1879
|
type: "point",
|
|
1780
1880
|
schemaVersion: 1,
|
|
@@ -1842,7 +1942,8 @@ var init_point = __esm({
|
|
|
1842
1942
|
strokeColor: obj.attrs.color ?? "#1e40af",
|
|
1843
1943
|
fillColor: obj.attrs.color ?? "#1e40af",
|
|
1844
1944
|
face: obj.attrs.face ?? "o",
|
|
1845
|
-
size: obj.attrs.size ?? 4
|
|
1945
|
+
size: obj.attrs.size ?? 4,
|
|
1946
|
+
...labelOpts(obj.attrs.labelOffset, [10, 10])
|
|
1846
1947
|
});
|
|
1847
1948
|
} catch {
|
|
1848
1949
|
}
|
|
@@ -1862,6 +1963,7 @@ var init_segment = __esm({
|
|
|
1862
1963
|
"src/core/scene/kinds/segment.ts"() {
|
|
1863
1964
|
init_registry();
|
|
1864
1965
|
init_labelOf();
|
|
1966
|
+
init_label();
|
|
1865
1967
|
def4 = {
|
|
1866
1968
|
type: "segment",
|
|
1867
1969
|
schemaVersion: 1,
|
|
@@ -1893,7 +1995,8 @@ var init_segment = __esm({
|
|
|
1893
1995
|
strokeWidth: obj.attrs.width ?? 2,
|
|
1894
1996
|
dash: obj.attrs.dash ?? 0,
|
|
1895
1997
|
visible: obj.visible,
|
|
1896
|
-
fixed: obj.locked
|
|
1998
|
+
fixed: obj.locked,
|
|
1999
|
+
...labelOpts(obj.attrs.labelOffset)
|
|
1897
2000
|
});
|
|
1898
2001
|
}
|
|
1899
2002
|
};
|
|
@@ -1930,6 +2033,7 @@ var init_line = __esm({
|
|
|
1930
2033
|
"src/core/scene/kinds/line.ts"() {
|
|
1931
2034
|
init_registry();
|
|
1932
2035
|
init_labelOf();
|
|
2036
|
+
init_label();
|
|
1933
2037
|
init_pointConstructions();
|
|
1934
2038
|
def5 = {
|
|
1935
2039
|
type: "line",
|
|
@@ -1972,7 +2076,8 @@ var init_line = __esm({
|
|
|
1972
2076
|
strokeWidth: obj.attrs.width ?? 2,
|
|
1973
2077
|
dash: obj.attrs.dash ?? 0,
|
|
1974
2078
|
visible: obj.visible,
|
|
1975
|
-
fixed: obj.locked
|
|
2079
|
+
fixed: obj.locked,
|
|
2080
|
+
...labelOpts(obj.attrs.labelOffset)
|
|
1976
2081
|
};
|
|
1977
2082
|
const c = obj.attrs.construction;
|
|
1978
2083
|
if (!c) {
|
|
@@ -2228,6 +2333,7 @@ var init_circle = __esm({
|
|
|
2228
2333
|
"src/core/scene/kinds/circle.ts"() {
|
|
2229
2334
|
init_registry();
|
|
2230
2335
|
init_labelOf();
|
|
2336
|
+
init_label();
|
|
2231
2337
|
init_pointConstructions();
|
|
2232
2338
|
def8 = {
|
|
2233
2339
|
type: "circle",
|
|
@@ -2289,15 +2395,17 @@ var init_circle = __esm({
|
|
|
2289
2395
|
const board = ctx.jxg;
|
|
2290
2396
|
const isCenterLabel = (l) => /^[A-Z]['′]?\d*$/u.test(l);
|
|
2291
2397
|
const isCenter = isCenterLabel(obj.label);
|
|
2398
|
+
const isRenamedCircle = /_c$/.test(obj.label);
|
|
2292
2399
|
const baseOpts = {
|
|
2293
2400
|
name: obj.label,
|
|
2294
|
-
withLabel: isCenter ? obj.attrs.showLabel ?? false : true,
|
|
2401
|
+
withLabel: isCenter ? obj.attrs.showLabel ?? false : isRenamedCircle ? false : true,
|
|
2295
2402
|
strokeColor: obj.attrs.color ?? "#0f172a",
|
|
2296
2403
|
strokeWidth: obj.attrs.width ?? 2,
|
|
2297
2404
|
dash: obj.attrs.dash ?? 0,
|
|
2298
2405
|
fillColor: "none",
|
|
2299
2406
|
visible: obj.visible,
|
|
2300
|
-
fixed: obj.locked
|
|
2407
|
+
fixed: obj.locked,
|
|
2408
|
+
...labelOpts(obj.attrs.labelOffset)
|
|
2301
2409
|
};
|
|
2302
2410
|
const c = asConstruction(obj.attrs);
|
|
2303
2411
|
if (c?.kind === "circumscribed") {
|
|
@@ -2782,8 +2890,11 @@ var init_intersection = __esm({
|
|
|
2782
2890
|
const opts = {
|
|
2783
2891
|
name: obj.label,
|
|
2784
2892
|
withLabel: true,
|
|
2785
|
-
|
|
2786
|
-
|
|
2893
|
+
// Cùng màu xanh với mọi điểm khác (buildPointOpts dùng '#1e40af').
|
|
2894
|
+
// Trước đây điểm giao tô đỏ '#dc2626' → tách biệt thị giác nhưng gây
|
|
2895
|
+
// khó hiểu ("vì sao điểm này khác màu?"). Giữ chung một màu.
|
|
2896
|
+
strokeColor: obj.attrs.color ?? "#1e40af",
|
|
2897
|
+
fillColor: obj.attrs.color ?? "#1e40af",
|
|
2787
2898
|
visible: obj.visible,
|
|
2788
2899
|
fixed: obj.locked
|
|
2789
2900
|
};
|
|
@@ -2792,6 +2903,38 @@ var init_intersection = __esm({
|
|
|
2792
2903
|
}
|
|
2793
2904
|
const branch = obj.attrs.branch ?? 0;
|
|
2794
2905
|
return board.create("intersection", [a, b, branch], opts);
|
|
2906
|
+
},
|
|
2907
|
+
/**
|
|
2908
|
+
* Cập nhật TẠI CHỖ các thuộc tính "trang trí" (tên/màu/ẩn-hiện/khoá) qua
|
|
2909
|
+
* setAttribute — giữ nguyên JxgObj identity nên các object phụ thuộc điểm
|
|
2910
|
+
* giao (đường thẳng qua nó, …) KHÔNG bị stale parent ref. Mô phỏng update
|
|
2911
|
+
* hook của point.ts.
|
|
2912
|
+
*
|
|
2913
|
+
* Nếu định nghĩa hình học đổi (kind/ref1/ref2/branch) thì throw → renderer
|
|
2914
|
+
* fallback remove + create để JSXGraph dựng lại phép giao đúng.
|
|
2915
|
+
*/
|
|
2916
|
+
update: (obj, prev, ctx, existing) => {
|
|
2917
|
+
const a = obj.attrs;
|
|
2918
|
+
const p = prev.attrs;
|
|
2919
|
+
const branchA = a.branch;
|
|
2920
|
+
const branchP = p.branch;
|
|
2921
|
+
if (a.kind !== p.kind || a.ref1 !== p.ref1 || a.ref2 !== p.ref2 || branchA !== branchP) {
|
|
2922
|
+
throw new Error("intersection: \u0111\u1ECBnh ngh\u0129a h\xECnh h\u1ECDc \u0111\u1ED5i \u2014 recreate");
|
|
2923
|
+
}
|
|
2924
|
+
const el = existing;
|
|
2925
|
+
if (typeof el.setAttribute === "function") {
|
|
2926
|
+
try {
|
|
2927
|
+
el.setAttribute({
|
|
2928
|
+
name: obj.label,
|
|
2929
|
+
withLabel: true,
|
|
2930
|
+
strokeColor: a.color ?? "#1e40af",
|
|
2931
|
+
fillColor: a.color ?? "#1e40af",
|
|
2932
|
+
visible: obj.visible,
|
|
2933
|
+
fixed: obj.locked
|
|
2934
|
+
});
|
|
2935
|
+
} catch {
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2795
2938
|
}
|
|
2796
2939
|
};
|
|
2797
2940
|
registerKind(def12);
|
|
@@ -7911,11 +8054,17 @@ async function insertStampImage(api, opts) {
|
|
|
7911
8054
|
const elements = api.getSceneElements();
|
|
7912
8055
|
const editingId = opts.editingElementId ?? null;
|
|
7913
8056
|
if (editingId) {
|
|
8057
|
+
const old = elements.find((e) => e.id === editingId) ;
|
|
8058
|
+
const oldLongest = old ? Math.max(old.width ?? 0, old.height ?? 0) : 0;
|
|
8059
|
+
const newLongest = Math.max(width, height);
|
|
8060
|
+
const scale3 = oldLongest > 0 && newLongest > 0 ? oldLongest / newLongest : 1;
|
|
8061
|
+
const w = width * scale3;
|
|
8062
|
+
const h = height * scale3;
|
|
7914
8063
|
const updated = elements.map(
|
|
7915
|
-
(e) => e.id === editingId ? { ...e, fileId, customData, width, height } : e
|
|
8064
|
+
(e) => e.id === editingId ? { ...e, fileId, customData, width: w, height: h } : e
|
|
7916
8065
|
);
|
|
7917
8066
|
api.updateScene({ elements: updated, appState: clearAppStateAfterInsert() });
|
|
7918
|
-
return { fileId, width, height, elementId: editingId };
|
|
8067
|
+
return { fileId, width: w, height: h, elementId: editingId };
|
|
7919
8068
|
}
|
|
7920
8069
|
const newElement = buildStampImageElement(
|
|
7921
8070
|
api,
|
|
@@ -8065,7 +8214,8 @@ var init_host = __esm({
|
|
|
8065
8214
|
version: 2,
|
|
8066
8215
|
jsonState
|
|
8067
8216
|
}),
|
|
8068
|
-
editingElementId: editingElement?.id ?? null
|
|
8217
|
+
editingElementId: editingElement?.id ?? null,
|
|
8218
|
+
preserveExistingSize: true
|
|
8069
8219
|
});
|
|
8070
8220
|
onClose();
|
|
8071
8221
|
},
|