xvai-loi 0.1.64 → 0.1.66

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 +219 -93
package/co.txt CHANGED
@@ -1 +1 @@
1
- xvaiLoi111325
1
+ xvaiLoi111450
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xvai-loi",
3
- "version": "0.1.64",
3
+ "version": "0.1.66",
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
@@ -1422,6 +1422,26 @@ async function veDirectorCard(th, W4, H2) {
1422
1422
  var CDN = "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.20";
1423
1423
  var MODEL = "https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task";
1424
1424
  var landmarkerPromise = null;
1425
+ var LMsan = null;
1426
+ function loiMatAnh(im, W4, H2, z = 1.03) {
1427
+ if (!LMsan || !im || !im.width) return null;
1428
+ const c = new OffscreenCanvas(384, Math.round(384 * H2 / W4)), x = c.getContext("2d"), k = z * Math.max(c.width / im.width, c.height / im.height);
1429
+ x.drawImage(im, (c.width - im.width * k) / 2, (c.height - im.height * k) / 2, im.width * k, im.height * k);
1430
+ let r = null;
1431
+ try {
1432
+ r = LMsan.detect(c);
1433
+ } catch (e) {
1434
+ return null;
1435
+ }
1436
+ const p = r && r.faceLandmarks && r.faceLandmarks[0];
1437
+ if (!p || p.length < 300) return null;
1438
+ let x0 = 1, x1 = 0;
1439
+ for (const q of p) {
1440
+ if (q.x < x0) x0 = q.x;
1441
+ if (q.x > x1) x1 = q.x;
1442
+ }
1443
+ return [x0, Math.min(p[70].y, p[300].y, p[159].y, p[386].y), x1, p[17].y];
1444
+ }
1425
1445
  var vd209c = (ten, su, ms) => {
1426
1446
  const g = globalThis;
1427
1447
  g.__vd209c = (g.__vd209c || 0) + 1;
@@ -1434,7 +1454,7 @@ async function loadFaceLandmarker() {
1434
1454
  const importUrl = new Function("u", "return import(u)");
1435
1455
  const mod = await importUrl(CDN + "/vision_bundle.mjs");
1436
1456
  const vision = await mod.FilesetResolver.forVisionTasks(CDN + "/wasm");
1437
- return mod.FaceLandmarker.createFromOptions(vision, { baseOptions: { modelAssetPath: MODEL, delegate: "GPU" }, runningMode: "IMAGE", numFaces: 1, outputFaceBlendshapes: false, outputFacialTransformationMatrixes: false });
1457
+ return LMsan = await mod.FaceLandmarker.createFromOptions(vision, { baseOptions: { modelAssetPath: MODEL, delegate: "GPU" }, runningMode: "IMAGE", numFaces: 1, outputFaceBlendshapes: false, outputFacialTransformationMatrixes: false });
1438
1458
  })().catch((e) => {
1439
1459
  landmarkerPromise = null;
1440
1460
  throw e;
@@ -1462,9 +1482,83 @@ function sampleFromLandmarks(t, lm) {
1462
1482
  const eyeY = ((lm[33]?.y ?? face.y) + (lm[263]?.y ?? face.y)) / 2;
1463
1483
  return { t, face, headTop, chin, mouth: bounds(lm, LIPS), eyeY, confidence: 1 };
1464
1484
  }
1485
+ var SEG = "https://storage.googleapis.com/mediapipe-models/image_segmenter/selfie_segmenter/float16/latest/selfie_segmenter.tflite";
1486
+ var segP = null;
1487
+ function napSeg() {
1488
+ if (!segP) segP = (async () => {
1489
+ const imp = new Function("u", "return import(u)"), mod = await imp(CDN + "/vision_bundle.mjs"), v = await mod.FilesetResolver.forVisionTasks(CDN + "/wasm");
1490
+ return mod.ImageSegmenter.createFromOptions(v, { baseOptions: { modelAssetPath: SEG, delegate: "CPU" }, runningMode: "IMAGE", outputConfidenceMasks: true, outputCategoryMask: false });
1491
+ })().catch(() => null);
1492
+ return segP;
1493
+ }
1494
+ function luoiNguoi(seg2, canvas) {
1495
+ let r = null;
1496
+ try {
1497
+ r = seg2.segment(canvas);
1498
+ } catch (e) {
1499
+ return null;
1500
+ }
1501
+ const m = r && r.confidenceMasks && r.confidenceMasks[0];
1502
+ if (!m) return null;
1503
+ const f2 = m.getAsFloat32Array(), mw = m.width, mh = m.height, g = new Uint8Array(36 * 64);
1504
+ for (let y = 0; y < 64; y++) for (let x = 0; x < 36; x++) {
1505
+ let s = 0, n = 0;
1506
+ for (let yy = Math.floor(y * mh / 64); yy < Math.floor((y + 1) * mh / 64); yy++) for (let xx = Math.floor(x * mw / 36); xx < Math.floor((x + 1) * mw / 36); xx++) {
1507
+ s += f2[yy * mw + xx];
1508
+ n++;
1509
+ }
1510
+ g[y * 36 + x] = n && s / n > 0.5 ? 1 : 0;
1511
+ }
1512
+ try {
1513
+ r.close && r.close();
1514
+ } catch (e) {
1515
+ }
1516
+ return g;
1517
+ }
1465
1518
  async function detectOnCanvas(landmarker, canvas, t) {
1466
1519
  const res = landmarker.detect(canvas);
1467
- return sampleFromLandmarks(t, res && res.faceLandmarks && res.faceLandmarks[0]);
1520
+ let s = sampleFromLandmarks(t, res && res.faceLandmarks && res.faceLandmarks[0]);
1521
+ const seg2 = await napSeg(), g = seg2 ? luoiNguoi(seg2, canvas) : null, W4 = canvas.width, H2 = canvas.height;
1522
+ if (!s.face && g) {
1523
+ let r0 = -1;
1524
+ for (let y = 0; y < 64 && r0 < 0; y++) for (let x = 0; x < 36; x++) if (g[y * 36 + x]) {
1525
+ r0 = y;
1526
+ break;
1527
+ }
1528
+ if (r0 >= 0) {
1529
+ let c0 = 36, c1 = -1, sx = 0, n = 0;
1530
+ for (let y = r0; y < Math.min(64, r0 + 6); y++) for (let x = 0; x < 36; x++) if (g[y * 36 + x]) {
1531
+ c0 = Math.min(c0, x);
1532
+ c1 = Math.max(c1, x);
1533
+ sx += x;
1534
+ n++;
1535
+ }
1536
+ const cx = (sx / Math.max(1, n) + 0.5) / 36, cy = (r0 + 4) / 64, sz = Math.max(0.16 * H2, (c1 - c0 + 1) / 36 * W4 * 2.2), x0 = Math.max(0, cx * W4 - sz / 2), y0 = Math.max(0, cy * H2 - sz / 2), cw = Math.min(W4, x0 + sz) - x0, ch = Math.min(H2, y0 + sz) - y0;
1537
+ if (cw > 8 && ch > 8) {
1538
+ const cv = document.createElement("canvas");
1539
+ cv.width = 480;
1540
+ cv.height = Math.max(2, Math.round(480 * ch / cw));
1541
+ cv.getContext("2d").drawImage(canvas, x0, y0, cw, ch, 0, 0, cv.width, cv.height);
1542
+ const r22 = landmarker.detect(cv), p = r22 && r22.faceLandmarks && r22.faceLandmarks[0];
1543
+ if (p) {
1544
+ s = sampleFromLandmarks(t, p.map((q) => ({ x: (x0 + q.x * cw) / W4, y: (y0 + q.y * ch) / H2 })));
1545
+ s.haiTang = 1;
1546
+ }
1547
+ }
1548
+ }
1549
+ }
1550
+ if (s.face) {
1551
+ let dinh = -1;
1552
+ if (g) {
1553
+ const c0 = Math.floor(s.face.x * 36), c1 = Math.max(c0 + 1, Math.floor((s.face.x + s.face.w) * 36));
1554
+ for (let y = 0; y < 64 && dinh < 0; y++) for (let x = c0; x < c1; x++) if (g[y * 36 + x]) {
1555
+ dinh = y / 64;
1556
+ break;
1557
+ }
1558
+ }
1559
+ s.headTop = dinh >= 0 && dinh < s.face.y + 0.02 ? dinh : Math.max(0, s.face.y - s.face.h * 0.35);
1560
+ }
1561
+ return s;
1468
1562
  }
1469
1563
  async function analyzeFaceMap(src, step = 0.5, cancel = () => false, onStatus = () => {
1470
1564
  }, maxSide = 480) {
@@ -1533,7 +1627,7 @@ async function analyzeFaceMap(src, step = 0.5, cancel = () => false, onStatus =
1533
1627
  video.onseeked = null;
1534
1628
  video.src = "";
1535
1629
  video.load();
1536
- return { step, width: vw, height: vh, samples, ms: Math.round(performance.now() - t0), engine: "mediapipe-face-landmarker-0.10.20" };
1630
+ return { step, width: vw, height: vh, samples, ms: Math.round(performance.now() - t0), engine: "mediapipe-face-landmarker-0.10.20+mat2" };
1537
1631
  }
1538
1632
  async function faceMapWC(src, step, cancel, onStatus, maxSide, landmarker, t0) {
1539
1633
  onStatus("Nh\u1EADn m\u1EB7t (gi\u1EA3i m\xE3 WebCodecs)\u2026");
@@ -1560,7 +1654,7 @@ async function faceMapWC(src, step, cancel, onStatus, maxSide, landmarker, t0) {
1560
1654
  samples.push(await detectOnCanvas(landmarker, canvas, t));
1561
1655
  if (samples.length % 10 === 0) onStatus("Nh\u1EADn m\u1EB7t " + Math.round(t) + "/" + Math.round(dur) + " s");
1562
1656
  }
1563
- return { step, width: vw, height: vh, samples, ms: Math.round(performance.now() - t0), engine: "mediapipe-face-landmarker-0.10.20+webcodecs" };
1657
+ return { step, width: vw, height: vh, samples, ms: Math.round(performance.now() - t0), engine: "mediapipe-face-landmarker-0.10.20+webcodecs+mat2" };
1564
1658
  }
1565
1659
  function faceMapSummary(map) {
1566
1660
  const n = map.samples.length, hit2 = map.samples.filter((s) => s.face).length;
@@ -2028,7 +2122,7 @@ function sachMau(raw, words) {
2028
2122
  }
2029
2123
  function lapTrong(mau7, words) {
2030
2124
  if (!words.length) return mau7;
2031
- const out = [], cuoi = words[words.length - 1].t1, sach3 = (w) => {
2125
+ const out = [], cuoi = words[words.length - 1].t1, sach4 = (w) => {
2032
2126
  let t = String(w || "");
2033
2127
  for (const c of [",", ".", "?", "!", ":", ";", '"', "[", "]"]) t = t.split(c).join("");
2034
2128
  return t;
@@ -2040,7 +2134,7 @@ function lapTrong(mau7, words) {
2040
2134
  if (i < 0) break;
2041
2135
  const cum3 = [words[i]];
2042
2136
  for (let k = i + 1; k < words.length && cum3.length < 4 && words[k].t0 - words[k - 1].t1 <= 0.6 && words[k].t0 < den - 0.3; k++) cum3.push(words[k]);
2043
- const tu2 = cum3.map((w) => sach3(w.text)).filter(Boolean);
2137
+ const tu2 = cum3.map((w) => sach4(w.text)).filter(Boolean);
2044
2138
  if (tu2.length < 2) break;
2045
2139
  const chu3 = tu2.length >= 3 ? tu2.slice(0, -2).join(" ") + " [" + tu2.slice(-2).join(" ") + "]" : "[" + tu2.join(" ") + "]";
2046
2140
  out.push({ t0: cum3[0].t0, t1: cum3[cum3.length - 1].t1, chu: chotSo(chu3, words, cum3[0].t0), emoji: "", vai: "cap", manh: false, so: false, lap: true });
@@ -5944,6 +6038,7 @@ function catNen(im, buoc = 7, tol = 40) {
5944
6038
  }
5945
6039
  var ts = /* @__PURE__ */ new Map();
5946
6040
  var dsTenTaiSan = () => [...ts.keys()].filter((k) => /^(trang|anh|vat|story|logo):|\.(png|jpg)$/i.test(k)).sort();
6041
+ var moTaTaiSan = () => [...ts.entries()].filter(([, v]) => v).map(([k, v]) => [k, v.laVideo ? 1 : 0, +(v.dai || 0), v.width || 0, v.height || 0]);
5947
6042
  var taiSan = (ten) => ten ? ts.get(ten) || globalThis.__taiSanThu?.(ten) || null : null;
5948
6043
  var nhanTaiSan = (ten, im) => {
5949
6044
  ts.set(ten, ten.indexOf("anh:") === 0 ? im : catNen(im));
@@ -9724,6 +9819,7 @@ function datKhoiChu(g, kc, coThanh, coTach, vungTruoc, choThu = false, WH = 9 /
9724
9819
 
9725
9820
  // flow-src/engine/veCuongMe.ts
9726
9821
  var luoiAnhCache = /* @__PURE__ */ new Map();
9822
+ var matAnhCache = /* @__PURE__ */ new Map();
9727
9823
  var kep12 = (x) => Math.max(0, Math.min(1, x));
9728
9824
  var eOut = (x) => 1 - Math.pow(1 - kep12(x), 3);
9729
9825
  var eSoft = (x) => {
@@ -10001,7 +10097,7 @@ function thuLuoi(L, t) {
10001
10097
  }
10002
10098
  return o;
10003
10099
  }
10004
- function luoiNguoi(p, key) {
10100
+ function luoiNguoi2(p, key) {
10005
10101
  if (!p || !key) return null;
10006
10102
  key = key._goc || key;
10007
10103
  if (luoiCache.has(key)) return luoiCache.get(key);
@@ -10050,7 +10146,7 @@ function datChuNhan(g, W4, H2, F, giant, chu22, pxG, pxC, kieuG, maxW, tren = 0.
10050
10146
  return r;
10051
10147
  };
10052
10148
  {
10053
- const L = luoiNguoi(pN, khoaC);
10149
+ const L = luoiNguoi2(pN, khoaC);
10054
10150
  if (L && F) {
10055
10151
  let dinhM = null;
10056
10152
  {
@@ -10368,7 +10464,7 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10368
10464
  const kS = 1;
10369
10465
  let p = (d.bo === "depth" || d.bo === "cut" && !d.anNguoi) && nen2 ? nguoi(nen2, W4, H2) : null;
10370
10466
  if (p && d.bo === "cut" && F) {
10371
- const L0 = luoiNguoi(p, d);
10467
+ const L0 = luoiNguoi2(p, d);
10372
10468
  if (L0) {
10373
10469
  const c0 = Math.max(0, Math.floor(F[0] * 36)), c1 = Math.min(35, Math.ceil(F[2] * 36)), r0 = Math.max(0, Math.floor(F[1] * 64)), r1 = Math.min(63, Math.ceil(F[3] * 64));
10374
10470
  let n = 0, t = 0;
@@ -10388,7 +10484,7 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10388
10484
  const F7 = phongDinh(F || hopNguoi(p, d), d.z || d.phong || 1);
10389
10485
  if (F7) {
10390
10486
  const t7 = datChuNhan(g, W4, H2, F7, d.giant, String(d.giant || "").indexOf(String.fromCharCode(10)) >= 0 ? "" : d.chu2 || "", 165 * (d.coChu || 1) * H2 / 1920, 96 * H2 / 1920, "giant", 0.76 * W4, d.thanh ? 0.1 : 0.075, p, d, true);
10391
- const L7 = luoiNguoi(p, d);
10487
+ const L7 = luoiNguoi2(p, d);
10392
10488
  let day7 = 0;
10393
10489
  if (L7) for (let i = 60 * 36; i < 64 * 36; i++) day7 += L7[i];
10394
10490
  if (t7 && day7 >= 4 && (t7.vung === "het-cho" || t7.pxG < 0.6 * 165 * (d.coChu || 1) * H2 / 1920)) d = { ...d, _goc: d._goc || d, bo: "cut" };
@@ -10644,7 +10740,7 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10644
10740
  if (d.ui) theUI(g, d.ui, tuoi, W4, H2, 1);
10645
10741
  if (d.hang) {
10646
10742
  let yh = d.so ? 0.23 : 0.17, kh = 1;
10647
- const L2 = luoiNguoi(p || (nen2 ? nguoi(nen2, W4, H2) : null), d), F2 = F || (nen2 ? dauCanh(d, nen2, W4, H2) : null);
10743
+ const L2 = luoiNguoi2(p || (nen2 ? nguoi(nen2, W4, H2) : null), d), F2 = F || (nen2 ? dauCanh(d, nen2, W4, H2) : null);
10648
10744
  if (L2 && F2) {
10649
10745
  const tt = d.bo === "cut" && p ? THU_HANG : 1, Lt = tt < 1 ? thuLuoi(L2, tt) : L2, Ft = tt < 1 ? [0.5 + tt * (F2[0] - 0.5), 1 - tt * (1 - F2[1]), 0.5 + tt * (F2[2] - 0.5), 1 - tt * (1 - F2[3])] : F2;
10650
10746
  const nr = Math.ceil(d.hang.length / (d.hang.length > 3 ? 2 : 1)), hb2 = nr * 0.078, c = datKhoiChu({ luoi: Lt, mat: [Ft[0], Ft[1] + 0.25 * (Ft[3] - Ft[1]), Ft[2], Ft[3]], dinh: Ft[1], cam: Ft[3] }, { h: hb2, w: d.hang.length > 3 ? 0.87 : 0.7 }, false, false, void 0, false, W4 / H2, [[0, 0, 1, d.so ? 0.21 : 0.17]]);
@@ -10754,17 +10850,19 @@ dangKy("cmAnh", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
10754
10850
  }
10755
10851
  }
10756
10852
  luoiAnhCache.set(kh, U);
10853
+ matAnhCache.set(kh, loiMatAnh(im, W4, H2));
10757
10854
  }
10758
10855
  const LA = luoiAnhCache.get(kh);
10759
10856
  if (LA) globalThis.__anhLuoi = { k: globalThis.__khungSo, L: LA };
10760
10857
  if (LA && LA.some((v) => v)) {
10761
- const n1 = String(d.chu).split(String.fromCharCode(10)).length, hK = (n1 * 1.15 * 112 + (d.chu2 ? 125 : 0)) / 1920, c = datKhoiChu({ luoi: LA, mat: null, dinh: null, anh: 1 }, { h: hK, w: 0.76 }, false, false, void 0, false, W4 / H2, d.pip && _n ? [[0.06, 0.555, 0.42, 0.8]] : []);
10858
+ const n1 = String(d.chu).split(String.fromCharCode(10)).length, hK = (n1 * 1.15 * 112 + (d.chu2 ? 125 : 0)) / 1920, c = datKhoiChu({ luoi: LA, mat: null, dinh: null, anh: 1 }, { h: hK, w: 0.76 }, false, false, void 0, false, W4 / H2, [...d.pip && _n ? [[0.06, 0.555, 0.42, 0.8]] : [], ...matAnhCache.get(kh) ? [matAnhCache.get(kh)] : []]);
10762
10859
  if (c.k >= 0.75) {
10763
10860
  kK = c.k;
10764
10861
  xK = c.x * W4;
10765
10862
  wK2 = 0.76 * W4;
10766
10863
  yK = (c.y - hK * c.k / 2 + 0.575 * 112 / 1920 * c.k) * H2;
10767
10864
  } else {
10865
+ const MA = matAnhCache.get(kh);
10768
10866
  let rT = 64;
10769
10867
  for (let r = 0; r < 64 && rT === 64; r++) {
10770
10868
  let m = 0;
@@ -10775,7 +10873,7 @@ dangKy("cmAnh", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
10775
10873
  let n = 0, t = 0;
10776
10874
  for (let r = Math.floor(y0 * 64); r < Math.min(64, Math.ceil((y0 + hK) * 64)); r++) for (let cc = 4; cc < 32; cc++) {
10777
10875
  t++;
10778
- n += LA[r * 36 + cc] * (r >= rT && r < rT + 16 ? 4 : 1);
10876
+ n += LA[r * 36 + cc] * (r >= rT && r < rT + 16 ? 4 : 1) + (MA && r >= MA[1] * 64 && r <= MA[3] * 64 && cc >= MA[0] * 36 && cc <= MA[2] * 36 ? 20 : 0);
10779
10877
  }
10780
10878
  return t ? n / t : 1;
10781
10879
  };
@@ -11158,10 +11256,9 @@ dangKy("cmKinh", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
11158
11256
  });
11159
11257
  dangKy("cmSticker", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
11160
11258
  const a = kep13(Math.min(1, (dai2 - tuoi) / 0.07));
11161
- 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);
11162
11259
  if (a > 0) {
11163
- const G3 = globalThis, r = d.r ?? 0.065, ry = r * W4 / H2;
11164
- let x = d.x ?? 0.82, y = d.y ?? 0.3;
11260
+ const G3 = globalThis, lg = !!d.logo, r = d.r ?? (lg ? 0.085 : 0.065), ry = r * W4 / H2;
11261
+ let x = d.x ?? (lg ? 0.5 : 0.82), y = d.y ?? (lg ? 0.17 : 0.3);
11165
11262
  if (d.st === "chuot" && G3.__hangO && (G3.__khungSo || 0) - G3.__hangO.k <= 1) {
11166
11263
  x = G3.__hangO.x;
11167
11264
  y = G3.__hangO.y;
@@ -11191,16 +11288,73 @@ dangKy("cmSticker", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
11191
11288
  x = c[0];
11192
11289
  y = c[1];
11193
11290
  }
11291
+ if (lg) return veLogo(g, d.logo, d.hex, x * W4, y * H2, r * W4, tuoi - (d.tre ?? 0), a);
11194
11292
  veSticker3(g, d.st, x * W4, y * H2, r * W4, tuoi - (d.tre ?? 0.25), a);
11195
11293
  }
11196
11294
  });
11197
11295
 
11296
+ // flow-src/engine/khuon.ts
11297
+ var KHUON_TOPN = {
11298
+ ten: "Top N chi\u1EC1u s\xE2u (Captions)",
11299
+ tram: { phut: 18.3, tyLe: 0.7, phan: [0.83, 0.81, 0.46], daiTV: 2.1, video: 0.33 },
11300
+ // cảnh trám / phút, % thời lượng, 3 phần đầu/giữa/cuối, độ dài trung vị (s), tỉ lệ clip động
11301
+ chu: { phut: [8, 18] },
11302
+ icon: { phut: 11.5 },
11303
+ cat: { moi10s: [4, 6] },
11304
+ bien: { dau: 3, cuoi: 2.5, ctaAnh: true }
11305
+ // không đặt ảnh trám ở 3 s đầu (móc) và 2,5 s cuối; vùng CTA VẪN có ảnh (đối thủ CTA 8,7 s vẫn trám)
11306
+ };
11307
+ var HU3 = /^(và|với|là|thì|mà|nhưng|rồi|cái|những|các|một|này|đó|chúng|ta|tôi|mình|bạn|em|anh|chị|của|cho|để|nên|vì|cũng|đã|đang|sẽ|có|không|được|rất|ạ|nhé|nha|à|ơi|lại|ra|vào|đi|nó|họ|hãy|chỉ|cần|phải|mới|khi|nếu|vậy|thế|như|từ|trong|về|bị|hết|luôn|sau|trước)$/i;
11308
+ var sach2 = (x) => String(x || "").replace(/[.,!?;:…"“”]/g, "");
11309
+ function lapAnhTheoKhuon(kb, ws, K = KHUON_TOPN, toiDa = 12) {
11310
+ const W4 = (ws || []).filter((w) => w && w.text && w.t1 > w.t0);
11311
+ if (!kb || !Array.isArray(kb.canh) || W4.length < 20) return 0;
11312
+ const lo = (x) => String(x || "").toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}\s]/gu, "").trim(), wl = W4.map((w) => lo(w.text));
11313
+ const timTu = (tu) => {
11314
+ const q = lo(tu).split(/\s+/).filter(Boolean).slice(0, 3);
11315
+ if (!q.length) return -1;
11316
+ for (let i = 0; i + q.length <= wl.length; i++) {
11317
+ let ok = true;
11318
+ for (let j = 0; j < q.length; j++) if (wl[i + j] !== q[j]) {
11319
+ ok = false;
11320
+ break;
11321
+ }
11322
+ if (ok) return i;
11323
+ }
11324
+ return -1;
11325
+ };
11326
+ const g = 60 / K.tram.phut, t0 = W4[0].t0 + K.bien.dau, t1 = W4[W4.length - 1].t1 - K.bien.cuoi;
11327
+ const moc = kb.canh.filter(
11328
+ (c) => c && c.tu && /^(anh|ds)$/.test(String(c.kieu))
11329
+ /* 'so' vẽ thành chữ to trên người / ô tròn (cut/tron) — không phải trám */
11330
+ ).map((c) => timTu(c.tu)).filter((i) => i >= 0).map((i) => W4[i].t0).filter((t) => t > t0 && t < t1).sort((a, b) => a - b);
11331
+ const pts = [t0, ...moc, t1];
11332
+ let them = 0;
11333
+ for (let k = 0; k + 1 < pts.length && them < toiDa; k++) {
11334
+ const a0 = pts[k], b0 = pts[k + 1];
11335
+ if (b0 - a0 < 1.6 * g) continue;
11336
+ const n = Math.max(1, Math.round((b0 - a0) / g) - 1);
11337
+ for (let m = 1; m <= n && them < toiDa; m++) {
11338
+ const tm = a0 + (b0 - a0) * m / (n + 1), i0 = W4.findIndex((w) => w.t0 >= tm);
11339
+ if (i0 < 0) continue;
11340
+ const nd = [];
11341
+ for (let i2 = i0; i2 < Math.min(W4.length, i0 + 8) && nd.length < 3; i2++) if (!HU3.test(sach2(W4[i2].text))) nd.push(i2);
11342
+ if (nd.length < 2) continue;
11343
+ const i = nd[0], tu = W4.slice(i, i + 3).map((w) => sach2(w.text)).join(" "), cau = W4.slice(Math.max(0, i - 5), i + 10).map((w) => w.text).join(" ");
11344
+ if (timTu(tu) !== i) continue;
11345
+ kb.canh.push({ tu, kieu: "anh", chu: " ", chu2: "", khuon: 1, en: 'Cinematic photorealistic vertical photo that illustrates the meaning of this Vietnamese sentence: "' + cau + '". Vietnamese people, real everyday setting, natural light, no text, no captions.' });
11346
+ them++;
11347
+ }
11348
+ }
11349
+ return them;
11350
+ }
11351
+
11198
11352
  // flow-src/engine/khoiCuongMe.ts
11199
11353
  napLogo();
11200
11354
  var DAU_MUC = /^(đầu tiên|thứ nhất|thứ (hai|ba|tư|năm|sáu|bảy|tám|\d+)|tiếp theo|kế tiếp|tiếp nữa|cuối cùng|và cuối cùng|số (một|hai|ba|\d+)|công cụ (thứ|số)|skill (thứ|số))/;
11201
- var HU3 = " mu\u1ED1n bi\u1EBFt c\u1EE9 l\xE0 c\xF3 th\xEC m\xE0 v\xE0 c\u1EE7a nh\u1EEFng c\xE1c m\u1ED9t c\xE1i \u0111\xE3 \u0111ang s\u1EBD r\u1EA5t c\u0169ng nh\u01B0ng n\xE0y n\xF3 anh em m\xECnh b\u1EA1n cho v\u1EDBi \u0111\u1EC3 \u0111\u01B0\u1EE3c kh\xF4ng th\u1EC3 ra v\xE0o ";
11355
+ var HU4 = " mu\u1ED1n bi\u1EBFt c\u1EE9 l\xE0 c\xF3 th\xEC m\xE0 v\xE0 c\u1EE7a nh\u1EEFng c\xE1c m\u1ED9t c\xE1i \u0111\xE3 \u0111ang s\u1EBD r\u1EA5t c\u0169ng nh\u01B0ng n\xE0y n\xF3 anh em m\xECnh b\u1EA1n cho v\u1EDBi \u0111\u1EC3 \u0111\u01B0\u1EE3c kh\xF4ng th\u1EC3 ra v\xE0o ";
11202
11356
  var VIET = /^(AI|OK|An|Anh|Em|Con|Cho|Hay|Khi|Nhung|Minh|Ta|Toi|Ai|Thi|Theo|Thanh|Cung|Chi|Chinh|Nhanh|Sau|Lam|Ban|Muon|Tim|Xem|Video|Hello|Hi|Nha|Ok|Ha|Hoa|Tin|Tai|Lan|Ngon|Ngay)$/;
11203
- var sach2 = (s) => String(s || "").replace(/(\d)\.(\d)/g, "$1\xA7$2").replace(/(\d),(\d)/g, "$1\xA4$2").replace(/[.,!?;:…"“”()]/g, "").replace(/§/g, ".").replace(/¤/g, ",").trim();
11357
+ var sach3 = (s) => String(s || "").replace(/(\d)\.(\d)/g, "$1\xA7$2").replace(/(\d),(\d)/g, "$1\xA4$2").replace(/[.,!?;:…"“”()]/g, "").replace(/§/g, ".").replace(/¤/g, ",").trim();
11204
11358
  var hoa3 = (s) => s.toLocaleUpperCase("vi");
11205
11359
  function tenRieng(ws) {
11206
11360
  let best = "", cur = [];
@@ -11209,7 +11363,7 @@ function tenRieng(ws) {
11209
11363
  if (t.length > best.length) best = t;
11210
11364
  cur = [];
11211
11365
  };
11212
- ws.map(sach2).forEach((w) => {
11366
+ ws.map(sach3).forEach((w) => {
11213
11367
  if (/^[A-Z][A-Za-z0-9+.-]+$/.test(w) && !VIET.test(w)) cur.push(w);
11214
11368
  else xong();
11215
11369
  });
@@ -11217,7 +11371,7 @@ function tenRieng(ws) {
11217
11371
  return /^(Claude|Google|Facebook|Youtube|YouTube|TikTok)$/.test(best) ? "" : best;
11218
11372
  }
11219
11373
  function cum2(ws) {
11220
- const w = ws.map(sach2).filter(Boolean), hu = (x) => HU3.indexOf(" " + x.toLocaleLowerCase("vi") + " ") >= 0;
11374
+ const w = ws.map(sach3).filter(Boolean), hu = (x) => HU4.indexOf(" " + x.toLocaleLowerCase("vi") + " ") >= 0;
11221
11375
  for (let i = 0; i + 1 < w.length; i++) if (!hu(w[i]) && !hu(w[i + 1]) && laTuGhep(w[i], w[i + 1])) return w[i] + " " + w[i + 1];
11222
11376
  for (let i = w.length - 2; i >= 0; i--) if (!hu(w[i]) && !hu(w[i + 1])) return w[i] + " " + w[i + 1];
11223
11377
  return w.slice(-2).join(" ");
@@ -11266,7 +11420,7 @@ function tomTatLoai(loai) {
11266
11420
  function lapCuongMe(o) {
11267
11421
  if (globalThis.__ghiDauVaoCm) {
11268
11422
  try {
11269
- globalThis.__dauVaoCm = JSON.parse(JSON.stringify({ ...o, __wsGocKB: globalThis.__wsGocKB || null }, (k, v) => typeof v === "string" && v.length > 4e3 ? "[cat " + v.length + "]" : v));
11423
+ globalThis.__dauVaoCm = JSON.parse(JSON.stringify({ ...o, __wsGocKB: globalThis.__wsGocKB || null, __taiSan: moTaTaiSan() }, (k, v) => typeof v === "string" && v.length > 4e3 ? "[cat " + v.length + "]" : v));
11270
11424
  } catch (e) {
11271
11425
  }
11272
11426
  }
@@ -11310,8 +11464,8 @@ function lapCuongMe(o) {
11310
11464
  const F = (fa, fb) => matRa(fm, nguon3(fa), nguon3(fb), [0, 0, 0, 0], 1, zc);
11311
11465
  const sF = (f2, rong) => f2 ? Math.max(0.8, Math.min(1.35, rong / Math.max(0.1, f2[2] - f2[0]))) : 1;
11312
11466
  napTach();
11313
- const loi2 = " " + ws.map((w) => sach2(w.text).toLocaleLowerCase("vi")).join(" ") + " ";
11314
- const LOAI2 = kb?.nhom ? ((x) => x.length <= 12 ? x : x.split(" ").slice(0, 2).join(" "))(hoa3(sach2(kb.nhom))) : /skill/.test(loi2) ? "SKILL" : /công cụ|tool/.test(loi2) ? "C\xD4NG C\u1EE4" : /mẹo/.test(loi2) ? "M\u1EB8O" : /bước/.test(loi2) ? "B\u01AF\u1EDAC" : "M\u1EE4C";
11467
+ const loi2 = " " + ws.map((w) => sach3(w.text).toLocaleLowerCase("vi")).join(" ") + " ";
11468
+ const LOAI2 = kb?.nhom ? ((x) => x.length <= 12 ? x : x.split(" ").slice(0, 2).join(" "))(hoa3(sach3(kb.nhom))) : /skill/.test(loi2) ? "SKILL" : /công cụ|tool/.test(loi2) ? "C\xD4NG C\u1EE4" : /mẹo/.test(loi2) ? "M\u1EB8O" : /bước/.test(loi2) ? "B\u01AF\u1EDAC" : "M\u1EE4C";
11315
11469
  const gioTu = (w) => {
11316
11470
  if (!o.fTu) return -1;
11317
11471
  for (const t of [w.t0, Math.min(w.t1 - 0.02, w.t0 + 0.12), (w.t0 + w.t1) / 2, w.t1 - 0.02]) {
@@ -11320,8 +11474,8 @@ function lapCuongMe(o) {
11320
11474
  }
11321
11475
  return -1;
11322
11476
  };
11323
- const W22 = ws.map((w) => ({ t: sach2(w.text).toLocaleLowerCase("vi"), f: gioTu(w) }));
11324
- const WG = Array.isArray(globalThis.__wsGocKB) ? globalThis.__wsGocKB.filter((w) => w && w.t1 > w.t0 && sach2(w.text)).map((w) => ({ t: sach2(w.text).toLocaleLowerCase("vi"), f: gioTu(w) })) : null;
11477
+ const W22 = ws.map((w) => ({ t: sach3(w.text).toLocaleLowerCase("vi"), f: gioTu(w) }));
11478
+ const WG = Array.isArray(globalThis.__wsGocKB) ? globalThis.__wsGocKB.filter((w) => w && w.t1 > w.t0 && sach3(w.text)).map((w) => ({ t: sach3(w.text).toLocaleLowerCase("vi"), f: gioTu(w) })) : null;
11325
11479
  const SUA = [...kb?.sua || [], ...(() => {
11326
11480
  try {
11327
11481
  const v = JSON.parse(localStorage.getItem("xvaiTuDien") || "[]");
@@ -11329,14 +11483,14 @@ function lapCuongMe(o) {
11329
11483
  } catch (e) {
11330
11484
  return [];
11331
11485
  }
11332
- })(), ["\xEDch x\xEC m\u01B0\u01A1i", "x10"], ["\xEDch x\xEC m\u01B0\u1EDDi", "x10"], ["\xEDch m\u01B0\u1EDDi", "x10"], ["\xEDch m\u01B0\u01A1i", "x10"], ["x m\u01B0\u1EDDi", "x10"], ["\xEDt x\xEC m\u01B0\u01A1i", "x10"], ["\xEDch x\xEC hai", "x2"], ["\xEDch x\xEC ba", "x3"], ["\xEDch x\xEC n\u0103m", "x5"], ["\xEDch x\xEC m\u1ED9t tr\u0103m", "x100"]].filter((x) => Array.isArray(x) && x[0] && x[1]).map((x) => [String(x[0]).split(/\s+/).map((t) => sach2(t).toLocaleLowerCase("vi")).filter(Boolean), sach2(String(x[1]))]).filter((x) => x[0].length && x[1] && x[0].join(" ") !== x[1].toLocaleLowerCase("vi")).filter((x) => {
11486
+ })(), ["\xEDch x\xEC m\u01B0\u01A1i", "x10"], ["\xEDch x\xEC m\u01B0\u1EDDi", "x10"], ["\xEDch m\u01B0\u1EDDi", "x10"], ["\xEDch m\u01B0\u01A1i", "x10"], ["x m\u01B0\u1EDDi", "x10"], ["\xEDt x\xEC m\u01B0\u01A1i", "x10"], ["\xEDch x\xEC hai", "x2"], ["\xEDch x\xEC ba", "x3"], ["\xEDch x\xEC n\u0103m", "x5"], ["\xEDch x\xEC m\u1ED9t tr\u0103m", "x100"]].filter((x) => Array.isArray(x) && x[0] && x[1]).map((x) => [String(x[0]).split(/\s+/).map((t) => sach3(t).toLocaleLowerCase("vi")).filter(Boolean), sach3(String(x[1]))]).filter((x) => x[0].length && x[1] && x[0].join(" ") !== x[1].toLocaleLowerCase("vi")).filter((x) => {
11333
11487
  const a = x[0].join(" "), b = String(x[1]).toLowerCase();
11334
11488
  return /[À-ỹđ]/i.test(a + b) || levD(a, b) <= Math.max(3, 0.45 * Math.max(a.length, b.length));
11335
11489
  });
11336
11490
  const suaChu = (t) => {
11337
11491
  const w = t.split(/\s+/).filter(Boolean);
11338
11492
  SUA.forEach(([sai, dung]) => {
11339
- for (let i = 0; i + sai.length <= w.length; i++) if (sai.every((x, j) => sach2(w[i + j]).toLocaleLowerCase("vi") === x)) w.splice(i, sai.length, dung);
11493
+ for (let i = 0; i + sai.length <= w.length; i++) if (sai.every((x, j) => sach3(w[i + j]).toLocaleLowerCase("vi") === x)) w.splice(i, sai.length, dung);
11340
11494
  });
11341
11495
  return w.join(" ");
11342
11496
  };
@@ -11364,7 +11518,7 @@ function lapCuongMe(o) {
11364
11518
  return d + (a.length - i) + (b.length - j) <= 1;
11365
11519
  };
11366
11520
  const tim = (tu, tu0) => {
11367
- const q = String(tu || "").replace(/\[\d+s\]/g, " ").split(/\s+/).map((x) => sach2(x).toLocaleLowerCase("vi")).filter(Boolean).slice(0, 3);
11521
+ const q = String(tu || "").replace(/\[\d+s\]/g, " ").split(/\s+/).map((x) => sach3(x).toLocaleLowerCase("vi")).filter(Boolean).slice(0, 3);
11368
11522
  if (!q.length) return -1;
11369
11523
  for (const W4 of WG ? [WG, W22] : [W22]) for (let n = q.length; n >= Math.min(2, q.length); n--) for (let i = 0; i + n <= W4.length; i++) {
11370
11524
  const f0 = W4[i].f >= 0 ? W4[i].f : W4[i + 1] && W4[i + 1].f >= 0 ? W4[i + 1].f : -1;
@@ -11404,17 +11558,17 @@ function lapCuongMe(o) {
11404
11558
  return;
11405
11559
  }
11406
11560
  {
11407
- const tenM = suaChu(sach2(m.ten || "")).toLocaleLowerCase("vi");
11561
+ const tenM = suaChu(sach3(m.ten || "")).toLocaleLowerCase("vi");
11408
11562
  if (muc.length && tenM && tenM === String(muc[muc.length - 1].ten || "").toLocaleLowerCase("vi") && f2 - muc[muc.length - 1].f < 10) {
11409
11563
  ghiL("bo", { bo: "muc", f: f2, d: 0 }, "muc trung ten muc truoc trong 10 s \u2192 gop (giu the + ket qua muc truoc): " + tenM);
11410
11564
  return;
11411
11565
  }
11412
11566
  }
11413
- 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) });
11567
+ muc.push({ f: f2, c, cach, ten: suaChu(sach3(m.ten || "")) || tenRieng(suaChu(String(m.tu || "")).split(/\s+/)), mo: suaChu(sach3(m.mo || "")), kq: (Array.isArray(m.kq) ? m.kq : []).map((x) => suaChu(sach3(String(x)))).filter(Boolean).slice(0, 3) });
11414
11568
  truocM = f2 + 1;
11415
11569
  });
11416
11570
  {
11417
- const HU22 = HU3 + "trong l\xFAc khi n\u1EBFu th\xEC \u0111\xE2y \u0111\xF3 hay ho\u1EB7c n\xEAn v\xEC b\u1EDFi lu\xF4n nha nh\xE9 \u1EA1 ";
11571
+ const HU22 = HU4 + "trong l\xFAc khi n\u1EBFu th\xEC \u0111\xE2y \u0111\xF3 hay ho\u1EB7c n\xEAn v\xEC b\u1EDFi lu\xF4n nha nh\xE9 \u1EA1 ";
11418
11572
  const bdx = (x) => String(x || "").toLocaleLowerCase("vi");
11419
11573
  for (const m of muc) {
11420
11574
  const ww = bdx(m.mo).split(/\s+/).filter(Boolean);
@@ -11437,7 +11591,7 @@ function lapCuongMe(o) {
11437
11591
  muc.length = 0;
11438
11592
  cs.forEach((c, i) => {
11439
11593
  if (c.f < 4) return;
11440
- const dau = c.chu.slice(0, 4).map(sach2).join(" ").toLocaleLowerCase("vi");
11594
+ const dau = c.chu.slice(0, 4).map(sach3).join(" ").toLocaleLowerCase("vi");
11441
11595
  let ten2 = tenRieng(c.chu) || (cs[i + 1] && cs[i + 1].f - c.f < 4 ? tenRieng(cs[i + 1].chu) : "");
11442
11596
  const coDau2 = DAU_MUC.test(dau);
11443
11597
  if (!coDau2 && (!ten2 || daTen.has(ten2.toLowerCase()))) return;
@@ -11542,7 +11696,7 @@ function lapCuongMe(o) {
11542
11696
  if (idx.length) {
11543
11697
  const a0 = idx[0], a1 = Math.max(...idx.filter((k) => k <= a0 + ten2.length + 2)), sp2 = [];
11544
11698
  for (let k = a0; k <= a1; k++) sp2.push(k);
11545
- if (sp2.length > ten2.length && sp2.every((k) => /^[a-z]{2,}$/.test(W22[k].t))) m.ten = sp2.map((k) => sach2(ws[k].text)).join(" ");
11699
+ if (sp2.length > ten2.length && sp2.every((k) => /^[a-z]{2,}$/.test(W22[k].t))) m.ten = sp2.map((k) => sach3(ws[k].text)).join(" ");
11546
11700
  return;
11547
11701
  }
11548
11702
  const i = W22.findIndex((w) => w.f >= m.f - 0.5 && w.f <= m.f + 4 && /^[a-z]{5,}$/.test(w.t) && !amViet(w.t) && !THUONG.test(w.t));
@@ -11584,7 +11738,7 @@ function lapCuongMe(o) {
11584
11738
  }
11585
11739
  while (k > 2 && k < w.length && /^(của|và|là|các|những|cuộc|sự|việc|người|cho|với|để|thì|mà|một|này|đã|sẽ|đang|rất|thật|được|không)$/i.test(w[k - 1])) k--;
11586
11740
  return w.slice(0, Math.max(2, k)).join(" ");
11587
- })(sach2(kb?.moc || layMoc(ws, kb)).split(" "))) || hoa3(cum2(cs[0] ? cs[0].chu : []));
11741
+ })(sach3(kb?.moc || layMoc(ws, kb)).split(" "))) || hoa3(cum2(cs[0] ? cs[0].chu : []));
11588
11742
  const Lm = Math.min(Math.max(2.4, docGiay(moc) + 0.4), Math.max(1.2, f1 - 0.3));
11589
11743
  bc = "B2 moc";
11590
11744
  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" });
@@ -11600,7 +11754,7 @@ function lapCuongMe(o) {
11600
11754
  bc = "B3 the muc";
11601
11755
  muc.forEach((m, k) => {
11602
11756
  const L = m.b - m.f, Lc = Math.min(2.6, Math.max(2.2, 0.3 * L));
11603
- const sau = suaChu(m.c.chu.map(sach2).join(" ")), go2 = sau.length > 48 ? sau.slice(0, 48).replace(/\s\S*$/, "") + "\u2026" : sau;
11757
+ const sau = suaChu(m.c.chu.map(sach3).join(" ")), go2 = sau.length > 48 ? sau.slice(0, 48).replace(/\s\S*$/, "") + "\u2026" : sau;
11604
11758
  de(m.f, Lc, { uuTien: UT.card, bo: "card", tenMuc: m.ten, tieu: hoa3(gonTen(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" });
11605
11759
  if (L >= 10 && !(kb?.canh || []).length) {
11606
11760
  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];
@@ -11645,12 +11799,12 @@ function lapCuongMe(o) {
11645
11799
  {
11646
11800
  bc = "B3 da test";
11647
11801
  const k = W22.findIndex((w, i) => i > 0 && w.f > tong * 0.7 && w.f < tong - 6 && gan2(w.t, "test") && !/^(chưa|không|đừng|chẳng|ko)$/.test(W22[i - 1].t) && !(i > 1 && /^(chưa|không|đừng|chẳng|ko)$/.test(W22[i - 2].t)));
11648
- if (k > 0) de(W22[k].f - 0.15, 2.2, { uuTien: UT.test, bo: "cut", giant: "\u0110\xC3 TEST", chu2: hoa3(suaChu([k + 1, k + 2].filter((q) => W22[q]).map((q) => sach2(ws[q].text)).join(" "))), st: "tich", stX: 0.915, stY: 0.2, stR: 0.055, keu: "pop" }, 1);
11802
+ if (k > 0) de(W22[k].f - 0.15, 2.2, { uuTien: UT.test, bo: "cut", giant: "\u0110\xC3 TEST", chu2: hoa3(suaChu([k + 1, k + 2].filter((q) => W22[q]).map((q) => sach3(ws[q].text)).join(" "))), st: "tich", stX: 0.915, stY: 0.2, stR: 0.055, keu: "pop" }, 1);
11649
11803
  }
11650
11804
  const gioLogo = (a, b) => {
11651
11805
  for (let q = 0; q < ws.length; q++) {
11652
11806
  const f2 = W22[q].f;
11653
- if (f2 >= a && f2 < b && timLogo(suaChu(sach2(ws[q].text) + " " + sach2(ws[q + 1]?.text || "")))[0]) return f2;
11807
+ if (f2 >= a && f2 < b && timLogo(suaChu(sach3(ws[q].text) + " " + sach3(ws[q + 1]?.text || "")))[0]) return f2;
11654
11808
  }
11655
11809
  return -1;
11656
11810
  };
@@ -11690,7 +11844,7 @@ function lapCuongMe(o) {
11690
11844
  return;
11691
11845
  }
11692
11846
  truocC = f2 + 0.5;
11693
- if (soBia(x.chu) || soBia(x.chu2) || x.kieu === "anh" && (f2 < 3 || f2 >= fCta - 0.5)) {
11847
+ if (soBia(x.chu) || soBia(x.chu2) || x.kieu === "anh" && (f2 < KHUON_TOPN.bien.dau || !KHUON_TOPN.bien.ctaAnh && f2 >= fCta - 0.5)) {
11694
11848
  boC.push([x.tu, f2, "chan"]);
11695
11849
  ghiL("bo", { bo: x.kieu || "chu", f: f2, d: 0 }, "chan cung: so % khong co trong loi / anh o moc 0-3 s / anh vung CTA: " + String(x.tu || ""));
11696
11850
  return;
@@ -11700,21 +11854,21 @@ function lapCuongMe(o) {
11700
11854
  ghiL("bo", { bo: x.kieu || "chu", f: f2, d: 0 }, "trung CTA: canh AI vung CTA lap dung chu CTA may (comment / luu / tai lieu / tang): " + String(x.tu || ""));
11701
11855
  return;
11702
11856
  }
11703
- const ten2 = x.kieu + ":" + String(x.tu || "").toLocaleLowerCase("vi"), im0 = taiSan(ten2), co = !!im0 && !daAnh.has(im0) && !!daAnh.add(im0), chuK = hoa3(suaChu(sach2(x.chu || (x.kieu === "anh" || x.kieu === "vat" ? (() => {
11704
- const v = String(x.tu || "").split(/\s+/).map((w) => sach2(w)).filter((w) => w && !/^(và|với|là|thì|mà|nhưng|rồi|cái|những|các|một|này|đó|chúng|ta|tôi|mình|bạn|em|anh|chị|của|cho|để|nên|vì|cũng|đã|đang|sẽ|có|không|được|rất|ạ|nhé|nha|à|ơi|lại|ra|vào|đi|nó|họ|hãy|chỉ|cần|phải|mới|khi|nếu|vậy|thế|như|từ|trong|về|bị|hết|luôn|sau|trước)$/i.test(w)).slice(0, 3);
11857
+ const ten2 = x.kieu + ":" + String(x.tu || "").toLocaleLowerCase("vi"), im0 = taiSan(ten2), co = !!im0 && !daAnh.has(im0) && !!daAnh.add(im0), chuK = hoa3(suaChu(sach3(x.chu || (x.kieu === "anh" || x.kieu === "vat" ? (() => {
11858
+ const v = String(x.tu || "").split(/\s+/).map((w) => sach3(w)).filter((w) => w && !/^(và|với|là|thì|mà|nhưng|rồi|cái|những|các|một|này|đó|chúng|ta|tôi|mình|bạn|em|anh|chị|của|cho|để|nên|vì|cũng|đã|đang|sẽ|có|không|được|rất|ạ|nhé|nha|à|ơi|lại|ra|vào|đi|nó|họ|hãy|chỉ|cần|phải|mới|khi|nếu|vậy|thế|như|từ|trong|về|bị|hết|luôn|sau|trước)$/i.test(w)).slice(0, 3);
11705
11859
  return v.length >= 2 ? v.join(" ") : "";
11706
- })() : "")))).split(" ").slice(0, 4).join(" "), chu22 = hoa3(suaChu(sach2(x.chu2 || ""))).split(" ").slice(0, 4).join(" ");
11860
+ })() : "")))).split(" ").slice(0, 4).join(" "), chu22 = hoa3(suaChu(sach3(x.chu2 || ""))).split(" ").slice(0, 4).join(" ");
11707
11861
  const n0 = ung.length, n1 = loai.length, dV = co && im0.laVideo ? Math.min(2.8, Math.max(2, +im0.dai || 2.4)) : 0;
11708
11862
  if (x.kieu === "anh" && dV) {
11709
11863
  de(f2, dV, { uuTien: UT.so + 5, bo: "anh", ten: ten2, chu: chuK, chu2: chu22, keu: "whoosh", video: 1 }, 3, datAnh);
11710
11864
  ghiL("video", { bo: "anh", f: f2, d: dV }, "kho video: ung vien clip " + dV.toFixed(1) + " s thay anh: " + String(x.tu || ""));
11711
11865
  } else if (x.kieu === "anh" && (co || chuK)) de(f2, (f2 < f1 ? 2 : 2.4) * kTram(), { uuTien: UT.anh, ...co ? [{ bo: "anh", ten: ten2, chu: chuK, chu2: chu22, keu: "whoosh" }, { bo: "chia", ten: ten2, chu: chuK, keu: "whoosh" }, { bo: "anh", ten: ten2, chu: chuK, chu2: chu22, pip: 1, keu: "whoosh" }][nAnh++ % 3] : { bo: "kinh", dong: [chuK, chu22].filter(Boolean), keu: "whoosh" } }, 3, datAnh);
11712
11866
  else if (x.kieu === "vat") {
11713
- const LG = timLogo(suaChu(chuK + " " + sach2(String(x.tu || ""))))[0];
11867
+ const LG = timLogo(suaChu(chuK + " " + sach3(String(x.tu || ""))))[0];
11714
11868
  if (LG) napHinhLogo(LG.slug);
11715
11869
  de(f2, 2.3, { uuTien: UT.vat, bo: "cut", vat: co && !LG ? ten2 : "", logoTo: LG, giant: haiDong4(chuK, 11), chu2: co || LG ? "" : chu22, keu: "pop" }, 3);
11716
11870
  } else if (x.kieu === "ds" && Array.isArray(x.dong) && x.dong.length >= 2) {
11717
- const dg = x.dong.slice(0, 3).map((v) => hoa3(suaChu(sach2(String(v || "")))).split(" ").slice(0, 6).join(" ")).filter(Boolean);
11871
+ const dg = x.dong.slice(0, 3).map((v) => hoa3(suaChu(sach3(String(v || "")))).split(" ").slice(0, 6).join(" ")).filter(Boolean);
11718
11872
  const qs = dg.map((v) => {
11719
11873
  const q = tim(v, f2);
11720
11874
  return q >= 0 && q < f2 + 6 ? q - f2 : 99;
@@ -11799,7 +11953,7 @@ function lapCuongMe(o) {
11799
11953
  });
11800
11954
  if (k < 2) k = kc;
11801
11955
  if (k < 2) return;
11802
- const t3 = hoa3(suaChu([k - 2, k - 1, k].map((q) => sach2(ws[q].text)).join(" "))), f32 = Math.max(a + 0.3, Math.min(W22[k - 2].f - 0.1, b - 1.9));
11956
+ const t3 = hoa3(suaChu([k - 2, k - 1, k].map((q) => sach3(ws[q].text)).join(" "))), f32 = Math.max(a + 0.3, Math.min(W22[k - 2].f - 0.1, b - 1.9));
11803
11957
  if (t3) dat(f32, Math.max(1.3, Math.min(2.1, b - f32 - 0.16)), { bo: "depth", giant: haiDong4(t3, 11), keu: "pop" }, 0.5);
11804
11958
  });
11805
11959
  }
@@ -11889,10 +12043,10 @@ function lapCuongMe(o) {
11889
12043
  if (cum3.length < 3 || GF[cum3[cum3.length - 1][0]] - GF[i] > 5) continue;
11890
12044
  if (cum3.slice(0, 3).some((c) => c.length < 2 || c.length > 5)) continue;
11891
12045
  {
11892
- const tu3 = cum3.slice(0, 3).map((c) => c.map((k) => sach2(GW[k].text).toLocaleLowerCase("vi")));
12046
+ const tu3 = cum3.slice(0, 3).map((c) => c.map((k) => sach3(GW[k].text).toLocaleLowerCase("vi")));
11893
12047
  if (tu3.some((A2, x) => tu3.some((B, y) => x !== y && A2.filter((w) => B.includes(w)).length >= Math.min(A2.length, B.length) * 0.5))) continue;
11894
12048
  }
11895
- const f0 = GF[i], dong = cum3.slice(0, 3).map((c) => hoa3(suaChu(c.map((k) => sach2(GW[k].text)).join(" ")))), moc2 = cum3.slice(0, 3).map((c) => Math.max(0, +(GF[c[0]] - f0).toFixed(2)));
12049
+ const f0 = GF[i], dong = cum3.slice(0, 3).map((c) => hoa3(suaChu(c.map((k) => sach3(GW[k].text)).join(" ")))), moc2 = cum3.slice(0, 3).map((c) => Math.max(0, +(GF[c[0]] - f0).toFixed(2)));
11896
12050
  {
11897
12051
  const bo22 = (t) => bd(String(t || "").toLocaleLowerCase("vi")), trung = sp.filter((x) => (x.tieuDoc || x.bo === "kinh") && Array.isArray(x.dong) && Math.abs(x.f - f0) < (x.bo === "card" ? 7 : 5) && dong.filter((d0) => x.dong.some((e) => {
11898
12052
  const A2 = bo22(d0).split(" "), B = bo22(e).split(" ");
@@ -11991,7 +12145,7 @@ function lapCuongMe(o) {
11991
12145
  W22.forEach((w, i) => {
11992
12146
  if (w.f < 2 || w.f > tong - 3 || w.f - tr < 6) return;
11993
12147
  const t = w.t, n1 = W22[i + 1]?.t || "", so4 = /^\d+([.,]\d+)?%?$/.test(t) ? t : SO[t] != null ? String(SO[t]) : "";
11994
- const chu3 = /^x\d+$/.test(t) ? hoa3(t) : (t === "\xEDch" || t === "x") && /^mư[ơờ]i$/.test(n1) ? "X10" : so4 && (/%$/.test(so4) || DV.test(n1)) && !(i > 0 && /^thứ$/.test(W22[i - 1].t)) ? /%$/.test(so4) ? hoa3(so4) : hoa3(so4 + " " + sach2(ws[i + 1].text)) : "";
12148
+ const chu3 = /^x\d+$/.test(t) ? hoa3(t) : (t === "\xEDch" || t === "x") && /^mư[ơờ]i$/.test(n1) ? "X10" : so4 && (/%$/.test(so4) || DV.test(n1)) && !(i > 0 && /^thứ$/.test(W22[i - 1].t)) ? /%$/.test(so4) ? hoa3(so4) : hoa3(so4 + " " + sach3(ws[i + 1].text)) : "";
11995
12149
  if (!chu3) return;
11996
12150
  const k1 = chu3.toLocaleLowerCase("vi").split(" ")[0], da = sp.some((s) => Math.abs(s.f - w.f) < 2.5 && (String(s.giant || "") + " " + String(s.chu || "") + " " + String(s.chu2 || "")).toLocaleLowerCase("vi").includes(k1));
11997
12151
  if (da) return;
@@ -12006,7 +12160,7 @@ function lapCuongMe(o) {
12006
12160
  const o2 = sp.find((x) => ["depth", "cut", "tron"].includes(x.bo) && (x.giant || x.chu) && !x.vat && !x.cam && x.f - 1.6 < w.f && w.f < x.f + x.d);
12007
12161
  if (o2 && (w.f - o2.f <= 0.8 || o2.f + o2.d - (w.f - 0.1) >= 1.2)) {
12008
12162
  ghiL("doi-noi-dung", o2, "chu to cu \u2192 dong phu (3 tu), chu to = " + chu3);
12009
- o2.chu2 = hoa3(sach2(String(o2.giant || o2.chu).replace(/\n/g, " "))).split(" ").slice(0, 3).join(" ");
12163
+ o2.chu2 = hoa3(sach3(String(o2.giant || o2.chu).replace(/\n/g, " "))).split(" ").slice(0, 3).join(" ");
12010
12164
  o2.giant = chu3;
12011
12165
  o2.chu = "";
12012
12166
  o2.cam = 1;
@@ -12026,7 +12180,7 @@ function lapCuongMe(o) {
12026
12180
  }
12027
12181
  {
12028
12182
  bc = "B6f bam nhip";
12029
- const bd3 = (x) => bd(sach2(x).toLocaleLowerCase("vi")), LD = globalThis.__lyDoNhip = [];
12183
+ const bd3 = (x) => bd(sach3(x).toLocaleLowerCase("vi")), LD = globalThis.__lyDoNhip = [];
12030
12184
  sp.sort((p, q) => p.f - q.f);
12031
12185
  for (let k = 0; k < sp.length; k++) {
12032
12186
  const s = sp[k];
@@ -12157,7 +12311,7 @@ function lapCuongMe(o) {
12157
12311
  }
12158
12312
  {
12159
12313
  bc = "B6i bang kq";
12160
- const bd3 = (t) => bd(sach2(t).toLocaleLowerCase("vi")), tuDai = (t) => t.split(/\s+/).map(bd3).filter((w) => w.length >= 3), ke = (f2) => Math.min(...sp.filter((s) => s.f > f2).map((s) => s.f), tong), datKe = (f2, d0, x) => {
12314
+ const bd3 = (t) => bd(sach3(t).toLocaleLowerCase("vi")), tuDai = (t) => t.split(/\s+/).map(bd3).filter((w) => w.length >= 3), ke = (f2) => Math.min(...sp.filter((s) => s.f > f2).map((s) => s.f), tong), datKe = (f2, d0, x) => {
12161
12315
  const dd = Math.min(d0, +(ke(f2) - f2 - 0.16).toFixed(2));
12162
12316
  if (dd < minD(d0) || !dat(f2, dd, x, 0, 0.01)) return false;
12163
12317
  if (dd < d0 - 0.01) ghiL("rut", { bo: "chia", f: f2, d: d0 }, "bang kq ngan: cham canh sau (khong con 1 s mat)", [f2, f2 + dd]);
@@ -12750,7 +12904,7 @@ function lapCuongMe(o) {
12750
12904
  const thanhO = (t) => coBuoc && t >= f1 - 0.1 && t < hetMuc;
12751
12905
  const bd0 = (x) => String(x || "").split(String.fromCharCode(10)).join(" ").trim().toLocaleLowerCase("vi"), SAC = /* @__PURE__ */ new Map();
12752
12906
  (kb?.canh || []).forEach((c) => {
12753
- if (c && c.chu && c.sac) SAC.set(bd0(hoa3(suaChu(sach2(c.chu)))), String(c.sac));
12907
+ if (c && c.chu && c.sac) SAC.set(bd0(hoa3(suaChu(sach3(c.chu)))), String(c.sac));
12754
12908
  });
12755
12909
  bc = "B7 phat the";
12756
12910
  const stTr = { n: 0 }, keuTr = {};
@@ -12891,7 +13045,7 @@ function lapCuongMe(o) {
12891
13045
  bc = "B6b logo loi";
12892
13046
  const daL = {};
12893
13047
  for (let q = 0; q < ws.length; q++) {
12894
- const f2 = W22[q].f, L = timLogo(suaChu(sach2(ws[q].text) + " " + sach2(ws[q + 1]?.text || "")))[0];
13048
+ const f2 = W22[q].f, L = timLogo(suaChu(sach3(ws[q].text) + " " + sach3(ws[q + 1]?.text || "")))[0];
12895
13049
  if (!L || daL[L.slug] > f2 - 10) continue;
12896
13050
  const sc = sp.find((x) => f2 >= x.f - 0.1 && f2 < x.f + x.d), deL = (x) => !x || x.bo === "phong" || (x.bo === "cut" || x.bo === "depth") && !x.hang && !x.doc && !x.ui && !x.dong && !x.tieu && !x.tieuDoc && !x.vat && !x.logoTo;
12897
13051
  if (sc && sc.logoTo && sc.logoTo.slug === L.slug) {
@@ -12959,7 +13113,7 @@ function lapCuongMe(o) {
12959
13113
  const sb = (ms || []).filter((q) => q.kind === "sub" && q.tu).sort((p, q) => p.t0 - q.t0), fl = sb.flatMap((q) => q.tu.map((_w, k) => ({ q, k }))), X = (e) => e.q.tu[e.k];
12960
13114
  SUA.forEach(([sai, dung]) => {
12961
13115
  for (let i = 0; i + sai.length <= fl.length; i++) {
12962
- if (sai.some((t, j) => sach2(X(fl[i + j]).x).toLocaleLowerCase("vi") !== t)) continue;
13116
+ if (sai.some((t, j) => sach3(X(fl[i + j]).x).toLocaleLowerCase("vi") !== t)) continue;
12963
13117
  const cuoi = [...fl.slice(i, i + sai.length)].reverse().find((e) => e.q === fl[i].q), dau = (String(X(fl[i + sai.length - 1]).x).match(/[.,!?…]+$/) || [""])[0];
12964
13118
  const dw = String(dung).split(/\s+/), n = sai.length;
12965
13119
  if (dw.length >= n && n > 1) {
@@ -12987,7 +13141,7 @@ function lapCuongMe(o) {
12987
13141
  boC,
12988
13142
  loai,
12989
13143
  nhip: sp.filter((s) => s.giant || s.chu || s.tieu || s.bo === "kinh" && s.dong && s.dong.length).map((s) => {
12990
- const bd2 = (x) => bd(sach2(x).toLocaleLowerCase("vi")), tu = String(s.tieu || s.giant || s.chu || (s.dong || []).join(" ")).split(/\s+/).map(bd2).filter((x) => x.length > 1);
13144
+ const bd2 = (x) => bd(sach3(x).toLocaleLowerCase("vi")), tu = String(s.tieu || s.giant || s.chu || (s.dong || []).join(" ")).split(/\s+/).map(bd2).filter((x) => x.length > 1);
12991
13145
  let lech = null;
12992
13146
  W22.forEach((w) => {
12993
13147
  if (Math.abs(w.f - s.f) <= 4 && tu.includes(bd(w.t))) {
@@ -13306,9 +13460,12 @@ function veTrangTu(g, c, T, W4, H2, nen2, mo4) {
13306
13460
  const h = HV[q];
13307
13461
  if (h.t < tk - 0.05) break;
13308
13462
  if (/^icon|^logo/.test(String(h.lop))) vat.push([h.x0 * W4 - e, h.y0 * H2 - e, h.x1 * W4 + e, h.y1 * H2 + e, 2]);
13463
+ else if (/^chu:/.test(String(h.lop)) && h.lop !== "chu:phude") vat.push([h.x0 * W4 - e, h.y0 * H2 - e, h.x1 * W4 + e, h.y1 * H2 + e, 4]);
13309
13464
  }
13310
13465
  }
13311
- if (D && D[3] > D[1]) {
13466
+ const LM = !G3.__dauMH && G3.__phuKin !== G3.__khungSo ? G3.__matLoi : null;
13467
+ if (LM && D && D[3] > D[1]) vat.push([LM[0] * W4, LM[1] * H2, LM[2] * W4, LM[3] * H2, 8], [D[0] * W4, D[1] * H2, D[2] * W4, LM[1] * H2, 2], [D[0] * W4, LM[3] * H2, D[2] * W4, (D[3] + 0.025) * H2, 1.2]);
13468
+ else if (D && D[3] > D[1]) {
13312
13469
  const hh = D[3] - D[1];
13313
13470
  vat.push([D[0] * W4, (D[1] + 0.3 * hh) * H2, D[2] * W4, (D[1] + 0.8 * hh) * H2, 3], [D[0] * W4, (D[1] - 0.35 * hh) * H2, D[2] * W4, (D[1] + 0.3 * hh) * H2, 2], [D[0] * W4, (D[1] + 0.8 * hh) * H2, D[2] * W4, (D[3] + 0.025) * H2, 1.2]);
13314
13471
  }
@@ -14269,6 +14426,7 @@ async function renderNhanh(ff, clips, files, audio, cards, nen2, options, paint,
14269
14426
  {
14270
14427
  globalThis.__matKhung = null;
14271
14428
  globalThis.__matNguon = null;
14429
+ globalThis.__matLoi = null;
14272
14430
  if (FM.length) {
14273
14431
  const ts2 = c.trimStart + u;
14274
14432
  let m = FM[0];
@@ -14277,6 +14435,7 @@ async function renderNhanh(ff, clips, files, audio, cards, nen2, options, paint,
14277
14435
  const mx = (nx) => (((W4 - sw * c0) / 2 + nx * sw * c0 - sx) * z - dx) / q / W4, my = (ny) => (((H2 - sh * c0) / 2 + ny * sh * c0 - sy) * z - dy) / q / H2, top = typeof m.headTop === "number" ? Math.min(m.headTop, m.face.y) : m.face.y, cam = typeof m.chin === "number" && m.chin > m.face.y ? m.chin : m.face.y + m.face.h;
14278
14436
  globalThis.__matKhung = [mx(m.face.x), my(top), mx(m.face.x + m.face.w), my(cam)];
14279
14437
  globalThis.__matNguon = [m.face.x, top, m.face.x + m.face.w, cam];
14438
+ if (m.mouth) globalThis.__matLoi = [mx(m.face.x), my(m.eyeY - 0.12 * m.face.h), mx(m.face.x + m.face.w), my(m.mouth.y + m.mouth.h)];
14280
14439
  }
14281
14440
  }
14282
14441
  }
@@ -16517,7 +16676,7 @@ var ProEditPanel = (props) => {
16517
16676
  try {
16518
16677
  const heard = await heardWithRetry(cancelled);
16519
16678
  if (cancelled()) return;
16520
- let faceMap = prior && prior.fingerprint === heard.fingerprint && prior.faceMap && Array.isArray(prior.faceMap.samples) ? prior.faceMap : null;
16679
+ let faceMap = prior && prior.fingerprint === heard.fingerprint && prior.faceMap && Array.isArray(prior.faceMap.samples) && /mat2/.test(String(prior.faceMap.engine || "")) ? prior.faceMap : null;
16521
16680
  if (!faceMap) try {
16522
16681
  const raw = atob(currentScene.videoBase64), bytes = new Uint8Array(raw.length);
16523
16682
  for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);
@@ -16594,7 +16753,7 @@ var ProEditPanel = (props) => {
16594
16753
  if (!d) {
16595
16754
  const heard = await heardWithRetry(cancelled);
16596
16755
  if (cancelled()) return;
16597
- let faceMap = prior && prior.fingerprint === heard.fingerprint && prior.faceMap && Array.isArray(prior.faceMap.samples) ? prior.faceMap : null;
16756
+ let faceMap = prior && prior.fingerprint === heard.fingerprint && prior.faceMap && Array.isArray(prior.faceMap.samples) && /mat2/.test(String(prior.faceMap.engine || "")) ? prior.faceMap : null;
16598
16757
  if (!faceMap) try {
16599
16758
  const raw = atob(currentScene.videoBase64), bytes = new Uint8Array(raw.length);
16600
16759
  for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);
@@ -18753,40 +18912,7 @@ async function handleExport(currentProject, setExporting, setExportedBlob, addLo
18753
18912
  } catch (e) {
18754
18913
  }
18755
18914
  try {
18756
- const W4 = (window.__wsGocKB || currentProject.speechDraft?.analysis?.words || []).filter((w) => w && w.text && w.t1 > w.t0);
18757
- if (kb && Array.isArray(kb.canh) && W4.length > 20) {
18758
- const lo = (x) => String(x || "").toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}\s]/gu, "").trim(), wl = W4.map((w) => lo(w.text));
18759
- const timTu = (tu) => {
18760
- const q = lo(tu).split(/\s+/).filter(Boolean).slice(0, 3);
18761
- if (!q.length) return -1;
18762
- for (let i = 0; i + q.length <= wl.length; i++) {
18763
- let ok = true;
18764
- for (let j = 0; j < q.length; j++) if (wl[i + j] !== q[j]) {
18765
- ok = false;
18766
- break;
18767
- }
18768
- if (ok) return i;
18769
- }
18770
- return -1;
18771
- };
18772
- const moc = kb.canh.filter((c) => c && c.tu).map((c) => timTu(c.tu)).filter((i) => i >= 0).map((i) => W4[i].t0).sort((x, y) => x - y), pts = [W4[0].t0 + 3, ...moc, W4[W4.length - 1].t1 - 3];
18773
- let them = 0;
18774
- for (let k = 0; k + 1 < pts.length && them < 8; k++) {
18775
- const a0 = pts[k], b0 = pts[k + 1];
18776
- if (b0 - a0 < 7) continue;
18777
- const n = Math.floor((b0 - a0) / 5.5);
18778
- for (let m = 1; m <= n && them < 8; m++) {
18779
- const tm = a0 + (b0 - a0) * m / (n + 1), HU4 = /^(và|với|là|thì|mà|nhưng|rồi|cái|những|các|một|này|đó|chúng|ta|tôi|mình|bạn|em|anh|chị|của|cho|để|nên|vì|cũng|đã|đang|sẽ|có|không|được|rất|thì|ạ|nhé|nha|à|ơi|lại|ra|vào|đi|nó|họ)$/i, i0 = W4.findIndex((w) => w.t0 >= tm);
18780
- let i = i0;
18781
- while (i >= 0 && i < i0 + 5 && i < W4.length - 3 && HU4.test(String(W4[i].text).replace(/[.,!?;:…"“”]/g, ""))) i++;
18782
- if (i < 0 || i + 3 > W4.length) continue;
18783
- const tu = W4.slice(i, i + 3).map((w) => String(w.text).replace(/[.,!?;:…"“”]/g, "")).join(" "), cau = W4.slice(Math.max(0, i - 5), i + 10).map((w) => w.text).join(" ");
18784
- kb.canh.push({ tu, kieu: "anh", chu: " ", chu2: "", en: 'Cinematic photorealistic vertical photo that illustrates the meaning of this Vietnamese sentence: "' + cau + '". Vietnamese people, real everyday setting, natural light, no text, no captions.' });
18785
- them++;
18786
- }
18787
- }
18788
- window.__anhBu = them;
18789
- }
18915
+ window.__anhBu = lapAnhTheoKhuon(kb, window.__wsGocKB || currentProject.speechDraft?.analysis?.words || []);
18790
18916
  } catch (e) {
18791
18917
  }
18792
18918
  if (String((() => {
@@ -20536,7 +20662,7 @@ async function napLoi(d) {
20536
20662
  return "LOI: " + String(e && e.message || e).slice(0, 300);
20537
20663
  }
20538
20664
  }
20539
- var LOI_URL = "https://cdn.jsdelivr.net/npm/xvai-loi@0.1.63/nap.js";
20665
+ var LOI_URL = "https://cdn.jsdelivr.net/npm/xvai-loi@0.1.64/nap.js";
20540
20666
  var TRONG_LOI = !!globalThis.__xvaiReact;
20541
20667
  try {
20542
20668
  if (!TRONG_LOI) setTimeout(() => {
@@ -20566,7 +20692,7 @@ function datCauLenh(a) {
20566
20692
  on2 = true;
20567
20693
  window.addEventListener("message", async (ev) => {
20568
20694
  const d = ev.data;
20569
- if (!d || d.xvaiLoi111325 !== true) return;
20695
+ if (!d || d.xvaiLoi111450 !== true) return;
20570
20696
  const o = String(ev.origin || "");
20571
20697
  if (!(o.indexOf("https://flow.google.com") === 0 || o.indexOf("https://labs.google") === 0)) return;
20572
20698
  const tra = (kq) => {