xvai-loi 0.1.65 → 0.1.67

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 +151 -92
package/co.txt CHANGED
@@ -1 +1 @@
1
- xvaiLoi111348
1
+ xvaiLoi111619
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xvai-loi",
3
- "version": "0.1.65",
3
+ "version": "0.1.67",
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;
@@ -2102,7 +2122,7 @@ function sachMau(raw, words) {
2102
2122
  }
2103
2123
  function lapTrong(mau7, words) {
2104
2124
  if (!words.length) return mau7;
2105
- const out = [], cuoi = words[words.length - 1].t1, sach3 = (w) => {
2125
+ const out = [], cuoi = words[words.length - 1].t1, sach4 = (w) => {
2106
2126
  let t = String(w || "");
2107
2127
  for (const c of [",", ".", "?", "!", ":", ";", '"', "[", "]"]) t = t.split(c).join("");
2108
2128
  return t;
@@ -2114,7 +2134,7 @@ function lapTrong(mau7, words) {
2114
2134
  if (i < 0) break;
2115
2135
  const cum3 = [words[i]];
2116
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]);
2117
- const tu2 = cum3.map((w) => sach3(w.text)).filter(Boolean);
2137
+ const tu2 = cum3.map((w) => sach4(w.text)).filter(Boolean);
2118
2138
  if (tu2.length < 2) break;
2119
2139
  const chu3 = tu2.length >= 3 ? tu2.slice(0, -2).join(" ") + " [" + tu2.slice(-2).join(" ") + "]" : "[" + tu2.join(" ") + "]";
2120
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 });
@@ -6018,6 +6038,7 @@ function catNen(im, buoc = 7, tol = 40) {
6018
6038
  }
6019
6039
  var ts = /* @__PURE__ */ new Map();
6020
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]);
6021
6042
  var taiSan = (ten) => ten ? ts.get(ten) || globalThis.__taiSanThu?.(ten) || null : null;
6022
6043
  var nhanTaiSan = (ten, im) => {
6023
6044
  ts.set(ten, ten.indexOf("anh:") === 0 ? im : catNen(im));
@@ -9796,8 +9817,67 @@ function datKhoiChu(g, kc, coThanh, coTach, vungTruoc, choThu = false, WH = 9 /
9796
9817
  return ra;
9797
9818
  }
9798
9819
 
9820
+ // flow-src/engine/khuon.ts
9821
+ var KHUON_TOPN = {
9822
+ ten: "Top N chi\u1EC1u s\xE2u (Captions)",
9823
+ tram: { phut: 18.3, tyLe: 0.7, phan: [0.83, 0.81, 0.46], daiTV: 2.1, video: 0.33, nhanVat: ["Vietnamese people in a real everyday setting.", "Close-up of an object, hands or a place that shows the idea, no faces."] },
9824
+ // 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; nhanVat: xen kẽ ảnh có người / cận vật-tay-nơi (đối thủ trộn web, stock, 3D — B06-1027: toàn ảnh người → 'không thấy mặt' 12 % < 15)
9825
+ chu: { phut: [8, 18] },
9826
+ icon: { phut: 11.5 },
9827
+ cat: { moi10s: [4, 6] },
9828
+ nguoi: { phongToiDa: 1.8 },
9829
+ // MỌI ô người (PIP, thẻ, chia) phóng khung gốc tối đa 1,8× (độ nét) — trước: PIP 1,6, thẻ 1,3 (B05-1027: thẻ hiện cả người nhỏ)
9830
+ bien: { dau: 3, cuoi: 2.5, ctaAnh: true }
9831
+ // 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)
9832
+ };
9833
+ 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;
9834
+ var sach2 = (x) => String(x || "").replace(/[.,!?;:…"“”]/g, "");
9835
+ function lapAnhTheoKhuon(kb, ws, K = KHUON_TOPN, toiDa = 12) {
9836
+ const W4 = (ws || []).filter((w) => w && w.text && w.t1 > w.t0);
9837
+ if (!kb || !Array.isArray(kb.canh) || W4.length < 20) return 0;
9838
+ const lo = (x) => String(x || "").toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}\s]/gu, "").trim(), wl = W4.map((w) => lo(w.text));
9839
+ const timTu = (tu) => {
9840
+ const q = lo(tu).split(/\s+/).filter(Boolean).slice(0, 3);
9841
+ if (!q.length) return -1;
9842
+ for (let i = 0; i + q.length <= wl.length; i++) {
9843
+ let ok = true;
9844
+ for (let j = 0; j < q.length; j++) if (wl[i + j] !== q[j]) {
9845
+ ok = false;
9846
+ break;
9847
+ }
9848
+ if (ok) return i;
9849
+ }
9850
+ return -1;
9851
+ };
9852
+ const g = 60 / K.tram.phut, t0 = W4[0].t0 + K.bien.dau, t1 = W4[W4.length - 1].t1 - K.bien.cuoi;
9853
+ const moc = kb.canh.filter(
9854
+ (c) => c && c.tu && /^(anh|ds)$/.test(String(c.kieu))
9855
+ /* 'so' vẽ thành chữ to trên người / ô tròn (cut/tron) — không phải trám */
9856
+ ).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);
9857
+ const pts = [t0, ...moc, t1];
9858
+ let them = 0;
9859
+ for (let k = 0; k + 1 < pts.length && them < toiDa; k++) {
9860
+ const a0 = pts[k], b0 = pts[k + 1];
9861
+ if (b0 - a0 < 1.6 * g) continue;
9862
+ const n = Math.max(1, Math.round((b0 - a0) / g) - 1);
9863
+ for (let m = 1; m <= n && them < toiDa; m++) {
9864
+ const tm = a0 + (b0 - a0) * m / (n + 1), i0 = W4.findIndex((w) => w.t0 >= tm);
9865
+ if (i0 < 0) continue;
9866
+ const nd = [];
9867
+ 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);
9868
+ if (nd.length < 2) continue;
9869
+ 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(" ");
9870
+ if (timTu(tu) !== i) continue;
9871
+ kb.canh.push({ tu, kieu: "anh", chu: " ", chu2: "", khuon: 1, en: 'Cinematic photorealistic vertical photo that illustrates the meaning of this Vietnamese sentence: "' + cau + '". ' + (them % 2 ? K.tram.nhanVat[1] : K.tram.nhanVat[0]) + " Natural light, no text, no captions." });
9872
+ them++;
9873
+ }
9874
+ }
9875
+ return them;
9876
+ }
9877
+
9799
9878
  // flow-src/engine/veCuongMe.ts
