xvai-loi 0.1.50 → 0.1.52

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.
Files changed (3) hide show
  1. package/co.txt +1 -1
  2. package/package.json +1 -1
  3. package/xvai-loi.js +257 -59
package/co.txt CHANGED
@@ -1 +1 @@
1
- xvaiLoi101303
1
+ xvaiLoi101845
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xvai-loi",
3
- "version": "0.1.50",
3
+ "version": "0.1.52",
4
4
  "description": "Loi dung video (Edit Video Tu Dong) nap vao tool Google Flow qua o cam engine/oCam.ts",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
package/xvai-loi.js CHANGED
@@ -1475,21 +1475,26 @@ async function analyzeFaceMap(src, step = 0.5, cancel = () => false, onStatus =
1475
1475
  video.muted = true;
1476
1476
  video.preload = "auto";
1477
1477
  video.playsInline = true;
1478
- await new Promise((ok, err) => {
1479
- const timer = setTimeout(() => {
1480
- vd209c("faceMap", "loadeddata", 6e4);
1481
- err(new Error("N\u1EA1p video \u0111\u1EC3 nh\u1EADn m\u1EB7t qu\xE1 60 s."));
1482
- }, 6e4);
1483
- video.onloadeddata = () => {
1484
- clearTimeout(timer);
1485
- ok();
1486
- };
1487
- video.onerror = () => {
1488
- clearTimeout(timer);
1489
- err(new Error("Kh\xF4ng m\u1EDF \u0111\u01B0\u1EE3c video \u0111\u1EC3 nh\u1EADn m\u1EB7t."));
1490
- };
1491
- video.src = src;
1492
- });
1478
+ try {
1479
+ await new Promise((ok, err) => {
1480
+ const timer = setTimeout(() => {
1481
+ vd209c("faceMap", "loadeddata", 12e3);
1482
+ err(new Error("N\u1EA1p video \u0111\u1EC3 nh\u1EADn m\u1EB7t qu\xE1 12 s."));
1483
+ }, 12e3);
1484
+ video.onloadeddata = () => {
1485
+ clearTimeout(timer);
1486
+ ok();
1487
+ };
1488
+ video.onerror = () => {
1489
+ clearTimeout(timer);
1490
+ err(new Error("Kh\xF4ng m\u1EDF \u0111\u01B0\u1EE3c video \u0111\u1EC3 nh\u1EADn m\u1EB7t."));
1491
+ };
1492
+ video.src = src;
1493
+ });
1494
+ } catch (e) {
1495
+ video.src = "";
1496
+ return await faceMapWC(src, step, cancel, onStatus, maxSide, landmarker, t0);
1497
+ }
1493
1498
  const scale = Math.min(1, maxSide / Math.max(video.videoWidth, video.videoHeight));
1494
1499
  const canvas = document.createElement("canvas");
1495
1500
  canvas.width = Math.max(2, Math.round(video.videoWidth * scale));
@@ -1530,6 +1535,33 @@ async function analyzeFaceMap(src, step = 0.5, cancel = () => false, onStatus =
1530
1535
  video.load();
1531
1536
  return { step, width: vw, height: vh, samples, ms: Math.round(performance.now() - t0), engine: "mediapipe-face-landmarker-0.10.20" };
1532
1537
  }
1538
+ async function faceMapWC(src, step, cancel, onStatus, maxSide, landmarker, t0) {
1539
+ onStatus("Nh\u1EADn m\u1EB7t (gi\u1EA3i m\xE3 WebCodecs)\u2026");
1540
+ const M = await import(
1541
+ /* @vite-ignore */
1542
+ "https://cdn.jsdelivr.net/npm/mediabunny@1.61.1/+esm"
1543
+ );
1544
+ const inp = new M.Input({ source: new M.BlobSource(await (await fetch(src)).blob()), formats: M.ALL_FORMATS }), tr = await inp.getPrimaryVideoTrack(), dur = await inp.computeDuration();
1545
+ const vw = tr.displayWidth, vh = tr.displayHeight, sc = Math.min(1, maxSide / Math.max(vw, vh)), canvas = document.createElement("canvas");
1546
+ canvas.width = Math.max(2, Math.round(vw * sc));
1547
+ canvas.height = Math.max(2, Math.round(vh * sc));
1548
+ const ctx = canvas.getContext("2d", { willReadFrequently: true }), sink = new M.CanvasSink(tr, { width: canvas.width, height: canvas.height, fit: "fill", poolSize: 2 }), ts2 = [];
1549
+ for (let t = 0; t < dur; t += step) ts2.push(t);
1550
+ const samples = [];
1551
+ let i = 0;
1552
+ for await (const w of sink.canvasesAtTimestamps(ts2)) {
1553
+ if (cancel()) break;
1554
+ const t = Math.round(ts2[i++] * 100) / 100;
1555
+ if (!w) {
1556
+ samples.push(sampleFromLandmarks(t, void 0));
1557
+ continue;
1558
+ }
1559
+ ctx.drawImage(w.canvas, 0, 0, canvas.width, canvas.height);
1560
+ samples.push(await detectOnCanvas(landmarker, canvas, t));
1561
+ if (samples.length % 10 === 0) onStatus("Nh\u1EADn m\u1EB7t " + Math.round(t) + "/" + Math.round(dur) + " s");
1562
+ }
1563
+ return { step, width: vw, height: vh, samples, ms: Math.round(performance.now() - t0), engine: "mediapipe-face-landmarker-0.10.20+webcodecs" };
1564
+ }
1533
1565
  function faceMapSummary(map) {
1534
1566
  const n = map.samples.length, hit2 = map.samples.filter((s) => s.face).length;
1535
1567
  const avgH = hit2 ? map.samples.filter((s) => s.face).reduce((a, s) => a + s.face.h, 0) / hit2 : 0;
@@ -2161,6 +2193,13 @@ function safeKeepRanges(start, end, silences, words, shorten) {
2161
2193
  if (cuts.length && a < cuts[cuts.length - 1].t1) continue;
2162
2194
  cuts.push({ t0: a, t1: b });
2163
2195
  }
2196
+ {
2197
+ const wl = words[words.length - 1];
2198
+ if (wl && Number.isFinite(wl.t1) && end - wl.t1 > 1.2) {
2199
+ const a = Math.max(start, wl.t1 + 0.75);
2200
+ if (!cuts.some((c) => c.t1 >= end - 0.05 && c.t0 <= a)) cuts.push({ t0: a, t1: end });
2201
+ }
2202
+ }
2164
2203
  {
2165
2204
  let tay = [];
2166
2205
  try {
@@ -5527,7 +5566,7 @@ var PRISM = {
5527
5566
  { "id": "giong-prism-triple", "ten": "gi\u1ED1ng Prism - Triple", "ho": "H4", "nguon": "79689756-8A36-48DB-B649-5F0B589FD8F7", "mau": { "chu": [1, 1, 1, 1], "nenTu": [0, 0, 0, 1], "nhan": [1, 1, 1, 0.9996], "dangNoi": [0, 0.4962, 0.7676, 1] }, "phong": "Inter", "dam": 400, "nghieng": false, "phongNhan": { "phong": "Inter", "dam": 700, "nghieng": true }, "phongNap": "family=Inter:ital,opsz,wght@0,14..32,400;1,14..32,700", "co": 96, "gianChu": -1.7786561264822112, "gianDong": -30.23715415019763, "caoDong": null, "vien": null, "bong": { "mo": 16, "mau": [0, 0, 0, 1], "dx": 0, "dy": 0 }, "sang": { "bat": false, "r": 10, "duc": 1, "chiNhan": true }, "nen": null, "ngat": { "lang": 0.4, "kyTu": 10, "soTu": null, "giuTuGhep": false }, "dongMoiTrang": 3, "hoa": "HoaDau", "anDauCau": true, "can": "ngauNhien", "rongToiDa": 625, "tuCo": true, "tuToKhongNgat": true, "vao": { "dich": "tu", "kieu": "truotTrai", "kieuNhan": "noiMem", "ms": 100, "msNhan": 200 }, "sapNoi": { "bat": false, "mau": [0, 0, 0, 0] }, "dangNoi": { "doiMau": false, "doiCo": false, "dam": false }, "nhanAI": { "bat": true, "tuKhoa": ["doiMau", "phongTo", "doiPhong", "daoNen", "hoatHinhRieng"], "danhTu": [], "goiHinh": [], "heSoTo": 1.5 }, "viTri": { "x": 0.5, "y": 0.7 }, "ghiChu": "\u{1F7E2} s\u1ED1 g\u1ED1c Captions (captionTemplateView, ch\u1EC9 \u0111\u1ECDc). \u{1F7E1} kh\xF4ng c\xF3 trong d\u1EEF li\u1EC7u h\u1ECD: vao.ms 100 / msNhan 200 (\u0111o video xem tr\u01B0\u1EDBc), nhanAI.heSoTo 1,5, viTri, daoNen ch\u01B0a v\u1EBD (n\u1EC1n t\u1EEB ch\u01B0a b\u1EADt)." }
5528
5567
  ],
5529
5568
  "sua": { "sua": { "dau": true, "nenSang": true }, "ngat": { "giuTuGhep": true } },
5530
- "tuGhep": ["d\xE3 man", "\u0111\u1EAFt gi\xE1", "tuy\u1EC7t \u0111\u1ED1i", "n\xE1t n\u01B0\u1EDBc", "n\u1ED9i dung", "s\xE1ng t\u1EA1o", "th\u01B0\u01A1ng hi\u1EC7u", "\u0111i\u1EC7n tho\u1EA1i", "t\xE0i li\u1EC7u", "th\u1ECB tr\u01B0\u1EDDng", "s\u1ED1 li\u1EC7u", "th\xE0nh ph\u1EA9m", "\xFD t\u01B0\u1EDFng", "b\u1EA3n th\xE2n", "t\u1ED1n ti\u1EC1n", "thu\xEA ngo\xE0i", "hi\u1EC7u \u1EE9ng", "n\u0103ng su\u1EA5t", "\u0111\u1ED1i th\u1EE7", "kh\xE1ch h\xE0ng", "qu\u1EA3ng c\xE1o", "anh em", "chuy\xEAn nghi\u1EC7p", "t\u1EF1 \u0111\u1ED9ng", "k\xEDch ho\u1EA1t", "\u0111i\u1EC7p vi\xEAn", "th\u1EA3nh th\u01A1i", "c\xE1 nh\xE2n", "\u0111\u1ECBa ph\u01B0\u01A1ng", "\u0111\xE0m tho\u1EA1i", "phong c\xE1ch", "v\xF4 h\u1ED3n", "d\u1EABn d\u1EAFt", "n\u1EAFm th\xF3p", "c\xF2ng l\u01B0ng", "\u1EA3o di\u1EC7u", "th\u1EF1c s\u1EF1", "t\xECm ki\u1EBFm", "m\u1EABu m\xE3", "\xE2m thanh", "h\xECnh \u1EA3nh", "gi\u1ECDng n\xF3i", "doanh thu", "b\xE1n h\xE0ng", "m\u1ED3 h\xF4i", "n\u01B0\u1EDBc m\u1EAFt", "l\xF2ng ng\u01B0\u1EDDi", "ng\u01B0\u1EDDi \u0111\u1EDDi", "n\xF4ng s\xE2u", "phong b\xEC", "qu\u1EA7n \xE1o", "t\xFAi qu\u1EA7n", "ti\u1EC1n m\u1EEBng", "b\u1EC1 ngo\xE0i", "ho\u1EA1n n\u1EA1n", "kh\xF3 kh\u0103n", "t\xECnh ngh\u0129a", "ch\u01A1i \u0111\u1EB9p", "xu\u1EA5t hi\u1EC7n", "khen ng\u1EE3i", "c\xE0y cu\u1ED1c", "ch\u01B0a ch\u1EAFc", "c\u1EF1c k\u1EF3", "b\u1EAFt m\u1EB7t", "tay b\u1EAFt", "m\u1EB7t m\u1EEBng", "n\u0103m tr\u0103m", "m\u1ED9t tri\u1EC7u", "hai tay", "th\u1EB1ng ngh\xE8o", "th\u1EB1ng gi\xE0u", "c\xF3 t\xE2m", "gia \u0111\xECnh", "cu\u1ED9c s\u1ED1ng", "con ng\u01B0\u1EDDi", "th\u1EDDi gian", "c\xF4ng vi\u1EC7c", "ti\u1EC1n b\u1EA1c", "b\u1EA1n b\xE8", "anh em", "cha m\u1EB9", "b\u1ED1 m\u1EB9", "v\u1EE3 ch\u1ED3ng", "con c\xE1i", "s\u1EE9c kh\u1ECFe", "kinh doanh", "kh\xE1ch h\xE0ng", "s\u1EA3n ph\u1EA9m", "th\xE0nh c\xF4ng", "th\u1EA5t b\u1EA1i", "h\u1EA1nh ph\xFAc", "\u01B0\u1EDBc m\u01A1", "c\u01A1 h\u1ED9i", "kinh nghi\u1EC7m", "ki\u1EBFn th\u1EE9c", "tr\xE1ch nhi\u1EC7m", "t\xF4n tr\u1ECDng", "y\xEAu th\u01B0\u01A1ng", "t\u1EF1 do", "t\u01B0\u01A1ng lai", "qu\xE1 kh\u1EE9", "hi\u1EC7n t\u1EA1i", "ng\xE0y mai", "h\xF4m nay", "b\xE2y gi\u1EDD", "l\xFAc n\xE0o", "t\u1EA1i sao", "nh\u01B0 th\u1EBF", "th\u1EBF n\xE0o", "bao nhi\xEAu", "kh\xF4ng ph\u1EA3i", "c\xF3 th\u1EC3", "vi\u1EC7c l\xE0m", "\u0111\u1ED3ng ti\u1EC1n", "s\u1EF1 th\u1EADt", "th\u1EADt s\u1EF1", "ch\u1EAFc ch\u1EAFn", "b\xECnh th\u01B0\u1EDDng", "\u0111\u1EB7c bi\u1EC7t", "quan tr\u1ECDng", "nhi\u1EC1u ng\u01B0\u1EDDi", "m\u1ECDi ng\u01B0\u1EDDi", "ai c\u0169ng"],
5569
+ "tuGhep": ["chu\u1EA9n x\xE1c", "ch\xEDnh x\xE1c", "d\xE3 man", "\u0111\u1EAFt gi\xE1", "tuy\u1EC7t \u0111\u1ED1i", "n\xE1t n\u01B0\u1EDBc", "n\u1ED9i dung", "s\xE1ng t\u1EA1o", "th\u01B0\u01A1ng hi\u1EC7u", "\u0111i\u1EC7n tho\u1EA1i", "t\xE0i li\u1EC7u", "th\u1ECB tr\u01B0\u1EDDng", "s\u1ED1 li\u1EC7u", "th\xE0nh ph\u1EA9m", "\xFD t\u01B0\u1EDFng", "b\u1EA3n th\xE2n", "t\u1ED1n ti\u1EC1n", "thu\xEA ngo\xE0i", "hi\u1EC7u \u1EE9ng", "n\u0103ng su\u1EA5t", "\u0111\u1ED1i th\u1EE7", "kh\xE1ch h\xE0ng", "qu\u1EA3ng c\xE1o", "anh em", "chuy\xEAn nghi\u1EC7p", "t\u1EF1 \u0111\u1ED9ng", "k\xEDch ho\u1EA1t", "\u0111i\u1EC7p vi\xEAn", "th\u1EA3nh th\u01A1i", "c\xE1 nh\xE2n", "\u0111\u1ECBa ph\u01B0\u01A1ng", "\u0111\xE0m tho\u1EA1i", "phong c\xE1ch", "v\xF4 h\u1ED3n", "d\u1EABn d\u1EAFt", "n\u1EAFm th\xF3p", "c\xF2ng l\u01B0ng", "\u1EA3o di\u1EC7u", "th\u1EF1c s\u1EF1", "t\xECm ki\u1EBFm", "m\u1EABu m\xE3", "\xE2m thanh", "h\xECnh \u1EA3nh", "gi\u1ECDng n\xF3i", "doanh thu", "b\xE1n h\xE0ng", "m\u1ED3 h\xF4i", "n\u01B0\u1EDBc m\u1EAFt", "l\xF2ng ng\u01B0\u1EDDi", "ng\u01B0\u1EDDi \u0111\u1EDDi", "n\xF4ng s\xE2u", "phong b\xEC", "qu\u1EA7n \xE1o", "t\xFAi qu\u1EA7n", "ti\u1EC1n m\u1EEBng", "b\u1EC1 ngo\xE0i", "ho\u1EA1n n\u1EA1n", "kh\xF3 kh\u0103n", "t\xECnh ngh\u0129a", "ch\u01A1i \u0111\u1EB9p", "xu\u1EA5t hi\u1EC7n", "khen ng\u1EE3i", "c\xE0y cu\u1ED1c", "ch\u01B0a ch\u1EAFc", "c\u1EF1c k\u1EF3", "b\u1EAFt m\u1EB7t", "tay b\u1EAFt", "m\u1EB7t m\u1EEBng", "n\u0103m tr\u0103m", "m\u1ED9t tri\u1EC7u", "hai tay", "th\u1EB1ng ngh\xE8o", "th\u1EB1ng gi\xE0u", "c\xF3 t\xE2m", "gia \u0111\xECnh", "cu\u1ED9c s\u1ED1ng", "con ng\u01B0\u1EDDi", "th\u1EDDi gian", "c\xF4ng vi\u1EC7c", "ti\u1EC1n b\u1EA1c", "b\u1EA1n b\xE8", "anh em", "cha m\u1EB9", "b\u1ED1 m\u1EB9", "v\u1EE3 ch\u1ED3ng", "con c\xE1i", "s\u1EE9c kh\u1ECFe", "kinh doanh", "kh\xE1ch h\xE0ng", "s\u1EA3n ph\u1EA9m", "th\xE0nh c\xF4ng", "th\u1EA5t b\u1EA1i", "h\u1EA1nh ph\xFAc", "\u01B0\u1EDBc m\u01A1", "c\u01A1 h\u1ED9i", "kinh nghi\u1EC7m", "ki\u1EBFn th\u1EE9c", "tr\xE1ch nhi\u1EC7m", "t\xF4n tr\u1ECDng", "y\xEAu th\u01B0\u01A1ng", "t\u1EF1 do", "t\u01B0\u01A1ng lai", "qu\xE1 kh\u1EE9", "hi\u1EC7n t\u1EA1i", "ng\xE0y mai", "h\xF4m nay", "b\xE2y gi\u1EDD", "l\xFAc n\xE0o", "t\u1EA1i sao", "nh\u01B0 th\u1EBF", "th\u1EBF n\xE0o", "bao nhi\xEAu", "kh\xF4ng ph\u1EA3i", "c\xF3 th\u1EC3", "vi\u1EC7c l\xE0m", "\u0111\u1ED3ng ti\u1EC1n", "s\u1EF1 th\u1EADt", "th\u1EADt s\u1EF1", "ch\u1EAFc ch\u1EAFn", "b\xECnh th\u01B0\u1EDDng", "\u0111\u1EB7c bi\u1EC7t", "quan tr\u1ECDng", "nhi\u1EC1u ng\u01B0\u1EDDi", "m\u1ECDi ng\u01B0\u1EDDi", "ai c\u0169ng"],
5531
5570
  "huTu": ["c\u1EE9", "c\xF3", "c\xE1i", "c\u1EE7a", "c\xE1c", "l\xE0", "l\xFAc", "l\u1EA1i", "n\xF3", "n\xE0y", "nh\u1EEFng", "nh\u01B0ng", "kh\xF4ng", "khi", "th\xEC", "m\xE0", "\u0111\xE3", "\u0111\u01B0\u1EE3c", "\u0111\u1EC3", "\u0111\u1EBFn", "\u0111i", "\u0111\xE2u", "\u1EDF", "v\xE0", "v\u1EDBi", "v\xE0o", "ra", "r\u1ED3i", "s\u1EBD", "sao", "ai", "\u1EA1", "\u1EA5y", "cho", "c\u0169ng", "c\xF2n", "ch\u1EC9", "ch\u1EE9", "n\xEAn", "n\u1EBFu", "v\xEC", "v\u1EC1", "t\u1EEB", "trong", "ngo\xE0i", "tr\xEAn", "d\u01B0\u1EDBi", "m\u1ED9t", "hai", "ba", "bao", "b\u1ECB", "b\u1EB1ng", "\u0111\xF3", "kia", "n\xE0o", "th\u1EBF", "v\u1EADy", "hay", "ho\u1EB7c", "r\u1EA5t", "qu\xE1", "l\u1EAFm", "nh\xE9", "nha", "\xE0", "\u1EEB", "\u01A1"]
5532
5571
  };
5533
5572
  var mauPrism_default = PRISM;
@@ -7247,7 +7286,8 @@ function matRa(fm, a, b, le, z = 1, zc = [0.5, 0.5]) {
7247
7286
  const q = (v, i) => 0.5 + (zc[i] + (v - zc[i]) * z - 0.5) * 1.111;
7248
7287
  return [
7249
7288
  q(Math.min(...ss.map((x) => x.face.x)), 0) - le[0],
7250
- q(Math.min(...ss.map((x) => x.headTop ?? x.face.y)), 1) - le[1],
7289
+ q(Math.min(...ss.map((x) => Math.min(x.headTop ?? 1, x.face.y - x.face.h * 0.3))), 1) - le[1],
7290
+ /* 10/10 cm71 (chữ phụ đè tóc khi CÓ bản đồ mặt): headTop = điểm 10 − 0,18 mặt = mép trán, chưa có tóc → đỉnh tóc ≈ điểm 10 − 0,30 mặt (đọc lúc dùng, đúng cả bản đồ cũ) */
7251
7291
  q(Math.max(...ss.map((x) => x.face.x + x.face.w)), 0) + le[2],
7252
7292
  q(Math.max(...ss.map((x) => x.chin ?? x.face.y + x.face.h)), 1) + le[3]
7253
7293
  ];
@@ -9519,6 +9559,17 @@ var eSoft = (x) => {
9519
9559
  var FB = "'Be Vietnam Pro', 'Segoe UI', sans-serif";
9520
9560
  var CAM = "rgb(232,112,52)";
9521
9561
  var VANG = "rgb(255,214,60)";
9562
+ var napPhongViet = () => {
9563
+ try {
9564
+ const d = globalThis.document;
9565
+ if (!d || !d.fonts) return Promise.resolve(0);
9566
+ const mau7 = "\u1EA0\u1EB6\u1EAC\u1EB8\u1EC6\u1ECA\u1ECC\u1ED8\u1EE2\u1EE4\u1EF0\u1EF4 \u1EA1\u1EB7\u1EAD\u1EB9\u1EC7\u1ECB\u1ECD\u1ED9\u1EE3\u1EE5\u1EF1\u1EF5 \u0110\xC0\u1EA2\xC3\xC1\xC8\u1EBA\u1EBC\xC9\u1EC0\u1EC2\u1EC4\u1EBE";
9567
+ return Promise.all(["700", "800", "900", "italic 700", "italic 800", "italic 900"].map((k) => d.fonts.load(k + " 64px 'Be Vietnam Pro'", mau7).catch(() => 0)));
9568
+ } catch (e) {
9569
+ return Promise.resolve(0);
9570
+ }
9571
+ };
9572
+ napPhongViet();
9522
9573
  var mo2 = (tuoi, dai2, vao = 0.15, ra = 0.15) => kep12(Math.min(tuoi / vao, (dai2 - tuoi) / ra));
9523
9574
  function nenCam(W4, H2, toi = false) {
9524
9575
  return nho2("cmNen" + (toi ? "T" : "") + W4 + "x" + H2, () => {
@@ -9589,6 +9640,7 @@ function kieuChu() {
9589
9640
  }
9590
9641
  function chu2(g, txt, x, y, px, kieu, a = 1, maxW = 0) {
9591
9642
  if (!txt || a <= 0) return;
9643
+ txt = String(txt).normalize("NFC");
9592
9644
  g.save();
9593
9645
  g.globalAlpha = a;
9594
9646
  const KC = kieu === "brand" || kieu === "cam" ? {} : kieuChu();
@@ -9684,6 +9736,100 @@ function locFx(fx) {
9684
9736
  if (fx.xam) a.push("grayscale(" + Math.min(1, Math.abs(+fx.xam)).toFixed(2) + ")");
9685
9737
  return a.join(" ");
9686
9738
  }
9739
+ var NUA_DUOI_CY = 0.63;
9740
+ function sNuaDuoi(F) {
9741
+ return F ? Math.max(0.5, Math.min(1, 0.26 / Math.max(0.08, F[2] - F[0]))) : 0.75;
9742
+ }
9743
+ function tfTam(g, W4, H2, F, s, cy) {
9744
+ const cx = F ? (F[0] + F[2]) / 2 : 0.5, fy = F ? (F[1] + F[3]) / 2 : 0.4;
9745
+ g.translate(W4 / 2 - cx * W4 * s, cy * H2 - fy * H2 * s);
9746
+ g.scale(s, s);
9747
+ }
9748
+ var dauCache = /* @__PURE__ */ new WeakMap();
9749
+ function hopNguoi(p, key) {
9750
+ if (!p) return null;
9751
+ const kc = key || p;
9752
+ if (dauCache.has(kc)) return dauCache.get(kc);
9753
+ let r = null;
9754
+ try {
9755
+ const c = new OffscreenCanvas(36, 64), x = c.getContext("2d", { willReadFrequently: true });
9756
+ x.drawImage(p, 0, 0, 36, 64);
9757
+ const d = x.getImageData(0, 0, 36, 64).data;
9758
+ let top = -1, l = 36, rr = -1;
9759
+ for (let y = 0; y < 64 && top < 0; y++) for (let i = 7; i < 29; i++) if (d[(y * 36 + i) * 4 + 3] > 128) {
9760
+ top = y;
9761
+ break;
9762
+ }
9763
+ if (top >= 0) {
9764
+ let wm = 0;
9765
+ for (let y = top; y < Math.min(64, top + 26); y++) {
9766
+ let a0 = -1, b0 = -1;
9767
+ for (let i = 0; i < 36; i++) if (d[(y * 36 + i) * 4 + 3] > 128) {
9768
+ if (a0 < 0) a0 = i;
9769
+ b0 = i;
9770
+ }
9771
+ if (a0 < 0) continue;
9772
+ const w = b0 - a0 + 1;
9773
+ if (y > top + 3 && wm > 0 && (w < wm * 0.8 || w > wm * 1.35)) break;
9774
+ if (w > wm) wm = w;
9775
+ l = Math.min(l, a0);
9776
+ rr = Math.max(rr, b0);
9777
+ }
9778
+ r = [l / 36, top / 64, (rr + 1) / 36, Math.min(1, top / 64 + 1.3 * ((rr + 1 - l) / 36) * (p.width / p.height))];
9779
+ }
9780
+ } catch (e) {
9781
+ r = null;
9782
+ }
9783
+ dauCache.set(kc, r);
9784
+ return r;
9785
+ }
9786
+ globalThis.__dauCanh = (d, nen2, W4, H2) => dauCanh(d, nen2, W4, H2);
9787
+ function dauCanh(d, nen2, W4, H2) {
9788
+ if (!nen2 || !d) return null;
9789
+ if (dauCache.has(d)) return dauCache.get(d);
9790
+ return hopNguoi(nguoi(nen2, W4, H2), d);
9791
+ }
9792
+ function phongDinh(F, z) {
9793
+ if (!F || !(z > 1.001)) return F;
9794
+ const fy = (F[1] + F[3]) / 2;
9795
+ return [F[0], Math.max(0, fy - (fy - F[1]) * z), F[2], F[3]];
9796
+ }
9797
+ function datChuNhan(g, W4, H2, F, giant, chu22, pxG, pxC, kieuG, maxW, tren = 0.075) {
9798
+ const KC = kieuChu(), FBc = KC.font ? "'" + KC.font + "', " + FB : FB;
9799
+ const do1 = (txt2, px, k2) => {
9800
+ if (!txt2) return { px: 0, h: 0 };
9801
+ const ng = k2 === "brand" || k2 === "cam" || KC.nghieng === false ? "" : "italic ";
9802
+ g.save();
9803
+ g.font = ng + "900 " + px.toFixed(1) + "px " + FBc;
9804
+ const dong = String(txt2).split(String.fromCharCode(10));
9805
+ const w = Math.max(...dong.map((x) => g.measureText(x).width));
9806
+ g.restore();
9807
+ const p2 = w > maxW ? px * maxW / w : px, lh = p2 * (k2 === "giant" ? 1.12 : 1.15);
9808
+ return { px: p2, h: (dong.length - 1) * lh + lh * 1.05 };
9809
+ };
9810
+ const a = do1(giant, pxG, kieuG), b = do1(chu22, pxC, "vang"), gap = chu22 ? 0.012 * H2 : 0;
9811
+ let need = a.h + b.h + gap;
9812
+ const dinh = ((F ? F[1] : 0.2) - 0.038) * H2, top0 = tren * H2;
9813
+ let k = 1, y0 = top0, truoc = false, txt = giant;
9814
+ if (dinh - top0 < need * 0.55 && String(giant || "").indexOf(String.fromCharCode(10)) >= 0) {
9815
+ const g1 = String(giant).split(String.fromCharCode(10)).map((x) => x.trim()).join(" "), a1 = do1(g1, pxG, kieuG), need1 = a1.h + b.h + gap;
9816
+ if (dinh - top0 >= need1 * 0.55) {
9817
+ txt = g1;
9818
+ a.px = a1.px;
9819
+ a.h = a1.h;
9820
+ need = need1;
9821
+ }
9822
+ }
9823
+ if (dinh - top0 >= need * 0.55) k = Math.min(1, (dinh - top0) / need);
9824
+ else {
9825
+ const n0 = (F ? Math.max(0.62, F[3] + 0.04) : 0.66) * H2, n1 = 0.83 * H2;
9826
+ k = Math.max(0.5, Math.min(1, (n1 - n0) / need));
9827
+ y0 = Math.min(n0, n1 - need * k);
9828
+ truoc = true;
9829
+ }
9830
+ const hG = a.h * k, hC = b.h * k;
9831
+ return { yG: (y0 + hG / 2) / H2, yC: (y0 + hG + gap + hC / 2) / H2, pxG: a.px * k, pxC: b.px * k, truoc, txt };
9832
+ }
9687
9833
  function tf(g, W4, H2, F, s, yDau) {
9688
9834
  const cx = F ? (F[0] + F[2]) / 2 : 0.5, top = F ? F[1] : 0.2;
9689
9835
  g.translate(W4 / 2 - cx * W4 * s, yDau * H2 - top * H2 * s);
@@ -9918,8 +10064,15 @@ function taiLieu(g, ds2, tuoi, W4, H2, a) {
9918
10064
  g.restore();
9919
10065
  }
9920
10066
  dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10067
+ if (d.bo === "chia" && d.ten && nen2 && !(d.dong && d.dong.length) && !/^vat:/.test(String(d.ten))) {
10068
+ const im0 = khungTS(d.ten, tuoi);
10069
+ if (im0 && im0.height > im0.width * 1.15) {
10070
+ KHOI2.cmAnh(g, { ...d, bo: "anh", pip: 1 }, tuoi, W4, H2, nen2, _s, dai2);
10071
+ return;
10072
+ }
10073
+ }
9921
10074
  if (d.bo === "chia" && d.ten && nen2 && !(d.dong && d.dong.length) && !khungTS(d.ten, tuoi)) d = { ...d, bo: "cut", giant: d.chu, chu: void 0, ten: void 0, huong: 2, yDau: 0.36 };
9922
- const a = mo2(tuoi, dai2, d.vao ?? 0.07, d.ra ?? 0.07), F = d.F || null, ka = eOut(tuoi / 0.25);
10075
+ const a = mo2(tuoi, dai2, d.vao ?? 0.07, d.ra ?? 0.07), F = d.F || (/^(chia|card|cut|depth|tron)$/.test(String(d.bo)) ? dauCanh(d, nen2, W4, H2) : null), ka = eOut(tuoi / 0.25);
9923
10076
  if (a <= 0) return;
9924
10077
  g.save();
9925
10078
  g.globalAlpha = a;
@@ -9928,15 +10081,19 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
9928
10081
  if (fS) g.filter = fS;
9929
10082
  }
9930
10083
  const kS = 1;
9931
- const p = (d.bo === "card" || d.bo === "depth" || d.bo === "cut" && !d.anNguoi) && nen2 ? nguoi(nen2, W4, H2) : null;
10084
+ const p = (d.bo === "depth" || d.bo === "cut" && !d.anNguoi) && nen2 ? nguoi(nen2, W4, H2) : null;
9932
10085
  const hv = d.huong ?? -1, kv = 1 - Math.pow(1 - Math.min(1, tuoi / 0.35), 3), ox = hv === 0 ? -(1 - kv) * 0.3 * W4 : hv === 1 ? (1 - kv) * 0.3 * W4 : 0, oy = hv === 2 ? (1 - kv) * 0.1 * H2 : 0;
9933
10086
  const zk = d.z && nen2 ? 1 + (d.z - 1) * (1 - eOut(Math.min(1, tuoi / 0.6))) : d.phong && nen2 ? 1 + (d.phong - 1) * (tuoi < 0.42 ? 1 : 1 - eOut((tuoi - 0.42) / 0.33)) : 1;
10087
+ if (F && (d.bo === "depth" || d.bo === "cut")) {
10088
+ const fx = (F[0] + F[2]) / 2, fy = (F[1] + F[3]) / 2, cxs = d.bo === "cut" ? 0.5 : fx;
10089
+ globalThis.__dauMH = [cxs - (fx - F[0]) * zk, fy - (fy - F[1]) * zk, cxs + (F[2] - fx) * zk, fy + (F[3] - fy) * zk];
10090
+ }
9934
10091
  if (d.bo === "card" || d.bo === "cut" || d.bo === "toi") {
9935
10092
  g.drawImage(nenCam(W4, H2, d.bo === "toi" || !!d.toiNen), 0, 0);
9936
10093
  if (d.bo === "card" && nen2) {
9937
10094
  g.save();
9938
10095
  g.translate(ox, oy);
9939
- const yT = Math.min(0.715, (d.yDau ?? 0.46) + 0.255), x = 0.07 * W4, y = yT * H2, w = 0.86 * W4, h = (0.985 - yT) * H2, r = 46 * W4 / 1080, s = d.s || 1;
10096
+ const yT = 0.5, x = 0.07 * W4, y = yT * H2, w = 0.86 * W4, h = (0.985 - yT) * H2, r = 46 * W4 / 1080, s = d.s || 1;
9940
10097
  hop3(g, "the:card", x, y, x + w, y + h);
9941
10098
  g.save();
9942
10099
  g.shadowColor = "rgba(0,0,0,0.45)";
@@ -9949,36 +10106,21 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
9949
10106
  g.save();
9950
10107
  bo(g, x, y, w, h, r);
9951
10108
  g.clip();
9952
- tfE(g, W4, H2, F, s, d.yDau ?? 0.42, kS);
10109
+ tfTam(g, W4, H2, F, sNuaDuoi(F), NUA_DUOI_CY);
9953
10110
  g.drawImage(nen2, 0, 0, W4, H2);
9954
10111
  g.restore();
10112
+ void s;
9955
10113
  g.save();
9956
10114
  bo(g, x, y, w, h, r);
9957
10115
  g.lineWidth = 4 * W4 / 1080;
9958
10116
  g.strokeStyle = "rgba(255,255,255,0.35)";
9959
10117
  g.stroke();
9960
10118
  g.restore();
9961
- if (p) {
9962
- g.save();
9963
- tfE(g, W4, H2, F, s, d.yDau ?? 0.42, kS);
9964
- g.drawImage(p, 0, 0, W4, H2);
9965
- g.restore();
9966
- }
9967
10119
  g.restore();
9968
10120
  } else if (d.bo === "cut" && p && !d.anNguoi) {
9969
10121
  g.save();
9970
10122
  g.translate(ox, oy);
9971
- tfE(
9972
- g,
9973
- W4,
9974
- H2,
9975
- F,
9976
- d.s || 1,
9977
- d.yDau ?? 0.36,
9978
- kS,
9979
- zk
9980
- /* 09/10 lát 2 ⑧: phóng chồng */
9981
- );
10123
+ F ? tfTam(g, W4, H2, F, zk, (F[1] + F[3]) / 2) : tfE(g, W4, H2, F, 1, 0.2, kS, zk);
9982
10124
  g.drawImage(p, 0, 0, W4, H2);
9983
10125
  g.restore();
9984
10126
  }
@@ -9999,7 +10141,8 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
9999
10141
  c.drawImage(nen2, 0, 0, W4, H2);
10000
10142
  }, Math.round(0.012 * W4), "brightness(0.8)");
10001
10143
  const kz = eOut(Math.min(1, tuoi / 0.5));
10002
- tfE(g, W4, H2, F, (d.s || 1.05) * (1 - 0.3 * kz), 0.5 + 0.015 * kz, kS);
10144
+ tfTam(g, W4, H2, F, sNuaDuoi(F) * (1 + 0.12 * (1 - kz)), NUA_DUOI_CY);
10145
+ void kS;
10003
10146
  g.drawImage(nen2, 0, 0, W4, H2);
10004
10147
  }
10005
10148
  g.restore();
@@ -10066,17 +10209,28 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10066
10209
  g.drawImage(nen2, cx - cxF * W4 * s, cy - 0.08 * r - cyF * H2 * s, W4 * s, H2 * s);
10067
10210
  g.restore();
10068
10211
  }
10212
+ let daC2 = false;
10069
10213
  if (d.bo === "depth") {
10070
- const yG = d.yChu ?? 0.24, truoc = d.yChu != null && F && yG > F[1] - 0.06 && yG < F[3];
10071
- const veChu = () => chu2(g, d.giant, W4 / 2, yG * H2 + (d.z ? 0 : (1 - ka) * 70 * H2 / 1920), 165 * (d.coChu || 1) * H2 / 1920, "giant", d.z ? 1 : kep12(tuoi / 0.2), 0.76 * W4);
10214
+ const F6 = phongDinh(F || hopNguoi(p, d), d.z || d.phong || 1), L6 = d.yChu == null && F6 ? datChuNhan(g, W4, H2, F6, d.giant, /\n/.test(String(d.giant || "")) ? "" : d.chu2 || "", 165 * (d.coChu || 1) * H2 / 1920, 96 * H2 / 1920, "giant", 0.76 * W4, d.thanh ? 0.1 : 0.075) : null;
10215
+ daC2 = !!(L6 && d.chu2 && !/\n/.test(String(d.giant || "")));
10216
+ const yG = L6 ? L6.yG : d.yChu ?? 0.24, truoc = L6 ? L6.truoc : !!(d.yChu != null && F && yG > F[1] - 0.06 && yG < F[3]);
10217
+ const veChu = () => {
10218
+ chu2(g, L6 && L6.txt || d.giant, W4 / 2, yG * H2 + (d.z ? 0 : (1 - ka) * 70 * H2 / 1920), L6 ? L6.pxG : 165 * (d.coChu || 1) * H2 / 1920, "giant", d.z ? 1 : kep12(tuoi / 0.2), 0.76 * W4);
10219
+ if (daC2 && L6) chu2(g, d.chu2, W4 / 2, L6.yC * H2, L6.pxC, d.do2 ? "do" : "vang", kep12((tuoi - 0.35) / 0.15), 0.76 * W4);
10220
+ };
10072
10221
  if (!truoc) veChu();
10073
10222
  if (p) {
10074
10223
  if (zk > 1.001) phongK(g, p, W4, H2, F, zk);
10075
10224
  else g.drawImage(p, 0, 0, W4, H2);
10076
10225
  }
10077
10226
  if (truoc) veChu();
10078
- } else if (d.giant) chu2(g, d.giant, W4 / 2, (d.yChu ?? (d.v3 ? 0.145 : d.bo === "toi" ? 0.4 : d.bo === "tron" ? 0.25 : 0.2)) * H2 + (1 - ka) * 70 * H2 / 1920, (d.cam ? 170 : d.v3 ? 108 : 132) * (d.coChu || 1) * H2 / 1920, d.cam ? "cam" : d.do ? "do" : "kw", kep12(tuoi / 0.06), 0.78 * W4);
10079
- if (d.chu2 && d.bo !== "chia" && !(d.bo === "depth" && /\n/.test(String(d.giant || "")))) chu2(g, d.chu2, W4 / 2, (d.bo === "depth" ? (d.yChu ?? 0.24) + 0.02 : d.yChu ?? (d.bo === "toi" ? 0.4 : d.bo === "tron" ? 0.25 : 0.2)) * H2 + (/\n/.test(String(d.giant || "")) ? 290 : d.cam ? 200 : 150) * (d.coChu || 1) * H2 / 1920, 96 * H2 / 1920 * (d.z ? 1 + 0.7 * (1 - eOut((tuoi - 0.35) / 0.35)) : 1), d.do2 ? "do" : d.bo === "cut" || d.bo === "tron" || d.bo === "toi" ? "kw" : "vang", kep12((tuoi - 0.35) / 0.15), 0.76 * W4);
10227
+ } else if (d.giant) {
10228
+ const F6c = phongDinh(F || hopNguoi(p, d), d.z || d.phong || 1), L6c = d.bo === "cut" && d.yChu == null && F6c && !d.v3 ? datChuNhan(g, W4, H2, F6c, d.giant, d.chu2 || "", (d.cam ? 170 : 132) * (d.coChu || 1) * H2 / 1920, 96 * H2 / 1920, d.cam ? "cam" : "kw", 0.78 * W4, d.thanh ? 0.1 : 0.075) : null;
10229
+ daC2 = !!(L6c && d.chu2);
10230
+ if (L6c && d.chu2) chu2(g, d.chu2, W4 / 2, L6c.yC * H2, L6c.pxC, d.do2 ? "do" : "kw", kep12((tuoi - 0.35) / 0.15), 0.76 * W4);
10231
+ chu2(g, L6c && L6c.txt || d.giant, W4 / 2, (L6c ? L6c.yG : d.yChu ?? (d.v3 ? 0.145 : d.bo === "toi" ? 0.4 : d.bo === "tron" ? 0.25 : 0.2)) * H2 + (1 - ka) * 70 * H2 / 1920, L6c ? L6c.pxG : (d.cam ? 170 : d.v3 ? 108 : 132) * (d.coChu || 1) * H2 / 1920, d.cam ? "cam" : d.do ? "do" : "kw", kep12(tuoi / 0.06), 0.78 * W4);
10232
+ }
10233
+ if (d.chu2 && !daC2 && d.bo !== "chia" && !(d.bo === "depth" && /\n/.test(String(d.giant || "")))) chu2(g, d.chu2, W4 / 2, (d.bo === "depth" ? (d.yChu ?? 0.24) + 0.02 : d.yChu ?? (d.bo === "toi" ? 0.4 : d.bo === "tron" ? 0.25 : 0.2)) * H2 + (/\n/.test(String(d.giant || "")) ? 290 : d.cam ? 200 : 150) * (d.coChu || 1) * H2 / 1920, 96 * H2 / 1920 * (d.z ? 1 + 0.7 * (1 - eOut((tuoi - 0.35) / 0.35)) : 1), d.do2 ? "do" : d.bo === "cut" || d.bo === "tron" || d.bo === "toi" ? "kw" : "vang", kep12((tuoi - 0.35) / 0.15), 0.76 * W4);
10080
10234
  const vt = d.v3 && taiSan(d.v3), dl = String(d.giant || "").indexOf(String.fromCharCode(10)) >= 0;
10081
10235
  if (vt) {
10082
10236
  const p2 = eSoft((tuoi - 0.1) / 0.3), hh = (dl ? 0.2 : 0.26) * H2 * (0.9 + 0.1 * p2), ww = Math.min(hh * vt.width / vt.height, 0.6 * W4), h2 = ww * vt.height / vt.width;
@@ -10085,7 +10239,20 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10085
10239
  g.shadowColor = "rgba(60,20,0,0.45)";
10086
10240
  g.shadowBlur = 0.03 * W4;
10087
10241
  g.shadowOffsetY = 0.015 * W4;
10088
- g.drawImage(vt, W4 / 2 - ww / 2, (dl ? 0.355 : 0.3) * H2 - h2 / 2, ww, h2);
10242
+ let yv = (dl ? 0.355 : 0.3) * H2, hv2 = h2, wv = ww;
10243
+ {
10244
+ const Fv = phongDinh(F || hopNguoi(p, d), d.z || d.phong || 1), day = Fv ? (Fv[1] - 0.02) * H2 : H2;
10245
+ if (yv + hv2 / 2 > day) {
10246
+ const t0v = (dl ? 0.26 : 0.2) * H2, cao = day - t0v;
10247
+ if (cao < 0.08 * H2) hv2 = 0;
10248
+ else {
10249
+ hv2 = Math.min(hv2, cao);
10250
+ wv = hv2 * vt.width / vt.height;
10251
+ yv = t0v + hv2 / 2;
10252
+ }
10253
+ }
10254
+ }
10255
+ if (hv2 > 0) g.drawImage(vt, W4 / 2 - wv / 2, yv - hv2 / 2, wv, hv2);
10089
10256
  g.restore();
10090
10257
  }
10091
10258
  if (d.tieu) chu2(g, d.tieu, W4 / 2, 0.135 * H2 + (1 - ka) * 70 * H2 / 1920, 122 * H2 / 1920, "brand", kep12(tuoi / 0.15), 0.76 * W4);
@@ -10524,7 +10691,19 @@ dangKy("cmKinh", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10524
10691
  dangKy("cmSticker", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
10525
10692
  const a = kep13(Math.min(1, (dai2 - tuoi) / 0.07));
10526
10693
  if (a > 0 && d.logo) return veLogo(g, d.logo, d.hex, (d.x ?? 0.5) * W4, (d.y ?? 0.17) * H2, (d.r ?? 0.085) * W4, tuoi - (d.tre ?? 0), a);
10527
- if (a > 0) veSticker3(g, d.st, (d.x ?? 0.82) * W4, (d.y ?? 0.3) * H2, (d.r ?? 0.065) * W4, tuoi - (d.tre ?? 0.25), a);
10694
+ if (a > 0) {
10695
+ const G3 = globalThis, r = d.r ?? 0.065, ry = r * W4 / H2;
10696
+ let x = d.x ?? 0.82, y = d.y ?? 0.3;
10697
+ const B = G3.__dauMH || (G3.__dauCanh && _n ? G3.__dauCanh(d, _n, W4, H2) : null);
10698
+ if (B) {
10699
+ const dung = (cx, cy) => cx - r >= 0.02 && cx + r <= 0.98 && cy - ry >= 0.09 && cy + ry <= 0.9 && (cx + r < B[0] - 0.02 || cx - r > B[2] + 0.02 || cy + ry < B[1] - 0.02 || cy - ry > B[3] + 0.02);
10700
+ const yc = Math.min(0.86, B[3] + 0.04 + ry), c = [[x, y], [1 - x, y], [x < 0.5 ? 0.13 : 0.87, yc], [x < 0.5 ? 0.87 : 0.13, yc]].find((p) => dung(p[0], p[1]));
10701
+ if (!c) return;
10702
+ x = c[0];
10703
+ y = c[1];
10704
+ }
10705
+ veSticker3(g, d.st, x * W4, y * H2, r * W4, tuoi - (d.tre ?? 0.25), a);
10706
+ }
10528
10707
  });
10529
10708
 
10530
10709
  // flow-src/engine/khoiCuongMe.ts
@@ -10742,7 +10921,7 @@ function lapCuongMe(o) {
10742
10921
  return;
10743
10922
  }
10744
10923
  }
10745
- muc.push({ f: f2, c, ten: suaChu(sach2(m.ten || "")) || tenRieng(suaChu(String(m.tu || "")).split(/\s+/)), mo: suaChu(sach2(m.mo || "")), kq: (Array.isArray(m.kq) ? m.kq : []).map((x) => suaChu(sach2(String(x)))).filter(Boolean).slice(0, 3) });
10924
+ muc.push({ f: f2, c, cach, ten: suaChu(sach2(m.ten || "")) || tenRieng(suaChu(String(m.tu || "")).split(/\s+/)), mo: suaChu(sach2(m.mo || "")), kq: (Array.isArray(m.kq) ? m.kq : []).map((x) => suaChu(sach2(String(x)))).filter(Boolean).slice(0, 3) });
10746
10925
  truocM = f2 + 1;
10747
10926
  });
10748
10927
  {
@@ -10782,6 +10961,10 @@ function lapCuongMe(o) {
10782
10961
  muc.push({ f: c.f, c, ten: ten2 });
10783
10962
  });
10784
10963
  }
10964
+ if (muc.length < 2) {
10965
+ if (muc.length) ghiL("bo", { bo: "muc", f: muc[0].f, d: 0 }, "chi 1 muc \u2192 khong phai video liet ke, bo the muc: " + String(muc[0].ten || ""));
10966
+ muc.length = 0;
10967
+ }
10785
10968
  const cta = cs.filter((c) => c.f > tong * 0.7 && /comment|bình luận|cmt|lưu video|lưu lại|theo dõi|follow|đăng ký/.test(" " + c.chu.join(" ").toLocaleLowerCase("vi") + " "))[0];
10786
10969
  const hetMuc = cta && muc.length && cta.f > muc[muc.length - 1].f + 4 ? cta.f : tong;
10787
10970
  muc.forEach((m, k) => {
@@ -10789,6 +10972,8 @@ function lapCuongMe(o) {
10789
10972
  m.ten = m.ten || cum2(m.c.chu);
10790
10973
  });
10791
10974
  const N = muc.length, ten = muc.map((m) => m.ten);
10975
+ const loiDem = W22.map((w) => w.t).join(" "), coBuoc = N >= 3 && (muc.filter((m) => m.cach === "ten").length >= Math.ceil(N * 0.6) || /(đầu tiên|thứ hai|thứ ba|thứ tư|tiếp theo|cuối cùng|số một|số hai|số ba|bước một|bước hai|thứ nhất)/.test(loiDem));
10976
+ globalThis.__coBuoc = { N, coBuoc, ten: muc.filter((m) => m.cach === "ten").length };
10792
10977
  const sp = [];
10793
10978
  let ctxSt = "";
10794
10979
  const IC = { tien: "xu", dongho: "dongho", canhbao: "canh", tich: "tich", bieudo: "bieu", tim: "tim", khong: "none" };
@@ -10905,14 +11090,14 @@ function lapCuongMe(o) {
10905
11090
  })(sach2(kb?.moc || layMoc(ws, kb)).split(" "))) || hoa3(cum2(cs[0] ? cs[0].chu : []));
