siluzan-tso-cli 1.1.64-beta.2 → 1.1.64-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2172,8 +2172,8 @@ function jsonParseReviverStringifyIds(key, value) {
2172
2172
  }
2173
2173
  return value;
2174
2174
  }
2175
- function parseJsonWithStringIds(text3) {
2176
- return JSON.parse(text3, jsonParseReviverStringifyIds);
2175
+ function parseJsonWithStringIds(text4) {
2176
+ return JSON.parse(text4, jsonParseReviverStringifyIds);
2177
2177
  }
2178
2178
  function hasSiluzanAgentCredentials() {
2179
2179
  const apiKey = process.env.SILUZAN_API_KEY?.trim();
@@ -2414,7 +2414,7 @@ function rawRequest(url, options) {
2414
2414
  });
2415
2415
  stream.on("end", () => {
2416
2416
  if (failed) return;
2417
- const text3 = Buffer.concat(chunks).toString("utf8");
2417
+ const text4 = Buffer.concat(chunks).toString("utf8");
2418
2418
  const responseHeaders = {};
2419
2419
  for (const [key, val] of Object.entries(res.headers)) {
2420
2420
  if (val !== void 0) {
@@ -2432,7 +2432,7 @@ function rawRequest(url, options) {
2432
2432
  ok: status >= 200 && status < 300
2433
2433
  });
2434
2434
  }
2435
- resolve52({ status, text: text3, headers: responseHeaders });
2435
+ resolve52({ status, text: text4, headers: responseHeaders });
2436
2436
  });
2437
2437
  });