9800
9879
  var luoiAnhCache = /* @__PURE__ */ new Map();
9880
+ var matAnhCache = /* @__PURE__ */ new Map();
9801
9881
  var kep12 = (x) => Math.max(0, Math.min(1, x));
9802
9882
  var eOut = (x) => 1 - Math.pow(1 - kep12(x), 3);
9803
9883
  var eSoft = (x) => {
@@ -9990,7 +10070,7 @@ function sNuaDuoi(F) {
9990
10070
  return F ? Math.max(0.5, Math.min(1, 0.26 / Math.max(0.08, F[2] - F[0]))) : 0.75;
9991
10071
  }
9992
10072
  function tfDau(g, W4, H2, D, yTop, kz = 1) {
9993
- const s = Math.max(1, Math.min(1.3, 0.21 / Math.max(0.08, D[3] - D[1]))) * kz, cx = (D[0] + D[2]) / 2;
10073
+ const s = Math.max(1, Math.min(KHUON_TOPN.nguoi.phongToiDa, 0.21 / Math.max(0.05, D[3] - D[1]))) * kz, cx = (D[0] + D[2]) / 2;
9994
10074
  const tx = Math.min(0, Math.max(W4 - W4 * s, W4 / 2 - cx * W4 * s)), ty = Math.min((yTop - 0.05) * H2, yTop * H2 - D[1] * H2 * s);
9995
10075
  g.translate(tx, ty);
9996
10076
  g.scale(s, s);
@@ -10493,7 +10573,7 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10493
10573
  bo(g, x, y, w, h, r);
10494
10574
  g.clip();
10495
10575
  {
10496
- const Dc = dauCanh(d, nen2, W4, H2);
10576
+ const Dc = (d.F && d.F[3] > d.F[1] ? d.F : null) || dauCanh(d, nen2, W4, H2);
10497
10577
  if (Dc) tfDau(g, W4, H2, Dc, y / H2 + 0.05);
10498
10578
  else tfTam(g, W4, H2, F, sNuaDuoi(F), NUA_DUOI_CY);
10499
10579
  }
@@ -10565,7 +10645,7 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10565
10645
  }, Math.round(0.012 * W4), "brightness(0.8)");
10566
10646
  const kz = eOut(Math.min(1, tuoi / 0.5));
10567
10647
  {
10568
- const Dc = dauCanh(d, nen2, W4, H2);
10648
+ const Dc = (d.F && d.F[3] > d.F[1] ? d.F : null) || dauCanh(d, nen2, W4, H2);
10569
10649
  if (Dc) tfDau(g, W4, H2, Dc, hT / H2 + 0.05, 1 + 0.12 * (1 - kz));
10570
10650
  else tfTam(g, W4, H2, F, sNuaDuoi(F) * (1 + 0.12 * (1 - kz)), NUA_DUOI_CY);
10571
10651
  }
@@ -10828,17 +10908,19 @@ dangKy("cmAnh", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
10828
10908
  }
10829
10909
  }
10830
10910
  luoiAnhCache.set(kh, U);
10911
+ matAnhCache.set(kh, loiMatAnh(im, W4, H2));
10831
10912
  }
10832
10913
  const LA = luoiAnhCache.get(kh);
10833
10914
  if (LA) globalThis.__anhLuoi = { k: globalThis.__khungSo, L: LA };