10906
11091
  const Lm = Math.min(Math.max(2.4, docGiay(moc) + 0.4), Math.max(1.2, f1 - 0.3));
10907
11092
  bc = "B2 moc";
10908
- de(0, Lm, { uuTien: UT.moc, bo: "depth", giant: haiDong4(moc, 11), chu2: N >= 2 ? N + " " + LOAI2 : "", yChu: 0.165, vao: 1e-3, z: 1.3, keu: "whoosh" });
10909
- if (N >= 2 && f1 - Lm > 3.4) de(Lm + 0.3, Math.min(3.2, f1 - Lm - 0.6), { uuTien: UT.moc, bo: "cut", tieu: N + " " + LOAI2, hang: muc.map((m) => m.ten).slice(0, 8), keu: "pop", st: "chuot", stX: 0.43, stY: 0.188, stR: 0.042, stTre: 1.2 });
11093
+ de(0, Lm, { uuTien: UT.moc, bo: "depth", giant: haiDong4(moc, 11), chu2: coBuoc ? N + " " + LOAI2 : "", yChu: 0.165, vao: 1e-3, z: 1.3, keu: "whoosh" });
11094
+ if (coBuoc && f1 - Lm > 3.4) de(Lm + 0.3, Math.min(3.2, f1 - Lm - 0.6), { uuTien: UT.moc, bo: "cut", tieu: N + " " + LOAI2, hang: muc.map((m) => m.ten).slice(0, 8), keu: "pop", st: "chuot", stX: 0.43, stY: 0.188, stR: 0.042, stTre: 1.2 });
10910
11095
  else if (N >= 2) ghiL("bo", { bo: "cut", f: Lm + 0.3, d: 3.2 }, "moc ngan (f1 - Lm <= 3,4 s) \u2192 bo hang N muc");