2438
2438
  req.on("timeout", () => {
@@ -2483,8 +2483,8 @@ function redactSensitive(input) {
2483
2483
  );
2484
2484
  return output;
2485
2485
  }
2486
- function trimDetail(text3, maxLen) {
2487
- const t = text3.trim();
2486
+ function trimDetail(text4, maxLen) {
2487
+ const t = text4.trim();
2488
2488
  if (t.length <= maxLen) return t;
2489
2489
  return `${t.slice(0, maxLen)}\u2026`;
2490
2490
  }
@@ -2530,25 +2530,25 @@ function messageFromJsonValue(value) {
2530
2530
  return void 0;
2531
2531
  }
2532
2532
  function extractHttpErrorDetail(rawBody) {
2533
- const text3 = rawBody?.trim();
2534
- if (!text3) return void 0;
2535
- if (text3.startsWith('"')) {
2533
+ const text4 = rawBody?.trim();
2534
+ if (!text4) return void 0;
2535
+ if (text4.startsWith('"')) {
2536
2536
  try {
2537
- const parsed = JSON.parse(text3);
2537
+ const parsed = JSON.parse(text4);
2538
2538
  if (typeof parsed === "string" && parsed.trim()) return parsed.trim();
2539
2539
  } catch {
2540
2540
  }
2541
2541
  }
2542
- if (text3.startsWith("{") || text3.startsWith("[")) {
2542
+ if (text4.startsWith("{") || text4.startsWith("[")) {
2543
2543
  try {
2544
- const parsed = JSON.parse(text3);
2544
+ const parsed = JSON.parse(text4);
2545
2545
  const msg = messageFromJsonValue(parsed);
2546
2546
  if (msg) return msg;
2547
2547
  } catch {
2548
2548
  }
2549
2549
  }
2550
- if (text3.startsWith("<")) return void 0;
2551
- return text3;
2550
+ if (text4.startsWith("<")) return void 0;
2551
+ return text4;
2552
2552
  }
2553
2553
  function formatHttpError(status, rawBody, opts) {
2554
2554
  const verbose = opts?.verbose === true;
@@ -2565,20 +2565,20 @@ function formatHttpError(status, rawBody, opts) {
2565
2565
  function buildAuthHeaders(config) {
2566
2566
  return buildSiluzanAuthHeaders(config);
2567
2567
  }
2568
- async function parseApiResponse(status, text3, verbose) {
2568
+ async function parseApiResponse(status, text4, verbose) {
2569
2569
  if (status < 200 || status >= 300) {
2570
- const err = new Error(formatHttpError(status, text3, { verbose }));
2571
- Object.assign(err, { status, rawBody: text3 });
2570
+ const err = new Error(formatHttpError(status, text4, { verbose }));
2571
+ Object.assign(err, { status, rawBody: text4 });
2572
2572
  throw err;
2573
2573
  }
2574
- if (!text3.trim()) return null;
2574
+ if (!text4.trim()) return null;
2575
2575
  try {
2576
- return parseJsonWithStringIds(text3);
2576
+ return parseJsonWithStringIds(text4);
2577
2577
  } catch {
2578
2578
  if (verbose) {
2579
- console.error(` \u26A0\uFE0F \u54CD\u5E94\u975E JSON\uFF0C\u539F\u59CB\u5185\u5BB9\uFF1A${redactSensitive(text3).slice(0, 200)}`);
2579
+ console.error(` \u26A0\uFE0F \u54CD\u5E94\u975E JSON\uFF0C\u539F\u59CB\u5185\u5BB9\uFF1A${redactSensitive(text4).slice(0, 200)}`);
2580
2580
  }
2581
- return text3;
2581
+ return text4;
2582
2582
  }
2583
2583
  }
2584
2584
  function isTransientNetworkError(err) {
@@ -2634,18 +2634,18 @@ async function apiFetchWithHeaders(url, config, options = {}, verbose = false) {
2634
2634
  };
2635
2635
  const body = typeof options.body === "string" ? options.body : void 0;
2636
2636
  const res = await requestWithReadRetry(url, { method, headers: reqHeaders, body });
2637
- const text3 = res.text;
2637
+ const text4 = res.text;
2638
2638
  if (res.status < 200 || res.status >= 300) {
2639
- throw new Error(formatHttpError(res.status, text3, { verbose }));
2639
+ throw new Error(formatHttpError(res.status, text4, { verbose }));
2640
2640
  }
2641
2641
  let data;
2642
- if (!text3.trim()) {
2642
+ if (!text4.trim()) {
2643
2643
  data = null;
2644
2644
  } else {
2645
2645
  try {
2646
- data = parseJsonWithStringIds(text3);
2646
+ data = parseJsonWithStringIds(text4);
2647
2647
  } catch {
2648
- data = text3;
2648
+ data = text4;
2649
2649
  }
2650
2650
  }
2651
2651
  return { data, headers: res.headers };
@@ -3247,9 +3247,9 @@ function pickCompanyId(data) {
3247
3247
  }
3248
3248
  return void 0;
3249
3249
  }
3250
- function parseMeResponse(text3) {
3250
+ function parseMeResponse(text4) {
3251
3251
  try {
3252
- const json = JSON.parse(text3);
3252
+ const json = JSON.parse(text4);
3253
3253
  const data = json?.data && typeof json.data === "object" ? json.data : json;
3254
3254
  const id = pickStr(data, "entityId") ?? pickStr(data, "id") ?? pickStr(data, "userId") ?? pickStr(data, "accountId");
3255
3255
  const email = pickStr(data, "email");
@@ -4395,12 +4395,12 @@ async function apiDeleteRaw(url, config, options = {}) {
4395
4395
  if (res.status < 200 || res.status >= 300) {
4396
4396
  throw new Error(formatHttpError(res.status, res.text, { verbose: options.verbose }));
4397
4397
  }
4398
- const text3 = res.text;
4399
- const value = !text3.trim() ? null : (() => {
4398
+ const text4 = res.text;
4399
+ const value = !text4.trim() ? null : (() => {
4400
4400
  try {
4401
- return JSON.parse(text3);
4401
+ return JSON.parse(text4);
4402
4402
  } catch {
4403
- return text3;
4403
+ return text4;
4404
4404
  }
4405
4405
  })();
4406
4406
  return { value, httpStatus: res.status };
@@ -5497,13 +5497,13 @@ function skippedNoSpendCampaignTypes() {
5497
5497
  };
5498
5498
  }
5499
5499
  function errorCampaignTypes(message) {
5500
- const text3 = message.replace(/\s+/g, " ").trim().slice(0, 180);
5500
+ const text4 = message.replace(/\s+/g, " ").trim().slice(0, 180);
5501
5501
  return {
5502
5502
  campaignTypesStatus: "error",
5503
5503
  campaignTypes: null,
5504
5504
  hasDisplay: null,
5505
5505
  hasPmax: null,
5506
- campaignTypesError: text3 || "unknown error"
5506
+ campaignTypesError: text4 || "unknown error"
5507
5507
  };
5508
5508
  }
5509
5509
  function errorMessage(err) {
@@ -5565,8 +5565,8 @@ function negativeKeywordSlimListUrl(googleApiUrl, accountId, query) {
5565
5565
  if (query?.appliedLevel) params.set("appliedlevel", query.appliedLevel);
5566
5566
  if (query?.readDeleted) params.set("readDeleted", "true");
5567
5567
  if (query?.excludePaused) params.set("excludePaused", "true");
5568
- const text3 = query?.keywordText?.trim();
5569
- if (text3) params.set("keywordtext", text3);
5568
+ const text4 = query?.keywordText?.trim();
5569
+ if (text4) params.set("keywordtext", text4);
5570
5570
  if (query?.matchType) params.set("matchtype", query.matchType);
5571
5571
  const qs = params.toString();
5572
5572
  return `${googleApiUrl}/negativekeywordmanagement/v2/list/${accountId}/slim${qs ? `?${qs}` : ""}`;
@@ -6837,8 +6837,8 @@ function relLuminance(hex) {
6837
6837
  function textColorFor(bgHex) {
6838
6838
  return relLuminance(bgHex) > 0.55 ? NEUTRAL.textDark : NEUTRAL.white;
6839
6839
  }
6840
- function xmlEscape(text3) {
6841
- return text3.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
6840
+ function xmlEscape(text4) {
6841
+ return text4.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
6842
6842
  }
6843
6843
  function colLetter(index) {
6844
6844
  let n = index + 1;
@@ -6960,8 +6960,8 @@ function sheetRelsXml(sheet) {
6960
6960
  ).join("");
6961
6961
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${rels}</Relationships>`;
6962
6962
  }
6963
- function estimateWrapHeight(text3, colWidthChars) {
6964
- const str3 = String(text3 ?? "");
6963
+ function estimateWrapHeight(text4, colWidthChars) {
6964
+ const str3 = String(text4 ?? "");
6965
6965
  if (!str3) return void 0;
6966
6966
  const lines = str3.split("\n").reduce((sum, line) => {
6967
6967
  const width = Math.max(colWidthChars || 20, 8);
@@ -7109,7 +7109,7 @@ var init_xlsx_style_engine = __esm({
7109
7109
  for (let i = 0; i < n; i++) this.pushRow([]);
7110
7110
  return this;
7111
7111
  }
7112
- titleBar(text3, opts = {}) {
7112
+ titleBar(text4, opts = {}) {
7113
7113
  const fill = opts.fill === null ? void 0 : opts.fill ?? NEUTRAL.titleFill;
7114
7114
  const fontColor = opts.fontColor ?? (fill ? textColorFor(fill) : NEUTRAL.textDark);
7115
7115
  const s = this.registry.resolve({
@@ -7120,22 +7120,22 @@ var init_xlsx_style_engine = __esm({
7120
7120
  border: opts.border ?? false,
7121
7121
  hAlign: opts.hAlign ?? "left"
7122
7122
  });
7123
- this.pushRow([{ value: text3, styleId: s }], { height: 28 });
7123
+ this.pushRow([{ value: text4, styleId: s }], { height: 28 });
7124
7124
  this.mergeCurrentRow(opts.span || this.colCount);
7125
7125
  return this;
7126
7126
  }
7127
- subtitleBar(text3, opts = {}) {
7127
+ subtitleBar(text4, opts = {}) {
7128
7128
  const s = this.registry.resolve({
7129
7129
  fontSize: 10.5,
7130
7130
  fontColor: NEUTRAL.subtitleText,
7131
7131
  fill: NEUTRAL.subtitleFill,
7132
7132
  border: false
7133
7133
  });
7134
- this.pushRow([{ value: text3, styleId: s }], { height: 20 });
7134
+ this.pushRow([{ value: text4, styleId: s }], { height: 20 });
7135
7135
  this.mergeCurrentRow(opts.span || this.colCount);
7136
7136
  return this;
7137
7137
  }
7138
- sectionBar(text3, opts = {}) {
7138
+ sectionBar(text4, opts = {}) {
7139
7139
  const fill = opts.fill ?? this.accentHex;
7140
7140
  const s = this.registry.resolve({
7141
7141
  fontSize: 11,
@@ -7145,11 +7145,11 @@ var init_xlsx_style_engine = __esm({
7145
7145
  border: false,
7146
7146
  hAlign: "center"
7147
7147
  });
7148
- this.pushRow([{ value: text3, styleId: s }], { height: 22 });
7148
+ this.pushRow([{ value: text4, styleId: s }], { height: 22 });
7149
7149
  this.mergeCurrentRow(opts.span || this.colCount);
7150
7150
  return this;
7151
7151
  }
7152
- noteRow(text3, span) {
7152
+ noteRow(text4, span) {
7153
7153
  const s = this.registry.resolve({
7154
7154
  fontSize: 9,
7155
7155
  fontColor: NEUTRAL.textMuted,
@@ -7157,8 +7157,8 @@ var init_xlsx_style_engine = __esm({
7157
7157
  border: true,
7158
7158
  vAlign: "top"
7159
7159
  });
7160
- const height = estimateWrapHeight(text3, this.colWidths.reduce((a, b) => a + b, 0) || 60);
7161
- this.pushRow([{ value: text3, styleId: s }], { height });
7160
+ const height = estimateWrapHeight(text4, this.colWidths.reduce((a, b) => a + b, 0) || 60);
7161
+ this.pushRow([{ value: text4, styleId: s }], { height });
7162
7162
  this.mergeCurrentRow(span || this.colCount);
7163
7163
  return this;
7164
7164
  }
@@ -104178,6 +104178,121 @@ var init_fetch = __esm({
104178
104178
  }
104179
104179
  });
104180
104180
 
104181
+ // src/commands/google-analysis/demand-gen-report-content.ts
104182
+ function isRecord4(value) {
104183
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
104184
+ }
104185
+ function text3(value) {
104186
+ return typeof value === "string" ? value.trim() : "";
104187
+ }
104188
+ function asDemandGenReport(value) {
104189
+ if (!isRecord4(value)) throw new Error("\u62A5\u544A\u6570\u636E\u987B\u4E3A JSON \u5BF9\u8C61");
104190
+ return value;
104191
+ }
104192
+ function validateDemandGenReport(payload) {
104193
+ const errors = [];
104194
+ const meta = payload.meta;
104195
+ const narrative = payload.narrative;
104196
+ if (!meta || !narrative) {
104197
+ return { ok: false, errors: ["JSON \u987B\u542B meta \u4E0E narrative"] };
104198
+ }
104199
+ if (!text3(meta.accountId)) errors.push("meta.accountId \u5FC5\u586B");
104200
+ if (!text3(meta.currency)) errors.push("meta.currency \u5FC5\u586B");
104201
+ if (!text3(meta.startDate) || !text3(meta.endDate)) errors.push("meta.startDate / meta.endDate \u5FC5\u586B");
104202
+ if (!text3(narrative.headline)) errors.push("narrative.headline \u5FC5\u586B");
104203
+ const kpiCount = (narrative.headlineKpis?.length ?? 0) + (narrative.kpiGroups ?? []).reduce((sum, group) => sum + (group.items?.length ?? 0), 0);
104204
+ if (kpiCount < 1) errors.push("\u81F3\u5C11 1 \u4E2A\u6838\u5FC3\u6307\u6807\uFF08headlineKpis \u6216 kpiGroups\uFF09");
104205
+ if ((narrative.funnel?.stages?.length ?? 0) < 1) errors.push("narrative.funnel.stages \u81F3\u5C11 1 \u7EA7");
104206
+ if ((narrative.dimensions?.length ?? 0) < 1) errors.push("narrative.dimensions \u81F3\u5C11 1 \u4E2A\u7EF4\u5EA6");
104207
+ if ((narrative.actions?.length ?? 0) < 1) errors.push("narrative.actions \u81F3\u5C11 1 \u6761");
104208
+ if ((narrative.tests?.length ?? 0) < 1) errors.push("narrative.tests \u81F3\u5C11 1 \u6761");
104209
+ for (const dimension of narrative.dimensions ?? []) {
104210
+ if (!text3(dimension.title)) errors.push("\u7EF4\u5EA6\u7F3A\u5C11 title");
104211
+ if (!dimension.columns?.length) errors.push(`\u7EF4\u5EA6\u300C${dimension.title || "\u672A\u547D\u540D"}\u300D\u7F3A\u5C11 columns`);
104212
+ }
104213
+ return { ok: errors.length === 0, errors };
104214
+ }
104215
+ function formatDemandGenReportErrors(check) {
104216
+ return check.errors.map((item) => `- ${item}`).join("\n");
104217
+ }
104218
+ var init_demand_gen_report_content = __esm({
104219
+ "src/commands/google-analysis/demand-gen-report-content.ts"() {
104220
+ "use strict";
104221
+ }
104222
+ });
104223
+
104224
+ // src/commands/google-analysis/demand-gen-render.ts
104225
+ import fs28 from "fs";
104226
+ import fsPromises2 from "fs/promises";
104227
+ import path33 from "path";
104228
+ import { fileURLToPath as fileURLToPath9 } from "url";
104229
+ function resolveSkillTemplatePath3(basename13) {
104230
+ const dir = path33.dirname(fileURLToPath9(import.meta.url));
104231
+ const candidates = [
104232
+ path33.join(dir, "skill", "report-templates", basename13),
104233
+ path33.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
104234
+ path33.join(dir, "..", "..", "..", "assets", "siluzan-ads", "report-templates", basename13),
104235
+ path33.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
104236
+ ];
104237
+ for (const candidate of candidates) {
104238
+ if (fs28.existsSync(candidate)) return candidate;
104239
+ }
104240
+ return path33.join(dir, "skill", "report-templates", basename13);
104241
+ }
104242
+ function demandGenReportTemplatePath() {
104243
+ return resolveSkillTemplatePath3(TEMPLATE_BASENAME);
104244
+ }
104245
+ async function readJsonFile2(filePath) {
104246
+ const text4 = await fsPromises2.readFile(filePath, "utf8");
104247
+ try {
104248
+ return JSON.parse(text4);
104249
+ } catch {
104250
+ throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${filePath}`);
104251
+ }
104252
+ }
104253
+ function injectDemandGenReport(html, payload) {
104254
+ if (!html.includes(DEMAND_GEN_INJECT_MARKER)) {
104255
+ throw new Error("\u62A5\u544A\u6A21\u677F\u7F3A\u5C11\u6570\u636E\u6CE8\u5165\u951A\u70B9\uFF0C\u8BF7\u66F4\u65B0 demand-gen-analysis-report.html");
104256
+ }
104257
+ const json = JSON.stringify(payload).replace(/</g, "\\u003c");
104258
+ return html.replace(DEMAND_GEN_INJECT_MARKER, `window.__DEMAND_GEN_REPORT__ = ${json};`);
104259
+ }
104260
+ async function runDemandGenRender(opts) {
104261
+ const dataPath = path33.resolve(opts.dataFile);
104262
+ const data = asDemandGenReport(await readJsonFile2(dataPath));
104263
+ if (opts.lang?.trim()) data.meta.lang = opts.lang.trim();
104264
+ const check = validateDemandGenReport(data);
104265
+ if (!check.ok) {
104266
+ throw new Error(`Demand Gen \u62A5\u544A\u7F3A\u5FC5\u586B\u5185\u5BB9\uFF1A
104267
+ ${formatDemandGenReportErrors(check)}`);
104268
+ }
104269
+ const templatePath = demandGenReportTemplatePath();
104270
+ let html;
104271
+ try {
104272
+ html = await fsPromises2.readFile(templatePath, "utf8");
104273
+ } catch {
104274
+ throw new Error(`\u672A\u627E\u5230\u62A5\u544A\u6A21\u677F\uFF1A${templatePath}\u3002\u8BF7\u5148\u6267\u884C npm run build`);
104275
+ }
104276
+ const outPath = path33.resolve(
104277
+ opts.out ?? path33.join(path33.dirname(dataPath), "demand-gen-analysis-report.html")
104278
+ );
104279
+ await fsPromises2.mkdir(path33.dirname(outPath), { recursive: true });
104280
+ await fsPromises2.writeFile(outPath, injectDemandGenReport(html, data), "utf8");
104281
+ console.log(`
104282
+ \u2705 Demand Gen \u6295\u653E\u6570\u636E\u5206\u6790 HTML \u5DF2\u751F\u6210\uFF1A${outPath}
104283
+ `);
104284
+ return outPath;
104285
+ }
104286
+ var TEMPLATE_BASENAME, DEMAND_GEN_INJECT_MARKER;
104287
+ var init_demand_gen_render = __esm({
104288
+ "src/commands/google-analysis/demand-gen-render.ts"() {
104289
+ "use strict";
104290
+ init_demand_gen_report_content();
104291
+ TEMPLATE_BASENAME = "demand-gen-analysis-report.html";
104292
+ DEMAND_GEN_INJECT_MARKER = "window.__DEMAND_GEN_REPORT__ = window.__DEMAND_GEN_REPORT__ || null;";
104293
+ }
104294
+ });
104295
+
104181
104296
  // src/commands/google-analysis/okki-display.ts
104182
104297
  function num3(value) {
104183
104298
  const n = typeof value === "number" ? value : Number(value);
@@ -104267,8 +104382,8 @@ function summarizeOkkiDeviceSpend(rows) {
104267
104382
  otherConversions: conv.other
104268
104383
  };
104269
104384
  }
104270
- function narrativeClaimsMobileSpendLeads(text3) {
104271
- const t = text3.replace(/\s+/g, "");
104385
+ function narrativeClaimsMobileSpendLeads(text4) {
104386
+ const t = text4.replace(/\s+/g, "");
104272
104387
  if (!t.includes("\u79FB\u52A8")) return false;
104273
104388
  return /移动(?:端|设备)?(?:为|是)主要消耗/.test(t) || /移动(?:端|设备)?为主要(?:消耗)?设备/.test(t) || /移动(?:端|设备)?(?:消耗|花费|费用|流量)?占比高/.test(t);
104274
104389
  }
@@ -104304,8 +104419,8 @@ var init_okki_display = __esm({
104304
104419
  });
104305
104420
 
104306
104421
  // src/commands/google-analysis/merge-snapshot.ts
104307
- import * as fs28 from "fs/promises";
104308
- import * as path33 from "path";
104422
+ import * as fs29 from "fs/promises";
104423
+ import * as path34 from "path";
104309
104424
  function asRecord21(value) {
104310
104425
  if (value && typeof value === "object" && !Array.isArray(value)) {
104311
104426
  return value;
@@ -104323,7 +104438,7 @@ async function readManifest(snapshotDir, accountId) {
104323
104438
  const candidates = [];
104324
104439
  if (accountId) candidates.push(googleAnalysisManifestFile(accountId));
104325
104440
  try {
104326
- const entries = await fs28.readdir(snapshotDir);
104441
+ const entries = await fs29.readdir(snapshotDir);
104327
104442
  const manifestNames = entries.filter((n) => n.startsWith("manifest") && n.endsWith(".json"));
104328
104443
  for (const name2 of manifestNames) {
104329
104444
  if (!candidates.includes(name2)) candidates.push(name2);
@@ -104332,7 +104447,7 @@ async function readManifest(snapshotDir, accountId) {
104332
104447
  }
104333
104448
  for (const name2 of candidates) {
104334
104449
  try {
104335
- const raw = await fs28.readFile(path33.join(snapshotDir, name2), "utf8");
104450
+ const raw = await fs29.readFile(path34.join(snapshotDir, name2), "utf8");
104336
104451
  const parsed = JSON.parse(raw);
104337
104452
  if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
104338
104453
  } catch {
@@ -104342,7 +104457,7 @@ async function readManifest(snapshotDir, accountId) {
104342
104457
  }
104343
104458
  async function loadSectionFile(snapshotDir, file) {
104344
104459
  try {
104345
- const raw = await fs28.readFile(path33.join(snapshotDir, file), "utf8");
104460
+ const raw = await fs29.readFile(path34.join(snapshotDir, file), "utf8");
104346
104461
  const parsed = JSON.parse(raw);
104347
104462
  if (parsed && typeof parsed === "object") return parsed;
104348
104463
  return null;
@@ -104351,12 +104466,12 @@ async function loadSectionFile(snapshotDir, file) {
104351
104466
  }
104352
104467
  }
104353
104468
  function negativeKeywordText(row) {
104354
- const text3 = row.keywordText;
104355
- if (Array.isArray(text3)) {
104356
- const parts = text3.map((part) => String(part).trim()).filter(Boolean);
104469
+ const text4 = row.keywordText;
104470
+ if (Array.isArray(text4)) {
104471
+ const parts = text4.map((part) => String(part).trim()).filter(Boolean);
104357
104472
  if (parts.length > 0) return parts.join(", ");
104358
104473
  }
104359
- if (typeof text3 === "string" && text3.trim()) return text3.trim();
104474
+ if (typeof text4 === "string" && text4.trim()) return text4.trim();
104360
104475
  if (typeof row.keyword === "string" && row.keyword.trim()) return row.keyword.trim();
104361
104476
  return "\u2014";
104362
104477
  }
@@ -104411,7 +104526,7 @@ async function recoverMissingReportSections(sectionMap, absDir, accountId, prefe
104411
104526
  if (!accountId) return;
104412
104527
  let entries;
104413
104528
  try {
104414
- entries = await fs28.readdir(absDir);
104529
+ entries = await fs29.readdir(absDir);
104415
104530
  } catch {
104416
104531
  return;
104417
104532
  }
@@ -104483,7 +104598,7 @@ function sumCampaignRowsToPeriodKpis(rows) {
104483
104598
  };
104484
104599
  }
104485
104600
  async function mergeGoogleAnalysisSnapshotIntoReport(payload, snapshotDir) {
104486
- const absDir = path33.resolve(snapshotDir);
104601
+ const absDir = path34.resolve(snapshotDir);
104487
104602
  const metaAccountId = typeof asRecord21(payload.meta)?.accountId === "string" ? asRecord21(payload.meta)?.accountId : void 0;
104488
104603
  const manifest = await readManifest(snapshotDir, metaAccountId);
104489
104604
  if (!manifest) {
@@ -104839,8 +104954,8 @@ var init_okki_report_content = __esm({
104839
104954
  });
104840
104955
 
104841
104956
  // src/commands/google-analysis/okki-merge-snapshot.ts
104842
- import * as fs29 from "fs/promises";
104843
- import * as path34 from "path";
104957
+ import * as fs30 from "fs/promises";
104958
+ import * as path35 from "path";
104844
104959
  function num5(value) {
104845
104960
  const n = Number(value);
104846
104961
  return Number.isFinite(n) ? n : void 0;
@@ -104866,7 +104981,7 @@ async function readManifest2(snapshotDir, accountId) {
104866
104981
  const candidates = [];
104867
104982
  if (accountId) candidates.push(googleAnalysisManifestFile(accountId));
104868
104983
  try {
104869
- const entries = await fs29.readdir(snapshotDir);
104984
+ const entries = await fs30.readdir(snapshotDir);
104870
104985
  for (const name2 of entries.filter((n) => n.startsWith("manifest") && n.endsWith(".json"))) {
104871
104986
  if (!candidates.includes(name2)) candidates.push(name2);
104872
104987
  }
@@ -104874,7 +104989,7 @@ async function readManifest2(snapshotDir, accountId) {
104874
104989
  }
104875
104990
  for (const name2 of candidates) {
104876
104991
  try {
104877
- const raw = await fs29.readFile(path34.join(snapshotDir, name2), "utf8");
104992
+ const raw = await fs30.readFile(path35.join(snapshotDir, name2), "utf8");
104878
104993
  const parsed = JSON.parse(raw);
104879
104994
  if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
104880
104995
  } catch {
@@ -104884,7 +104999,7 @@ async function readManifest2(snapshotDir, accountId) {
104884
104999
  }
104885
105000
  async function loadSectionFile2(snapshotDir, file) {
104886
105001
  try {
104887
- const raw = await fs29.readFile(path34.join(snapshotDir, file), "utf8");
105002
+ const raw = await fs30.readFile(path35.join(snapshotDir, file), "utf8");
104888
105003
  const parsed = JSON.parse(raw);
104889
105004
  if (parsed && typeof parsed === "object") return parsed;
104890
105005
  return null;
@@ -104893,7 +105008,7 @@ async function loadSectionFile2(snapshotDir, file) {
104893
105008
  }
104894
105009
  }
104895
105010
  async function mergeOkkiSnapshotIntoReport(payload, snapshotDir) {
104896
- const absDir = path34.resolve(snapshotDir);
105011
+ const absDir = path35.resolve(snapshotDir);
104897
105012
  const metaAccountId = typeof asRecord22(payload.meta)?.accountId === "string" ? asRecord22(payload.meta)?.accountId : void 0;
104898
105013
  const manifest = await readManifest2(absDir, metaAccountId);
104899
105014
  if (!manifest) {
@@ -104910,7 +105025,7 @@ async function mergeOkkiSnapshotIntoReport(payload, snapshotDir) {
104910
105025
  if (accountId) {
104911
105026
  let entries = [];
104912
105027
  try {
104913
- entries = await fs29.readdir(absDir);
105028
+ entries = await fs30.readdir(absDir);
104914
105029
  } catch {
104915
105030
  entries = [];
104916
105031
  }
@@ -105078,9 +105193,9 @@ function sortBySpendDesc(rows) {
105078
105193
  return [...rows].sort((a, b) => (num6(b.spend) ?? 0) - (num6(a.spend) ?? 0));
105079
105194
  }
105080
105195
  function prefixLines(items3, firstPrefix) {
105081
- return items3.map((text3, idx) => {
105082
- if (idx === 0 && !text3.startsWith(firstPrefix)) return `${firstPrefix}${text3}`;
105083
- return text3;
105196
+ return items3.map((text4, idx) => {
105197
+ if (idx === 0 && !text4.startsWith(firstPrefix)) return `${firstPrefix}${text4}`;
105198
+ return text4;
105084
105199
  });
105085
105200
  }
105086
105201
  function analysisLines(data, key) {
@@ -105355,13 +105470,13 @@ function buildOkkiWeeklySheetDrafts(data, lang = "zh") {
105355
105470
  }
105356
105471
  function localizeOkkiDraft(draft, lang) {
105357
105472
  if (lang !== "en") return draft;
105358
- const text3 = (value) => applyEnglishPhrases(value);
105473
+ const text4 = (value) => applyEnglishPhrases(value);
105359
105474
  return {
105360
105475
  ...draft,
105361
- name: text3(draft.name),
105362
- title: text3(draft.title),
105363
- headers: draft.headers.map(text3),
105364
- reviewTitle: draft.reviewTitle ? text3(draft.reviewTitle) : draft.reviewTitle
105476
+ name: text4(draft.name),
105477
+ title: text4(draft.title),
105478
+ headers: draft.headers.map(text4),
105479
+ reviewTitle: draft.reviewTitle ? text4(draft.reviewTitle) : draft.reviewTitle
105365
105480
  };
105366
105481
  }
105367
105482
  function writeOkkiWeeklyExcel(outPath, data, lang = "zh") {
@@ -105433,12 +105548,12 @@ var init_okki_render_excel = __esm({
105433
105548
  });
105434
105549
 
105435
105550
  // src/commands/google-analysis/okki-render-report.ts
105436
- import fs30 from "fs/promises";
105437
- import path35 from "path";
105438
- async function readJsonFile2(filePath) {
105439
- const text3 = await fs30.readFile(filePath, "utf8");
105551
+ import fs31 from "fs/promises";
105552
+ import path36 from "path";
105553
+ async function readJsonFile3(filePath) {
105554
+ const text4 = await fs31.readFile(filePath, "utf8");
105440
105555
  try {
105441
- return JSON.parse(text3);
105556
+ return JSON.parse(text4);
105442
105557
  } catch {
105443
105558
  throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${filePath}`);
105444
105559
  }
@@ -105450,15 +105565,15 @@ function asPayload(value) {
105450
105565
  throw new Error("\u62A5\u544A\u6570\u636E\u987B\u4E3A JSON \u5BF9\u8C61");
105451
105566
  }
105452
105567
  async function runGoogleAnalysisOkkiRender(opts) {
105453
- const dataPath = path35.resolve(opts.dataFile);
105568
+ const dataPath = path36.resolve(opts.dataFile);
105454
105569
  const snapshotDir = opts.snapshotDir?.trim();
105455
105570
  if (!snapshotDir) {
105456
105571
  console.error("\n\u274C okki-render \u5FC5\u987B\u4F20 --snapshot-dir\uFF08google-analysis --json-out \u76EE\u5F55\uFF09\n");
105457
105572
  process.exit(1);
105458
105573
  }
105459
- let data = asPayload(await readJsonFile2(dataPath));
105574
+ let data = asPayload(await readJsonFile3(dataPath));
105460
105575
  try {
105461
- data = await mergeOkkiSnapshotIntoReport(data, path35.resolve(snapshotDir));
105576
+ data = await mergeOkkiSnapshotIntoReport(data, path36.resolve(snapshotDir));
105462
105577
  } catch (err) {
105463
105578
  console.error(`
105464
105579
  \u274C ${err instanceof Error ? err.message : String(err)}
@@ -105478,10 +105593,10 @@ async function runGoogleAnalysisOkkiRender(opts) {
105478
105593
  );
105479
105594
  process.exit(1);
105480
105595
  }
105481
- const outPath = path35.resolve(
105482
- opts.out ?? path35.join(path35.dirname(dataPath), "okki-weekly-report.xlsx")
105596
+ const outPath = path36.resolve(
105597
+ opts.out ?? path36.join(path36.dirname(dataPath), "okki-weekly-report.xlsx")
105483
105598
  );
105484
- await fs30.mkdir(path35.dirname(outPath), { recursive: true });
105599
+ await fs31.mkdir(path36.dirname(outPath), { recursive: true });
105485
105600
  writeOkkiWeeklyExcel(outPath, data, lang);
105486
105601
  console.log(`
105487
105602
  \u2705 OKKI \u5468\u62A5\u5DF2\u751F\u6210\uFF1A${outPath}
@@ -105654,29 +105769,29 @@ var init_report_content = __esm({
105654
105769
  });
105655
105770
 
105656
105771
  // src/commands/google-analysis/render-report.ts
105657
- import fs31 from "fs";
105658
- import fsPromises2 from "fs/promises";
105659
- import path36 from "path";
105660
- import { fileURLToPath as fileURLToPath9 } from "url";
105661
- function resolveSkillTemplatePath3(basename13) {
105662
- const dir = path36.dirname(fileURLToPath9(import.meta.url));
105772
+ import fs32 from "fs";
105773
+ import fsPromises3 from "fs/promises";
105774
+ import path37 from "path";
105775
+ import { fileURLToPath as fileURLToPath10 } from "url";
105776
+ function resolveSkillTemplatePath4(basename13) {
105777
+ const dir = path37.dirname(fileURLToPath10(import.meta.url));
105663
105778
  const candidates = [
105664
- path36.join(dir, "skill", "report-templates", basename13),
105665
- path36.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
105666
- path36.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
105779
+ path37.join(dir, "skill", "report-templates", basename13),
105780
+ path37.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
105781
+ path37.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
105667
105782
  ];
105668
105783
  for (const p of candidates) {
105669
- if (fs31.existsSync(p)) return p;
105784
+ if (fs32.existsSync(p)) return p;
105670
105785
  }
105671
105786
  return candidates[0];
105672
105787
  }
105673
105788
  function googlePeriodReportTemplatePath() {
105674
- return resolveSkillTemplatePath3(TEMPLATE_BASENAME);
105789
+ return resolveSkillTemplatePath4(TEMPLATE_BASENAME2);
105675
105790
  }
105676
- async function readJsonFile3(filePath) {
105677
- const text3 = await fsPromises2.readFile(filePath, "utf8");
105791
+ async function readJsonFile4(filePath) {
105792
+ const text4 = await fsPromises3.readFile(filePath, "utf8");
105678
105793
  try {
105679
- return JSON.parse(text3);
105794
+ return JSON.parse(text4);
105680
105795
  } catch {
105681
105796
  throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${filePath}`);
105682
105797
  }
@@ -105696,10 +105811,10 @@ function injectReportData2(html, payload, lang) {
105696
105811
  return localized.replace(INJECT_MARKER, `window.__GOOGLE_PERIOD_REPORT__ = ${json};`);
105697
105812
  }
105698
105813
  async function runGoogleAnalysisRender(opts) {
105699
- const dataPath = path36.resolve(opts.dataFile);
105700
- let data = asRecord24(await readJsonFile3(dataPath));
105814
+ const dataPath = path37.resolve(opts.dataFile);
105815
+ let data = asRecord24(await readJsonFile4(dataPath));
105701
105816
  if (opts.snapshotDir?.trim()) {
105702
- data = await mergeGoogleAnalysisSnapshotIntoReport(data, path36.resolve(opts.snapshotDir));
105817
+ data = await mergeGoogleAnalysisSnapshotIntoReport(data, path37.resolve(opts.snapshotDir));
105703
105818
  }
105704
105819
  const lang = readReportLangOrExit({ flag: opts.lang, meta: data.meta });
105705
105820
  const contentCheck = validateGooglePeriodReportContent(data);
@@ -105718,7 +105833,7 @@ async function runGoogleAnalysisRender(opts) {
105718
105833
  const templatePath = googlePeriodReportTemplatePath();
105719
105834
  let html;
105720
105835
  try {
105721
- html = await fsPromises2.readFile(templatePath, "utf8");
105836
+ html = await fsPromises3.readFile(templatePath, "utf8");
105722
105837
  } catch {
105723
105838
  console.error(`
105724
105839
  \u274C \u672A\u627E\u5230\u62A5\u544A\u6A21\u677F\uFF1A${templatePath}
@@ -105726,12 +105841,12 @@ async function runGoogleAnalysisRender(opts) {
105726
105841
  `);
105727
105842
  process.exit(1);
105728
105843
  }
105729
- const outPath = path36.resolve(
105730
- opts.out ?? path36.join(path36.dirname(dataPath), "google-period-report.html")
105844
+ const outPath = path37.resolve(
105845
+ opts.out ?? path37.join(path37.dirname(dataPath), "google-period-report.html")
105731
105846
  );
105732
- const outDir = path36.dirname(outPath);
105733
- await fsPromises2.mkdir(outDir, { recursive: true });
105734
- await fsPromises2.writeFile(outPath, injectReportData2(html, data, lang), "utf8");
105847
+ const outDir = path37.dirname(outPath);
105848
+ await fsPromises3.mkdir(outDir, { recursive: true });
105849
+ await fsPromises3.writeFile(outPath, injectReportData2(html, data, lang), "utf8");
105735
105850
  const { stats } = contentCheck;
105736
105851
  const cover = periodWord(attachPeriodChrome(data).periodChrome.unit, "\u5468\u671F");
105737
105852
  console.log(`
@@ -105745,7 +105860,7 @@ async function runGoogleAnalysisRender(opts) {
105745
105860
  "\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00 HTML \u6587\u4EF6\u5373\u53EF\u67E5\u770B\u56FE\u8868\u4E0E\u5B8C\u6574\u7AE0\u8282\uFF08ECharts\uFF1Astaticpn.siluzan.com/homeCDN/echarts.min.js\uFF09\u3002\n"
105746
105861
  );
105747
105862
  }
105748
- var TEMPLATE_BASENAME, INJECT_MARKER;
105863
+ var TEMPLATE_BASENAME2, INJECT_MARKER;
105749
105864
  var init_render_report = __esm({
105750
105865
  "src/commands/google-analysis/render-report.ts"() {
105751
105866
  "use strict";
@@ -105754,14 +105869,14 @@ var init_render_report = __esm({
105754
105869
  init_report_period();
105755
105870
  init_lang();
105756
105871
  init_html();
105757
- TEMPLATE_BASENAME = "google-period-report.html";
105872
+ TEMPLATE_BASENAME2 = "google-period-report.html";
105758
105873
  INJECT_MARKER = "window.__GOOGLE_PERIOD_REPORT__ = window.__GOOGLE_PERIOD_REPORT__ || null;";
105759
105874
  }
105760
105875
  });
105761
105876
 
105762
105877
  // src/utils/batch-manifest.ts
105763
- import * as fs32 from "fs/promises";
105764
- import * as path37 from "path";
105878
+ import * as fs33 from "fs/promises";
105879
+ import * as path38 from "path";
105765
105880
  import { randomUUID as randomUUID2 } from "crypto";
105766
105881
  function generateRunId(now = /* @__PURE__ */ new Date()) {
105767
105882
  const pad3 = (n) => String(n).padStart(2, "0");
@@ -105775,26 +105890,26 @@ function isValidRunId(id) {
105775
105890
  }
105776
105891
  function resolveBatchPaths(baseDir, runId) {
105777
105892
  if (!isValidRunId(runId)) throw new Error(`\u975E\u6CD5 runId\uFF1A${runId}`);
105778
- const runDir = path37.resolve(baseDir, runId);
105779
- const stateDir = path37.join(runDir, "state");
105893
+ const runDir = path38.resolve(baseDir, runId);
105894
+ const stateDir = path38.join(runDir, "state");
105780
105895
  return {
105781
105896
  runDir,
105782
- runManifestFile: path37.join(runDir, "run-manifest.json"),
105783
- progressFile: path37.join(runDir, "progress.json"),
105784
- accountsFile: path37.join(runDir, "accounts.json"),
105785
- resultsDir: path37.join(runDir, "results"),
105786
- errorsDir: path37.join(runDir, "errors"),
105897
+ runManifestFile: path38.join(runDir, "run-manifest.json"),
105898
+ progressFile: path38.join(runDir, "progress.json"),
105899
+ accountsFile: path38.join(runDir, "accounts.json"),
105900
+ resultsDir: path38.join(runDir, "results"),
105901
+ errorsDir: path38.join(runDir, "errors"),
105787
105902
  stateDir,
105788
- tasksLogFile: path37.join(stateDir, "tasks.jsonl"),
105789
- lockFile: path37.join(stateDir, "tasks.lock")
105903
+ tasksLogFile: path38.join(stateDir, "tasks.jsonl"),
105904
+ lockFile: path38.join(stateDir, "tasks.lock")
105790
105905
  };
105791
105906
  }
105792
105907
  async function ensureAccountDirs(paths, accountId) {
105793
105908
  const safe = sanitizeAccountSegment(accountId);
105794
- const results = path37.join(paths.resultsDir, safe);
105795
- const errors = path37.join(paths.errorsDir, safe);
105796
- await fs32.mkdir(results, { recursive: true });
105797
- await fs32.mkdir(errors, { recursive: true });
105909
+ const results = path38.join(paths.resultsDir, safe);
105910
+ const errors = path38.join(paths.errorsDir, safe);
105911
+ await fs33.mkdir(results, { recursive: true });
105912
+ await fs33.mkdir(errors, { recursive: true });
105798
105913
  return { results, errors };
105799
105914
  }
105800
105915
  function sanitizeAccountSegment(accountId) {
@@ -105809,20 +105924,20 @@ function sanitizeAccountSegment(accountId) {
105809
105924
  return slug;
105810
105925
  }
105811
105926
  async function atomicWriteFile(target, content) {
105812
- const dir = path37.dirname(target);
105813
- await fs32.mkdir(dir, { recursive: true });
105814
- const tmp = path37.join(dir, `.tmp-${randomUUID2()}-${path37.basename(target)}`);
105927
+ const dir = path38.dirname(target);
105928
+ await fs33.mkdir(dir, { recursive: true });
105929
+ const tmp = path38.join(dir, `.tmp-${randomUUID2()}-${path38.basename(target)}`);
105815
105930
  try {
105816
- await fs32.writeFile(tmp, content, "utf8");
105817
- await fs32.rename(tmp, target);
105931
+ await fs33.writeFile(tmp, content, "utf8");
105932
+ await fs33.rename(tmp, target);
105818
105933
  } catch (e) {
105819
- await fs32.rm(tmp, { force: true }).catch(() => void 0);
105934
+ await fs33.rm(tmp, { force: true }).catch(() => void 0);
105820
105935
  throw e;
105821
105936
  }
105822
105937
  }
105823
105938
  async function readJsonIfExists(file) {
105824
105939
  try {
105825
- const raw = await fs32.readFile(file, "utf8");
105940
+ const raw = await fs33.readFile(file, "utf8");
105826
105941
  return JSON.parse(raw);
105827
105942
  } catch (e) {
105828
105943
  if (e.code === "ENOENT") return null;
@@ -105865,8 +105980,8 @@ function isTaskLogEntry(value) {
105865
105980
  return typeof row.at === "string" && typeof row.id === "string" && typeof row.accountId === "string" && typeof row.section === "string" && typeof row.state === "string" && TASK_LOG_STATES.has(row.state) && typeof row.attempts === "number";
105866
105981
  }
105867
105982
  async function writeTaskLogLine(paths, entry) {
105868
- await fs32.mkdir(paths.stateDir, { recursive: true });
105869
- await fs32.appendFile(paths.tasksLogFile, JSON.stringify(clampTaskLogEntry(entry)) + "\n", "utf8");
105983
+ await fs33.mkdir(paths.stateDir, { recursive: true });
105984
+ await fs33.appendFile(paths.tasksLogFile, JSON.stringify(clampTaskLogEntry(entry)) + "\n", "utf8");
105870
105985
  }
105871
105986
  async function appendTaskLog(paths, entry) {
105872
105987
  const file = paths.tasksLogFile;
@@ -105884,7 +105999,7 @@ async function appendTaskLog(paths, entry) {
105884
105999
  async function readTaskLog(paths) {
105885
106000
  let raw;
105886
106001
  try {
105887
- raw = await fs32.readFile(paths.tasksLogFile, "utf8");
106002
+ raw = await fs33.readFile(paths.tasksLogFile, "utf8");
105888
106003
  } catch (e) {
105889
106004
  if (e.code === "ENOENT") return [];
105890
106005
  throw e;
@@ -105892,10 +106007,10 @@ async function readTaskLog(paths) {
105892
106007
  const entries = [];
105893
106008
  let skipped = 0;
105894
106009
  for (const line of raw.split("\n")) {
105895
- const text3 = line.trim();
105896
- if (!text3) continue;
106010
+ const text4 = line.trim();
106011
+ if (!text4) continue;
105897
106012
  try {
105898
- const parsed = JSON.parse(text3);
106013
+ const parsed = JSON.parse(text4);
105899
106014
  if (!isTaskLogEntry(parsed)) {
105900
106015
  skipped += 1;
105901
106016
  continue;
@@ -105962,9 +106077,9 @@ function emptyProgress(runId, totalTasks, accountConcurrency, sectionConcurrency
105962
106077
  };
105963
106078
  }
105964
106079
  async function tryAcquireLock(paths) {
105965
- await fs32.mkdir(paths.stateDir, { recursive: true });
106080
+ await fs33.mkdir(paths.stateDir, { recursive: true });
105966
106081
  try {
105967
- const handle = await fs32.open(paths.lockFile, "wx");
106082
+ const handle = await fs33.open(paths.lockFile, "wx");
105968
106083
  await handle.writeFile(`${process.pid}@${(/* @__PURE__ */ new Date()).toISOString()}`);
105969
106084
  await handle.close();
105970
106085
  return true;
@@ -105974,7 +106089,7 @@ async function tryAcquireLock(paths) {
105974
106089
  }
105975
106090
  }
105976
106091
  async function releaseLock(paths) {
105977
- await fs32.rm(paths.lockFile, { force: true }).catch(() => void 0);
106092
+ await fs33.rm(paths.lockFile, { force: true }).catch(() => void 0);
105978
106093
  }
105979
106094
  var BATCH_SCHEMA_VERSION, MAX_TASK_LOG_ERROR_CHARS, TASK_LOG_STATES, taskLogAppendQueue;
105980
106095
  var init_batch_manifest = __esm({
@@ -105996,8 +106111,8 @@ var init_batch_manifest = __esm({
105996
106111
 
105997
106112
  // src/utils/batch-runner.ts
105998
106113
  import { performance as performance2 } from "perf_hooks";
105999
- import * as path38 from "path";
106000
- import * as fs33 from "fs/promises";
106114
+ import * as path39 from "path";
106115
+ import * as fs34 from "fs/promises";
106001
106116
  async function runPool(items3, concurrencyRef, worker, signal) {
106002
106117
  let cursor = 0;
106003
106118
  const launch = () => {
@@ -106136,7 +106251,7 @@ async function runBatch(opts) {
106136
106251
  }
106137
106252
  const inner = {
106138
106253
  ...emptyProgress(
106139
- opts.paths.runDir.split(path38.sep).pop() ?? "run",
106254
+ opts.paths.runDir.split(path39.sep).pop() ?? "run",
106140
106255
  allTasks.length,
106141
106256
  opts.accountConcurrency,
106142
106257
  opts.sectionConcurrency
@@ -106261,7 +106376,7 @@ async function runBatch(opts) {
106261
106376
  signal: aborterToken.signal
106262
106377
  });
106263
106378
  await writer({
106264
- snapshotDir: path38.join(opts.paths.resultsDir, sanitizeAccountSegment(task.accountId)),
106379
+ snapshotDir: path39.join(opts.paths.resultsDir, sanitizeAccountSegment(task.accountId)),
106265
106380
  section: task.section,
106266
106381
  accountId: task.accountId,
106267
106382
  dateRange: result.dateRange,
@@ -106350,7 +106465,7 @@ async function runBatch(opts) {
106350
106465
  };
106351
106466
  }
106352
106467
  async function writeTaskError(paths, errorsDir, task, err, cls) {
106353
- const file = path38.join(errorsDir, `${sanitizeSection(task.section)}.error.json`);
106468
+ const file = path39.join(errorsDir, `${sanitizeSection(task.section)}.error.json`);
106354
106469
  const payload = {
106355
106470
  schemaVersion: 1,
106356
106471
  taskId: task.id,
@@ -106396,10 +106511,10 @@ async function persistRunMetadata(input) {
106396
106511
  accountsTotal: input.accounts.length,
106397
106512
  invocation: input.invocation
106398
106513
  };
106399
- await fs33.mkdir(paths.runDir, { recursive: true });
106400
- await fs33.mkdir(paths.stateDir, { recursive: true });
106401
- await fs33.mkdir(paths.resultsDir, { recursive: true });
106402
- await fs33.mkdir(paths.errorsDir, { recursive: true });
106514
+ await fs34.mkdir(paths.runDir, { recursive: true });
106515
+ await fs34.mkdir(paths.stateDir, { recursive: true });
106516
+ await fs34.mkdir(paths.resultsDir, { recursive: true });
106517
+ await fs34.mkdir(paths.errorsDir, { recursive: true });
106403
106518
  await writeRunManifest(paths, manifest);
106404
106519
  await writeAccounts(paths, input.accounts);
106405
106520
  return paths;
@@ -106462,7 +106577,7 @@ __export(google_analysis_batch_exports, {
106462
106577
  parseAccountIds: () => parseAccountIds,
106463
106578
  registerGoogleAnalysisBatchCommands: () => registerGoogleAnalysisBatchCommands
106464
106579
  });
106465
- import * as path39 from "path";
106580
+ import * as path40 from "path";
106466
106581
  import { performance as performance3 } from "perf_hooks";
106467
106582
  function parseSections(input) {
106468
106583
  if (!input || !input.trim()) return DEFAULT_SECTIONS;
@@ -106997,7 +107112,7 @@ var init_google_analysis_batch = __esm({
106997
107112
  });
106998
107113
 
106999
107114
  // src/commands/google-analysis/register-cli.ts
107000
- import * as path40 from "path";
107115
+ import * as path41 from "path";
107001
107116
  import { performance as performance4 } from "perf_hooks";
107002
107117
  import { Command } from "commander";
107003
107118
  function normalizeAnalysisDateOpts(opts) {
@@ -107135,7 +107250,7 @@ async function runAllSections(opts) {
107135
107250
  }
107136
107251
  const succeeded = results.filter((r) => r.ok).length;
107137
107252
  const failed = results.length - succeeded;
107138
- const absoluteSnapshotDir = path40.resolve(opts.jsonOut);
107253
+ const absoluteSnapshotDir = path41.resolve(opts.jsonOut);
107139
107254
  const summary = {
107140
107255
  kind: "siluzan-tso-google-analysis-snapshot-batch",
107141
107256
  absoluteSnapshotDir,
@@ -107332,7 +107447,7 @@ ${fixHint}
107332
107447
  }
107333
107448
  function registerGoogleAnalysisCommands(program2) {
107334
107449
  const root = program2.command("google-analysis").description(
107335
- "Google \u8D26\u6237\u5206\u6790\uFF1A\u6279\u91CF\u62C9\u53D6\u4E00\u4E2A\u6216\u591A\u4E2A\u7EF4\u5EA6\uFF08\u9ED8\u8BA4\uFF09\uFF0C\u6216\u7531 render \u751F\u6210\u5468\u671F HTML / okki-render \u751F\u6210 OKKI \u5468\u62A5 xlsx"
107450
+ "Google \u8D26\u6237\u5206\u6790\uFF1A\u6279\u91CF\u62C9\u53D6\u4E00\u4E2A\u6216\u591A\u4E2A\u7EF4\u5EA6\uFF08\u9ED8\u8BA4\uFF09\uFF0C\u6216\u7531 render \u751F\u6210\u5468\u671F HTML / okki-render \u751F\u6210 OKKI \u5468\u62A5 xlsx / demand-gen-render \u751F\u6210 Demand Gen \u6C47\u603B HTML"
107336
107451
  );
107337
107452
  root.addCommand(registerRunCommand(), { isDefault: true });
107338
107453
  root.command("render").description(
@@ -107361,6 +107476,18 @@ function registerGoogleAnalysisCommands(program2) {
107361
107476
  lang: opts.lang
107362
107477
  });
107363
107478
  });
107479
+ root.command("demand-gen-render").description(
107480
+ "\u6839\u636E Agent \u64B0\u5199\u7684 Demand Gen \u6C47\u603B JSON \u751F\u6210 8 \u8282 HTML\uFF08\u4E0D\u5408\u5E76\u5FEB\u7167\uFF1BExcel \u4E0D\u8D70\u672C\u547D\u4EE4\uFF09"
107481
+ ).requiredOption("--data <file>", "Agent \u4EA7\u51FA\u7684 demand-gen-analysis-report.json").option("--out <file>", "\u8F93\u51FA HTML \u8DEF\u5F84\uFF08\u9ED8\u8BA4\u540C --data \u76EE\u5F55\uFF09").option("--lang <lang>", "\u7EC8\u7A3F\u8BED\u8A00\uFF1Azh \u6216 en\u3002\u8986\u76D6 JSON meta.lang").action(async (opts) => {
107482
+ try {
107483
+ await runDemandGenRender({ dataFile: opts.data, out: opts.out, lang: opts.lang });
107484
+ } catch (err) {
107485
+ console.error(`
107486
+ \u274C ${err instanceof Error ? err.message : String(err)}
107487
+ `);
107488
+ process.exit(1);
107489
+ }
107490
+ });
107364
107491
  }
107365
107492
  var init_register_cli = __esm({
107366
107493
  "src/commands/google-analysis/register-cli.ts"() {
@@ -107372,6 +107499,7 @@ var init_register_cli = __esm({
107372
107499
  init_http_retry();
107373
107500
  init_sections();
107374
107501
  init_fetch();
107502
+ init_demand_gen_render();
107375
107503
  init_okki_render_report();
107376
107504
  init_render_report();
107377
107505
  }
@@ -107404,9 +107532,9 @@ var init_google_analysis3 = __esm({
107404
107532
  // src/index.ts
107405
107533
  init_dist();
107406
107534
  init_dist();
107407
- import * as fs44 from "fs";
107408
- import * as path55 from "path";
107409
- import { fileURLToPath as fileURLToPath15 } from "url";
107535
+ import * as fs45 from "fs";
107536
+ import * as path56 from "path";
107537
+ import { fileURLToPath as fileURLToPath16 } from "url";
107410
107538
  import { Command as Command6 } from "commander";
107411
107539
 
107412
107540
  // src/commands/login/urls.ts
@@ -107895,8 +108023,8 @@ function deriveWebUrl(apiBaseUrl) {
107895
108023
  }
107896
108024
  var TSO_UMI_ROUTE_PREFIX = "/v3umijs/tso";
107897
108025
  function buildTsoPageWebUrl(webUrl, tsoSubRoute, extraQuery) {
107898
- const path56 = tsoSubRoute.replace(/^\/+/, "");
107899
- const umiPath = `${TSO_UMI_ROUTE_PREFIX}/${path56}`;
108026
+ const path57 = tsoSubRoute.replace(/^\/+/, "");
108027
+ const umiPath = `${TSO_UMI_ROUTE_PREFIX}/${path57}`;
107900
108028
  const q = new URLSearchParams({ tso: umiPath });
107901
108029
  if (extraQuery) {
107902
108030
  for (const [key, value] of Object.entries(extraQuery)) {
@@ -107904,7 +108032,7 @@ function buildTsoPageWebUrl(webUrl, tsoSubRoute, extraQuery) {
107904
108032
  if (v) q.set(key, v);
107905
108033
  }
107906
108034
  }
107907
- return `${webUrl.replace(/\/+$/, "")}/v3/foreign_trade/tso/${path56}?${q.toString()}`;
108035
+ return `${webUrl.replace(/\/+$/, "")}/v3/foreign_trade/tso/${path57}?${q.toString()}`;
107908
108036
  }
107909
108037
  function cmdConfigShow() {
107910
108038
  const shared = readSharedConfig();
@@ -114793,27 +114921,27 @@ function validateCalloutProperties(prefix, rec, errors, _warnings, lengthViolati
114793
114921
  );
114794
114922
  return;
114795
114923
  }
114796
- const text3 = raw["Text"];
114797
- if (typeof text3 !== "string" || !text3.trim()) {
114924
+ const text4 = raw["Text"];
114925
+ if (typeof text4 !== "string" || !text4.trim()) {
114798
114926
  pushErr(
114799
114927
  errors,
114800
114928
  `${prefix}.Properties.Text \u4E0D\u80FD\u4E3A\u7A7A\uFF08CALLOUT \u5FC5\u586B\uFF0C\u540E\u7AEF CreateCalloutFeedItem \u8BFB\u53D6 Properties["Text"]\uFF09`
114801
114929
  );
114802
114930
  return;
114803
114931
  }
114804
- if (text3.length > CALLOUT_TEXT_MAX_LEN) {
114932
+ if (text4.length > CALLOUT_TEXT_MAX_LEN) {
114805
114933
  pushLengthViolation(lengthViolations, {
114806
114934
  path: `${prefix}.Properties.Text`,
114807
114935
  field: "Text",
114808
114936
  kind: "callout_text",
114809
114937
  limit: CALLOUT_TEXT_MAX_LEN,
114810
- actual: text3.length,
114938
+ actual: text4.length,
114811
114939
  countMode: "ascii",
114812
- text: text3
114940
+ text: text4
114813
114941
  });
114814
114942
  pushErr(
114815
114943
  errors,
114816
- `${prefix}.Properties.Text \u8D85\u8FC7 ${CALLOUT_TEXT_MAX_LEN} \u5B57\u7B26\uFF08\u5F53\u524D ${text3.length}\uFF0CGoogle \u786C\u7EA6\u675F\uFF09\uFF1A"${text3}"`
114944
+ `${prefix}.Properties.Text \u8D85\u8FC7 ${CALLOUT_TEXT_MAX_LEN} \u5B57\u7B26\uFF08\u5F53\u524D ${text4.length}\uFF0CGoogle \u786C\u7EA6\u675F\uFF09\uFF1A"${text4}"`
114817
114945
  );
114818
114946
  }
114819
114947
  }
@@ -115127,8 +115255,8 @@ function judgeBudgetAfterFailedPut(input) {
115127
115255
  }
115128
115256
  return { kind: "unchanged" };
115129
115257
  }
115130
- function coreKeyword(text3) {
115131
- const t = text3.trim();
115258
+ function coreKeyword(text4) {
115259
+ const t = text4.trim();
115132
115260
  if (t.length >= 2 && (t.startsWith('"') && t.endsWith('"') || t.startsWith("[") && t.endsWith("]"))) {
115133
115261
  return t.slice(1, -1).trim();
115134
115262
  }
@@ -115171,8 +115299,8 @@ function summarizeNegativeKeywordCreate(requested, response, listItems) {
115171
115299
  const pools = listItems == null ? responseRecords : [...responseRecords, ...listItems];
115172
115300
  const matched = [];
115173
115301
  const pending = [];
115174
- for (const text3 of requested) {
115175
- const core = coreKeyword(text3);
115302
+ for (const text4 of requested) {
115303
+ const core = coreKeyword(text4);
115176
115304
  const hit = pools.find((item) => {
115177
115305
  const cores = [
115178
115306
  ...collectKeywordCores(item["keywordText"]),
@@ -115182,11 +115310,11 @@ function summarizeNegativeKeywordCreate(requested, response, listItems) {
115182
115310
  return cores.includes(core);
115183
115311
  });
115184
115312
  if (!hit) {
115185
- pending.push(text3);
115313
+ pending.push(text4);
115186
115314
  continue;
115187
115315
  }
115188
115316
  const idRaw = hit["id"] ?? hit["Id"];
115189
- matched.push({ text: text3, id: typeof idRaw === "string" ? idRaw : void 0 });
115317
+ matched.push({ text: text4, id: typeof idRaw === "string" ? idRaw : void 0 });
115190
115318
  }
115191
115319
  let verification;
115192
115320
  if (requested.length > 0 && matched.length === requested.length) verification = "verified";
@@ -115298,10 +115426,10 @@ function firstKeywordTextFromRecord(k) {
115298
115426
  return "";
115299
115427
  }
115300
115428
  function negativeKeywordWriteBody(row) {
115301
- const text3 = firstKeywordTextFromRecord(row);
115429
+ const text4 = firstKeywordTextFromRecord(row);
115302
115430
  const body = {
115303
115431
  id: row["id"],
115304
- keywordText: text3 ? [text3] : [],
115432
+ keywordText: text4 ? [text4] : [],
115305
115433
  matchTypeV2: row["matchTypeV2"],
115306
115434
  negativeLevel: row["negativeLevel"]
115307
115435
  };
@@ -115934,8 +116062,8 @@ async function runAdNegativeKeywordDelete(opts) {
115934
116062
 
115935
116063
  // src/commands/ad/campaign-keywords.ts
115936
116064
  var GOOGLE_KEYWORD_MAX_CORE_LENGTH = 80;
115937
- function collapseDuplicateSpacesInKeywordText(text3) {
115938
- return text3.replace(/\s{2,}/g, " ");
116065
+ function collapseDuplicateSpacesInKeywordText(text4) {
116066
+ return text4.replace(/\s{2,}/g, " ");
115939
116067
  }
115940
116068
  var VALID_CORE_REGEX = /^[\p{L}\p{N}\s.\-]+$/u;
115941
116069
  function matchTypeV2ToUi(raw) {
@@ -115960,8 +116088,8 @@ function matchTypeUiToV2(ui) {
115960
116088
  }
115961
116089
  }
115962
116090
  }
115963
- function inferMatchTypeFromDisplayText(text3) {
115964
- const t = text3.trim();
116091
+ function inferMatchTypeFromDisplayText(text4) {
116092
+ const t = text4.trim();
115965
116093
  if (t.length >= 2 && t.startsWith('"') && t.endsWith('"')) return "Phrase";
115966
116094
  if (t.length >= 2 && t.startsWith("[") && t.endsWith("]")) return "Exact";
115967
116095
  return "Broad";
@@ -116002,7 +116130,7 @@ function cloneKeywordBlockShell(block) {
116002
116130
  delete shell["matchTypeV2"];
116003
116131
  return shell;
116004
116132
  }
116005
- function splitKeywordsForBatchJobBlockIfMixed(block, path56, warnings) {
116133
+ function splitKeywordsForBatchJobBlockIfMixed(block, path57, warnings) {
116006
116134
  const declaredUi = matchTypeV2ToUi(readBlockMatchTypeRaw(block));
116007
116135
  const entries = collectKeywordEntriesFromBlock(block);
116008
116136
  if (entries.length === 0) return [block];
@@ -116021,7 +116149,7 @@ function splitKeywordsForBatchJobBlockIfMixed(block, path56, warnings) {
116021
116149
  (ui) => matchTypeUiToV2(ui)
116022
116150
  );
116023
116151
  warnings.push(
116024
- `${path56} \u542B\u591A\u79CD\u5339\u914D\u7C7B\u578B\uFF0C\u5DF2\u81EA\u52A8\u62C6\u5206\u4E3A ${groups.size} \u4E2A KeywordsForBatchJob \u5757\uFF08${labels.join("\u3001")}\uFF09`
116152
+ `${path57} \u542B\u591A\u79CD\u5339\u914D\u7C7B\u578B\uFF0C\u5DF2\u81EA\u52A8\u62C6\u5206\u4E3A ${groups.size} \u4E2A KeywordsForBatchJob \u5757\uFF08${labels.join("\u3001")}\uFF09`
116025
116153
  );
116026
116154
  const shell = cloneKeywordBlockShell(block);
116027
116155
  const splitBlocks = [];
@@ -116041,16 +116169,16 @@ function splitKeywordsForBatchJobBlockIfMixed(block, path56, warnings) {
116041
116169
  }
116042
116170
  return splitBlocks;
116043
116171
  }
116044
- function validateKeywordCore(core, path56, errors, lengthViolations) {
116172
+ function validateKeywordCore(core, path57, errors, lengthViolations) {
116045
116173
  const trimmed = core.trim();
116046
116174
  if (!trimmed) {
116047
- errors.push(`${path56} \u5173\u952E\u8BCD\u8BCD\u5E72\u4E0D\u80FD\u4E3A\u7A7A`);
116175
+ errors.push(`${path57} \u5173\u952E\u8BCD\u8BCD\u5E72\u4E0D\u80FD\u4E3A\u7A7A`);
116048
116176
  return false;
116049
116177
  }
116050
116178
  if (trimmed.length > GOOGLE_KEYWORD_MAX_CORE_LENGTH) {
116051
116179
  if (lengthViolations) {
116052
116180
  pushLengthViolation(lengthViolations, {
116053
- path: path56,
116181
+ path: path57,
116054
116182
  field: "KeywordText",
116055
116183
  kind: "keyword_core",
116056
116184
  limit: GOOGLE_KEYWORD_MAX_CORE_LENGTH,
@@ -116060,13 +116188,13 @@ function validateKeywordCore(core, path56, errors, lengthViolations) {
116060
116188
  });
116061
116189
  }
116062
116190
  errors.push(
116063
- `${path56} \u5173\u952E\u8BCD\u8BCD\u5E72\u8D85\u8FC7 ${GOOGLE_KEYWORD_MAX_CORE_LENGTH} \u5B57\u7B26\uFF08\u5F53\u524D ${trimmed.length}\uFF09\uFF1A"${trimmed}"`
116191
+ `${path57} \u5173\u952E\u8BCD\u8BCD\u5E72\u8D85\u8FC7 ${GOOGLE_KEYWORD_MAX_CORE_LENGTH} \u5B57\u7B26\uFF08\u5F53\u524D ${trimmed.length}\uFF09\uFF1A"${trimmed}"`
116064
116192
  );
116065
116193
  return false;
116066
116194
  }
116067
116195
  if (!VALID_CORE_REGEX.test(trimmed)) {
116068
116196
  errors.push(
116069
- `${path56} \u542B Google \u4E0D\u5141\u8BB8\u7684\u5B57\u7B26\uFF08\u8BCD\u5E72\u4EC5\u5141\u8BB8\u5B57\u6BCD/\u6570\u5B57/\u7A7A\u683C/\u8FDE\u5B57\u7B26/\u53E5\u70B9\uFF09\uFF1A"${trimmed.slice(0, 40)}${trimmed.length > 40 ? "\u2026" : ""}"`
116197
+ `${path57} \u542B Google \u4E0D\u5141\u8BB8\u7684\u5B57\u7B26\uFF08\u8BCD\u5E72\u4EC5\u5141\u8BB8\u5B57\u6BCD/\u6570\u5B57/\u7A7A\u683C/\u8FDE\u5B57\u7B26/\u53E5\u70B9\uFF09\uFF1A"${trimmed.slice(0, 40)}${trimmed.length > 40 ? "\u2026" : ""}"`
116070
116198
  );
116071
116199
  return false;
116072
116200
  }
@@ -116123,10 +116251,10 @@ function canonicalizeKeywordBatchBlock(block, resolvedMatchV2, normalizedTexts,
116123
116251
  }
116124
116252
  }
116125
116253
  }
116126
- function pushKeywordAutoFixWarning(warnings, path56, fieldLabel, trimmedRaw, formatted, declaredUi, beforeUi, matchType, inferredMatchType) {
116254
+ function pushKeywordAutoFixWarning(warnings, path57, fieldLabel, trimmedRaw, formatted, declaredUi, beforeUi, matchType, inferredMatchType) {
116127
116255
  if (inferredMatchType) {
116128
116256
  warnings.push(
116129
- `${path56}.${fieldLabel} \u672A\u6307\u5B9A MatchTypeV2\uFF0C\u5DF2\u6309\u8BCD\u9762\u63A8\u65AD\u4E3A ${matchTypeUiToV2(matchType)}`
116257
+ `${path57}.${fieldLabel} \u672A\u6307\u5B9A MatchTypeV2\uFF0C\u5DF2\u6309\u8BCD\u9762\u63A8\u65AD\u4E3A ${matchTypeUiToV2(matchType)}`
116130
116258
  );
116131
116259
  return false;
116132
116260
  }
@@ -116135,16 +116263,16 @@ function pushKeywordAutoFixWarning(warnings, path56, fieldLabel, trimmedRaw, for
116135
116263
  }
116136
116264
  if (declaredUi && beforeUi !== declaredUi) {
116137
116265
  warnings.push(
116138
- `${path56}.${fieldLabel} MatchTypeV2=${matchTypeUiToV2(declaredUi)} \u4E0E\u8BCD\u9762\u4E0D\u4E00\u81F4\uFF0C\u5DF2\u81EA\u52A8\u4FEE\u590D\u4E3A\uFF1A${formatted}`
116266
+ `${path57}.${fieldLabel} MatchTypeV2=${matchTypeUiToV2(declaredUi)} \u4E0E\u8BCD\u9762\u4E0D\u4E00\u81F4\uFF0C\u5DF2\u81EA\u52A8\u4FEE\u590D\u4E3A\uFF1A${formatted}`
116139
116267
  );
116140
116268
  return false;
116141
116269
  }
116142
116270
  if (formatted !== trimmedRaw) {
116143
- warnings.push(`${path56}.${fieldLabel} \u5DF2\u81EA\u52A8\u4FEE\u590D\u8BCD\u9762\uFF1A${trimmedRaw} \u2192 ${formatted}`);
116271
+ warnings.push(`${path57}.${fieldLabel} \u5DF2\u81EA\u52A8\u4FEE\u590D\u8BCD\u9762\uFF1A${trimmedRaw} \u2192 ${formatted}`);
116144
116272
  }
116145
116273
  return false;
116146
116274
  }
116147
- function normalizeKeywordTextList(texts, matchTypeRaw, path56, fieldLabel, errors, warnings, lengthViolations) {
116275
+ function normalizeKeywordTextList(texts, matchTypeRaw, path57, fieldLabel, errors, warnings, lengthViolations) {
116148
116276
  const declaredUi = matchTypeV2ToUi(matchTypeRaw);
116149
116277
  const normalized = [];
116150
116278
  const seen = /* @__PURE__ */ new Set();
@@ -116153,7 +116281,7 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path56, fieldLabel, error
116153
116281
  for (let k = 0; k < texts.length; k++) {
116154
116282
  const raw = texts[k];
116155
116283
  if (typeof raw !== "string" || !raw.trim()) {
116156
- errors.push(`${path56}.${fieldLabel}[${k}] \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
116284
+ errors.push(`${path57}.${fieldLabel}[${k}] \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
116157
116285
  continue;
116158
116286
  }
116159
116287
  const trimmedRaw = collapseDuplicateSpacesInKeywordText(raw.trim());
@@ -116164,7 +116292,7 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path56, fieldLabel, error
116164
116292
  );
116165
116293
  if (pushKeywordAutoFixWarning(
116166
116294
  warnings,
116167
- path56,
116295
+ path57,
116168
116296
  fieldLabel,
116169
116297
  trimmedRaw,
116170
116298
  formatted,
@@ -116176,11 +116304,11 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path56, fieldLabel, error
116176
116304
  bareWrapped++;
116177
116305
  }
116178
116306
  const core = unwrapKeywordDisplayTextForEdit(formatted);
116179
- if (!validateKeywordCore(core, `${path56}.${fieldLabel}[${k}]`, errors, lengthViolations))
116307
+ if (!validateKeywordCore(core, `${path57}.${fieldLabel}[${k}]`, errors, lengthViolations))
116180
116308
  continue;
116181
116309
  const dedupeKey = `${matchTypeUiToV2(matchType)}:${core.toLowerCase()}`;
116182
116310
  if (seen.has(dedupeKey)) {
116183
- warnings.push(`${path56}.${fieldLabel}[${k}] \u4E0E\u540C\u7EC4\u91CD\u590D\uFF0C\u5DF2\u8DF3\u8FC7\uFF1A${formatted}`);
116311
+ warnings.push(`${path57}.${fieldLabel}[${k}] \u4E0E\u540C\u7EC4\u91CD\u590D\uFF0C\u5DF2\u8DF3\u8FC7\uFF1A${formatted}`);
116184
116312
  continue;
116185
116313
  }
116186
116314
  seen.add(dedupeKey);
@@ -116189,17 +116317,17 @@ function normalizeKeywordTextList(texts, matchTypeRaw, path56, fieldLabel, error
116189
116317
  }
116190
116318
  if (bareWrapped > 0 && declaredUi) {
116191
116319
  warnings.push(
116192
- `${path56}.${fieldLabel}\uFF1A${bareWrapped} \u4E2A\u88F8\u8BCD\u5DF2\u6309 MatchTypeV2=${matchTypeUiToV2(declaredUi)} \u81EA\u52A8\u4FEE\u590D\uFF08\u8865\u5168${declaredUi === "Exact" ? " [ ]" : "\u5F15\u53F7"}\uFF0C\u9884\u671F\u884C\u4E3A\uFF09`
116320
+ `${path57}.${fieldLabel}\uFF1A${bareWrapped} \u4E2A\u88F8\u8BCD\u5DF2\u6309 MatchTypeV2=${matchTypeUiToV2(declaredUi)} \u81EA\u52A8\u4FEE\u590D\uFF08\u8865\u5168${declaredUi === "Exact" ? " [ ]" : "\u5F15\u53F7"}\uFF0C\u9884\u671F\u884C\u4E3A\uFF09`
116193
116321
  );
116194
116322
  }
116195
116323
  return { normalized, resolvedUi };
116196
116324
  }
116197
- function normalizeKeywordsForBatchJobBlock(block, path56, errors, warnings, lengthViolations) {
116325
+ function normalizeKeywordsForBatchJobBlock(block, path57, errors, warnings, lengthViolations) {
116198
116326
  const matchTypeRaw = readBlockMatchTypeRaw(block);
116199
116327
  const declaredUi = matchTypeV2ToUi(matchTypeRaw);
116200
116328
  if (matchTypeRaw !== void 0 && declaredUi === null) {
116201
116329
  errors.push(
116202
- `${path56}.MatchTypeV2 \u65E0\u6548\uFF08${String(matchTypeRaw)}\uFF09\uFF0C\u5408\u6CD5\u503C\uFF1ABROAD | PHRASE | EXACT`
116330
+ `${path57}.MatchTypeV2 \u65E0\u6548\uFF08${String(matchTypeRaw)}\uFF09\uFF0C\u5408\u6CD5\u503C\uFF1ABROAD | PHRASE | EXACT`
116203
116331
  );
116204
116332
  return;
116205
116333
  }
@@ -116214,7 +116342,7 @@ function normalizeKeywordsForBatchJobBlock(block, path56, errors, warnings, leng
116214
116342
  const result = normalizeKeywordTextList(
116215
116343
  texts,
116216
116344
  matchTypeRaw,
116217
- path56,
116345
+ path57,
116218
116346
  "KeywordText",
116219
116347
  errors,
116220
116348
  warnings,
@@ -116223,7 +116351,7 @@ function normalizeKeywordsForBatchJobBlock(block, path56, errors, warnings, leng
116223
116351
  normalizedTexts = result.normalized;
116224
116352
  if (result.resolvedUi) resolvedUi = result.resolvedUi;
116225
116353
  if (normalizedTexts.length === 0 && texts.length > 0) {
116226
- errors.push(`${path56}.KeywordText \u7ECF\u6821\u9A8C\u540E\u65E0\u6709\u6548\u5173\u952E\u8BCD\uFF0C\u8BF7\u4FEE\u6B63\u8BCD\u9762\u6216 MatchTypeV2`);
116354
+ errors.push(`${path57}.KeywordText \u7ECF\u6821\u9A8C\u540E\u65E0\u6709\u6548\u5173\u952E\u8BCD\uFF0C\u8BF7\u4FEE\u6B63\u8BCD\u9762\u6216 MatchTypeV2`);
116227
116355
  }
116228
116356
  }
116229
116357
  if (hasItems && items3) {
@@ -116231,12 +116359,12 @@ function normalizeKeywordsForBatchJobBlock(block, path56, errors, warnings, leng
116231
116359
  for (let k = 0; k < items3.length; k++) {
116232
116360
  const item = items3[k];
116233
116361
  if (!item || typeof item !== "object") {
116234
- errors.push(`${path56}.Items[${k}] \u5FC5\u987B\u662F\u5BF9\u8C61`);
116362
+ errors.push(`${path57}.Items[${k}] \u5FC5\u987B\u662F\u5BF9\u8C61`);
116235
116363
  continue;
116236
116364
  }
116237
116365
  const raw = readItemText(item);
116238
116366
  if (raw === null || !raw.trim()) {
116239
- errors.push(`${path56}.Items[${k}].Text \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
116367
+ errors.push(`${path57}.Items[${k}].Text \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
116240
116368
  continue;
116241
116369
  }
116242
116370
  const trimmedRaw = collapseDuplicateSpacesInKeywordText(raw.trim());
@@ -116247,7 +116375,7 @@ function normalizeKeywordsForBatchJobBlock(block, path56, errors, warnings, leng
116247
116375
  );
116248
116376
  if (pushKeywordAutoFixWarning(
116249
116377
  warnings,
116250
- path56,
116378
+ path57,
116251
116379
  `Items[${k}].Text`,
116252
116380
  trimmedRaw,
116253
116381
  formatted,
@@ -116256,14 +116384,14 @@ function normalizeKeywordsForBatchJobBlock(block, path56, errors, warnings, leng
116256
116384
  matchType,
116257
116385
  inferredMatchType
116258
116386
  )) {
116259
- warnings.push(`${path56}.Items[${k}].Text \u5DF2\u6309\u5757\u7EA7\u5339\u914D\u7C7B\u578B\u81EA\u52A8\u4FEE\u590D\u4E3A\uFF1A${formatted}`);
116387
+ warnings.push(`${path57}.Items[${k}].Text \u5DF2\u6309\u5757\u7EA7\u5339\u914D\u7C7B\u578B\u81EA\u52A8\u4FEE\u590D\u4E3A\uFF1A${formatted}`);
116260
116388
  }
116261
116389
  const core = unwrapKeywordDisplayTextForEdit(formatted);
116262
- if (!validateKeywordCore(core, `${path56}.Items[${k}].Text`, errors, lengthViolations))
116390
+ if (!validateKeywordCore(core, `${path57}.Items[${k}].Text`, errors, lengthViolations))
116263
116391
  continue;
116264
116392
  const dedupeKey = `${matchTypeUiToV2(matchType)}:${core.toLowerCase()}`;
116265
116393
  if (seen.has(dedupeKey)) {
116266
- warnings.push(`${path56}.Items[${k}].Text \u4E0E\u540C\u7EC4\u91CD\u590D\uFF0C\u5DF2\u8DF3\u8FC7\uFF1A${formatted}`);
116394
+ warnings.push(`${path57}.Items[${k}].Text \u4E0E\u540C\u7EC4\u91CD\u590D\uFF0C\u5DF2\u8DF3\u8FC7\uFF1A${formatted}`);
116267
116395
  continue;
116268
116396
  }
116269
116397
  seen.add(dedupeKey);
@@ -116409,16 +116537,16 @@ function warnIfNegativeKeywordsInPositiveKeywords(campaign, warnings) {
116409
116537
  const raw = texts[ki];
116410
116538
  if (typeof raw !== "string" || !raw.trim()) continue;
116411
116539
  const core = normalizeKeywordCoreForNegativeCheck(raw);
116412
- const path56 = `campaign.AdGroupsForBatchJob[${gi}].KeywordsForBatchJob[${bi}].KeywordText[${ki}]`;
116540
+ const path57 = `campaign.AdGroupsForBatchJob[${gi}].KeywordsForBatchJob[${bi}].KeywordText[${ki}]`;
116413
116541
  if (plannedNegCores.has(core)) {
116414
116542
  warnings.push(
116415
- `${path56} \u8BCD\u9762\u300C${raw}\u300D\u5DF2\u51FA\u73B0\u5728 campaign.NegativeKeywordsForBatchJob\uFF0C\u4E0D\u5E94\u91CD\u590D\u5199\u5165\u6B63\u5411 KeywordsForBatchJob\uFF1B\u5426\u8BCD\u53EA\u653E NegativeKeywordsForBatchJob`
116543
+ `${path57} \u8BCD\u9762\u300C${raw}\u300D\u5DF2\u51FA\u73B0\u5728 campaign.NegativeKeywordsForBatchJob\uFF0C\u4E0D\u5E94\u91CD\u590D\u5199\u5165\u6B63\u5411 KeywordsForBatchJob\uFF1B\u5426\u8BCD\u53EA\u653E NegativeKeywordsForBatchJob`
116416
116544
  );
116417
116545
  continue;
116418
116546
  }
116419
116547
  if (looksLikeStandaloneNegativeKeyword(core)) {
116420
116548
  warnings.push(
116421
- `${path56} \u8BCD\u9762\u300C${raw}\u300D\u7591\u4F3C\u5426\u5B9A\u5173\u952E\u8BCD\uFF08\u5E38\u89C1\u5426\u8BCD\u8BCD\u6839\uFF09\uFF0C\u5E94\u5199\u5165 campaign.NegativeKeywordsForBatchJob\uFF08MatchTypeV2: BROAD\uFF09\uFF0C\u52FF\u653E\u5165 KeywordsForBatchJob`
116549
+ `${path57} \u8BCD\u9762\u300C${raw}\u300D\u7591\u4F3C\u5426\u5B9A\u5173\u952E\u8BCD\uFF08\u5E38\u89C1\u5426\u8BCD\u8BCD\u6839\uFF09\uFF0C\u5E94\u5199\u5165 campaign.NegativeKeywordsForBatchJob\uFF08MatchTypeV2: BROAD\uFF09\uFF0C\u52FF\u653E\u5165 KeywordsForBatchJob`
116422
116550
  );
116423
116551
  }
116424
116552
  }
@@ -116499,9 +116627,9 @@ var POLICY_RISK_RULES = [
116499
116627
  { re: /\b(alcohol|whisk(e)?y|vodka|liquor)\b/i, label: "\u9152\u7CBE\uFF08\u5730\u57DF\u9650\u5236\uFF09" },
116500
116628
  { re: /(最好|第一|国家级|绝对|100%)/, label: "\u5E7F\u544A\u6CD5\u7EDD\u5BF9\u5316\u7528\u8BED" }
116501
116629
  ];
116502
- function matchRisk(text3) {
116630
+ function matchRisk(text4) {
116503
116631
  for (const r of POLICY_RISK_RULES) {
116504
- if (r.re.test(text3)) return r.label;
116632
+ if (r.re.test(text4)) return r.label;
116505
116633
  }
116506
116634
  return void 0;
116507
116635
  }
@@ -116524,10 +116652,10 @@ function warnPolicyRiskTerms(campaign, warnings) {
116524
116652
  const groups = campaign["AdGroupsForBatchJob"];
116525
116653
  if (!Array.isArray(groups)) return;
116526
116654
  const hitsByLabel = /* @__PURE__ */ new Map();
116527
- const add = (label2, text3) => {
116655
+ const add = (label2, text4) => {
116528
116656
  let set = hitsByLabel.get(label2);
116529
116657
  if (!set) hitsByLabel.set(label2, set = /* @__PURE__ */ new Set());
116530
- set.add(text3.trim());
116658
+ set.add(text4.trim());
116531
116659
  };
116532
116660
  for (const g of groups) {
116533
116661
  const gr = g;
@@ -116563,8 +116691,8 @@ function warnPolicyRiskTerms(campaign, warnings) {
116563
116691
  }
116564
116692
 
116565
116693
  // src/commands/ad/campaign-rsa.ts
116566
- function normalizeRsaAssetKey(text3) {
116567
- return text3.trim().replace(/\s+/g, " ").toLowerCase();
116694
+ function normalizeRsaAssetKey(text4) {
116695
+ return text4.trim().replace(/\s+/g, " ").toLowerCase();
116568
116696
  }
116569
116697
  function listRsaHeadlines(ad) {
116570
116698
  const parts = [
@@ -116732,9 +116860,9 @@ function validateLocationsFidelity(cfg, campaign, errors) {
116732
116860
  }
116733
116861
  }
116734
116862
  }
116735
- function calcGoogleCharLength(text3) {
116863
+ function calcGoogleCharLength(text4) {
116736
116864
  let len = 0;
116737
- for (const ch of text3) {
116865
+ for (const ch of text4) {
116738
116866
  const code = ch.codePointAt(0) ?? 0;
116739
116867
  if (code >= 19968 && code <= 40959 || code >= 13312 && code <= 19903 || code >= 131072 && code <= 173791 || code >= 12288 && code <= 12351 || code >= 65280 && code <= 65519) {
116740
116868
  len += 2;
@@ -117537,8 +117665,8 @@ async function reportFailedCampaignPut(opts) {
117537
117665
  async function reportCampaignWrite(opts) {
117538
117666
  const nextQuery = `siluzan-tso ad campaigns -a ${opts.account} --json-out ./snap`;
117539
117667
  const unmatched = describeUnmatchedChecks(opts.checks);
117540
- const text3 = opts.verification === "verified" ? opts.detail : unmatched || opts.detail;
117541
- const headline = writeVerificationHeadline(opts.verification, text3);
117668
+ const text4 = opts.verification === "verified" ? opts.detail : unmatched || opts.detail;
117669
+ const headline = writeVerificationHeadline(opts.verification, text4);
117542
117670
  if (opts.verification !== "verified") {
117543
117671
  console.error(`
117544
117672
  ${headline}
@@ -120214,14 +120342,14 @@ function buildExtensionRemediateCommandLine(opts) {
120214
120342
  const campaignFlag = level === "Campaign" ? `--campaign-id ${campaignId}` : "";
120215
120343
  const base2 = ["siluzan-tso", "ad", "extension"];
120216
120344
  if (type === "SITELINK") {
120217
- const text3 = pickString(props["Text"], props["LinkText"]);
120345
+ const text4 = pickString(props["Text"], props["LinkText"]);
120218
120346
  const url = pickString(props["DestinationUrl"]);
120219
- if (!text3 || !url) return null;
120347
+ if (!text4 || !url) return null;
120220
120348
  const parts = [
120221
120349
  ...base2,
120222
120350
  "sitelink",
120223
120351
  `-a ${accountId}`,
120224
- `--text ${shellArg(text3)}`,
120352
+ `--text ${shellArg(text4)}`,
120225
120353
  `--url ${shellArg(url)}`
120226
120354
  ];
120227
120355
  const line2 = pickString(props["Line2"], props["Description1"]);
@@ -120235,9 +120363,9 @@ function buildExtensionRemediateCommandLine(opts) {
120235
120363
  return parts.join(" ");
120236
120364
  }
120237
120365
  if (type === "CALLOUT") {
120238
- const text3 = pickString(props["Text"], props["CalloutText"]);
120239
- if (!text3) return null;
120240
- const parts = [...base2, "callout", `-a ${accountId}`, `--text ${shellArg(text3)}`, levelFlag];
120366
+ const text4 = pickString(props["Text"], props["CalloutText"]);
120367
+ if (!text4) return null;
120368
+ const parts = [...base2, "callout", `-a ${accountId}`, `--text ${shellArg(text4)}`, levelFlag];
120241
120369
  if (campaignFlag) parts.push(campaignFlag);
120242
120370
  parts.push(`--json-out ${jsonOut}`);
120243
120371
  parts.push(`--commit ${shellArg("batch-diff remediate extension")}`);
@@ -120326,7 +120454,7 @@ function buildBatchOperationSlots(cfg) {
120326
120454
  const campaign = asRecord3(cfg.campaign) ?? {};
120327
120455
  const names = Array.isArray(cfg.locations) ? cfg.locations : [];
120328
120456
  const slots = [];
120329
- const push = (kind, path56, label2) => slots.push({ index: slots.length, kind, path: path56, label: label2 });
120457
+ const push = (kind, path57, label2) => slots.push({ index: slots.length, kind, path: path57, label: label2 });
120330
120458
  push("campaign_budget", "campaign.Budget", "\u7CFB\u5217\u9884\u7B97");
120331
120459
  push("campaign", "campaign.Name", `\u7CFB\u5217\u300C${pickText(campaign, "Name", "name") || "\u2014"}\u300D`);
120332
120460
  pickArray(campaign, "targetedLocations", "TargetedLocations").forEach((loc, i) => {
@@ -120397,11 +120525,11 @@ function buildBatchOperationSlots(cfg) {
120397
120525
  return;
120398
120526
  }
120399
120527
  pickArray(block, "Items", "items").forEach((it, ii) => {
120400
- const text3 = pickText(asRecord3(it), "Text", "text");
120528
+ const text4 = pickText(asRecord3(it), "Text", "text");
120401
120529
  push(
120402
120530
  "ad_group_criterion",
120403
120531
  `${groupPath}.KeywordsForBatchJob[${bi}].Items[${ii}]`,
120404
- `\u5173\u952E\u8BCD\u300C${text3}\u300D\uFF08\u7EC4\u300C${groupName}\u300D\uFF09`
120532
+ `\u5173\u952E\u8BCD\u300C${text4}\u300D\uFF08\u7EC4\u300C${groupName}\u300D\uFF09`
120405
120533
  );
120406
120534
  });
120407
120535
  });
@@ -120434,9 +120562,9 @@ function buildSubmittedOperationSlots(cfg) {
120434
120562
  return buildBatchOperationSlots(clone);
120435
120563
  }
120436
120564
  var OP_RE = /mutate_operations\[(\d+)\]\.([a-z_]+?)_operation\.([a-z_.]+)/;
120437
- function parseBatchOperationErrors(text3) {
120565
+ function parseBatchOperationErrors(text4) {
120438
120566
  const out = [];
120439
- for (const seg of text3.split(/Processing error:\s*/).slice(1)) {
120567
+ for (const seg of text4.split(/Processing error:\s*/).slice(1)) {
120440
120568
  const m = OP_RE.exec(seg);
120441
120569
  if (!m) continue;
120442
120570
  const head = seg.slice(0, m.index);
@@ -120593,8 +120721,8 @@ function pickLiveAdForPlannedRsa(plannedHeadlines, primary, unmatchedLiveAds) {
120593
120721
  const [picked] = unmatchedLiveAds.splice(bestIdx, 1);
120594
120722
  return picked ?? null;
120595
120723
  }
120596
- function livePoolHasText(pool, text3) {
120597
- const t = text3.trim().toLowerCase();
120724
+ function livePoolHasText(pool, text4) {
120725
+ const t = text4.trim().toLowerCase();
120598
120726
  return t.length > 0 && pool.has(t);
120599
120727
  }
120600
120728
  function listPlannedRsaAssets(ad, groupPath, adIndex, adGroupName) {
@@ -120809,13 +120937,13 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
120809
120937
  for (let ki = 0; ki < texts.length; ki++) {
120810
120938
  const t = texts[ki];
120811
120939
  if (typeof t !== "string" || !t.trim()) continue;
120812
- const path56 = `${groupPath}.KeywordsForBatchJob[${bi}].KeywordText[${ki}]`;
120940
+ const path57 = `${groupPath}.KeywordsForBatchJob[${bi}].KeywordText[${ki}]`;
120813
120941
  const key = keywordKey(t, matchTypeV2);
120814
120942
  const plannedContent = `\u8BCD\u9762: ${t} | \u5339\u914D: ${matchTypeV2}`;
120815
120943
  if (groupAbsent) {
120816
120944
  pushItem(items3, {
120817
120945
  layer: "keyword",
120818
- path: path56,
120946
+ path: path57,
120819
120947
  adGroupName: groupName,
120820
120948
  plannedContent,
120821
120949
  status: "skipped",
@@ -120827,7 +120955,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
120827
120955
  if (!liveKwKeys.has(key)) {
120828
120956
  pushItem(items3, {
120829
120957
  layer: "keyword",
120830
- path: path56,
120958
+ path: path57,
120831
120959
  adGroupName: groupName,
120832
120960
  plannedContent,
120833
120961
  status: "missing",
@@ -120837,7 +120965,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
120837
120965
  } else {
120838
120966
  pushItem(items3, {
120839
120967
  layer: "keyword",
120840
- path: path56,
120968
+ path: path57,
120841
120969
  adGroupName: groupName,
120842
120970
  plannedContent,
120843
120971
  status: "ok",
@@ -120857,7 +120985,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
120857
120985
  for (let ai = 0; ai < ads.length; ai++) {
120858
120986
  const ad = asRecord4(ads[ai]);
120859
120987
  if (!ad) continue;
120860
- const path56 = `${groupPath}.AdsForBatchJob[${ai}]`;
120988
+ const path57 = `${groupPath}.AdsForBatchJob[${ai}]`;
120861
120989
  const primary = pickString2(ad["headlinePart1"], ad["AdTitle"]);
120862
120990
  const finalUrl = pickString2(ad["Finalurl"], ad["DestinationUrl"], ad["finalUrl"]);
120863
120991
  const rsaAssets = listPlannedRsaAssets(ad, groupPath, ai, groupName);
@@ -120866,7 +120994,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
120866
120994
  if (groupAbsent) {
120867
120995
  pushItem(items3, {
120868
120996
  layer: "ad",
120869
- path: path56,
120997
+ path: path57,
120870
120998
  adGroupName: groupName,
120871
120999
  adLabel,
120872
121000
  plannedContent: primary ? `RSA \u9996\u6807\u9898: ${primary}${finalUrl ? ` | \u843D\u5730\u9875: ${finalUrl}` : ""}` : `AdsForBatchJob[${ai}]\uFF08\u7F3A\u5C11 headlinePart1\uFF09`,
@@ -120895,7 +121023,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
120895
121023
  if (!primary) {
120896
121024
  pushItem(items3, {
120897
121025
  layer: "ad",
120898
- path: path56,
121026
+ path: path57,
120899
121027
  adGroupName: groupName,
120900
121028
  adLabel,
120901
121029
  plannedContent: `AdsForBatchJob[${ai}]\uFF08\u7F3A\u5C11 headlinePart1\uFF0C\u65E0\u6CD5\u6BD4\u5BF9\u6574\u6761 RSA\uFF09`,
@@ -120923,7 +121051,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
120923
121051
  const rsaFound = matchedLive != null && liveAdHasHeadline(matchedLive, primary);
120924
121052
  pushItem(items3, {
120925
121053
  layer: "ad",
120926
- path: path56,
121054
+ path: path57,
120927
121055
  adGroupName: groupName,
120928
121056
  adLabel,
120929
121057
  plannedContent: `RSA \u9996\u6807\u9898: ${primary}${finalUrl ? ` | \u843D\u5730\u9875: ${finalUrl}` : ""}`,
@@ -120991,11 +121119,11 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
120991
121119
  for (let ei = 0; ei < extBlocks.length; ei++) {
120992
121120
  const ext = asRecord4(extBlocks[ei]);
120993
121121
  const plannedContent = formatExtensionPlanned(ext);
120994
- const path56 = `campaign.ExtensionsForBatchJob[${ei}]`;
121122
+ const path57 = `campaign.ExtensionsForBatchJob[${ei}]`;
120995
121123
  if (campaignMissing) {
120996
121124
  pushItem(items3, {
120997
121125
  layer: "extension",
120998
- path: path56,
121126
+ path: path57,
120999
121127
  plannedContent,
121000
121128
  status: "skipped",
121001
121129
  liveNote: "\u7CFB\u5217\u672A\u627E\u5230\uFF0C\u8DF3\u8FC7\u9644\u52A0\u4FE1\u606F\u6BD4\u5BF9",
@@ -121007,7 +121135,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
121007
121135
  const remediateCommand = !found && ext && accountId && campaignId ? buildExtensionRemediateCommandLine({ accountId, campaignId, ext }) ?? void 0 : void 0;
121008
121136
  pushItem(items3, {
121009
121137
  layer: "extension",
121010
- path: path56,
121138
+ path: path57,
121011
121139
  plannedContent,
121012
121140
  status: found ? "ok" : "missing",
121013
121141
  liveNote: `\u7CFB\u5217\u7EA7\u9644\u52A0\u4FE1\u606F\u8D26\u6237\u5185 ${liveExt}/${plannedExt} \u6761`,
@@ -121034,11 +121162,11 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
121034
121162
  if (!id) continue;
121035
121163
  const displayName = locationNames[li] || pickString2(loc["locationName"], loc["name"], loc["countryOrRegion"]) || "";
121036
121164
  const plannedContent = `locationId: ${id}${displayName ? ` | \u540D\u79F0: ${displayName}` : ""}`;
121037
- const path56 = `campaign.targetedLocations[${li}]`;
121165
+ const path57 = `campaign.targetedLocations[${li}]`;
121038
121166
  if (campaignMissing) {
121039
121167
  pushItem(items3, {
121040
121168
  layer: "location",
121041
- path: path56,
121169
+ path: path57,
121042
121170
  plannedContent,
121043
121171
  status: "skipped",
121044
121172
  liveNote: "\u7CFB\u5217\u672A\u627E\u5230\uFF0C\u8DF3\u8FC7\u5730\u57DF\u6BD4\u5BF9",
@@ -121050,7 +121178,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
121050
121178
  const remediateCommand = !found && accountId && campaignId ? buildGeoRemediateCommandLine({ accountId, campaignId, locationId: id }) : void 0;
121051
121179
  pushItem(items3, {
121052
121180
  layer: "location",
121053
- path: path56,
121181
+ path: path57,
121054
121182
  plannedContent,
121055
121183
  status: found ? "ok" : "missing",
121056
121184
  liveNote: `\u7CFB\u5217\u5DF2\u5B9A\u5411 ${liveLocIds.size}/${plannedLocCount} \u4E2A\u5730\u57DF`,
@@ -121070,12 +121198,12 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
121070
121198
  const loc = asRecord4(plannedExcl[li]);
121071
121199
  const id = loc ? pickString2(loc["id"], loc["Id"]) : "";
121072
121200
  if (!id) continue;
121073
- const path56 = `campaign.excludedLocations[${li}]`;
121201
+ const path57 = `campaign.excludedLocations[${li}]`;
121074
121202
  const plannedContent = `\u6392\u9664 locationId: ${id}`;
121075
121203
  if (campaignMissing) {
121076
121204
  pushItem(items3, {
121077
121205
  layer: "excluded_location",
121078
- path: path56,
121206
+ path: path57,
121079
121207
  plannedContent,
121080
121208
  status: "skipped",
121081
121209
  liveNote: "\u7CFB\u5217\u672A\u627E\u5230\uFF0C\u8DF3\u8FC7\u6392\u9664\u5730\u57DF\u6BD4\u5BF9",
@@ -121086,7 +121214,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
121086
121214
  const found = liveExclIds.has(id);
121087
121215
  pushItem(items3, {
121088
121216
  layer: "excluded_location",
121089
- path: path56,
121217
+ path: path57,
121090
121218
  plannedContent,
121091
121219
  status: found ? "ok" : "missing",
121092
121220
  liveNote: `\u7CFB\u5217\u5DF2\u6392\u9664 ${liveExclIds.size}/${plannedExclCount} \u4E2A\u5730\u57DF`,
@@ -121493,8 +121621,8 @@ function printPlanItemsByAdGroup(configFile, layer, layerItems) {
121493
121621
  }
121494
121622
  }
121495
121623
  }
121496
- function mdCell(text3) {
121497
- return text3.replace(/\r?\n/g, " ").replace(/\|/g, "\uFF5C").trim();
121624
+ function mdCell(text4) {
121625
+ return text4.replace(/\r?\n/g, " ").replace(/\|/g, "\uFF5C").trim();
121498
121626
  }
121499
121627
  function statusLabel(status, lang = "zh") {
121500
121628
  if (lang === "en") {
@@ -122342,8 +122470,8 @@ function normalizeBidding(raw) {
122342
122470
  return byNum[n] ?? null;
122343
122471
  }
122344
122472
  function validateTextLengths(errors, lengthViolations, texts, arrayField, kind, limit, label2) {
122345
- texts.forEach((text3, i) => {
122346
- const len = calcGoogleCharLength(text3);
122473
+ texts.forEach((text4, i) => {
122474
+ const len = calcGoogleCharLength(text4);
122347
122475
  if (len > limit) {
122348
122476
  const field = `${arrayField}[${i}]`;
122349
122477
  pushLengthViolation(lengthViolations, {
@@ -122353,9 +122481,9 @@ function validateTextLengths(errors, lengthViolations, texts, arrayField, kind,
122353
122481
  limit,
122354
122482
  actual: len,
122355
122483
  countMode: "google",
122356
- text: text3
122484
+ text: text4
122357
122485
  });
122358
- pushErr3(errors, `${label2}[${i}] \u8D85\u8FC7 ${limit} \u5B57\u7B26\uFF08\u5F53\u524D ${len}\uFF0CCJK \u8BA1 2\uFF09\uFF1A"${text3}"`);
122486
+ pushErr3(errors, `${label2}[${i}] \u8D85\u8FC7 ${limit} \u5B57\u7B26\uFF08\u5F53\u524D ${len}\uFF0CCJK \u8BA1 2\uFF09\uFF1A"${text4}"`);
122359
122487
  }
122360
122488
  });
122361
122489
  }
@@ -122766,8 +122894,8 @@ function pmaxChannelTypesUrl(googleApiUrl) {
122766
122894
  }
122767
122895
  function pmaxCampaignUrl(googleApiUrl, accountId, campaignId) {
122768
122896
  const base2 = googleApiUrl.replace(/\/$/, "");
122769
- const path56 = `${base2}/accounts/${accountId}/campaign/pmax`;
122770
- return campaignId ? `${path56}/${campaignId}` : path56;
122897
+ const path57 = `${base2}/accounts/${accountId}/campaign/pmax`;
122898
+ return campaignId ? `${path57}/${campaignId}` : path57;
122771
122899
  }
122772
122900
  function pmaxBrandAssetsUrl(googleApiUrl, accountId, campaignId) {
122773
122901
  return `${pmaxCampaignUrl(googleApiUrl, accountId, campaignId)}/brand-assets`;
@@ -122777,8 +122905,8 @@ function pmaxBrandGuidelinesEnableUrl(googleApiUrl, accountId, campaignId) {
122777
122905
  }
122778
122906
  function pmaxAssetGroupUrl(googleApiUrl, accountId, assetGroupId, suffix) {
122779
122907
  const base2 = googleApiUrl.replace(/\/$/, "");
122780
- const path56 = `${base2}/accounts/${accountId}/campaign/pmax/asset-group/${assetGroupId}`;
122781
- return suffix ? `${path56}/${suffix.replace(/^\//, "")}` : path56;
122908
+ const path57 = `${base2}/accounts/${accountId}/campaign/pmax/asset-group/${assetGroupId}`;
122909
+ return suffix ? `${path57}/${suffix.replace(/^\//, "")}` : path57;
122782
122910
  }
122783
122911
  function pmaxCampaignAssetGroupUrl(googleApiUrl, accountId, campaignId) {
122784
122912
  const base2 = googleApiUrl.replace(/\/$/, "");
@@ -122887,14 +123015,14 @@ async function uploadPmaxImageFileMultipart(config, googleApiUrl, accountId, abs
122887
123015
  if (config.apiKey) headers["x-api-key"] = config.apiKey;
122888
123016
  else headers.Authorization = `Bearer ${config.authToken}`;
122889
123017
  const res = await fetch(url, { method: "POST", headers, body: form });
122890
- const text3 = await res.text();
123018
+ const text4 = await res.text();
122891
123019
  if (!res.ok) {
122892
- const detail = verbose ? `\uFF1A${text3.slice(0, 300)}` : "";
123020
+ const detail = verbose ? `\uFF1A${text4.slice(0, 300)}` : "";
122893
123021
  throw new Error(`\u4E0A\u4F20\u56FE\u7247\u8D44\u4EA7 HTTP ${res.status}${detail}\uFF08${absImagePath}\uFF09`);
122894
123022
  }
122895
123023
  let data;
122896
123024
  try {
122897
- data = JSON.parse(text3);
123025
+ data = JSON.parse(text4);
122898
123026
  } catch {
122899
123027
  throw new Error(`\u4E0A\u4F20\u56FE\u7247\u8D44\u4EA7\u54CD\u5E94\u975E JSON\uFF08${absImagePath}\uFF09`);
122900
123028
  }
@@ -123034,9 +123162,9 @@ init_shared();
123034
123162
  // src/commands/ad/pmax-create-http-error.ts
123035
123163
  function normalizePmaxResumeId(value) {
123036
123164
  if (value == null) return null;
123037
- const text3 = String(value).trim();
123038
- if (!text3 || text3.toLowerCase() === "null") return null;
123039
- return text3;
123165
+ const text4 = String(value).trim();
123166
+ if (!text4 || text4.toLowerCase() === "null") return null;
123167
+ return text4;
123040
123168
  }
123041
123169
  function quoteLongResumeIds(rawBody) {
123042
123170
  return rawBody.replace(
@@ -123045,11 +123173,11 @@ function quoteLongResumeIds(rawBody) {
123045
123173
  );
123046
123174
  }
123047
123175
  function parsePmaxCreateFailureBody(rawBody) {
123048
- const text3 = rawBody.trim();
123049
- if (!text3.startsWith("{")) return null;
123176
+ const text4 = rawBody.trim();
123177
+ if (!text4.startsWith("{")) return null;
123050
123178
  let parsed;
123051
123179
  try {
123052
- parsed = JSON.parse(quoteLongResumeIds(text3));
123180
+ parsed = JSON.parse(quoteLongResumeIds(text4));
123053
123181
  } catch {
123054
123182
  return null;
123055
123183
  }
@@ -123169,19 +123297,19 @@ function validatePmaxSitelinkSpec(link, prefix, errors, warnings) {
123169
123297
  errors.push(`${prefix} \u4E0D\u80FD\u4E3A\u7A7A`);
123170
123298
  return;
123171
123299
  }
123172
- const text3 = link.text?.trim();
123300
+ const text4 = link.text?.trim();
123173
123301
  const url = link.destinationUrl?.trim();
123174
- if (!text3) errors.push(`${prefix}.text \u4E0D\u80FD\u4E3A\u7A7A`);
123302
+ if (!text4) errors.push(`${prefix}.text \u4E0D\u80FD\u4E3A\u7A7A`);
123175
123303
  if (!url) {
123176
123304
  errors.push(`${prefix}.destinationUrl \u4E0D\u80FD\u4E3A\u7A7A`);
123177
123305
  } else if (!/^https?:\/\/.+/i.test(url)) {
123178
123306
  errors.push(`${prefix}.destinationUrl \u683C\u5F0F\u4E0D\u6B63\u786E\uFF1A${url}`);
123179
123307
  }
123180
- if (text3 && url) {
123308
+ if (text4 && url) {
123181
123309
  validateSitelinkProperties(
123182
123310
  prefix,
123183
123311
  {
123184
- Text: text3,
123312
+ Text: text4,
123185
123313
  DestinationUrl: url,
123186
123314
  Line2: link.line2?.trim() ?? "",
123187
123315
  Line3: link.line3?.trim() ?? ""
@@ -123232,16 +123360,16 @@ function convertExtensionsForBatchJobToCampaignExtensions(items3) {
123232
123360
  const type = String(ext.typeV2 ?? ext.TypeV2 ?? ext.AssetFieldType ?? "").toUpperCase();
123233
123361
  const props = ext.Properties ?? {};
123234
123362
  if (type === "CALLOUT") {
123235
- const text3 = String(props.Text ?? props.CalloutText ?? "").trim();
123236
- if (text3) config.callouts.push(text3);
123363
+ const text4 = String(props.Text ?? props.CalloutText ?? "").trim();
123364
+ if (text4) config.callouts.push(text4);
123237
123365
  continue;
123238
123366
  }
123239
123367
  if (type === "SITELINK") {
123240
- const text3 = String(props.Text ?? props.LinkText ?? "").trim();
123368
+ const text4 = String(props.Text ?? props.LinkText ?? "").trim();
123241
123369
  const destinationUrl = String(props.DestinationUrl ?? "").trim();
123242
- if (text3 && destinationUrl) {
123370
+ if (text4 && destinationUrl) {
123243
123371
  config.sitelinks.push({
123244
- text: text3,
123372
+ text: text4,
123245
123373
  destinationUrl,
123246
123374
  line2: String(props.Line2 ?? props.Description1 ?? "").trim() || void 0,
123247
123375
  line3: String(props.Line3 ?? props.Description2 ?? "").trim() || void 0
@@ -123310,14 +123438,14 @@ function validatePmaxCampaignExtensions(ext, opts) {
123310
123438
  }
123311
123439
  const callouts = ext.callouts ?? [];
123312
123440
  for (let i = 0; i < callouts.length; i++) {
123313
- const text3 = callouts[i]?.trim();
123314
- if (!text3) {
123441
+ const text4 = callouts[i]?.trim();
123442
+ if (!text4) {
123315
123443
  errors.push(`campaignExtensions.callouts[${i}] \u4E0D\u80FD\u4E3A\u7A7A`);
123316
123444
  continue;
123317
123445
  }
123318
- if (text3.length > CALLOUT_TEXT_MAX_LEN) {
123446
+ if (text4.length > CALLOUT_TEXT_MAX_LEN) {
123319
123447
  errors.push(
123320
- `campaignExtensions.callouts[${i}] \u8D85\u8FC7 ${CALLOUT_TEXT_MAX_LEN} \u5B57\u7B26\uFF08\u5F53\u524D ${text3.length}\uFF09\uFF1A"${text3}"`
123448
+ `campaignExtensions.callouts[${i}] \u8D85\u8FC7 ${CALLOUT_TEXT_MAX_LEN} \u5B57\u7B26\uFF08\u5F53\u524D ${text4.length}\uFF09\uFF1A"${text4}"`
123321
123449
  );
123322
123450
  }
123323
123451
  }
@@ -123390,14 +123518,14 @@ async function postExtension(config, googleApiUrl, accountId, body, verbose) {
123390
123518
  return { ok: false, error: err instanceof Error ? err.message : String(err) };
123391
123519
  }
123392
123520
  }
123393
- function buildCalloutBody(accountId, campaignId, text3) {
123521
+ function buildCalloutBody(accountId, campaignId, text4) {
123394
123522
  return {
123395
123523
  activeuseridg: accountId,
123396
123524
  campaignId,
123397
123525
  level: "Campaign",
123398
123526
  typeV2: "CALLOUT",
123399
123527
  assetFieldType: "CALLOUT",
123400
- properties: { Text: text3.trim() }
123528
+ properties: { Text: text4.trim() }
123401
123529
  };
123402
123530
  }
123403
123531
  function buildSnippetBody(accountId, campaignId, header, values) {
@@ -123414,8 +123542,8 @@ function buildSnippetBody(accountId, campaignId, header, values) {
123414
123542
  };
123415
123543
  }
123416
123544
  function buildSitelinkBody(accountId, campaignId, link) {
123417
- const text3 = link.text.trim();
123418
- const line2 = link.line2?.trim() || text3;
123545
+ const text4 = link.text.trim();
123546
+ const line2 = link.line2?.trim() || text4;
123419
123547
  const line3 = link.line3?.trim() || line2;
123420
123548
  return {
123421
123549
  activeuseridg: accountId,
@@ -123424,7 +123552,7 @@ function buildSitelinkBody(accountId, campaignId, link) {
123424
123552
  typeV2: "SITELINK",
123425
123553
  assetFieldType: "SITELINK",
123426
123554
  properties: {
123427
- Text: text3,
123555
+ Text: text4,
123428
123556
  Line2: line2,
123429
123557
  Line3: line3,
123430
123558
  DestinationUrl: link.destinationUrl.trim()
@@ -123452,26 +123580,26 @@ async function attachPmaxCampaignExtensions(opts) {
123452
123580
  allOk: true
123453
123581
  };
123454
123582
  for (const raw of ext.callouts ?? []) {
123455
- const text3 = raw?.trim();
123456
- if (!text3) continue;
123583
+ const text4 = raw?.trim();
123584
+ if (!text4) continue;
123457
123585
  if (opts.logProgress) console.log(`
123458
- \u6302\u8F7D\u5BA3\u4F20\u4FE1\u606F\uFF1A${text3}`);
123586
+ \u6302\u8F7D\u5BA3\u4F20\u4FE1\u606F\uFF1A${text4}`);
123459
123587
  const posted = await postExtension(
123460
123588
  opts.config,
123461
123589
  opts.googleApiUrl,
123462
123590
  opts.accountId,
123463
- buildCalloutBody(opts.accountId, opts.campaignId, text3),
123591
+ buildCalloutBody(opts.accountId, opts.campaignId, text4),
123464
123592
  opts.verbose
123465
123593
  );
123466
123594
  if (posted.ok) {
123467
123595
  result.callouts.push({
123468
123596
  ok: true,
123469
123597
  id: String(posted.data["id"] ?? ""),
123470
- label: text3
123598
+ label: text4
123471
123599
  });
123472
123600
  } else {
123473
123601
  result.allOk = false;
123474
- result.callouts.push({ ok: false, error: posted.error, label: text3 });
123602
+ result.callouts.push({ ok: false, error: posted.error, label: text4 });
123475
123603
  }
123476
123604
  }
123477
123605
  for (const s of ext.structuredSnippets ?? []) {
@@ -123500,11 +123628,11 @@ async function attachPmaxCampaignExtensions(opts) {
123500
123628
  }
123501
123629
  }
123502
123630
  for (const link of ext.sitelinks ?? []) {
123503
- const text3 = link?.text?.trim();
123631
+ const text4 = link?.text?.trim();
123504
123632
  const url = link?.destinationUrl?.trim();
123505
- if (!text3 || !url) continue;
123633
+ if (!text4 || !url) continue;
123506
123634
  if (opts.logProgress) console.log(`
123507
- \u6302\u8F7D\u7AD9\u5185\u94FE\u63A5\uFF1A${text3} \u2192 ${url}`);
123635
+ \u6302\u8F7D\u7AD9\u5185\u94FE\u63A5\uFF1A${text4} \u2192 ${url}`);
123508
123636
  const posted = await postExtension(
123509
123637
  opts.config,
123510
123638
  opts.googleApiUrl,
@@ -123516,11 +123644,11 @@ async function attachPmaxCampaignExtensions(opts) {
123516
123644
  result.sitelinks.push({
123517
123645
  ok: true,
123518
123646
  id: String(posted.data["id"] ?? ""),
123519
- label: text3
123647
+ label: text4
123520
123648
  });
123521
123649
  } else {
123522
123650
  result.allOk = false;
123523
- result.sitelinks.push({ ok: false, error: posted.error, label: text3 });
123651
+ result.sitelinks.push({ ok: false, error: posted.error, label: text4 });
123524
123652
  }
123525
123653
  }
123526
123654
  if (ext.leadForm) {
@@ -123996,13 +124124,13 @@ function runPmaxVideoValidation(configFile, cfg) {
123996
124124
  async function fetchVideoUploadStatus(config, googleApiUrl, mediaAccountId, resourceName, verbose) {
123997
124125
  const url = pyapiVideoStatusUrl(googleApiUrl, mediaAccountId, resourceName);
123998
124126
  const res = await fetch(url, { method: "GET", headers: authHeaders(config) });
123999
- const text3 = await res.text();
124127
+ const text4 = await res.text();
124000
124128
  if (!res.ok) {
124001
- const detail = verbose ? `\uFF1A${text3.slice(0, 300)}` : "";
124129
+ const detail = verbose ? `\uFF1A${text4.slice(0, 300)}` : "";
124002
124130
  throw new Error(`\u67E5\u8BE2\u89C6\u9891\u5904\u7406\u72B6\u6001 HTTP ${res.status}${detail}`);
124003
124131
  }
124004
124132
  try {
124005
- return JSON.parse(text3);
124133
+ return JSON.parse(text4);
124006
124134
  } catch {
124007
124135
  throw new Error("\u67E5\u8BE2\u89C6\u9891\u5904\u7406\u72B6\u6001\u54CD\u5E94\u975E JSON");
124008
124136
  }
@@ -124058,14 +124186,14 @@ async function uploadPmaxLocalVideo(opts) {
124058
124186
  );
124059
124187
  const url = pyapiVideoUploadUrl(opts.googleApiUrl);
124060
124188
  const res = await fetch(url, { method: "POST", headers: authHeaders(opts.config), body: form });
124061
- const text3 = await res.text();
124189
+ const text4 = await res.text();
124062
124190
  if (!res.ok) {
124063
- const detail = opts.verbose ? `\uFF1A${text3.slice(0, 400)}` : "";
124191
+ const detail = opts.verbose ? `\uFF1A${text4.slice(0, 400)}` : "";
124064
124192
  throw new Error(`\u4E0A\u4F20\u89C6\u9891 HTTP ${res.status}${detail}\uFF08${opts.absVideoPath}\uFF09`);
124065
124193
  }
124066
124194
  let data;
124067
124195
  try {
124068
- data = JSON.parse(text3);
124196
+ data = JSON.parse(text4);
124069
124197
  } catch {
124070
124198
  throw new Error(`\u4E0A\u4F20\u89C6\u9891\u54CD\u5E94\u975E JSON\uFF08${opts.absVideoPath}\uFF09`);
124071
124199
  }
@@ -125760,8 +125888,8 @@ async function runAdPmaxImageConvert(opts) {
125760
125888
  }
125761
125889
 
125762
125890
  // src/commands/ad/pmax-brand-mgmt.ts
125763
- function loadBrandConfig(path56, accountId, campaignId) {
125764
- const cfg = loadPmaxJsonFile(path56);
125891
+ function loadBrandConfig(path57, accountId, campaignId) {
125892
+ const cfg = loadPmaxJsonFile(path57);
125765
125893
  return {
125766
125894
  ...cfg,
125767
125895
  account: String(cfg["account"] ?? accountId).trim(),
@@ -125944,16 +126072,16 @@ function quoteLongResumeIds2(rawBody) {
125944
126072
  }
125945
126073
  function normalizeResumeId(value) {
125946
126074
  if (value == null) return null;
125947
- const text3 = String(value).trim();
125948
- if (!text3 || text3.toLowerCase() === "null") return null;
125949
- return text3;
126075
+ const text4 = String(value).trim();
126076
+ if (!text4 || text4.toLowerCase() === "null") return null;
126077
+ return text4;
125950
126078
  }
125951
126079
  function parseDemandGenCreateFailure(rawBody) {
125952
- const text3 = rawBody.trim();
125953
- if (!text3.startsWith("{")) return null;
126080
+ const text4 = rawBody.trim();
126081
+ if (!text4.startsWith("{")) return null;
125954
126082
  let parsed;
125955
126083
  try {
125956
- parsed = JSON.parse(quoteLongResumeIds2(text3));
126084
+ parsed = JSON.parse(quoteLongResumeIds2(text4));
125957
126085
  } catch {
125958
126086
  return null;
125959
126087
  }
@@ -126009,10 +126137,10 @@ function decorateDemandGenRead(value) {
126009
126137
  }
126010
126138
  function normalizeCampaignStatus(raw) {
126011
126139
  if (raw == null || String(raw).trim() === "") return null;
126012
- const text3 = String(raw).trim().toLowerCase();
126013
- if (text3 === "enabled" || text3 === "2") return "Enabled";
126014
- if (text3 === "paused" || text3 === "3") return "Paused";
126015
- if (text3 === "removed" || text3 === "4") return "Removed";
126140
+ const text4 = String(raw).trim().toLowerCase();
126141
+ if (text4 === "enabled" || text4 === "2") return "Enabled";
126142
+ if (text4 === "paused" || text4 === "3") return "Paused";
126143
+ if (text4 === "removed" || text4 === "4") return "Removed";
126016
126144
  return null;
126017
126145
  }
126018
126146
  function normalizeAdStatus(raw) {
@@ -126116,12 +126244,12 @@ function demandGenConversionsValidateUrl(googleApiUrl, accountId) {
126116
126244
  return `${demandGenCollectionUrl(googleApiUrl, accountId)}/conversions/validate`;
126117
126245
  }
126118
126246
  function demandGenAdGroupUrl(googleApiUrl, accountId, campaignId, adGroupId, suffix) {
126119
- const path56 = `${demandGenCampaignUrl(googleApiUrl, accountId, campaignId)}/ad-groups/${adGroupId}`;
126120
- return suffix ? `${path56}/${suffix.replace(/^\//, "")}` : path56;
126247
+ const path57 = `${demandGenCampaignUrl(googleApiUrl, accountId, campaignId)}/ad-groups/${adGroupId}`;
126248
+ return suffix ? `${path57}/${suffix.replace(/^\//, "")}` : path57;
126121
126249
  }
126122
126250
  function demandGenAdUrl(googleApiUrl, accountId, campaignId, adGroupId, adId, suffix) {
126123
- const path56 = `${demandGenAdGroupUrl(googleApiUrl, accountId, campaignId, adGroupId)}/ads/${adId}`;
126124
- return suffix ? `${path56}/${suffix.replace(/^\//, "")}` : path56;
126251
+ const path57 = `${demandGenAdGroupUrl(googleApiUrl, accountId, campaignId, adGroupId)}/ads/${adId}`;
126252
+ return suffix ? `${path57}/${suffix.replace(/^\//, "")}` : path57;
126125
126253
  }
126126
126254
  function demandGenChannelReportUrl(googleApiUrl, accountId, campaignId, startDate, endDate) {
126127
126255
  const params = new URLSearchParams({ startDate, endDate });
@@ -126225,7 +126353,7 @@ function explainCreateError(err) {
126225
126353
  if (failure) return demandGenResumeHint(failure);
126226
126354
  return err instanceof Error ? err.message : String(err);
126227
126355
  }
126228
- async function postCreate(opts, path56, commandLabel) {
126356
+ async function postCreate(opts, path57, commandLabel) {
126229
126357
  const accountId = requireAccountId(opts.account);
126230
126358
  const raw = loadBody(opts.configFile);
126231
126359
  await withGoogleApi(opts, async (config, googleApiUrl) => {
@@ -126237,7 +126365,7 @@ async function postCreate(opts, path56, commandLabel) {
126237
126365
  fail(err instanceof Error ? err.message : String(err));
126238
126366
  }
126239
126367
  printIssues(demandGenCreateIssues(body));
126240
- const url = path56 ? `${demandGenCollectionUrl(googleApiUrl, accountId)}/${path56}` : demandGenCollectionUrl(googleApiUrl, accountId);
126368
+ const url = path57 ? `${demandGenCollectionUrl(googleApiUrl, accountId)}/${path57}` : demandGenCollectionUrl(googleApiUrl, accountId);
126241
126369
  let data;
126242
126370
  try {
126243
126371
  data = await pmaxApiFetch(
@@ -126250,7 +126378,7 @@ async function postCreate(opts, path56, commandLabel) {
126250
126378
  fail(explainCreateError(err));
126251
126379
  }
126252
126380
  const payload = decorateDemandGenRead(data);
126253
- if (await emit({ ...opts, account: accountId }, `ad-demand-gen-${path56 || "create"}`, commandLabel, payload, accountId)) {
126381
+ if (await emit({ ...opts, account: accountId }, `ad-demand-gen-${path57 || "create"}`, commandLabel, payload, accountId)) {
126254
126382
  return;
126255
126383
  }
126256
126384
  console.log(`
@@ -128392,15 +128520,15 @@ function formatMetaAdError(err) {
128392
128520
  }
128393
128521
  return appendMetaAdErrorHint(raw);
128394
128522
  }
128395
- function appendMetaAdErrorHint(text3) {
128396
- if (!/advantage_audience|targeting_automation/i.test(text3)) return text3;
128397
- return `${text3}
128523
+ function appendMetaAdErrorHint(text4) {
128524
+ if (!/advantage_audience|targeting_automation/i.test(text4)) return text4;
128525
+ return `${text4}
128398
128526
  \u63D0\u793A\uFF1Acreate / adset-create \u5DF2\u63D0\u4EA4 targeting_automation.advantage_audience\uFF08\u9ED8\u8BA4 1\uFF1B\u6709 flexibleSpec \u65F6\u9ED8\u8BA4 0\uFF09\u3002
128399
128527
  \u4E0D\u8981\u65B0\u5EFA\u7CFB\u5217\u3002\u7528 --json-out \u91CC\u5DF2\u5EFA\u6210\u7684 campaignId \u8DD1 adset-create \u7EED\u8DD1\uFF1B\u7EC6\u5B9A\u5411\u53EF\u663E\u5F0F\u8BBE adset.advantageAudience=0\u3002`;
128400
128528
  }
128401
128529
  function isBidAmountRequired(err) {
128402
- const text3 = formatMetaAdError(err);
128403
- return /BID_AMOUNT_REQUIRED/i.test(text3) || /缺少竞价金额/.test(text3) || /必须提供 bid_amount/.test(text3) || /必须在 bid_amount/.test(text3);
128530
+ const text4 = formatMetaAdError(err);
128531
+ return /BID_AMOUNT_REQUIRED/i.test(text4) || /缺少竞价金额/.test(text4) || /必须提供 bid_amount/.test(text4) || /必须在 bid_amount/.test(text4);
128404
128532
  }
128405
128533
  function failMetaAd(action, err) {
128406
128534
  console.error(`
@@ -128469,9 +128597,9 @@ function metaAdContext(token) {
128469
128597
  const config = loadConfig(token);
128470
128598
  return { config, facebookApiUrl: requireFacebookApi(config) };
128471
128599
  }
128472
- function adsUrl(facebookApiUrl, account, path56) {
128600
+ function adsUrl(facebookApiUrl, account, path57) {
128473
128601
  const base2 = metaAdsBaseUrl(facebookApiUrl, account);
128474
- const p = path56.startsWith("/") ? path56 : `/${path56}`;
128602
+ const p = path57.startsWith("/") ? path57 : `/${path57}`;
128475
128603
  return `${base2}${p}`;
128476
128604
  }
128477
128605
  async function metaAdGet(url, config, verbose, action) {
@@ -129678,9 +129806,9 @@ async function runMetaAdForms(opts) {
129678
129806
  if (opts.after) params.set("after", opts.after);
129679
129807
  if (opts.before) params.set("before", opts.before);
129680
129808
  const qs = params.toString();
129681
- const path56 = `/pages/${encodeURIComponent(opts.pageId)}/forms${qs ? `?${qs}` : ""}`;
129809
+ const path57 = `/pages/${encodeURIComponent(opts.pageId)}/forms${qs ? `?${qs}` : ""}`;
129682
129810
  const raw = await metaAdGet(
129683
- adsUrl(facebookApiUrl, digits, path56),
129811
+ adsUrl(facebookApiUrl, digits, path57),
129684
129812
  config,
129685
129813
  opts.verbose,
129686
129814
  "\u5217\u8868\u5355\u5931\u8D25"
@@ -129799,8 +129927,8 @@ var QUESTION_TYPE_LABEL = {
129799
129927
  JOB_TITLE: "Job Title",
129800
129928
  CUSTOM: "Custom"
129801
129929
  };
129802
- function chrome(text3, lang) {
129803
- return lang === "en" ? applyEnglishPhrases(text3) : text3;
129930
+ function chrome(text4, lang) {
129931
+ return lang === "en" ? applyEnglishPhrases(text4) : text4;
129804
129932
  }
129805
129933
  function text2(value) {
129806
129934
  if (value == null) return PENDING;
@@ -131185,9 +131313,9 @@ async function fetchAccountPositiveKeywordNormSet(config, googleApiUrl, accountI
131185
131313
  if (seenIds.has(id)) continue;
131186
131314
  seenIds.add(id);
131187
131315
  }
131188
- const text3 = extractKeywordTextFromManagementRow(row);
131189
- if (!text3) continue;
131190
- const norm = normalizeKeywordForAccountMatch(text3);
131316
+ const text4 = extractKeywordTextFromManagementRow(row);
131317
+ if (!text4) continue;
131318
+ const norm = normalizeKeywordForAccountMatch(text4);
131191
131319
  if (norm) normSet.add(norm);
131192
131320
  }
131193
131321
  return normSet;
@@ -131781,8 +131909,8 @@ function similarityPercent(score) {
131781
131909
  const s = Math.min(1, Math.max(0, score));
131782
131910
  return `${Math.round(s * 100)}%`;
131783
131911
  }
131784
- function blockquoteMarkdown(text3) {
131785
- return text3.split("\n").map((line) => `> ${line}`).join("\n");
131912
+ function blockquoteMarkdown(text4) {
131913
+ return text4.split("\n").map((line) => `> ${line}`).join("\n");
131786
131914
  }
131787
131915
  function formatTime(iso) {
131788
131916
  if (!iso) return "";
@@ -132450,8 +132578,8 @@ function assertGoogleMediaCustomerId(raw) {
132450
132578
  process.exit(1);
132451
132579
  }
132452
132580
  }
132453
- function parseCustomerAccessPermissionBody(text3) {
132454
- const trimmed = text3.trim();
132581
+ function parseCustomerAccessPermissionBody(text4) {
132582
+ const trimmed = text4.trim();
132455
132583
  if (!trimmed) return null;
132456
132584
  try {
132457
132585
  const parsed = JSON.parse(trimmed);
@@ -132493,8 +132621,8 @@ function interpretCustomerAccessPermission(mediaCustomerId, httpStatus, rawBody)
132493
132621
  };
132494
132622
  }
132495
132623
  if (httpStatus === 403) {
132496
- const text3 = typeof rawBody === "string" ? rawBody : rawBody == null ? "" : String(rawBody);
132497
- if (text3.includes("token\u4E0D\u80FD\u4E3A\u7A7A") || text3.toLowerCase().includes("token") && text3.includes("\u7A7A")) {
132624
+ const text4 = typeof rawBody === "string" ? rawBody : rawBody == null ? "" : String(rawBody);
132625
+ if (text4.includes("token\u4E0D\u80FD\u4E3A\u7A7A") || text4.toLowerCase().includes("token") && text4.includes("\u7A7A")) {
132498
132626
  return {
132499
132627
  ...base2,
132500
132628
  status: "google_not_bound",
@@ -134409,12 +134537,12 @@ async function uploadAttachment(filePath, apiBaseUrl, config, verbose) {
134409
134537
  headers,
134410
134538
  body: form
134411
134539
  });
134412
- const text3 = await res.text();
134540
+ const text4 = await res.text();
134413
134541
  if (!res.ok) {
134414
- const detail = verbose ? `\uFF1A${text3.slice(0, 300)}` : "";
134542
+ const detail = verbose ? `\uFF1A${text4.slice(0, 300)}` : "";
134415
134543
  throw new Error(`\u4E0A\u4F20\u6587\u4EF6 HTTP ${res.status}${detail}`);
134416
134544
  }
134417
- const data = JSON.parse(text3);
134545
+ const data = JSON.parse(text4);
134418
134546
  if (!data.id) {
134419
134547
  throw new Error("\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25\uFF1A\u54CD\u5E94\u4E2D\u672A\u5305\u542B\u6587\u4EF6 ID");
134420
134548
  }
@@ -136160,9 +136288,9 @@ init_cli_json_snapshot();
136160
136288
  import fs15 from "fs";
136161
136289
  import path20 from "path";
136162
136290
  function readJson(filePath) {
136163
- const text3 = fs15.readFileSync(filePath, "utf8");
136291
+ const text4 = fs15.readFileSync(filePath, "utf8");
136164
136292
  try {
136165
- const v = JSON.parse(text3);
136293
+ const v = JSON.parse(text4);
136166
136294
  if (!v || typeof v !== "object" || Array.isArray(v)) {
136167
136295
  throw new Error("\u987B\u4E3A JSON \u5BF9\u8C61");
136168
136296
  }
@@ -136271,9 +136399,9 @@ function websiteDiagnosisRuntimePath() {
136271
136399
  }
136272
136400
  function readJsonFile(filePath) {
136273
136401
  const raw = fsPromises.readFile(filePath, "utf8");
136274
- return raw.then((text3) => {
136402
+ return raw.then((text4) => {
136275
136403
  try {
136276
- return JSON.parse(text3);
136404
+ return JSON.parse(text4);
136277
136405
  } catch {
136278
136406
  throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${filePath}`);
136279
136407
  }
@@ -138655,9 +138783,9 @@ function asRecord12(value) {
138655
138783
  }
138656
138784
  return null;
138657
138785
  }
138658
- function getNestedValue(root, path56) {
138786
+ function getNestedValue(root, path57) {
138659
138787
  let cur = root;
138660
- for (const key of path56) {
138788
+ for (const key of path57) {
138661
138789
  const rec = asRecord12(cur);
138662
138790
  if (!rec) return void 0;
138663
138791
  cur = rec[key];
@@ -139049,7 +139177,7 @@ function collectGoldClaimTexts(data) {
139049
139177
  if (rec) texts.push(String(rec.title ?? ""), String(rec.description ?? ""));
139050
139178
  }
139051
139179
  }
139052
- return texts.filter((text3) => text3.trim().length > 0);
139180
+ return texts.filter((text4) => text4.trim().length > 0);
139053
139181
  }
139054
139182
  function findIdenticalTexts(texts, minCount) {
139055
139183
  const counts = /* @__PURE__ */ new Map();
@@ -139057,8 +139185,8 @@ function findIdenticalTexts(texts, minCount) {
139057
139185
  if (!t) continue;
139058
139186
  counts.set(t, (counts.get(t) ?? 0) + 1);
139059
139187
  }
139060
- for (const [text3, count2] of counts) {
139061
- if (count2 >= minCount) return text3;
139188
+ for (const [text4, count2] of counts) {
139189
+ if (count2 >= minCount) return text4;
139062
139190
  }
139063
139191
  return null;
139064
139192
  }
@@ -139131,20 +139259,20 @@ function asRecord15(value) {
139131
139259
  }
139132
139260
  return null;
139133
139261
  }
139134
- function proseColonIndex(text3) {
139135
- const cn = text3.indexOf("\uFF1A");
139136
- if (cn > 0 && cn < text3.length - 1) return cn;
139137
- for (let i = 1; i < text3.length - 1; i++) {
139138
- if (text3[i] !== ":") continue;
139139
- if (text3[i + 1] === "/") continue;
139140
- const scheme = text3.slice(Math.max(0, i - 5), i);
139262
+ function proseColonIndex(text4) {
139263
+ const cn = text4.indexOf("\uFF1A");
139264
+ if (cn > 0 && cn < text4.length - 1) return cn;
139265
+ for (let i = 1; i < text4.length - 1; i++) {
139266
+ if (text4[i] !== ":") continue;
139267
+ if (text4[i + 1] === "/") continue;
139268
+ const scheme = text4.slice(Math.max(0, i - 5), i);
139141
139269
  if (/https?$/i.test(scheme)) continue;
139142
139270
  return i;
139143
139271
  }
139144
139272
  return -1;
139145
139273
  }
139146
- function splitOverviewProse(text3) {
139147
- const trimmed = text3.trim();
139274
+ function splitOverviewProse(text4) {
139275
+ const trimmed = text4.trim();
139148
139276
  const cut = proseColonIndex(trimmed);
139149
139277
  if (cut > 0) {
139150
139278
  const title = trimmed.slice(0, cut).trim();
@@ -139155,9 +139283,9 @@ function splitOverviewProse(text3) {
139155
139283
  }
139156
139284
  function normalizeOverviewItem(item) {
139157
139285
  if (typeof item === "string" || typeof item === "number") {
139158
- const text3 = String(item).trim();
139159
- if (!text3) return null;
139160
- return splitOverviewProse(text3);
139286
+ const text4 = String(item).trim();
139287
+ if (!text4) return null;
139288
+ return splitOverviewProse(text4);
139161
139289
  }
139162
139290
  const rec = asRecord15(item);
139163
139291
  if (!rec) return null;
@@ -139238,16 +139366,16 @@ function creativeSuggestionFromRow(row) {
139238
139366
  function distinctCopies(rows, key) {
139239
139367
  const counts = /* @__PURE__ */ new Map();
139240
139368
  for (const row of rows) {
139241
- const text3 = String(row[key] ?? "");
139242
- counts.set(text3, (counts.get(text3) ?? 0) + 1);
139369
+ const text4 = String(row[key] ?? "");
139370
+ counts.set(text4, (counts.get(text4) ?? 0) + 1);
139243
139371
  }
139244
139372
  const seen = /* @__PURE__ */ new Map();
139245
139373
  return rows.map((row) => {
139246
- const text3 = String(row[key] ?? "");
139247
- if ((counts.get(text3) ?? 0) < 3) return row;
139248
- const n = (seen.get(text3) ?? 0) + 1;
139249
- seen.set(text3, n);
139250
- return { ...row, [key]: `${text3}\uFF08\u540C\u7ED3\u6784\u7B2C ${n} \u6761\uFF09` };
139374
+ const text4 = String(row[key] ?? "");
139375
+ if ((counts.get(text4) ?? 0) < 3) return row;
139376
+ const n = (seen.get(text4) ?? 0) + 1;
139377
+ seen.set(text4, n);
139378
+ return { ...row, [key]: `${text4}\uFF08\u540C\u7ED3\u6784\u7B2C ${n} \u6761\uFF09` };
139251
139379
  });
139252
139380
  }
139253
139381
  function mapRows(rows, write) {
@@ -140948,14 +141076,14 @@ var FACEBOOK_SECTION_ALIASES = {
140948
141076
  import { Command as Command2 } from "commander";
140949
141077
 
140950
141078
  // src/commands/facebook-analysis/render-report.ts
140951
- import fs35 from "fs";
140952
- import fsPromises3 from "fs/promises";
140953
- import path42 from "path";
140954
- import { fileURLToPath as fileURLToPath10 } from "url";
141079
+ import fs36 from "fs";
141080
+ import fsPromises4 from "fs/promises";
141081
+ import path43 from "path";
141082
+ import { fileURLToPath as fileURLToPath11 } from "url";
140955
141083
 
140956
141084
  // src/commands/facebook-analysis/merge-snapshot.ts
140957
- import * as fs34 from "fs/promises";
140958
- import * as path41 from "path";
141085
+ import * as fs35 from "fs/promises";
141086
+ import * as path42 from "path";
140959
141087
 
140960
141088
  // src/commands/facebook-analysis/report-metrics.ts
140961
141089
  function asRecord25(value) {
@@ -141107,7 +141235,7 @@ function hasResults(row) {
141107
141235
 
141108
141236
  // src/commands/facebook-analysis/merge-snapshot.ts
141109
141237
  async function readManifest3(snapshotDir) {
141110
- const entries = await fs34.readdir(snapshotDir);
141238
+ const entries = await fs35.readdir(snapshotDir);
141111
141239
  const manifestNames = entries.filter(
141112
141240
  (n) => n.startsWith("report-manifest") && n.endsWith(".json")
141113
141241
  );
@@ -141117,7 +141245,7 @@ async function readManifest3(snapshotDir) {
141117
141245
  ];
141118
141246
  for (const name2 of ordered) {
141119
141247
  try {
141120
- const raw = await fs34.readFile(path41.join(snapshotDir, name2), "utf8");
141248
+ const raw = await fs35.readFile(path42.join(snapshotDir, name2), "utf8");
141121
141249
  const parsed = JSON.parse(raw);
141122
141250
  if (parsed?.artifacts?.length) return parsed;
141123
141251
  } catch {
@@ -141127,7 +141255,7 @@ async function readManifest3(snapshotDir) {
141127
141255
  }
141128
141256
  async function loadSectionFile3(snapshotDir, file) {
141129
141257
  try {
141130
- const raw = await fs34.readFile(path41.join(snapshotDir, file), "utf8");
141258
+ const raw = await fs35.readFile(path42.join(snapshotDir, file), "utf8");
141131
141259
  return asRecord25(JSON.parse(raw));
141132
141260
  } catch {
141133
141261
  return null;
@@ -141171,7 +141299,7 @@ function mapAdSetRows(groups) {
141171
141299
  })).sort((a, b) => (b.spend ?? 0) - (a.spend ?? 0));
141172
141300
  }
141173
141301
  async function mergeFacebookSnapshotIntoReport(payload, snapshotDir) {
141174
- const absDir = path41.resolve(snapshotDir);
141302
+ const absDir = path42.resolve(snapshotDir);
141175
141303
  const manifest = await readManifest3(snapshotDir);
141176
141304
  if (!manifest) {
141177
141305
  throw new Error(
@@ -141438,7 +141566,7 @@ function buildMetaPeriodExcelSheets(data) {
141438
141566
  })
141439
141567
  ],
141440
141568
  [],
141441
- ...buildSummaryNarrative(data).map((text3) => [text3])
141569
+ ...buildSummaryNarrative(data).map((text4) => [text4])
141442
141570
  ];
141443
141571
  const dailyRows = [metricHeaders(currency, "\u5355\u65E5")];
141444
141572
  for (const raw of asArray3(tables.daily)) {
@@ -141485,8 +141613,8 @@ function buildMetaPeriodExcelSheets(data) {
141485
141613
  { name: "\u53D7\u4F17", rows: audienceRows }
141486
141614
  ];
141487
141615
  }
141488
- function chrome2(text3, lang) {
141489
- return lang === "en" ? applyEnglishPhrases(text3) : text3;
141616
+ function chrome2(text4, lang) {
141617
+ return lang === "en" ? applyEnglishPhrases(text4) : text4;
141490
141618
  }
141491
141619
  function writeMetaPeriodExcel(outPath, data, lang = "zh") {
141492
141620
  const sheets = buildMetaPeriodExcelSheets(data).map((sheet) => ({
@@ -141792,20 +141920,20 @@ var TEMPLATE_BASENAMES2 = {
141792
141920
  html: "meta-period-report.html"
141793
141921
  };
141794
141922
  var INJECT_MARKER2 = "window.__META_PERIOD_REPORT__ = window.__META_PERIOD_REPORT__ || null;";
141795
- function resolveSkillTemplatePath4(basename13) {
141796
- const dir = path42.dirname(fileURLToPath10(import.meta.url));
141923
+ function resolveSkillTemplatePath5(basename13) {
141924
+ const dir = path43.dirname(fileURLToPath11(import.meta.url));
141797
141925
  const candidates = [
141798
- path42.join(dir, "skill", "report-templates", basename13),
141799
- path42.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
141800
- path42.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
141926
+ path43.join(dir, "skill", "report-templates", basename13),
141927
+ path43.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
141928
+ path43.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
141801
141929
  ];
141802
141930
  for (const p of candidates) {
141803
- if (fs35.existsSync(p)) return p;
141931
+ if (fs36.existsSync(p)) return p;
141804
141932
  }
141805
141933
  return candidates[0];
141806
141934
  }
141807
141935
  function metaPeriodReportTemplatePath() {
141808
- return resolveSkillTemplatePath4(TEMPLATE_BASENAMES2.html);
141936
+ return resolveSkillTemplatePath5(TEMPLATE_BASENAMES2.html);
141809
141937
  }
141810
141938
  function parseRenderFormats(raw) {
141811
141939
  const tokens = (raw ?? "html").split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
@@ -141822,10 +141950,10 @@ function parseRenderFormats(raw) {
141822
141950
  }
141823
141951
  return [...new Set(out)];
141824
141952
  }
141825
- async function readJsonFile4(filePath) {
141826
- const text3 = await fsPromises3.readFile(filePath, "utf8");
141953
+ async function readJsonFile5(filePath) {
141954
+ const text4 = await fsPromises4.readFile(filePath, "utf8");
141827
141955
  try {
141828
- return JSON.parse(text3);
141956
+ return JSON.parse(text4);
141829
141957
  } catch {
141830
141958
  throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${filePath}`);
141831
141959
  }
@@ -141846,7 +141974,7 @@ function injectReportData3(html, payload, lang) {
141846
141974
  }
141847
141975
  function defaultOutPath(dataPath, format, out) {
141848
141976
  if (out?.trim()) {
141849
- const resolved = path42.resolve(out);
141977
+ const resolved = path43.resolve(out);
141850
141978
  if (format === "xlsx" && !/\.xlsx$/i.test(resolved)) {
141851
141979
  return resolved.replace(/\.(html?)$/i, ".xlsx");
141852
141980
  }
@@ -141855,14 +141983,14 @@ function defaultOutPath(dataPath, format, out) {
141855
141983
  }
141856
141984
  return resolved;
141857
141985
  }
141858
- const dir = path42.dirname(dataPath);
141859
- return path42.join(dir, format === "xlsx" ? "meta-period-report.xlsx" : "meta-period-report.html");
141986
+ const dir = path43.dirname(dataPath);
141987
+ return path43.join(dir, format === "xlsx" ? "meta-period-report.xlsx" : "meta-period-report.html");
141860
141988
  }
141861
141989
  async function runFacebookAnalysisRender(opts) {
141862
- const dataPath = path42.resolve(opts.dataFile);
141863
- let data = asRecord28(await readJsonFile4(dataPath));
141990
+ const dataPath = path43.resolve(opts.dataFile);
141991
+ let data = asRecord28(await readJsonFile5(dataPath));
141864
141992
  if (opts.snapshotDir?.trim()) {
141865
- data = await mergeFacebookSnapshotIntoReport(data, path42.resolve(opts.snapshotDir));
141993
+ data = await mergeFacebookSnapshotIntoReport(data, path43.resolve(opts.snapshotDir));
141866
141994
  }
141867
141995
  localizeFacebookReportLabels(data);
141868
141996
  const lang = readReportLangOrExit({ flag: opts.lang, meta: data.meta });
@@ -141882,14 +142010,14 @@ async function runFacebookAnalysisRender(opts) {
141882
142010
  const written = [];
141883
142011
  for (const format of formats) {
141884
142012
  const outPath = defaultOutPath(dataPath, format, opts.out);
141885
- await fsPromises3.mkdir(path42.dirname(outPath), { recursive: true });
142013
+ await fsPromises4.mkdir(path43.dirname(outPath), { recursive: true });
141886
142014
  if (format === "xlsx") {
141887
142015
  writeMetaPeriodExcel(outPath, data, lang);
141888
142016
  } else {
141889
142017
  const templatePath = metaPeriodReportTemplatePath();
141890
142018
  let html;
141891
142019
  try {
141892
- html = await fsPromises3.readFile(templatePath, "utf8");
142020
+ html = await fsPromises4.readFile(templatePath, "utf8");
141893
142021
  } catch {
141894
142022
  console.error(`
141895
142023
  \u274C \u672A\u627E\u5230\u62A5\u544A\u6A21\u677F\uFF1A${templatePath}
@@ -141897,7 +142025,7 @@ async function runFacebookAnalysisRender(opts) {
141897
142025
  `);
141898
142026
  process.exit(1);
141899
142027
  }
141900
- await fsPromises3.writeFile(outPath, injectReportData3(html, data, lang), "utf8");
142028
+ await fsPromises4.writeFile(outPath, injectReportData3(html, data, lang), "utf8");
141901
142029
  }
141902
142030
  written.push(outPath);
141903
142031
  }
@@ -141918,14 +142046,14 @@ async function runFacebookAnalysisRender(opts) {
141918
142046
  }
141919
142047
 
141920
142048
  // src/commands/facebook-analysis/diagnosis-render-report.ts
141921
- import fs37 from "fs";
141922
- import fsPromises4 from "fs/promises";
141923
- import path44 from "path";
141924
- import { fileURLToPath as fileURLToPath11 } from "url";
142049
+ import fs38 from "fs";
142050
+ import fsPromises5 from "fs/promises";
142051
+ import path45 from "path";
142052
+ import { fileURLToPath as fileURLToPath12 } from "url";
141925
142053
 
141926
142054
  // src/commands/facebook-analysis/diagnosis-merge-snapshot.ts
141927
- import * as fs36 from "fs/promises";
141928
- import * as path43 from "path";
142055
+ import * as fs37 from "fs/promises";
142056
+ import * as path44 from "path";
141929
142057
  function asRecord29(value) {
141930
142058
  if (value && typeof value === "object" && !Array.isArray(value)) {
141931
142059
  return value;
@@ -141961,7 +142089,7 @@ async function readManifest4(snapshotDir, accountId) {
141961
142089
  const candidates = [];
141962
142090
  if (accountId) candidates.push(reportManifestFile(accountId));
141963
142091
  try {
141964
- const entries = await fs36.readdir(snapshotDir);
142092
+ const entries = await fs37.readdir(snapshotDir);
141965
142093
  const manifestNames = entries.filter(
141966
142094
  (n) => n.startsWith("report-manifest") && n.endsWith(".json")
141967
142095
  );
@@ -141975,7 +142103,7 @@ async function readManifest4(snapshotDir, accountId) {
141975
142103
  }
141976
142104
  for (const name2 of candidates) {
141977
142105
  try {
141978
- const raw = await fs36.readFile(path43.join(snapshotDir, name2), "utf8");
142106
+ const raw = await fs37.readFile(path44.join(snapshotDir, name2), "utf8");
141979
142107
  const parsed = JSON.parse(raw);
141980
142108
  if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
141981
142109
  } catch {
@@ -141985,14 +142113,14 @@ async function readManifest4(snapshotDir, accountId) {
141985
142113
  }
141986
142114
  async function loadSectionFile4(snapshotDir, file) {
141987
142115
  try {
141988
- const raw = await fs36.readFile(path43.join(snapshotDir, file), "utf8");
142116
+ const raw = await fs37.readFile(path44.join(snapshotDir, file), "utf8");
141989
142117
  return asRecord29(JSON.parse(raw));
141990
142118
  } catch {
141991
142119
  return null;
141992
142120
  }
141993
142121
  }
141994
142122
  async function mergeMetaDiagnosisSnapshotIntoReport(payload, snapshotDir) {
141995
- const absDir = path43.resolve(snapshotDir);
142123
+ const absDir = path44.resolve(snapshotDir);
141996
142124
  const metaAccountId = typeof asRecord29(payload.meta)?.accountId === "string" ? asRecord29(payload.meta)?.accountId : void 0;
141997
142125
  const manifest = await readManifest4(snapshotDir, metaAccountId);
141998
142126
  if (!manifest) {
@@ -142270,27 +142398,27 @@ function formatMetaDiagnosisReportErrors(result) {
142270
142398
  // src/commands/facebook-analysis/diagnosis-render-report.ts
142271
142399
  init_lang();
142272
142400
  init_html();
142273
- var TEMPLATE_BASENAME2 = "meta-account-diagnosis-report.html";
142401
+ var TEMPLATE_BASENAME3 = "meta-account-diagnosis-report.html";
142274
142402
  var INJECT_MARKER3 = "window.__META_DIAGNOSIS_REPORT__ = window.__META_DIAGNOSIS_REPORT__ || null;";
142275
- function resolveSkillTemplatePath5(basename13) {
142276
- const dir = path44.dirname(fileURLToPath11(import.meta.url));
142403
+ function resolveSkillTemplatePath6(basename13) {
142404
+ const dir = path45.dirname(fileURLToPath12(import.meta.url));
142277
142405
  const candidates = [
142278
- path44.join(dir, "skill", "report-templates", basename13),
142279
- path44.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
142280
- path44.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
142406
+ path45.join(dir, "skill", "report-templates", basename13),
142407
+ path45.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
142408
+ path45.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
142281
142409
  ];
142282
142410
  for (const p of candidates) {
142283
- if (fs37.existsSync(p)) return p;
142411
+ if (fs38.existsSync(p)) return p;
142284
142412
  }
142285
142413
  return candidates[0];
142286
142414
  }
142287
142415
  function metaDiagnosisReportTemplatePath() {
142288
- return resolveSkillTemplatePath5(TEMPLATE_BASENAME2);
142416
+ return resolveSkillTemplatePath6(TEMPLATE_BASENAME3);
142289
142417
  }
142290
- async function readJsonFile5(filePath) {
142291
- const text3 = await fsPromises4.readFile(filePath, "utf8");
142418
+ async function readJsonFile6(filePath) {
142419
+ const text4 = await fsPromises5.readFile(filePath, "utf8");
142292
142420
  try {
142293
- return JSON.parse(text3);
142421
+ return JSON.parse(text4);
142294
142422
  } catch {
142295
142423
  throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${filePath}`);
142296
142424
  }
@@ -142310,10 +142438,10 @@ function injectReportData4(html, payload, lang) {
142310
142438
  return localized.replace(INJECT_MARKER3, `window.__META_DIAGNOSIS_REPORT__ = ${json};`);
142311
142439
  }
142312
142440
  async function runFacebookAnalysisDiagnosisRender(opts) {
142313
- const dataPath = path44.resolve(opts.dataFile);
142314
- let data = asRecord31(await readJsonFile5(dataPath));
142441
+ const dataPath = path45.resolve(opts.dataFile);
142442
+ let data = asRecord31(await readJsonFile6(dataPath));
142315
142443
  if (opts.snapshotDir?.trim()) {
142316
- data = await mergeMetaDiagnosisSnapshotIntoReport(data, path44.resolve(opts.snapshotDir));
142444
+ data = await mergeMetaDiagnosisSnapshotIntoReport(data, path45.resolve(opts.snapshotDir));
142317
142445
  }
142318
142446
  const lang = readReportLangOrExit({ flag: opts.lang, meta: data.meta });
142319
142447
  const contentCheck = validateMetaDiagnosisReportContent(data);
@@ -142332,7 +142460,7 @@ async function runFacebookAnalysisDiagnosisRender(opts) {
142332
142460
  const templatePath = metaDiagnosisReportTemplatePath();
142333
142461
  let html;
142334
142462
  try {
142335
- html = await fsPromises4.readFile(templatePath, "utf8");
142463
+ html = await fsPromises5.readFile(templatePath, "utf8");
142336
142464
  } catch {
142337
142465
  console.error(`
142338
142466
  \u274C \u672A\u627E\u5230\u62A5\u544A\u6A21\u677F\uFF1A${templatePath}
@@ -142340,12 +142468,12 @@ async function runFacebookAnalysisDiagnosisRender(opts) {
142340
142468
  `);
142341
142469
  process.exit(1);
142342
142470
  }
142343
- const outPath = path44.resolve(
142344
- opts.out ?? path44.join(path44.dirname(dataPath), "meta-account-diagnosis-report.html")
142471
+ const outPath = path45.resolve(
142472
+ opts.out ?? path45.join(path45.dirname(dataPath), "meta-account-diagnosis-report.html")
142345
142473
  );
142346
- const outDir = path44.dirname(outPath);
142347
- await fsPromises4.mkdir(outDir, { recursive: true });
142348
- await fsPromises4.writeFile(outPath, injectReportData4(html, data, lang), "utf8");
142474
+ const outDir = path45.dirname(outPath);
142475
+ await fsPromises5.mkdir(outDir, { recursive: true });
142476
+ await fsPromises5.writeFile(outPath, injectReportData4(html, data, lang), "utf8");
142349
142477
  const { stats } = contentCheck;
142350
142478
  console.log(`
142351
142479
  \u2705 Meta\uFF08Facebook\uFF09\u8D26\u6237\u8BCA\u65AD HTML \u62A5\u544A\u5DF2\u751F\u6210\uFF1A${outPath}
@@ -142361,7 +142489,7 @@ async function runFacebookAnalysisDiagnosisRender(opts) {
142361
142489
 
142362
142490
  // src/commands/facebook-analysis/run-batch.ts
142363
142491
  init_auth();
142364
- import * as path45 from "path";
142492
+ import * as path46 from "path";
142365
142493
  import { performance as performance5 } from "perf_hooks";
142366
142494
  init_version();
142367
142495
 
@@ -142463,7 +142591,7 @@ async function runAllFacebookSections(opts) {
142463
142591
  const results = await runWithConcurrency3(tasks, concurrency);
142464
142592
  const succeeded = results.filter((r) => r.ok).length;
142465
142593
  const failed = results.length - succeeded;
142466
- const absoluteSnapshotDir = path45.resolve(opts.jsonOut);
142594
+ const absoluteSnapshotDir = path46.resolve(opts.jsonOut);
142467
142595
  const summary = {
142468
142596
  kind: "siluzan-tso-facebook-analysis-snapshot-batch",
142469
142597
  absoluteSnapshotDir,
@@ -142587,9 +142715,9 @@ function parseEffectiveStatusFilter(raw) {
142587
142715
  }
142588
142716
  return canonical.length ? canonical.join(",") : void 0;
142589
142717
  }
142590
- function facebookAdsUrl(facebookApiUrl, digits, path56) {
142718
+ function facebookAdsUrl(facebookApiUrl, digits, path57) {
142591
142719
  const base2 = facebookApiUrl.replace(/\/$/, "");
142592
- const p = path56.startsWith("/") ? path56 : `/${path56}`;
142720
+ const p = path57.startsWith("/") ? path57 : `/${path57}`;
142593
142721
  return `${base2}/api/fb/ads/${digits}${p}`;
142594
142722
  }
142595
142723
  function facebookInsightsUrl(facebookApiUrl, digits, level) {
@@ -142626,7 +142754,7 @@ async function fetchFacebookAccount(config, digits, verbose) {
142626
142754
  verbose
142627
142755
  );
142628
142756
  }
142629
- async function fetchFacebookPagedList(config, digits, path56, opts) {
142757
+ async function fetchFacebookPagedList(config, digits, path57, opts) {
142630
142758
  const base2 = requireFacebookApi(config);
142631
142759
  const items3 = [];
142632
142760
  let after;
@@ -142641,7 +142769,7 @@ async function fetchFacebookPagedList(config, digits, path56, opts) {
142641
142769
  adsetId: opts.adsetId
142642
142770
  });
142643
142771
  const raw = await apiFetch2(
142644
- `${facebookAdsUrl(base2, digits, path56)}?${query}`,
142772
+ `${facebookAdsUrl(base2, digits, path57)}?${query}`,
142645
142773
  config,
142646
142774
  {},
142647
142775
  opts.verbose
@@ -142776,7 +142904,7 @@ async function runFacebookEntityList(opts, kind) {
142776
142904
  }
142777
142905
  const pageSize = resolveFacebookPageSize(opts.pageSize);
142778
142906
  const config = loadConfig(opts.token);
142779
- const path56 = `/${kind}`;
142907
+ const path57 = `/${kind}`;
142780
142908
  const labels = {
142781
142909
  campaigns: {
142782
142910
  section: "facebook-campaign-entities",
@@ -142789,7 +142917,7 @@ async function runFacebookEntityList(opts, kind) {
142789
142917
  const meta = labels[kind];
142790
142918
  let result;
142791
142919
  try {
142792
- result = await fetchFacebookPagedList(config, manifestId, path56, {
142920
+ result = await fetchFacebookPagedList(config, manifestId, path57, {
142793
142921
  pageSize,
142794
142922
  verbose: !!opts.verbose,
142795
142923
  effectiveStatus,
@@ -143537,7 +143665,7 @@ function endpointHintForBingSection(def) {
143537
143665
 
143538
143666
  // src/commands/bing-analysis/run-batch.ts
143539
143667
  init_auth();
143540
- import * as path46 from "path";
143668
+ import * as path47 from "path";
143541
143669
  import { performance as performance6 } from "perf_hooks";
143542
143670
  init_version();
143543
143671
  async function runWithConcurrency4(tasks, concurrency) {
@@ -143612,7 +143740,7 @@ async function runAllBingSections(opts) {
143612
143740
  const results = await runWithConcurrency4(tasks, concurrency);
143613
143741
  const succeeded = results.filter((r) => r.ok).length;
143614
143742
  const failed = results.length - succeeded;
143615
- const absoluteSnapshotDir = path46.resolve(opts.jsonOut);
143743
+ const absoluteSnapshotDir = path47.resolve(opts.jsonOut);
143616
143744
  const summary = {
143617
143745
  kind: "siluzan-tso-bing-analysis-snapshot-batch",
143618
143746
  absoluteSnapshotDir,
@@ -143956,14 +144084,14 @@ Bing \u5B98\u65B9\u6708\u6D88\u8017\uFF08${id}\uFF09
143956
144084
  import { Command as Command3 } from "commander";
143957
144085
 
143958
144086
  // src/commands/bing-analysis/render-report.ts
143959
- import fs39 from "fs";
143960
- import fsPromises5 from "fs/promises";
143961
- import path48 from "path";
143962
- import { fileURLToPath as fileURLToPath12 } from "url";
144087
+ import fs40 from "fs";
144088
+ import fsPromises6 from "fs/promises";
144089
+ import path49 from "path";
144090
+ import { fileURLToPath as fileURLToPath13 } from "url";
143963
144091
 
143964
144092
  // src/commands/bing-analysis/merge-snapshot.ts
143965
- import * as fs38 from "fs/promises";
143966
- import * as path47 from "path";
144093
+ import * as fs39 from "fs/promises";
144094
+ import * as path48 from "path";
143967
144095
  function asRecord33(value) {
143968
144096
  if (value && typeof value === "object" && !Array.isArray(value)) {
143969
144097
  return value;
@@ -143985,7 +144113,7 @@ function asRows2(value) {
143985
144113
  }
143986
144114
  async function loadSectionPayload(snapshotDir, file) {
143987
144115
  try {
143988
- const raw = await fs38.readFile(path47.join(snapshotDir, file), "utf8");
144116
+ const raw = await fs39.readFile(path48.join(snapshotDir, file), "utf8");
143989
144117
  return JSON.parse(raw);
143990
144118
  } catch {
143991
144119
  return null;
@@ -143995,7 +144123,7 @@ async function readManifest5(snapshotDir, accountId) {
143995
144123
  const candidates = [];
143996
144124
  if (accountId) candidates.push(reportManifestFile(accountId));
143997
144125
  try {
143998
- const entries = await fs38.readdir(snapshotDir);
144126
+ const entries = await fs39.readdir(snapshotDir);
143999
144127
  const manifestNames = entries.filter(
144000
144128
  (n) => n.startsWith("report-manifest") && n.endsWith(".json")
144001
144129
  );
@@ -144006,7 +144134,7 @@ async function readManifest5(snapshotDir, accountId) {
144006
144134
  }
144007
144135
  for (const name2 of candidates) {
144008
144136
  try {
144009
- const raw = await fs38.readFile(path47.join(snapshotDir, name2), "utf8");
144137
+ const raw = await fs39.readFile(path48.join(snapshotDir, name2), "utf8");
144010
144138
  const parsed = JSON.parse(raw);
144011
144139
  if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
144012
144140
  } catch {
@@ -144173,7 +144301,7 @@ function mapSearchTermRows(payload) {
144173
144301
  );
144174
144302
  }
144175
144303
  async function mergeBingAnalysisSnapshotIntoReport(payload, snapshotDir) {
144176
- const absDir = path47.resolve(snapshotDir);
144304
+ const absDir = path48.resolve(snapshotDir);
144177
144305
  const metaAccountId = typeof asRecord33(payload.meta)?.accountId === "string" ? asRecord33(payload.meta)?.accountId : void 0;
144178
144306
  const manifest = await readManifest5(snapshotDir, metaAccountId);
144179
144307
  if (!manifest) {
@@ -144408,27 +144536,27 @@ function formatBingPeriodReportErrors(result) {
144408
144536
  init_report_period();
144409
144537
  init_lang();
144410
144538
  init_html();
144411
- var TEMPLATE_BASENAME3 = "bing-period-report.html";
144539
+ var TEMPLATE_BASENAME4 = "bing-period-report.html";
144412
144540
  var INJECT_MARKER4 = "window.__BING_PERIOD_REPORT__ = window.__BING_PERIOD_REPORT__ || null;";
144413
- function resolveSkillTemplatePath6(basename13) {
144414
- const dir = path48.dirname(fileURLToPath12(import.meta.url));
144541
+ function resolveSkillTemplatePath7(basename13) {
144542
+ const dir = path49.dirname(fileURLToPath13(import.meta.url));
144415
144543
  const candidates = [
144416
- path48.join(dir, "skill", "report-templates", basename13),
144417
- path48.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
144418
- path48.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
144544
+ path49.join(dir, "skill", "report-templates", basename13),
144545
+ path49.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
144546
+ path49.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
144419
144547
  ];
144420
144548
  for (const p of candidates) {
144421
- if (fs39.existsSync(p)) return p;
144549
+ if (fs40.existsSync(p)) return p;
144422
144550
  }
144423
144551
  return candidates[0];
144424
144552
  }
144425
144553
  function bingPeriodReportTemplatePath() {
144426
- return resolveSkillTemplatePath6(TEMPLATE_BASENAME3);
144554
+ return resolveSkillTemplatePath7(TEMPLATE_BASENAME4);
144427
144555
  }
144428
- async function readJsonFile6(filePath) {
144429
- const text3 = await fsPromises5.readFile(filePath, "utf8");
144556
+ async function readJsonFile7(filePath) {
144557
+ const text4 = await fsPromises6.readFile(filePath, "utf8");
144430
144558
  try {
144431
- return JSON.parse(text3);
144559
+ return JSON.parse(text4);
144432
144560
  } catch {
144433
144561
  throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${filePath}`);
144434
144562
  }
@@ -144448,10 +144576,10 @@ function injectReportData5(html, payload, lang) {
144448
144576
  return localized.replace(INJECT_MARKER4, `window.__BING_PERIOD_REPORT__ = ${json};`);
144449
144577
  }
144450
144578
  async function runBingAnalysisRender(opts) {
144451
- const dataPath = path48.resolve(opts.dataFile);
144452
- let data = asRecord35(await readJsonFile6(dataPath));
144579
+ const dataPath = path49.resolve(opts.dataFile);
144580
+ let data = asRecord35(await readJsonFile7(dataPath));
144453
144581
  if (opts.snapshotDir?.trim()) {
144454
- data = await mergeBingAnalysisSnapshotIntoReport(data, path48.resolve(opts.snapshotDir));
144582
+ data = await mergeBingAnalysisSnapshotIntoReport(data, path49.resolve(opts.snapshotDir));
144455
144583
  }
144456
144584
  const lang = readReportLangOrExit({ flag: opts.lang, meta: data.meta });
144457
144585
  const contentCheck = validateBingPeriodReportContent(data);
@@ -144470,7 +144598,7 @@ async function runBingAnalysisRender(opts) {
144470
144598
  const templatePath = bingPeriodReportTemplatePath();
144471
144599
  let html;
144472
144600
  try {
144473
- html = await fsPromises5.readFile(templatePath, "utf8");
144601
+ html = await fsPromises6.readFile(templatePath, "utf8");
144474
144602
  } catch {
144475
144603
  console.error(`
144476
144604
  \u274C \u672A\u627E\u5230\u62A5\u544A\u6A21\u677F\uFF1A${templatePath}
@@ -144478,12 +144606,12 @@ async function runBingAnalysisRender(opts) {
144478
144606
  `);
144479
144607
  process.exit(1);
144480
144608
  }
144481
- const outPath = path48.resolve(
144482
- opts.out ?? path48.join(path48.dirname(dataPath), "bing-period-report.html")
144609
+ const outPath = path49.resolve(
144610
+ opts.out ?? path49.join(path49.dirname(dataPath), "bing-period-report.html")
144483
144611
  );
144484
- const outDir = path48.dirname(outPath);
144485
- await fsPromises5.mkdir(outDir, { recursive: true });
144486
- await fsPromises5.writeFile(outPath, injectReportData5(html, data, lang), "utf8");
144612
+ const outDir = path49.dirname(outPath);
144613
+ await fsPromises6.mkdir(outDir, { recursive: true });
144614
+ await fsPromises6.writeFile(outPath, injectReportData5(html, data, lang), "utf8");
144487
144615
  const { stats } = contentCheck;
144488
144616
  const cover = periodWord(attachPeriodChrome(data).periodChrome.unit, "\u8D26\u6237");
144489
144617
  console.log(`
@@ -144819,7 +144947,7 @@ async function fetchTikTokInterestList(config, account, verbose) {
144819
144947
 
144820
144948
  // src/commands/tiktok-analysis/run-batch.ts
144821
144949
  init_auth();
144822
- import * as path49 from "path";
144950
+ import * as path50 from "path";
144823
144951
  import { performance as performance7 } from "perf_hooks";
144824
144952
  init_version();
144825
144953
  async function runWithConcurrency5(tasks, concurrency) {
@@ -144894,7 +145022,7 @@ async function runAllTikTokSections(opts) {
144894
145022
  const results = await runWithConcurrency5(tasks, concurrency);
144895
145023
  const succeeded = results.filter((r) => r.ok).length;
144896
145024
  const failed = results.length - succeeded;
144897
- const absoluteSnapshotDir = path49.resolve(opts.jsonOut);
145025
+ const absoluteSnapshotDir = path50.resolve(opts.jsonOut);
144898
145026
  const summary = {
144899
145027
  kind: "siluzan-tso-tiktok-analysis-snapshot-batch",
144900
145028
  absoluteSnapshotDir,
@@ -144917,14 +145045,14 @@ init_auth();
144917
145045
  import { Command as Command4 } from "commander";
144918
145046
 
144919
145047
  // src/commands/tiktok-analysis/render-report.ts
144920
- import fs41 from "fs";
144921
- import fsPromises6 from "fs/promises";
144922
- import path51 from "path";
144923
- import { fileURLToPath as fileURLToPath13 } from "url";
145048
+ import fs42 from "fs";
145049
+ import fsPromises7 from "fs/promises";
145050
+ import path52 from "path";
145051
+ import { fileURLToPath as fileURLToPath14 } from "url";
144924
145052
 
144925
145053
  // src/commands/tiktok-analysis/merge-snapshot.ts
144926
- import * as fs40 from "fs/promises";
144927
- import * as path50 from "path";
145054
+ import * as fs41 from "fs/promises";
145055
+ import * as path51 from "path";
144928
145056
  function asRecord36(value) {
144929
145057
  if (value && typeof value === "object" && !Array.isArray(value)) {
144930
145058
  return value;
@@ -144940,7 +145068,7 @@ function round28(value) {
144940
145068
  }
144941
145069
  async function loadSectionPayload2(snapshotDir, file) {
144942
145070
  try {
144943
- const raw = await fs40.readFile(path50.join(snapshotDir, file), "utf8");
145071
+ const raw = await fs41.readFile(path51.join(snapshotDir, file), "utf8");
144944
145072
  return JSON.parse(raw);
144945
145073
  } catch {
144946
145074
  return null;
@@ -144950,7 +145078,7 @@ async function readManifest6(snapshotDir, accountId) {
144950
145078
  const candidates = [];
144951
145079
  if (accountId) candidates.push(reportManifestFile(accountId));
144952
145080
  try {
144953
- const entries = await fs40.readdir(snapshotDir);
145081
+ const entries = await fs41.readdir(snapshotDir);
144954
145082
  const manifestNames = entries.filter(
144955
145083
  (n) => n.startsWith("report-manifest") && n.endsWith(".json")
144956
145084
  );
@@ -144961,7 +145089,7 @@ async function readManifest6(snapshotDir, accountId) {
144961
145089
  }
144962
145090
  for (const name2 of candidates) {
144963
145091
  try {
144964
- const raw = await fs40.readFile(path50.join(snapshotDir, name2), "utf8");
145092
+ const raw = await fs41.readFile(path51.join(snapshotDir, name2), "utf8");
144965
145093
  const parsed = JSON.parse(raw);
144966
145094
  if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
144967
145095
  } catch {
@@ -145102,7 +145230,7 @@ function mapAudienceMerged(payload) {
145102
145230
  };
145103
145231
  }
145104
145232
  async function mergeTikTokAnalysisSnapshotIntoReport(payload, snapshotDir) {
145105
- const absDir = path50.resolve(snapshotDir);
145233
+ const absDir = path51.resolve(snapshotDir);
145106
145234
  const metaAccountId = typeof asRecord36(payload.meta)?.accountId === "string" ? asRecord36(payload.meta)?.accountId : void 0;
145107
145235
  const manifest = await readManifest6(snapshotDir, metaAccountId);
145108
145236
  if (!manifest) {
@@ -145312,27 +145440,27 @@ function formatTikTokPeriodReportErrors(result) {
145312
145440
  init_report_period();
145313
145441
  init_lang();
145314
145442
  init_html();
145315
- var TEMPLATE_BASENAME4 = "tiktok-period-report.html";
145443
+ var TEMPLATE_BASENAME5 = "tiktok-period-report.html";
145316
145444
  var INJECT_MARKER5 = "window.__TIKTOK_PERIOD_REPORT__ = window.__TIKTOK_PERIOD_REPORT__ || null;";
145317
- function resolveSkillTemplatePath7(basename13) {
145318
- const dir = path51.dirname(fileURLToPath13(import.meta.url));
145445
+ function resolveSkillTemplatePath8(basename13) {
145446
+ const dir = path52.dirname(fileURLToPath14(import.meta.url));
145319
145447
  const candidates = [
145320
- path51.join(dir, "skill", "report-templates", basename13),
145321
- path51.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
145322
- path51.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
145448
+ path52.join(dir, "skill", "report-templates", basename13),
145449
+ path52.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
145450
+ path52.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
145323
145451
  ];
145324
145452
  for (const p of candidates) {
145325
- if (fs41.existsSync(p)) return p;
145453
+ if (fs42.existsSync(p)) return p;
145326
145454
  }
145327
145455
  return candidates[0];
145328
145456
  }
145329
145457
  function tiktokPeriodReportTemplatePath() {
145330
- return resolveSkillTemplatePath7(TEMPLATE_BASENAME4);
145458
+ return resolveSkillTemplatePath8(TEMPLATE_BASENAME5);
145331
145459
  }
145332
- async function readJsonFile7(filePath) {
145333
- const text3 = await fsPromises6.readFile(filePath, "utf8");
145460
+ async function readJsonFile8(filePath) {
145461
+ const text4 = await fsPromises7.readFile(filePath, "utf8");
145334
145462
  try {
145335
- return JSON.parse(text3);
145463
+ return JSON.parse(text4);
145336
145464
  } catch {
145337
145465
  throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${filePath}`);
145338
145466
  }
@@ -145352,10 +145480,10 @@ function injectReportData6(html, payload, lang) {
145352
145480
  return localized.replace(INJECT_MARKER5, `window.__TIKTOK_PERIOD_REPORT__ = ${json};`);
145353
145481
  }
145354
145482
  async function runTikTokAnalysisRender(opts) {
145355
- const dataPath = path51.resolve(opts.dataFile);
145356
- let data = asRecord38(await readJsonFile7(dataPath));
145483
+ const dataPath = path52.resolve(opts.dataFile);
145484
+ let data = asRecord38(await readJsonFile8(dataPath));
145357
145485
  if (opts.snapshotDir?.trim()) {
145358
- data = await mergeTikTokAnalysisSnapshotIntoReport(data, path51.resolve(opts.snapshotDir));
145486
+ data = await mergeTikTokAnalysisSnapshotIntoReport(data, path52.resolve(opts.snapshotDir));
145359
145487
  }
145360
145488
  const lang = readReportLangOrExit({ flag: opts.lang, meta: data.meta });
145361
145489
  const contentCheck = validateTikTokPeriodReportContent(data);
@@ -145374,7 +145502,7 @@ async function runTikTokAnalysisRender(opts) {
145374
145502
  const templatePath = tiktokPeriodReportTemplatePath();
145375
145503
  let html;
145376
145504
  try {
145377
- html = await fsPromises6.readFile(templatePath, "utf8");
145505
+ html = await fsPromises7.readFile(templatePath, "utf8");
145378
145506
  } catch {
145379
145507
  console.error(`
145380
145508
  \u274C \u672A\u627E\u5230\u62A5\u544A\u6A21\u677F\uFF1A${templatePath}
@@ -145382,12 +145510,12 @@ async function runTikTokAnalysisRender(opts) {
145382
145510
  `);
145383
145511
  process.exit(1);
145384
145512
  }
145385
- const outPath = path51.resolve(
145386
- opts.out ?? path51.join(path51.dirname(dataPath), "tiktok-period-report.html")
145513
+ const outPath = path52.resolve(
145514
+ opts.out ?? path52.join(path52.dirname(dataPath), "tiktok-period-report.html")
145387
145515
  );
145388
- const outDir = path51.dirname(outPath);
145389
- await fsPromises6.mkdir(outDir, { recursive: true });
145390
- await fsPromises6.writeFile(outPath, injectReportData6(html, data, lang), "utf8");
145516
+ const outDir = path52.dirname(outPath);
145517
+ await fsPromises7.mkdir(outDir, { recursive: true });
145518
+ await fsPromises7.writeFile(outPath, injectReportData6(html, data, lang), "utf8");
145391
145519
  const { stats } = contentCheck;
145392
145520
  const cover = periodWord(attachPeriodChrome(data).periodChrome.unit, "\u8D26\u6237");
145393
145521
  console.log(`
@@ -146313,7 +146441,7 @@ var YANDEX_SECTION_ALIASES = {
146313
146441
 
146314
146442
  // src/commands/yandex-analysis/run-batch.ts
146315
146443
  init_auth();
146316
- import * as path53 from "path";
146444
+ import * as path54 from "path";
146317
146445
  import { performance as performance8 } from "perf_hooks";
146318
146446
  init_version();
146319
146447
 
@@ -146453,8 +146581,8 @@ function endpointHintForYandexSection(def) {
146453
146581
  }
146454
146582
 
146455
146583
  // src/commands/yandex-analysis/merge-snapshot.ts
146456
- import * as fs42 from "fs/promises";
146457
- import * as path52 from "path";
146584
+ import * as fs43 from "fs/promises";
146585
+ import * as path53 from "path";
146458
146586
  function asRecord39(value) {
146459
146587
  if (value && typeof value === "object" && !Array.isArray(value)) {
146460
146588
  return value;
@@ -146504,7 +146632,7 @@ function pickMetrics2(row, extras = []) {
146504
146632
  }
146505
146633
  async function loadSectionPayload3(snapshotDir, file) {
146506
146634
  try {
146507
- const raw = await fs42.readFile(path52.join(snapshotDir, file), "utf8");
146635
+ const raw = await fs43.readFile(path53.join(snapshotDir, file), "utf8");
146508
146636
  return JSON.parse(raw);
146509
146637
  } catch {
146510
146638
  return null;
@@ -146514,7 +146642,7 @@ async function readManifest7(snapshotDir, accountId) {
146514
146642
  const candidates = [];
146515
146643
  if (accountId) candidates.push(reportManifestFile(accountId));
146516
146644
  try {
146517
- const entries = await fs42.readdir(snapshotDir);
146645
+ const entries = await fs43.readdir(snapshotDir);
146518
146646
  for (const name2 of entries.filter(
146519
146647
  (n) => n.startsWith("report-manifest") && n.endsWith(".json")
146520
146648
  )) {
@@ -146524,7 +146652,7 @@ async function readManifest7(snapshotDir, accountId) {
146524
146652
  }
146525
146653
  for (const name2 of candidates) {
146526
146654
  try {
146527
- const raw = await fs42.readFile(path52.join(snapshotDir, name2), "utf8");
146655
+ const raw = await fs43.readFile(path53.join(snapshotDir, name2), "utf8");
146528
146656
  const parsed = JSON.parse(raw);
146529
146657
  if (Array.isArray(parsed.artifacts) && parsed.artifacts.length > 0) return parsed;
146530
146658
  } catch {
@@ -146683,7 +146811,7 @@ function mapDeviceRows2(payload) {
146683
146811
  return asItems(payload).map((r) => pickMetrics2(r, ["device", "network"]));
146684
146812
  }
146685
146813
  async function mergeYandexAnalysisSnapshotIntoReport(payload, snapshotDir) {
146686
- const absDir = path52.resolve(snapshotDir);
146814
+ const absDir = path53.resolve(snapshotDir);
146687
146815
  const metaAccountId = typeof asRecord39(payload.meta)?.accountId === "string" ? asRecord39(payload.meta)?.accountId : void 0;
146688
146816
  const manifest = await readManifest7(snapshotDir, metaAccountId);
146689
146817
  if (!manifest) {
@@ -146869,7 +146997,7 @@ async function runAllYandexSections(opts) {
146869
146997
  const results = await runWithConcurrency6(tasks, concurrency);
146870
146998
  const succeeded = results.filter((r) => r.ok).length;
146871
146999
  const failed = results.length - succeeded;
146872
- const absoluteSnapshotDir = path53.resolve(opts.jsonOut);
147000
+ const absoluteSnapshotDir = path54.resolve(opts.jsonOut);
146873
147001
  const summary = {
146874
147002
  kind: "siluzan-tso-yandex-analysis-snapshot-batch",
146875
147003
  absoluteSnapshotDir,
@@ -146887,10 +147015,10 @@ async function runAllYandexSections(opts) {
146887
147015
  }
146888
147016
 
146889
147017
  // src/commands/yandex-analysis/render-report.ts
146890
- import fs43 from "fs";
146891
- import fsPromises7 from "fs/promises";
146892
- import path54 from "path";
146893
- import { fileURLToPath as fileURLToPath14 } from "url";
147018
+ import fs44 from "fs";
147019
+ import fsPromises8 from "fs/promises";
147020
+ import path55 from "path";
147021
+ import { fileURLToPath as fileURLToPath15 } from "url";
146894
147022
 
146895
147023
  // src/commands/yandex-analysis/report-content.ts
146896
147024
  var SECTION_KEYS4 = [
@@ -147093,27 +147221,27 @@ function formatYandexPeriodReportErrors(result) {
147093
147221
  init_report_period();
147094
147222
  init_lang();
147095
147223
  init_html();
147096
- var TEMPLATE_BASENAME5 = "yandex-period-report.html";
147224
+ var TEMPLATE_BASENAME6 = "yandex-period-report.html";
147097
147225
  var INJECT_MARKER6 = "window.__YANDEX_PERIOD_REPORT__ = window.__YANDEX_PERIOD_REPORT__ || null;";
147098
- function resolveSkillTemplatePath8(basename13) {
147099
- const dir = path54.dirname(fileURLToPath14(import.meta.url));
147226
+ function resolveSkillTemplatePath9(basename13) {
147227
+ const dir = path55.dirname(fileURLToPath15(import.meta.url));
147100
147228
  const candidates = [
147101
- path54.join(dir, "skill", "report-templates", basename13),
147102
- path54.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
147103
- path54.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
147229
+ path55.join(dir, "skill", "report-templates", basename13),
147230
+ path55.join(dir, "skill", "siluzan-ads", "report-templates", basename13),
147231
+ path55.join(dir, "..", "..", "assets", "siluzan-ads", "report-templates", basename13)
147104
147232
  ];
147105
147233
  for (const p of candidates) {
147106
- if (fs43.existsSync(p)) return p;
147234
+ if (fs44.existsSync(p)) return p;
147107
147235
  }
147108
147236
  return candidates[0];
147109
147237
  }
147110
147238
  function yandexPeriodReportTemplatePath() {
147111
- return resolveSkillTemplatePath8(TEMPLATE_BASENAME5);
147239
+ return resolveSkillTemplatePath9(TEMPLATE_BASENAME6);
147112
147240
  }
147113
- async function readJsonFile8(filePath) {
147114
- const text3 = await fsPromises7.readFile(filePath, "utf8");
147241
+ async function readJsonFile9(filePath) {
147242
+ const text4 = await fsPromises8.readFile(filePath, "utf8");
147115
147243
  try {
147116
- return JSON.parse(text3);
147244
+ return JSON.parse(text4);
147117
147245
  } catch {
147118
147246
  throw new Error(`\u65E0\u6CD5\u89E3\u6790 JSON\uFF1A${filePath}`);
147119
147247
  }
@@ -147146,10 +147274,10 @@ function injectReportData7(html, payload, lang) {
147146
147274
  return localized.replace(INJECT_MARKER6, `window.__YANDEX_PERIOD_REPORT__ = ${json};`);
147147
147275
  }
147148
147276
  async function runYandexAnalysisRender(opts) {
147149
- const dataPath = path54.resolve(opts.dataFile);
147150
- let data = asRecord41(await readJsonFile8(dataPath));
147277
+ const dataPath = path55.resolve(opts.dataFile);
147278
+ let data = asRecord41(await readJsonFile9(dataPath));
147151
147279
  if (opts.snapshotDir?.trim()) {
147152
- data = await mergeYandexAnalysisSnapshotIntoReport(data, path54.resolve(opts.snapshotDir));
147280
+ data = await mergeYandexAnalysisSnapshotIntoReport(data, path55.resolve(opts.snapshotDir));
147153
147281
  }
147154
147282
  data = refreshWeeklyFromDaily(data);
147155
147283
  const lang = readReportLangOrExit({ flag: opts.lang, meta: data.meta });
@@ -147167,7 +147295,7 @@ async function runYandexAnalysisRender(opts) {
147167
147295
  const templatePath = yandexPeriodReportTemplatePath();
147168
147296
  let html;
147169
147297
  try {
147170
- html = await fsPromises7.readFile(templatePath, "utf8");
147298
+ html = await fsPromises8.readFile(templatePath, "utf8");
147171
147299
  } catch {
147172
147300
  console.error(`
147173
147301
  \u274C \u672A\u627E\u5230\u62A5\u544A\u6A21\u677F\uFF1A${templatePath}
@@ -147175,12 +147303,12 @@ async function runYandexAnalysisRender(opts) {
147175
147303
  `);
147176
147304
  process.exit(1);
147177
147305
  }
147178
- const outPath = path54.resolve(
147179
- opts.out ?? path54.join(path54.dirname(dataPath), "yandex-period-report.html")
147306
+ const outPath = path55.resolve(
147307
+ opts.out ?? path55.join(path55.dirname(dataPath), "yandex-period-report.html")
147180
147308
  );
147181
- const outDir = path54.dirname(outPath);
147182
- await fsPromises7.mkdir(outDir, { recursive: true });
147183
- await fsPromises7.writeFile(outPath, injectReportData7(html, data, lang), "utf8");
147309
+ const outDir = path55.dirname(outPath);
147310
+ await fsPromises8.mkdir(outDir, { recursive: true });
147311
+ await fsPromises8.writeFile(outPath, injectReportData7(html, data, lang), "utf8");
147184
147312
  const { stats } = contentCheck;
147185
147313
  const cover = periodWord(attachPeriodChrome(data).periodChrome.unit, "\u8D26\u6237");
147186
147314
  console.log(`
@@ -147279,13 +147407,13 @@ function optionalId(raw) {
147279
147407
  function insightsLevelToPath(level) {
147280
147408
  return level;
147281
147409
  }
147282
- function assertYandexAnalysisQuery(path56, query) {
147283
- const caps = YANDEX_PATH_CAPS[path56];
147410
+ function assertYandexAnalysisQuery(path57, query) {
147411
+ const caps = YANDEX_PATH_CAPS[path57];
147284
147412
  if (query.timeIncrement != null && !caps.timeIncrement) {
147285
- throw new Error(`--time-increment \u4E0D\u80FD\u7528\u4E8E /${path56}\uFF08\u4EC5 campaigns / adgroups / ads\uFF09\u3002`);
147413
+ throw new Error(`--time-increment \u4E0D\u80FD\u7528\u4E8E /${path57}\uFF08\u4EC5 campaigns / adgroups / ads\uFF09\u3002`);
147286
147414
  }
147287
147415
  if (query.network != null && !caps.network) {
147288
- throw new Error(`--network \u4E0D\u80FD\u7528\u4E8E /${path56}\uFF08\u4EC5 campaigns / geo / devices\uFF09\u3002`);
147416
+ throw new Error(`--network \u4E0D\u80FD\u7528\u4E8E /${path57}\uFF08\u4EC5 campaigns / geo / devices\uFF09\u3002`);
147289
147417
  }
147290
147418
  if (query.status != null && !caps.status) {
147291
147419
  throw new Error(`--status \u4EC5\u7528\u4E8E /ads\uFF08\u62D2\u5BA1/\u5BA1\u6838\u6001\u8D70\u7ED3\u6784\u67E5\u8BE2\uFF0C\u884C\u5185 spend \u4E3A 0\uFF09\u3002`);
@@ -147302,12 +147430,12 @@ function assertYandexAnalysisQuery(path56, query) {
147302
147430
  );
147303
147431
  }
147304
147432
  if (query.limit != null && !caps.limit) {
147305
- throw new Error(`--limit \u4E0D\u80FD\u7528\u4E8E /${path56}\uFF08overview / daily / devices \u65E0\u6B64\u53C2\u6570\uFF09\u3002`);
147433
+ throw new Error(`--limit \u4E0D\u80FD\u7528\u4E8E /${path57}\uFF08overview / daily / devices \u65E0\u6B64\u53C2\u6570\uFF09\u3002`);
147306
147434
  }
147307
147435
  }
147308
- function buildYandexAnalysisSearchParams(path56, query) {
147309
- assertYandexAnalysisQuery(path56, query);
147310
- const caps = YANDEX_PATH_CAPS[path56];
147436
+ function buildYandexAnalysisSearchParams(path57, query) {
147437
+ assertYandexAnalysisQuery(path57, query);
147438
+ const caps = YANDEX_PATH_CAPS[path57];
147311
147439
  const params = new URLSearchParams({
147312
147440
  account: query.account,
147313
147441
  start: query.start,
@@ -147333,10 +147461,10 @@ function buildYandexAnalysisSearchParams(path56, query) {
147333
147461
  }
147334
147462
  return params;
147335
147463
  }
147336
- async function fetchYandexAnalysisPath(config, path56, query, verbose) {
147464
+ async function fetchYandexAnalysisPath(config, path57, query, verbose) {
147337
147465
  const yandexApiUrl = requireYandexApi(config);
147338
- const params = buildYandexAnalysisSearchParams(path56, query);
147339
- const url = analysisUrl(yandexApiUrl, path56, params.toString());
147466
+ const params = buildYandexAnalysisSearchParams(path57, query);
147467
+ const url = analysisUrl(yandexApiUrl, path57, params.toString());
147340
147468
  return apiFetch2(url, config, {}, verbose);
147341
147469
  }
147342
147470
  function unwrapYandexItems(raw) {
@@ -147400,13 +147528,13 @@ ${args.title}
147400
147528
  console.log(` ${args.footnote}
147401
147529
  `);
147402
147530
  }
147403
- async function fetchPath(opts, path56, extra) {
147531
+ async function fetchPath(opts, path57, extra) {
147404
147532
  const accountId = assertYandexAccountId(opts.account);
147405
147533
  const { startDate, endDate } = resolveRange(opts.start, opts.end);
147406
147534
  const config = loadConfig(opts.token);
147407
147535
  const raw = await fetchYandexAnalysisPath(
147408
147536
  config,
147409
- path56,
147537
+ path57,
147410
147538
  {
147411
147539
  account: accountId,
147412
147540
  start: startDate,
@@ -147775,12 +147903,12 @@ function hasDateFromTo(args) {
147775
147903
  }
147776
147904
  var RERUN_HINT = "\u7ACB\u523B\u6539\u8DD1\u63D0\u793A\u4E2D\u7684\u90A3\u6761\uFF0C\u4E0D\u8981\u505C\u5728\u9519\u8BEF\u547D\u4EE4\u3002";
147777
147905
  function fatal(body) {
147778
- const text3 = body.replace(/\s+$/g, "");
147779
- if (text3.includes(RERUN_HINT)) return `
147780
- ${text3}
147906
+ const text4 = body.replace(/\s+$/g, "");
147907
+ if (text4.includes(RERUN_HINT)) return `
147908
+ ${text4}
147781
147909
  `;
147782
147910
  return `
147783
- ${text3}
147911
+ ${text4}
147784
147912
  ${RERUN_HINT}
147785
147913
  `;
147786
147914
  }
@@ -147930,9 +148058,9 @@ function interceptAgentCompatArgv(argv) {
147930
148058
  installProcessHandlers();
147931
148059
  function getVersion() {
147932
148060
  try {
147933
- const __dirname3 = path55.dirname(fileURLToPath15(import.meta.url));
147934
- const pkgPath = path55.join(__dirname3, "..", "package.json");
147935
- const pkg = JSON.parse(fs44.readFileSync(pkgPath, "utf8"));
148061
+ const __dirname3 = path56.dirname(fileURLToPath16(import.meta.url));
148062
+ const pkgPath = path56.join(__dirname3, "..", "package.json");
148063
+ const pkg = JSON.parse(fs45.readFileSync(pkgPath, "utf8"));
147936
148064
  return pkg.version ?? "0.0.0";
147937
148065
  } catch {
147938
148066
  return "0.0.0";