10834
10915
  if (LA && LA.some((v) => v)) {
10835
- 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]] : []);
10916
+ 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)] : []]);
10836
10917
  if (c.k >= 0.75) {
10837
10918
  kK = c.k;
10838
10919
  xK = c.x * W4;
10839
10920
  wK2 = 0.76 * W4;
10840
10921
  yK = (c.y - hK * c.k / 2 + 0.575 * 112 / 1920 * c.k) * H2;
10841
10922
  } else {
10923
+ const MA = matAnhCache.get(kh);
10842
10924
  let rT = 64;
10843
10925
  for (let r = 0; r < 64 && rT === 64; r++) {
10844
10926
  let m = 0;
@@ -10849,9 +10931,9 @@ dangKy("cmAnh", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
10849
10931
  let n = 0, t = 0;
10850
10932
  for (let r = Math.floor(y0 * 64); r < Math.min(64, Math.ceil((y0 + hK) * 64)); r++) for (let cc = 4; cc < 32; cc++) {
10851
10933
  t++;
10852
- n += LA[r * 36 + cc] * (r >= rT && r < rT + 16 ? 4 : 1);
10934
+ 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);
10853
10935
  }
10854
- return t ? n / t : 1;
10936
+ return (t ? n / t : 1) + (d.pip && _n && y0 < 0.8 && y0 + hK > 0.555 ? 5 : 0);
10855
10937
  };
10856
10938
  const yB = [0.6, 0.55, 0.14, 0.66, 0.5].filter((y) => y + hK <= 0.82).map((y) => [y, ph(y)]).sort((a2, b) => a2[1] - b[1])[0][0];
10857
10939
  yK = (yB + 0.575 * 112 / 1920) * H2;
@@ -10864,7 +10946,7 @@ dangKy("cmAnh", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
10864
10946
  if (d.chu2) chu2(g, d.chu2, xK, yK + 125 * kK * H2 / 1920 + (1 - k) * 70 * H2 / 1920, 96 * kK * H2 / 1920, d.do2 ? "do" : "vang", kep12((tuoi - 0.35) / 0.15) * kc, wK2);
10865
10947
  }
10866
10948
  if (d.pip && _n) {
10867
- const bw = 0.36 * W4, bh = bw * 1.2, bx = 0.06 * W4, by = 0.555 * H2 + (1 - eOut(Math.min(1, tuoi / 0.35))) * 0.05 * H2, F = d.F, Dm = dauCanh(d, _n, W4, H2), Fd = F && F[3] - F[1] > 0.45 ? F : Dm || F || globalThis.__matNguon, top = Fd ? Fd[1] : 0.2, cam = Fd ? Math.max(Fd[3], top + 0.12) : 0.6, s = Math.max(bw / W4, bh / H2, Math.min(1.6, 0.54 * bh / (Math.max(0.08, cam - top) * H2))), cx0 = Fd ? (Fd[0] + Fd[2]) / 2 : 0.5, MK = globalThis.__matKhung, kd = d._goc || d, cx = MK ? kd.__pipCx = kd.__pipCx == null ? (MK[0] + MK[2]) / 2 : kd.__pipCx + ((MK[0] + MK[2]) / 2 - kd.__pipCx) * 0.12 : cx0;
10949
+ const bw = 0.36 * W4, bh = bw * 1.2, bx = 0.06 * W4, by = 0.555 * H2 + (1 - eOut(Math.min(1, tuoi / 0.35))) * 0.05 * H2, F = d.F, Dm = dauCanh(d, _n, W4, H2), Fd = F || globalThis.__matNguon || Dm, top = Fd ? Fd[1] : 0.2, cam = Fd ? Math.max(Fd[3], top + 0.12) : 0.6, s = Math.max(bw / W4, bh / H2, Math.min(KHUON_TOPN.nguoi.phongToiDa, 0.54 * bh / (Math.max(0.08, cam - top) * H2))), cx0 = Fd ? (Fd[0] + Fd[2]) / 2 : 0.5, MK = globalThis.__matKhung, kd = d._goc || d, cx = MK ? kd.__pipCx = kd.__pipCx == null ? (MK[0] + MK[2]) / 2 : kd.__pipCx + ((MK[0] + MK[2]) / 2 - kd.__pipCx) * 0.12 : cx0;
10868
10950
  hop3(g, "nguoi:pip", bx, by, bx + bw, by + bh);
10869
10951
  globalThis.__pipO = { k: globalThis.__khungSo, b: [bx, 0.555 * H2, bx + bw, 0.555 * H2 + bh] };
10870
10952
  g.save();
@@ -11232,10 +11314,9 @@ dangKy("cmKinh", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
11232
11314
  });
11233
11315
  dangKy("cmSticker", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
11234
11316
  const a = kep13(Math.min(1, (dai2 - tuoi) / 0.07));
11235
- 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);
11236
11317
  if (a > 0) {
11237
- const G3 = globalThis, r = d.r ?? 0.065, ry = r * W4 / H2;
11238
- let x = d.x ?? 0.82, y = d.y ?? 0.3;
11318
+ const G3 = globalThis, lg = !!d.logo, r = d.r ?? (lg ? 0.085 : 0.065), ry = r * W4 / H2;
11319
+ let x = d.x ?? (lg ? 0.5 : 0.82), y = d.y ?? (lg ? 0.17 : 0.3);
11239
11320
  if (d.st === "chuot" && G3.__hangO && (G3.__khungSo || 0) - G3.__hangO.k <= 1) {
11240
11321
  x = G3.__hangO.x;
11241
11322
  y = G3.__hangO.y;
@@ -11265,6 +11346,7 @@ dangKy("cmSticker", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
11265
11346
  x = c[0];
11266
11347
  y = c[1];
11267
11348
  }
11349
+ if (lg) return veLogo(g, d.logo, d.hex, x * W4, y * H2, r * W4, tuoi - (d.tre ?? 0), a);
11268
11350
  veSticker3(g, d.st, x * W4, y * H2, r * W4, tuoi - (d.tre ?? 0.25), a);
11269
11351
  }
11270
11352
  });
@@ -11272,9 +11354,9 @@ dangKy("cmSticker", (g, d, tuoi, W4, H2, _n, _s, dai2) => {
11272
11354
  // flow-src/engine/khoiCuongMe.ts
11273
11355
  napLogo();
11274
11356
  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ố))/;
11275
- 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 ";
11357
+ 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 ";
11276
11358
  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)$/;
11277
- 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();
11359
+ 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();
11278
11360
  var hoa3 = (s) => s.toLocaleUpperCase("vi");