10911
11096
  bc = "B3 the muc";
10912
11097
  muc.forEach((m, k) => {
10913
11098
  const L = m.b - m.f, Lc = Math.min(2.6, Math.max(2.2, 0.3 * L));
10914
11099
  const sau = suaChu(m.c.chu.map(sach2).join(" ")), go2 = sau.length > 48 ? sau.slice(0, 48).replace(/\s\S*$/, "") + "\u2026" : sau;
10915
- de(m.f, Lc, { uuTien: UT.card, bo: "card", tieu: hoa3(m.ten), so: k + 1, N, nhom: LOAI2, ui: { ten: m.ten, anh: "trang:" + String(m.ten).toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}]+/gu, ""), go: m.mo ? "/" + String(m.ten).toLocaleLowerCase("vi").normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/đ/g, "d").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") + " " + m.mo.toLocaleLowerCase("vi") : go2.toLocaleLowerCase("vi"), kq: m.kq }, keu: "whoosh-nhanh" });
11100
+ de(m.f, Lc, { uuTien: UT.card, bo: "card", tieu: hoa3(m.ten), so: coBuoc ? k + 1 : void 0, N, nhom: LOAI2, ui: !/SKILL|CÔNG CỤ|TOOL|APP/i.test(LOAI2) ? void 0 : { ten: m.ten, anh: "trang:" + String(m.ten).toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}]+/gu, ""), go: m.mo ? "/" + String(m.ten).toLocaleLowerCase("vi").normalize("NFD").replace(/[̀-ͯ]/g, "").replace(/đ/g, "d").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") + " " + m.mo.toLocaleLowerCase("vi") : go2.toLocaleLowerCase("vi"), kq: m.kq }, keu: "whoosh-nhanh" });
10916
11101
  if (L >= 10 && !(kb?.canh || []).length) {
10917
11102
  const c = cs.filter((x) => x.f >= m.f + Lc + 2 && x.f + 2.4 <= m.b - 1).sort((p, q) => Math.abs(p.f - (m.f + L * 0.6)) - Math.abs(q.f - (m.f + L * 0.6)))[0];
10918
11103
  if (c) {
@@ -11081,7 +11266,7 @@ function lapCuongMe(o) {
11081
11266
  const m = a + k * (b - a) / (n + 1), i = W22.findIndex((w) => w.f >= m - 0.3);
11082
11267
  if (i < 0 || W22[i].f > b - 2.3) continue;
11083
11268
  const km = muc.findIndex((x) => W22[i].f >= x.f + 8 && W22[i].f < x.b - 4.5);
11084
- if (km >= 0 && !muc[km].nhac && (muc[km].nhac = dat(W22[i].f, 2.4, { uuTien: UT.nhac, bo: "cut", tieu: hoa3(muc[km].ten), so: km + 1, N, nhom: LOAI2, hang: muc[km].kq && muc[km].kq.length ? muc[km].kq : void 0, keu: "pop" }, 0.5))) continue;
11269
+ if (km >= 0 && !muc[km].nhac && (muc[km].nhac = dat(W22[i].f, 2.4, { uuTien: UT.nhac, bo: "cut", tieu: hoa3(muc[km].ten), so: coBuoc ? km + 1 : void 0, N, nhom: LOAI2, hang: muc[km].kq && muc[km].kq.length ? muc[km].kq : void 0, keu: "pop" }, 0.5))) continue;
11085
11270
  }
11086
11271
  });
11087
11272
  }