11279
11361
  function tenRieng(ws) {
11280
11362
  let best = "", cur = [];
@@ -11283,7 +11365,7 @@ function tenRieng(ws) {
11283
11365
  if (t.length > best.length) best = t;
11284
11366
  cur = [];
11285
11367
  };
11286
- ws.map(sach2).forEach((w) => {
11368
+ ws.map(sach3).forEach((w) => {
11287
11369
  if (/^[A-Z][A-Za-z0-9+.-]+$/.test(w) && !VIET.test(w)) cur.push(w);
11288
11370
  else xong();
11289
11371
  });
@@ -11291,7 +11373,7 @@ function tenRieng(ws) {
11291
11373
  return /^(Claude|Google|Facebook|Youtube|YouTube|TikTok)$/.test(best) ? "" : best;
11292
11374
  }
11293
11375
  function cum2(ws) {
11294
- const w = ws.map(sach2).filter(Boolean), hu = (x) => HU3.indexOf(" " + x.toLocaleLowerCase("vi") + " ") >= 0;
11376
+ const w = ws.map(sach3).filter(Boolean), hu = (x) => HU4.indexOf(" " + x.toLocaleLowerCase("vi") + " ") >= 0;
11295
11377
  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];
11296
11378
  for (let i = w.length - 2; i >= 0; i--) if (!hu(w[i]) && !hu(w[i + 1])) return w[i] + " " + w[i + 1];
11297
11379
  return w.slice(-2).join(" ");
@@ -11340,7 +11422,7 @@ function tomTatLoai(loai) {
11340
11422
  function lapCuongMe(o) {
11341
11423
  if (globalThis.__ghiDauVaoCm) {
11342
11424
  try {
11343
- globalThis.__dauVaoCm = JSON.parse(JSON.stringify({ ...o, __wsGocKB: globalThis.__wsGocKB || null }, (k, v) => typeof v === "string" && v.length > 4e3 ? "[cat " + v.length + "]" : v));
11425
+ 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));
11344
11426
  } catch (e) {
11345
11427
  }
11346
11428
  }
@@ -11384,8 +11466,8 @@ function lapCuongMe(o) {
11384
11466
  const F = (fa, fb) => matRa(fm, nguon3(fa), nguon3(fb), [0, 0, 0, 0], 1, zc);
11385
11467
  const sF = (f2, rong) => f2 ? Math.max(0.8, Math.min(1.35, rong / Math.max(0.1, f2[2] - f2[0]))) : 1;
11386
11468
  napTach();
11387
- const loi2 = " " + ws.map((w) => sach2(w.text).toLocaleLowerCase("vi")).join(" ") + " ";
11388
- 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";
11469
+ const loi2 = " " + ws.map((w) => sach3(w.text).toLocaleLowerCase("vi")).join(" ") + " ";
11470
+ 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";
11389
11471
  const gioTu = (w) => {
11390
11472
  if (!o.fTu) return -1;
11391
11473
  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]) {
@@ -11394,8 +11476,8 @@ function lapCuongMe(o) {
11394
11476
  }
11395
11477
  return -1;
11396
11478
  };
11397
- const W22 = ws.map((w) => ({ t: sach2(w.text).toLocaleLowerCase("vi"), f: gioTu(w) }));
11398
- 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;
11479
+ const W22 = ws.map((w) => ({ t: sach3(w.text).toLocaleLowerCase("vi"), f: gioTu(w) }));
11480
+ 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;
11399
11481
  const SUA = [...kb?.sua || [], ...(() => {
11400
11482
  try {
11401
11483
  const v = JSON.parse(localStorage.getItem("xvaiTuDien") || "[]");
@@ -11403,14 +11485,14 @@ function lapCuongMe(o) {
11403
11485
  } catch (e) {
11404
11486
  return [];
11405
11487
  }
11406
- })(), ["\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) => {
11488
+ })(), ["\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) => {
11407
11489
  const a = x[0].join(" "), b = String(x[1]).toLowerCase();
11408
11490
  return /[À-ỹđ]/i.test(a + b) || levD(a, b) <= Math.max(3, 0.45 * Math.max(a.length, b.length));
11409
11491
  });
11410
11492
  const suaChu = (t) => {
11411
11493
  const w = t.split(/\s+/).filter(Boolean);
11412
11494
  SUA.forEach(([sai, dung]) => {
11413
- 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);
11495
+ 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);
11414
11496
  });
11415
11497
  return w.join(" ");
11416
11498
  };
@@ -11438,7 +11520,7 @@ function lapCuongMe(o) {
11438
11520
  return d + (a.length - i) + (b.length - j) <= 1;
11439
11521
  };
11440
11522
  const tim = (tu, tu0) => {
11441
- const q = String(tu || "").replace(/\[\d+s\]/g, " ").split(/\s+/).map((x) => sach2(x).toLocaleLowerCase("vi")).filter(Boolean).slice(0, 3);
11523
+ const q = String(tu || "").replace(/\[\d+s\]/g, " ").split(/\s+/).map((x) => sach3(x).toLocaleLowerCase("vi")).filter(Boolean).slice(0, 3);
11442
11524
  if (!q.length) return -1;
11443
11525
  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++) {
11444
11526
  const f0 = W4[i].f >= 0 ? W4[i].f : W4[i + 1] && W4[i + 1].f >= 0 ? W4[i + 1].f : -1;
@@ -11478,17 +11560,17 @@ function lapCuongMe(o) {
11478
11560
  return;
11479
11561
  }
11480
11562
  {
11481
- const tenM = suaChu(sach2(m.ten || "")).toLocaleLowerCase("vi");
11563
+ const tenM = suaChu(sach3(m.ten || "")).toLocaleLowerCase("vi");
11482
11564
  if (muc.length && tenM && tenM === String(muc[muc.length - 1].ten || "").toLocaleLowerCase("vi") && f2 - muc[muc.length - 1].f < 10) {
11483
11565
  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);
11484
11566
  return;
11485
11567
  }
11486
11568
  }
11487
- 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) });
11569
+ 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) });
11488
11570
  truocM = f2 + 1;
11489
11571
  });