@@ -12013,7 +12198,7 @@ function lapCuongMe(o) {
12013
12198
  }
12014
12199
  G4.__lichSp = sp.map((s, i) => ({ i, id: s.id, yChu: s.yChu, coChu: s.coChu, fx: s.fx, stX: s.stX, stY: s.stY, f: +s.f.toFixed(2), d: +s.d.toFixed(2), bo: s.bo, giant: s.giant || "", chu: s.chu || "", chu2: s.chu2 || "", st: s.st || "", ten: s.ten || "", tieu: s.tieu || "", khoa: s.khoa ? 1 : 0 }));
12015
12200
  }
12016
- const thanhO = (t) => N >= 2 && t >= f1 - 0.1 && t < hetMuc;
12201
+ const thanhO = (t) => coBuoc && t >= f1 - 0.1 && t < hetMuc;
12017
12202
  bc = "B7 phat the";
12018
12203
  const stTr = { n: 0 }, keuTr = {};
12019
12204
  let iH = 0;
@@ -12065,7 +12250,8 @@ function lapCuongMe(o) {
12065
12250
  phong: s.phong,
12066
12251
  ra: s.ra,
12067
12252
  chu2: s.chu2,
12068
- yChu: s.yChu ?? (Fs ? Math.max(0.15, Math.min(0.26, Fs[1] - 0.05)) : 0.2)
12253
+ thanh: thanhO(s.f) || thanhO(s.f + s.d - 0.05) ? 1 : void 0,
12254
+ yChu: (s.bo === "depth" || s.bo === "cut") && !s.khoa ? void 0 : s.yChu ?? (Fs ? Math.max(0.15, Math.min(0.26, Fs[1] - 0.05)) : 0.2)
12069
12255
  });
12070
12256
  {
12071
12257
  const chu3 = (String(s.giant || "") + " " + String(s.chu || "") + " " + String(s.chu2 || "")).toLocaleLowerCase("vi"), xau = /tốn|mất|mỏi|khổ|oan|sai|lỗi|đau|chậm|dừng|đừng|cực|vô hồn|tránh/.test(chu3), tien = /tiền|triệu|view|đô|\$|doanh|ads|spend/.test(chu3), so4 = /\d|x10/.test(chu3);
@@ -12220,7 +12406,7 @@ function lapCuongMe(o) {
12220
12406
  if (!q.tu.length) q.t1 = q.t0;
12221
12407
  });
12222
12408
  }
12223
- if (N >= 2) the(nguon3(f1), nguon3(f1) + Math.min(hetMuc, tong) - 0.05 - f1, { loai: "cmTien", rel: muc.map((m) => +(m.f - f1).toFixed(2)) });
12409
+ if (coBuoc) the(nguon3(f1), nguon3(f1) + Math.min(hetMuc, tong) - 0.05 - f1, { loai: "cmTien", rel: muc.map((m) => +(m.f - f1).toFixed(2)) });
12224
12410
  o.lichCm = globalThis.__lichCm = {
12225
12411
  N,
12226
12412
  muc: muc.map((m) => [+m.f.toFixed(2), m.ten]),
@@ -12365,7 +12551,7 @@ function chiaTrang(ws, m) {
12365
12551
  dong.push(i);
12366
12552
  const nx = ws[i + 1], lang = nx ? nx.t0 - w.t1 : 99, dau = DAU2.indexOf(w.text.trim().slice(-1)) >= 0 || !!m.ngat.hoaMoi && !!nx && /^\p{Lu}/u.test(nx.text.trim()) && !/^\p{Lu}/u.test(w.text.trim());
12367
12553
  const giu = !!m.ngat.giuTuGhep && nx && !dau && lang < m.ngat.lang && laTuGhep(w.text, nx.text) && rong(dong.concat(i + 1)) <= m.rongToiDa * 1.3 && (!m.ngat.soTu || dong.length <= m.ngat.soTu);
12368
- const hetDong = !nx || lang >= 1 || !!m.nhanRieng && (!!w.n || !!nx.n) && !(w.n && nx.n && giu) || !giu && ((dau || lang >= m.ngat.lang) && boDau(dong.map((j) => ws[j].text).join(" ")).length >= m.ngat.kyTu || rong(dong.concat(i + 1)) > m.rongToiDa || !!m.ngat.soTu && dong.length >= m.ngat.soTu);
12554
+ const hetDong = !nx || lang >= 1 || HET_CAU.indexOf(w.text.trim().slice(-1)) >= 0 || !!m.nhanRieng && (!!w.n || !!nx.n) && !(w.n && nx.n && giu) || !giu && ((dau || lang >= m.ngat.lang) && boDau(dong.map((j) => ws[j].text).join(" ")).length >= m.ngat.kyTu || rong(dong.concat(i + 1)) > m.rongToiDa || !!m.ngat.soTu && dong.length >= m.ngat.soTu);
12369
12555
  if (!hetDong) return;
12370
12556
  tr.push(dong);
12371
12557
  dong = [];
@@ -13283,6 +13469,13 @@ async function renderNhanh(ff, clips, files, audio, cards, nen2, options, paint,
13283
13469
  } catch (e) {
13284
13470
  }
13285
13471
  }
13472
+ {
13473
+ const o = cu && cu.rung && cu.rung.o;
13474
+ if (o && typeof o.get !== "function") {
13475
+ if (Array.isArray(o.__map)) cu.rung.o = new Map(o.__map);
13476
+ else cu = null;
13477
+ }
13478
+ }
13286
13479
  S0.rung = cu ? (S0.dau = cu.dau, Promise.resolve(cu.rung)) : (async () => {
13287
13480
  S0.dau = await coDau(M, tr, lo + 4.5, hi - 4.5).catch(() => false);
13288
13481
  if (!rungOn) return null;
@@ -13293,7 +13486,7 @@ async function renderNhanh(ff, clips, files, audio, cards, nen2, options, paint,
13293
13486
  }
13294
13487
  })().then((r) => {
13295
13488
  NHO.set(kRung + "|" + rungOn, { rung: r, dau: S0.dau });
13296
- const js = JSON.stringify({ rung: r, dau: S0.dau }, (_k, x) => ArrayBuffer.isView(x) ? Array.from(x) : x);
13489
+ const js = JSON.stringify({ rung: r, dau: S0.dau }, (_k, x) => x instanceof Map ? { __map: Array.from(x.entries()) } : ArrayBuffer.isView(x) ? Array.from(x) : x);
13297
13490
  try {
13298
13491
  localStorage.setItem(LSR, js);
13299
13492
  } catch (e) {
@@ -13500,6 +13693,7 @@ async function renderNhanh(ff, clips, files, audio, cards, nen2, options, paint,
13500
13693
  if (d > 0 && T >= t.T0 && T < t.T1) day += H2 * d * Math.max(0, Math.min(1, (T - t.T0) / 0.3, (t.T1 - T) / 0.3));
13501
13694
  }
13502
13695
  if (day > 0) g.drawImage(nenCv, 0, day);
13696
+ globalThis.__dauMH = null;
13503
13697
  for (const t of ds2) {
13504
13698
  if (T < t.T0 || T >= t.T1) continue;
13505
13699
  if (t.doan) {
@@ -17552,7 +17746,7 @@ function dsTaiSan(kieu, kb) {
17552
17746
  });
17553
17747
  (kb?.muc || []).slice(0, 8).forEach((m) => {
17554
17748
  const ten2 = String(m && m.ten || "").trim();
17555
- if (ten2) ds2.push(["trang:" + ten2.toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}]+/gu, ""), 'A realistic desktop browser screenshot of the GitHub repository page of the AI skill "' + ten2.slice(0, 40) + '"' + (m.mo ? " (" + String(m.mo).slice(0, 60) + ")" : "") + ', dark GitHub theme, repository name and README title clearly reading "' + ten2.slice(0, 40) + '", short bullet list, file tree, crisp readable UI text, no people, no watermark', "16:9"]);
17749
+ if (ten2) ds2.push(["trang:" + ten2.toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}]+/gu, ""), !/SKILL|CÔNG CỤ|CONG CU|TOOL|APP/i.test(String(kb?.nhom || "")) ? 'Cinematic photorealistic wide scene illustrating "' + ten2.slice(0, 40) + '"' + (m.mo ? ": " + String(m.mo).slice(0, 60) : "") + ", Vietnamese everyday context, natural light, clear single subject, no text, no letters, no watermark" : 'A realistic desktop browser screenshot of the GitHub repository page of the AI skill "' + ten2.slice(0, 40) + '"' + (m.mo ? " (" + String(m.mo).slice(0, 60) + ")" : "") + ', dark GitHub theme, repository name and README title clearly reading "' + ten2.slice(0, 40) + '", short bullet list, file tree, crisp readable UI text, no people, no watermark', "16:9"]);
17556
17750
  });