11490
11572
  {
11491
- 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 ";
11573
+ 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 ";
11492
11574
  const bdx = (x) => String(x || "").toLocaleLowerCase("vi");
11493
11575
  for (const m of muc) {
11494
11576
  const ww = bdx(m.mo).split(/\s+/).filter(Boolean);
@@ -11511,7 +11593,7 @@ function lapCuongMe(o) {
11511
11593
  muc.length = 0;
11512
11594
  cs.forEach((c, i) => {
11513
11595
  if (c.f < 4) return;
11514
- const dau = c.chu.slice(0, 4).map(sach2).join(" ").toLocaleLowerCase("vi");
11596
+ const dau = c.chu.slice(0, 4).map(sach3).join(" ").toLocaleLowerCase("vi");
11515
11597
  let ten2 = tenRieng(c.chu) || (cs[i + 1] && cs[i + 1].f - c.f < 4 ? tenRieng(cs[i + 1].chu) : "");
11516
11598
  const coDau2 = DAU_MUC.test(dau);
11517
11599
  if (!coDau2 && (!ten2 || daTen.has(ten2.toLowerCase()))) return;
@@ -11616,7 +11698,7 @@ function lapCuongMe(o) {
11616
11698
  if (idx.length) {
11617
11699
  const a0 = idx[0], a1 = Math.max(...idx.filter((k) => k <= a0 + ten2.length + 2)), sp2 = [];
11618
11700
  for (let k = a0; k <= a1; k++) sp2.push(k);
11619
- 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(" ");
11701
+ 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(" ");
11620
11702
  return;
11621
11703
  }
11622
11704
  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));
@@ -11658,7 +11740,7 @@ function lapCuongMe(o) {
11658
11740
  }
11659
11741
  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--;
11660
11742
  return w.slice(0, Math.max(2, k)).join(" ");
11661
- })(sach2(kb?.moc || layMoc(ws, kb)).split(" "))) || hoa3(cum2(cs[0] ? cs[0].chu : []));
11743
+ })(sach3(kb?.moc || layMoc(ws, kb)).split(" "))) || hoa3(cum2(cs[0] ? cs[0].chu : []));
11662
11744
  const Lm = Math.min(Math.max(2.4, docGiay(moc) + 0.4), Math.max(1.2, f1 - 0.3));
11663
11745
  bc = "B2 moc";
11664
11746
  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" });
@@ -11674,7 +11756,7 @@ function lapCuongMe(o) {
11674
11756
  bc = "B3 the muc";
11675
11757
  muc.forEach((m, k) => {
11676
11758
  const L = m.b - m.f, Lc = Math.min(2.6, Math.max(2.2, 0.3 * L));
11677
- const sau = suaChu(m.c.chu.map(sach2).join(" ")), go2 = sau.length > 48 ? sau.slice(0, 48).replace(/\s\S*$/, "") + "\u2026" : sau;
11759
+ const sau = suaChu(m.c.chu.map(sach3).join(" ")), go2 = sau.length > 48 ? sau.slice(0, 48).replace(/\s\S*$/, "") + "\u2026" : sau;
11678
11760
  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" });
11679
11761
  if (L >= 10 && !(kb?.canh || []).length) {
11680
11762
  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];
@@ -11719,12 +11801,12 @@ function lapCuongMe(o) {
11719
11801
  {
11720
11802
  bc = "B3 da test";
11721
11803
  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)));
11722
- 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);
11804
+ 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);
11723
11805
  }
11724
11806
  const gioLogo = (a, b) => {
11725
11807
  for (let q = 0; q < ws.length; q++) {
11726
11808
  const f2 = W22[q].f;
11727
- if (f2 >= a && f2 < b && timLogo(suaChu(sach2(ws[q].text) + " " + sach2(ws[q + 1]?.text || "")))[0]) return f2;
11809
+ if (f2 >= a && f2 < b && timLogo(suaChu(sach3(ws[q].text) + " " + sach3(ws[q + 1]?.text || "")))[0]) return f2;
11728
11810
  }
11729
11811
  return -1;
11730
11812
  };
@@ -11764,7 +11846,7 @@ function lapCuongMe(o) {
11764
11846
  return;
11765
11847
  }
11766
11848
  truocC = f2 + 0.5;
11767
- if (soBia(x.chu) || soBia(x.chu2) || x.kieu === "anh" && (f2 < 3 || f2 >= fCta - 0.5)) {
11849
+ if (soBia(x.chu) || soBia(x.chu2) || x.kieu === "anh" && (f2 < KHUON_TOPN.bien.dau || !KHUON_TOPN.bien.ctaAnh && f2 >= fCta - 0.5)) {
11768
11850
  boC.push([x.tu, f2, "chan"]);
11769
11851
  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 || ""));
11770
11852
  return;
@@ -11774,21 +11856,21 @@ function lapCuongMe(o) {
11774
11856
  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 || ""));
11775
11857
  return;
11776
11858
  }
11777
- 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" ? (() => {
11778
- 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);
11859
+ 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" ? (() => {
11860
+ 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);
11779
11861
  return v.length >= 2 ? v.join(" ") : "";
11780
- })() : "")))).split(" ").slice(0, 4).join(" "), chu22 = hoa3(suaChu(sach2(x.chu2 || ""))).split(" ").slice(0, 4).join(" ");
11862
+ })() : "")))).split(" ").slice(0, 4).join(" "), chu22 = hoa3(suaChu(sach3(x.chu2 || ""))).split(" ").slice(0, 4).join(" ");
11781
11863
  const n0 = ung.length, n1 = loai.length, dV = co && im0.laVideo ? Math.min(2.8, Math.max(2, +im0.dai || 2.4)) : 0;