17557
17751
  const TRAN_ANH = (() => {
17558
17752
  try {
@@ -17828,6 +18022,10 @@ function ghepKichBan(words, kichBan) {
17828
18022
  // flow-src/services/exportFlow.ts
17829
18023
  async function handleExport(currentProject, setExporting, setExportedBlob, addLog, khung) {
17830
18024
  if (!currentProject || currentProject.timeline.length === 0) return;
18025
+ try {
18026
+ await napPhongViet();
18027
+ } catch (e) {
18028
+ }
17831
18029
  window.__khoVideoDa = /* @__PURE__ */ new Set();
17832
18030
  {
17833
18031
  const kbg = String(currentProject.kichBanGoc || window.__kichBanGoc || "").trim(), ws0 = currentProject.speechDraft?.analysis?.words;
@@ -19592,7 +19790,7 @@ async function napLoi(d) {
19592
19790
  return "LOI: " + String(e && e.message || e).slice(0, 300);
19593
19791
  }
19594
19792
  }
19595
- var LOI_URL = "https://cdn.jsdelivr.net/npm/xvai-loi@0.1.49/nap.js";
19793
+ var LOI_URL = "https://cdn.jsdelivr.net/npm/xvai-loi@0.1.51/nap.js";
19596
19794
  var TRONG_LOI = !!globalThis.__xvaiReact;
19597
19795
  try {
19598
19796
  if (!TRONG_LOI) setTimeout(() => {
@@ -19622,7 +19820,7 @@ function datCauLenh(a) {
19622
19820
  on2 = true;
19623
19821
  window.addEventListener("message", async (ev) => {
19624
19822
  const d = ev.data;
19625
- if (!d || d.xvaiLoi101303 !== true) return;
19823
+ if (!d || d.xvaiLoi101845 !== true) return;
19626
19824
  const o = String(ev.origin || "");
19627
19825
  if (!(o.indexOf("https://flow.google.com") === 0 || o.indexOf("https://labs.google") === 0)) return;
19628
19826
  const tra = (kq) => {
@@ -20326,7 +20524,7 @@ var SuaLich = ({ ten, onDong }) => {
20326
20524
  };
20327
20525
 
20328
20526
  // loi/vo-flow.tsx
20329
- var PHIEN_BAN = "loi-1010BL";
20527
+ var PHIEN_BAN = "loi-1010BV";
20330
20528
  var TRONG = () => migrateProject({ id: crypto.randomUUID(), name: "D\u1EF1 \xE1n m\u1EDBi", scenes: [], timeline: [], images: [null, null, null] });
20331
20529
  var nut4 = "px-3 py-1.5 rounded-lg border border-[#2C4A73] text-[11px] font-bold text-[#A2B2C9] hover:text-[#F6D178] hover:border-[#F6D178]/60";
20332
20530
  var Vo = () => {