11782
11864
  if (x.kieu === "anh" && dV) {
11783
11865
  de(f2, dV, { uuTien: UT.so + 5, bo: "anh", ten: ten2, chu: chuK, chu2: chu22, keu: "whoosh", video: 1 }, 3, datAnh);
11784
11866
  ghiL("video", { bo: "anh", f: f2, d: dV }, "kho video: ung vien clip " + dV.toFixed(1) + " s thay anh: " + String(x.tu || ""));
11785
- } 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);
11867
+ } else if (x.kieu === "anh" && (co || chuK)) de(f2, (f2 < f1 ? 2 : 2.4) * kTram(), { uuTien: UT.anh, ...co ? nAnh++ % 3 === 0 || !F(f2, f2 + 2.4) ? { bo: "anh", ten: ten2, chu: chuK, chu2: chu22, keu: "whoosh" } : (nAnh - 1) % 3 === 1 ? { bo: "chia", ten: ten2, chu: chuK, keu: "whoosh" } : { bo: "anh", ten: ten2, chu: chuK, chu2: chu22, pip: 1, keu: "whoosh" } : { bo: "kinh", dong: [chuK, chu22].filter(Boolean), keu: "whoosh" } }, 3, datAnh);
11786
11868
  else if (x.kieu === "vat") {
11787
- const LG = timLogo(suaChu(chuK + " " + sach2(String(x.tu || ""))))[0];
11869
+ const LG = timLogo(suaChu(chuK + " " + sach3(String(x.tu || ""))))[0];
11788
11870
  if (LG) napHinhLogo(LG.slug);
11789
11871
  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);
11790
11872
  } else if (x.kieu === "ds" && Array.isArray(x.dong) && x.dong.length >= 2) {
11791
- const dg = x.dong.slice(0, 3).map((v) => hoa3(suaChu(sach2(String(v || "")))).split(" ").slice(0, 6).join(" ")).filter(Boolean);
11873
+ const dg = x.dong.slice(0, 3).map((v) => hoa3(suaChu(sach3(String(v || "")))).split(" ").slice(0, 6).join(" ")).filter(Boolean);
11792
11874
  const qs = dg.map((v) => {
11793
11875
  const q = tim(v, f2);
11794
11876
  return q >= 0 && q < f2 + 6 ? q - f2 : 99;
@@ -11873,7 +11955,7 @@ function lapCuongMe(o) {
11873
11955
  });
11874
11956
  if (k < 2) k = kc;
11875
11957
  if (k < 2) return;
11876
- 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));
11958
+ 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));
11877
11959
  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);
11878
11960
  });
11879
11961
  }
@@ -11963,10 +12045,10 @@ function lapCuongMe(o) {
11963
12045
  if (cum3.length < 3 || GF[cum3[cum3.length - 1][0]] - GF[i] > 5) continue;
11964
12046
  if (cum3.slice(0, 3).some((c) => c.length < 2 || c.length > 5)) continue;
11965
12047
  {
11966
- const tu3 = cum3.slice(0, 3).map((c) => c.map((k) => sach2(GW[k].text).toLocaleLowerCase("vi")));
12048
+ const tu3 = cum3.slice(0, 3).map((c) => c.map((k) => sach3(GW[k].text).toLocaleLowerCase("vi")));
11967
12049
  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;
11968
12050
  }
11969
- 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)));
12051
+ 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)));
11970
12052
  {
11971
12053
  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) => {
11972
12054
  const A2 = bo22(d0).split(" "), B = bo22(e).split(" ");
@@ -12065,7 +12147,7 @@ function lapCuongMe(o) {
12065
12147
  W22.forEach((w, i) => {
12066
12148
  if (w.f < 2 || w.f > tong - 3 || w.f - tr < 6) return;
12067
12149
  const t = w.t, n1 = W22[i + 1]?.t || "", so4 = /^\d+([.,]\d+)?%?$/.test(t) ? t : SO[t] != null ? String(SO[t]) : "";
12068
- 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)) : "";
12150
+ 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)) : "";
12069
12151
  if (!chu3) return;
12070
12152
  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));
12071
12153
  if (da) return;
@@ -12080,7 +12162,7 @@ function lapCuongMe(o) {
12080
12162
  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);
12081
12163
  if (o2 && (w.f - o2.f <= 0.8 || o2.f + o2.d - (w.f - 0.1) >= 1.2)) {
12082
12164
  ghiL("doi-noi-dung", o2, "chu to cu \u2192 dong phu (3 tu), chu to = " + chu3);
12083
- o2.chu2 = hoa3(sach2(String(o2.giant || o2.chu).replace(/\n/g, " "))).split(" ").slice(0, 3).join(" ");
12165
+ o2.chu2 = hoa3(sach3(String(o2.giant || o2.chu).replace(/\n/g, " "))).split(" ").slice(0, 3).join(" ");
12084
12166
  o2.giant = chu3;
12085
12167
  o2.chu = "";
12086
12168
  o2.cam = 1;
@@ -12100,7 +12182,7 @@ function lapCuongMe(o) {
12100
12182
  }
12101
12183
  {
12102
12184
  bc = "B6f bam nhip";
12103
- const bd3 = (x) => bd(sach2(x).toLocaleLowerCase("vi")), LD = globalThis.__lyDoNhip = [];
12185
+ const bd3 = (x) => bd(sach3(x).toLocaleLowerCase("vi")), LD = globalThis.__lyDoNhip = [];
12104
12186
  sp.sort((p, q) => p.f - q.f);
12105
12187
  for (let k = 0; k < sp.length; k++) {
12106
12188
  const s = sp[k];
@@ -12231,7 +12313,7 @@ function lapCuongMe(o) {
12231
12313
  }
12232
12314
  {
12233
12315
  bc = "B6i bang kq";
12234
- 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) => {
12316
+ 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) => {
12235
12317
  const dd = Math.min(d0, +(ke(f2) - f2 - 0.16).toFixed(2));
12236
12318
  if (dd < minD(d0) || !dat(f2, dd, x, 0, 0.01)) return false;
12237
12319
  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]);
@@ -12824,7 +12906,7 @@ function lapCuongMe(o) {
12824
12906
  const thanhO = (t) => coBuoc && t >= f1 - 0.1 && t < hetMuc;
12825
12907
  const bd0 = (x) => String(x || "").split(String.fromCharCode(10)).join(" ").trim().toLocaleLowerCase("vi"), SAC = /* @__PURE__ */ new Map();
12826
12908
  (kb?.canh || []).forEach((c) => {
12827
- if (c && c.chu && c.sac) SAC.set(bd0(hoa3(suaChu(sach2(c.chu)))), String(c.sac));
12909
+ if (c && c.chu && c.sac) SAC.set(bd0(hoa3(suaChu(sach3(c.chu)))), String(c.sac));
12828
12910
  });
12829
12911
  bc = "B7 phat the";
12830
12912
  const stTr = { n: 0 }, keuTr = {};
@@ -12924,7 +13006,7 @@ function lapCuongMe(o) {
12924
13006
  if (s.logoTo && !s.logoY && !s.anNguoi) s.logoY = thanhO(s.f) ? 0.12 : 0.1;
12925
13007
  if (s.logoTo) the(a, bT, { loai: "cmSticker", logo: s.logoTo.slug, hex: s.logoTo.hex, x: 0.5, y: s.logoY ?? 0.34, r: s.logoY ? 0.05 : 0.13, tre: 0.12 });
12926
13008
  {
12927
- const st = s.st === "none" || s.bo === "anh" && !s.stX ? "" : s.st || "";
13009
+ const st = s.st === "none" || s.bo === "anh" && !s.stX && /^(tich|sao|chuot)$/.test(String(s.st || "tich")) ? "" : s.st || "";
12928
13010
  if (st && !(stTr[st] > s.f - 6)) {
12929
13011
  stTr[st] = s.f;
12930
13012
  the(a, bT, {
@@ -12965,7 +13047,7 @@ function lapCuongMe(o) {
12965
13047
  bc = "B6b logo loi";
12966
13048
  const daL = {};
12967
13049
  for (let q = 0; q < ws.length; q++) {
12968
- const f2 = W22[q].f, L = timLogo(suaChu(sach2(ws[q].text) + " " + sach2(ws[q + 1]?.text || "")))[0];
13050
+ const f2 = W22[q].f, L = timLogo(suaChu(sach3(ws[q].text) + " " + sach3(ws[q + 1]?.text || "")))[0];
12969
13051
  if (!L || daL[L.slug] > f2 - 10) continue;
12970
13052
  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;
12971
13053
  if (sc && sc.logoTo && sc.logoTo.slug === L.slug) {
@@ -13033,7 +13115,7 @@ function lapCuongMe(o) {
13033
13115
  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];
13034
13116
  SUA.forEach(([sai, dung]) => {
13035
13117
  for (let i = 0; i + sai.length <= fl.length; i++) {
13036
- if (sai.some((t, j) => sach2(X(fl[i + j]).x).toLocaleLowerCase("vi") !== t)) continue;
13118
+ if (sai.some((t, j) => sach3(X(fl[i + j]).x).toLocaleLowerCase("vi") !== t)) continue;
13037
13119
  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];
13038
13120
  const dw = String(dung).split(/\s+/), n = sai.length;
13039
13121
  if (dw.length >= n && n > 1) {
@@ -13061,7 +13143,7 @@ function lapCuongMe(o) {
13061
13143
  boC,
13062
13144
  loai,
13063
13145
  nhip: sp.filter((s) => s.giant || s.chu || s.tieu || s.bo === "kinh" && s.dong && s.dong.length).map((s) => {
13064
- 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);
13146
+ 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);
13065
13147
  let lech = null;
13066
13148
  W22.forEach((w) => {
13067
13149
  if (Math.abs(w.f - s.f) <= 4 && tu.includes(bd(w.t))) {
@@ -13380,9 +13462,12 @@ function veTrangTu(g, c, T, W4, H2, nen2, mo4) {
13380
13462
  const h = HV[q];
13381
13463
  if (h.t < tk - 0.05) break;
13382
13464
  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]);
13465
+ 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]);
13383
13466
  }
13384
13467
  }
13385
- if (D && D[3] > D[1]) {
13468
+ const LM = !G3.__dauMH && G3.__phuKin !== G3.__khungSo ? G3.__matLoi : null;
13469
+ 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]);
13470
+ else if (D && D[3] > D[1]) {
13386
13471
  const hh = D[3] - D[1];
13387
13472
  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]);
13388
13473
  }
@@ -13401,9 +13486,10 @@ function veTrangTu(g, c, T, W4, H2, nen2, mo4) {
13401
13486
  P3.neK = coPip ? 1 : 0;
13402
13487
  }
13403
13488
  [dx, dy] = P3.ne;
13489
+ if (P3.dich && phat(P3.dich[1]) > 0) P3.dich = [dx, dy];
13404
13490
  }
13405
13491
  }
13406
- P3.dich = P3.dich || [0, 0];
13492
+ P3.dich = P3.dich || [dx, dy];
13407
13493
  P3.dich[0] += (dx - P3.dich[0]) * 0.35;
13408
13494
  P3.dich[1] += (dy - P3.dich[1]) * 0.35;
13409
13495
  g.save();
@@ -14343,6 +14429,7 @@ async function renderNhanh(ff, clips, files, audio, cards, nen2, options, paint,
14343
14429
  {
14344
14430
  globalThis.__matKhung = null;
14345
14431
  globalThis.__matNguon = null;
14432
+ globalThis.__matLoi = null;
14346
14433
  if (FM.length) {
14347
14434
  const ts2 = c.trimStart + u;
14348
14435
  let m = FM[0];
@@ -14351,6 +14438,7 @@ async function renderNhanh(ff, clips, files, audio, cards, nen2, options, paint,
14351
14438
  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;
14352
14439
  globalThis.__matKhung = [mx(m.face.x), my(top), mx(m.face.x + m.face.w), my(cam)];
14353
14440
  globalThis.__matNguon = [m.face.x, top, m.face.x + m.face.w, cam];
14441
+ 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)];
14354
14442
  }
14355
14443
  }
14356
14444
  }
@@ -18294,7 +18382,7 @@ async function chuanBiKho(kb, words, bao) {
18294
18382
  return !im || coVid && !im.laVideo && c.khoa.indexOf("anh:") === 0;
18295
18383
  });
18296
18384
  if (!can.length) return 0;
18297
- const mo4 = await moTaKho(kho6, bao), co = kho6.filter((a) => mo4[a.id]).map((a) => ({ id: a.id, ten: a.ten, mo: mo4[a.id], blob: a.blob, loai: a.loai, dai: a.dai }));
18385
+ const mo4 = await moTaKho(kho6, bao), co = kho6.map((a) => ({ id: a.id, ten: a.ten, mo: mo4[a.id] || "", blob: a.blob, loai: a.loai, dai: a.dai }));
18298
18386
  bao?.("AI gh\xE9p " + co.length + " \u1EA3nh / clip c\xF3 s\u1EB5n v\xE0o " + can.length + " c\u1EA3nh theo ngh\u0129a...");
18299
18387
  const chuan = (x) => String(x || "").toLowerCase().normalize("NFD").replace(/[^a-z0-9]/g, "");
18300
18388
  const gTay = {};
@@ -18308,7 +18396,7 @@ async function chuanBiKho(kb, words, bao) {
18308
18396
  });
18309
18397
  if (a) gTay[c.khoa] = a.id;
18310
18398
  }
18311
- const gAI = can.some((c) => !gTay[c.khoa]) ? await ghepKho(can.filter((c) => !gTay[c.khoa]), co) : {};
18399
+ const gAI = can.some((c) => !gTay[c.khoa]) ? await ghepKho(can.filter((c) => !gTay[c.khoa]), co.filter((x) => x.mo)) : {};
18312
18400
  const g = { ...gAI, ...gTay };
18313
18401
  globalThis.__ghepTay = Object.keys(gTay).length;
18314
18402
  let n = 0;
@@ -18786,6 +18874,10 @@ function ghepKichBan(words, kichBan) {
18786
18874
  // flow-src/services/exportFlow.ts
18787
18875
  async function handleExport(currentProject, setExporting, setExportedBlob, addLog, khung) {
18788
18876
  if (!currentProject || currentProject.timeline.length === 0) return;
18877
+ try {
18878
+ await loadFaceLandmarker();
18879
+ } catch (e) {
18880
+ }
18789
18881
  try {
18790
18882
  await napPhongViet();
18791
18883
  {
@@ -18827,40 +18919,7 @@ async function handleExport(currentProject, setExporting, setExportedBlob, addLo
18827
18919
  } catch (e) {
18828
18920
  }
18829
18921
  try {
18830
- const W4 = (window.__wsGocKB || currentProject.speechDraft?.analysis?.words || []).filter((w) => w && w.text && w.t1 > w.t0);
18831
- if (kb && Array.isArray(kb.canh) && W4.length > 20) {
18832
- const lo = (x) => String(x || "").toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}\s]/gu, "").trim(), wl = W4.map((w) => lo(w.text));
18833
- const timTu = (tu) => {
18834
- const q = lo(tu).split(/\s+/).filter(Boolean).slice(0, 3);
18835
- if (!q.length) return -1;
18836
- for (let i = 0; i + q.length <= wl.length; i++) {
18837
- let ok = true;
18838
- for (let j = 0; j < q.length; j++) if (wl[i + j] !== q[j]) {
18839
- ok = false;
18840
- break;
18841
- }
18842
- if (ok) return i;
18843
- }
18844
- return -1;
18845
- };
18846
- 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];
18847
- let them = 0;
18848
- for (let k = 0; k + 1 < pts.length && them < 8; k++) {
18849
- const a0 = pts[k], b0 = pts[k + 1];
18850
- if (b0 - a0 < 7) continue;
18851
- const n = Math.floor((b0 - a0) / 5.5);
18852
- for (let m = 1; m <= n && them < 8; m++) {
18853
- 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);
18854
- let i = i0;
18855
- while (i >= 0 && i < i0 + 5 && i < W4.length - 3 && HU4.test(String(W4[i].text).replace(/[.,!?;:…"“”]/g, ""))) i++;
18856
- if (i < 0 || i + 3 > W4.length) continue;
18857
- 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(" ");
18858
- 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.' });
18859
- them++;
18860
- }
18861
- }
18862
- window.__anhBu = them;
18863
- }
18922
+ window.__anhBu = lapAnhTheoKhuon(kb, window.__wsGocKB || currentProject.speechDraft?.analysis?.words || []);
18864
18923
  } catch (e) {
18865
18924
  }
18866
18925
  if (String((() => {
@@ -20640,7 +20699,7 @@ function datCauLenh(a) {
20640
20699
  on2 = true;
20641
20700
  window.addEventListener("message", async (ev) => {
20642
20701
  const d = ev.data;
20643
- if (!d || d.xvaiLoi111348 !== true) return;
20702
+ if (!d || d.xvaiLoi111619 !== true) return;
20644
20703
  const o = String(ev.origin || "");
20645
20704
  if (!(o.indexOf("https://flow.google.com") === 0 || o.indexOf("https://labs.google") === 0)) return;
20646
20705
  const tra = (kq) => {