aads-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.ja.md +159 -0
- package/README.md +159 -0
- package/data/campaign-layer-policy.json +68 -0
- package/dist/analysis/anomaly-detection.d.ts +16 -0
- package/dist/analysis/anomaly-detection.d.ts.map +1 -0
- package/dist/analysis/anomaly-detection.js +55 -0
- package/dist/analysis/anomaly-detection.js.map +1 -0
- package/dist/analysis/auto-to-manual.d.ts +11 -0
- package/dist/analysis/auto-to-manual.d.ts.map +1 -0
- package/dist/analysis/auto-to-manual.js +57 -0
- package/dist/analysis/auto-to-manual.js.map +1 -0
- package/dist/analysis/campaign-layer-classifier.d.ts +10 -0
- package/dist/analysis/campaign-layer-classifier.d.ts.map +1 -0
- package/dist/analysis/campaign-layer-classifier.js +50 -0
- package/dist/analysis/campaign-layer-classifier.js.map +1 -0
- package/dist/analysis/campaign-structure.d.ts +3 -0
- package/dist/analysis/campaign-structure.d.ts.map +1 -0
- package/dist/analysis/campaign-structure.js +51 -0
- package/dist/analysis/campaign-structure.js.map +1 -0
- package/dist/analysis/cpc-optimizer.d.ts +11 -0
- package/dist/analysis/cpc-optimizer.d.ts.map +1 -0
- package/dist/analysis/cpc-optimizer.js +46 -0
- package/dist/analysis/cpc-optimizer.js.map +1 -0
- package/dist/analysis/performance-analyzer.d.ts +3 -0
- package/dist/analysis/performance-analyzer.d.ts.map +1 -0
- package/dist/analysis/performance-analyzer.js +58 -0
- package/dist/analysis/performance-analyzer.js.map +1 -0
- package/dist/analysis/sku-classifier.d.ts +3 -0
- package/dist/analysis/sku-classifier.d.ts.map +1 -0
- package/dist/analysis/sku-classifier.js +64 -0
- package/dist/analysis/sku-classifier.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +351 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/campaign-layer-policy.d.ts +28 -0
- package/dist/config/campaign-layer-policy.d.ts.map +1 -0
- package/dist/config/campaign-layer-policy.js +56 -0
- package/dist/config/campaign-layer-policy.js.map +1 -0
- package/dist/config/constants.d.ts +74 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +61 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/optimisation-config.d.ts +24 -0
- package/dist/config/optimisation-config.d.ts.map +1 -0
- package/dist/config/optimisation-config.js +41 -0
- package/dist/config/optimisation-config.js.map +1 -0
- package/dist/core/header-mapper.d.ts +6 -0
- package/dist/core/header-mapper.d.ts.map +1 -0
- package/dist/core/header-mapper.js +34 -0
- package/dist/core/header-mapper.js.map +1 -0
- package/dist/core/normalizer.d.ts +9 -0
- package/dist/core/normalizer.d.ts.map +1 -0
- package/dist/core/normalizer.js +76 -0
- package/dist/core/normalizer.js.map +1 -0
- package/dist/io/csv-reader.d.ts +3 -0
- package/dist/io/csv-reader.d.ts.map +1 -0
- package/dist/io/csv-reader.js +52 -0
- package/dist/io/csv-reader.js.map +1 -0
- package/dist/io/excel-reader.d.ts +4 -0
- package/dist/io/excel-reader.d.ts.map +1 -0
- package/dist/io/excel-reader.js +83 -0
- package/dist/io/excel-reader.js.map +1 -0
- package/dist/io/excel-writer.d.ts +7 -0
- package/dist/io/excel-writer.d.ts.map +1 -0
- package/dist/io/excel-writer.js +42 -0
- package/dist/io/excel-writer.js.map +1 -0
- package/dist/pipeline/analyze-pipeline.d.ts +8 -0
- package/dist/pipeline/analyze-pipeline.d.ts.map +1 -0
- package/dist/pipeline/analyze-pipeline.js +145 -0
- package/dist/pipeline/analyze-pipeline.js.map +1 -0
- package/dist/pipeline/types.d.ts +142 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +2 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/ranking/keyword-matcher.d.ts +10 -0
- package/dist/ranking/keyword-matcher.d.ts.map +1 -0
- package/dist/ranking/keyword-matcher.js +62 -0
- package/dist/ranking/keyword-matcher.js.map +1 -0
- package/dist/ranking/ranking-db.d.ts +14 -0
- package/dist/ranking/ranking-db.d.ts.map +1 -0
- package/dist/ranking/ranking-db.js +97 -0
- package/dist/ranking/ranking-db.js.map +1 -0
- package/dist/ranking/seo-factor.d.ts +5 -0
- package/dist/ranking/seo-factor.d.ts.map +1 -0
- package/dist/ranking/seo-factor.js +57 -0
- package/dist/ranking/seo-factor.js.map +1 -0
- package/dist/ranking/types.d.ts +25 -0
- package/dist/ranking/types.d.ts.map +1 -0
- package/dist/ranking/types.js +2 -0
- package/dist/ranking/types.js.map +1 -0
- package/dist/schemas/types.d.ts +32 -0
- package/dist/schemas/types.d.ts.map +1 -0
- package/dist/schemas/types.js +2 -0
- package/dist/schemas/types.js.map +1 -0
- package/dist/utils/date-utils.d.ts +17 -0
- package/dist/utils/date-utils.d.ts.map +1 -0
- package/dist/utils/date-utils.js +56 -0
- package/dist/utils/date-utils.js.map +1 -0
- package/dist/utils/logger.d.ts +12 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +45 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import ExcelJS from "exceljs";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const wildcardToRegExp = (pattern) => {
|
|
5
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
6
|
+
const regex = escaped.replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
7
|
+
return new RegExp(`^${regex}$`, "i");
|
|
8
|
+
};
|
|
9
|
+
export const resolveInputFiles = (inputPattern) => {
|
|
10
|
+
const normalized = inputPattern.replace(/\\/g, "/");
|
|
11
|
+
const hasWildcard = /[*?]/.test(normalized);
|
|
12
|
+
if (!hasWildcard) {
|
|
13
|
+
return [inputPattern];
|
|
14
|
+
}
|
|
15
|
+
const parsed = path.parse(normalized);
|
|
16
|
+
const dir = parsed.dir || ".";
|
|
17
|
+
const filePattern = parsed.base;
|
|
18
|
+
const regex = wildcardToRegExp(filePattern);
|
|
19
|
+
if (!fs.existsSync(dir)) {
|
|
20
|
+
throw new Error(`Input directory not found: ${dir}`);
|
|
21
|
+
}
|
|
22
|
+
return fs
|
|
23
|
+
.readdirSync(dir)
|
|
24
|
+
.filter((name) => regex.test(name))
|
|
25
|
+
.map((name) => path.join(dir, name))
|
|
26
|
+
.sort((a, b) => a.localeCompare(b));
|
|
27
|
+
};
|
|
28
|
+
const normalizeCell = (value) => {
|
|
29
|
+
if (value === null || value === undefined)
|
|
30
|
+
return "";
|
|
31
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
|
|
32
|
+
return value;
|
|
33
|
+
if (value instanceof Date)
|
|
34
|
+
return value;
|
|
35
|
+
if (typeof value === "object" && "text" in value && typeof value.text === "string")
|
|
36
|
+
return value.text;
|
|
37
|
+
if (typeof value === "object" && "result" in value)
|
|
38
|
+
return value.result ?? "";
|
|
39
|
+
return String(value);
|
|
40
|
+
};
|
|
41
|
+
const readWorksheetAsRows = (worksheet) => {
|
|
42
|
+
const rows = [];
|
|
43
|
+
worksheet.eachRow((row) => {
|
|
44
|
+
const values = row.values;
|
|
45
|
+
rows.push(values.slice(1).map((value) => (value === undefined ? "" : value)));
|
|
46
|
+
});
|
|
47
|
+
if (rows.length === 0) {
|
|
48
|
+
return { headers: [], rows: [] };
|
|
49
|
+
}
|
|
50
|
+
const headers = rows[0].map((h) => String(h ?? "").trim());
|
|
51
|
+
const dataRows = rows.slice(1).map((cells) => {
|
|
52
|
+
const item = {};
|
|
53
|
+
for (let i = 0; i < headers.length; i += 1) {
|
|
54
|
+
item[headers[i]] = normalizeCell(cells[i]);
|
|
55
|
+
}
|
|
56
|
+
return item;
|
|
57
|
+
});
|
|
58
|
+
return { headers, rows: dataRows };
|
|
59
|
+
};
|
|
60
|
+
export const readBulkExcelFiles = async (inputPattern) => {
|
|
61
|
+
const files = resolveInputFiles(inputPattern);
|
|
62
|
+
if (files.length === 0) {
|
|
63
|
+
throw new Error(`No input files matched: ${inputPattern}`);
|
|
64
|
+
}
|
|
65
|
+
const results = [];
|
|
66
|
+
for (const file of files) {
|
|
67
|
+
const workbook = new ExcelJS.Workbook();
|
|
68
|
+
await workbook.xlsx.readFile(file);
|
|
69
|
+
for (const worksheet of workbook.worksheets) {
|
|
70
|
+
const parsed = readWorksheetAsRows(worksheet);
|
|
71
|
+
if (parsed.headers.length === 0 || parsed.rows.length === 0) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
results.push({
|
|
75
|
+
sourceFile: `${file}#${worksheet.name}`,
|
|
76
|
+
headers: parsed.headers,
|
|
77
|
+
rows: parsed.rows,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return results;
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=excel-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"excel-reader.js","sourceRoot":"","sources":["../../src/io/excel-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"excel-writer.d.ts","sourceRoot":"","sources":["../../src/io/excel-writer.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;CAC5C;AAmBD,eAAO,MAAM,SAAS,GAAU,YAAY,MAAM,EAAE,QAAQ,eAAe,EAAE,KAAG,OAAO,CAAC,IAAI,CAwB3F,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import ExcelJS from "exceljs";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const autoFitColumns = (worksheet) => {
|
|
5
|
+
worksheet.columns?.forEach((column) => {
|
|
6
|
+
let maxLength = 10;
|
|
7
|
+
if (!column.eachCell) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
column.eachCell({ includeEmpty: true }, (cell) => {
|
|
11
|
+
const value = cell.value;
|
|
12
|
+
const cellText = value === null || value === undefined ? "" : String(value);
|
|
13
|
+
if (cellText.length > maxLength) {
|
|
14
|
+
maxLength = Math.min(cellText.length + 2, 80);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
column.width = maxLength;
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
export const writeXlsx = async (outputPath, sheets) => {
|
|
21
|
+
if (sheets.length === 0) {
|
|
22
|
+
throw new Error("No sheets to write.");
|
|
23
|
+
}
|
|
24
|
+
const workbook = new ExcelJS.Workbook();
|
|
25
|
+
workbook.creator = "aads";
|
|
26
|
+
workbook.created = new Date();
|
|
27
|
+
for (const sheet of sheets) {
|
|
28
|
+
const ws = workbook.addWorksheet(sheet.name);
|
|
29
|
+
ws.addRow(sheet.header);
|
|
30
|
+
for (const row of sheet.rows) {
|
|
31
|
+
ws.addRow(row);
|
|
32
|
+
}
|
|
33
|
+
const headerRow = ws.getRow(1);
|
|
34
|
+
headerRow.font = { bold: true };
|
|
35
|
+
headerRow.alignment = { vertical: "middle", horizontal: "left" };
|
|
36
|
+
ws.views = [{ state: "frozen", ySplit: 1 }];
|
|
37
|
+
autoFitColumns(ws);
|
|
38
|
+
}
|
|
39
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
40
|
+
await workbook.xlsx.writeFile(outputPath);
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=excel-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"excel-writer.js","sourceRoot":"","sources":["../../src/io/excel-writer.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAQ7B,MAAM,cAAc,GAAG,CAAC,SAA4B,EAAQ,EAAE;IAC5D,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACpC,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;YAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACzB,MAAM,QAAQ,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,IAAI,QAAQ,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;gBAChC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;YAChD,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,UAAkB,EAAE,MAAyB,EAAiB,EAAE;IAC9F,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IACxC,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;IAE9B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACxB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YAC7B,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;QACD,MAAM,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/B,SAAS,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAChC,SAAS,CAAC,SAAS,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QACjE,EAAE,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5C,cAAc,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;IAED,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;AAC5C,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AnalyzePipelineResult } from "./types.js";
|
|
2
|
+
import type { OptimisationConfig } from "../config/optimisation-config.js";
|
|
3
|
+
export interface AnalyzePipelineOptions {
|
|
4
|
+
layerPolicyPath?: string;
|
|
5
|
+
rankingDbPath?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const runAnalyzePipeline: (inputPattern: string, config: OptimisationConfig, options?: AnalyzePipelineOptions) => Promise<AnalyzePipelineResult>;
|
|
8
|
+
//# sourceMappingURL=analyze-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-pipeline.d.ts","sourceRoot":"","sources":["../../src/pipeline/analyze-pipeline.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,qBAAqB,EAA4C,MAAM,YAAY,CAAC;AAClG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAqE3E,MAAM,WAAW,sBAAsB;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,kBAAkB,GAC7B,cAAc,MAAM,EACpB,QAAQ,kBAAkB,EAC1B,UAAU,sBAAsB,KAC/B,OAAO,CAAC,qBAAqB,CAwE/B,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { createHeaderMap } from "../core/header-mapper.js";
|
|
4
|
+
import { asNumber, normalizeMatchType, normalizeState, normalizeText, safeDivide, toNumber, } from "../core/normalizer.js";
|
|
5
|
+
import { readBulkExcelFiles } from "../io/excel-reader.js";
|
|
6
|
+
import { readCsvFiles } from "../io/csv-reader.js";
|
|
7
|
+
import { analyzePerformance } from "../analysis/performance-analyzer.js";
|
|
8
|
+
import { buildCampaignStructure } from "../analysis/campaign-structure.js";
|
|
9
|
+
import { classifySkus } from "../analysis/sku-classifier.js";
|
|
10
|
+
import { generateCpcRecommendations } from "../analysis/cpc-optimizer.js";
|
|
11
|
+
import { analyzeAutoToManual } from "../analysis/auto-to-manual.js";
|
|
12
|
+
import { classifyCampaignLayers } from "../analysis/campaign-layer-classifier.js";
|
|
13
|
+
import { loadCampaignLayerPolicy } from "../config/campaign-layer-policy.js";
|
|
14
|
+
import { extractDateRangeFromFiles } from "../utils/date-utils.js";
|
|
15
|
+
import { RankingDb } from "../ranking/ranking-db.js";
|
|
16
|
+
const readInputs = async (inputPattern) => {
|
|
17
|
+
const ext = path.extname(inputPattern).toLowerCase();
|
|
18
|
+
if (ext === ".csv") {
|
|
19
|
+
return readCsvFiles(inputPattern);
|
|
20
|
+
}
|
|
21
|
+
return readBulkExcelFiles(inputPattern);
|
|
22
|
+
};
|
|
23
|
+
const normalizeRecord = (row, source) => {
|
|
24
|
+
const map = createHeaderMap(source.headers);
|
|
25
|
+
const pick = (index) => (index >= 0 ? row[source.headers[index]] : "");
|
|
26
|
+
const asText = (index) => normalizeText(pick(index));
|
|
27
|
+
const asNum = (index) => asNumber(pick(index), 0);
|
|
28
|
+
const asNumOrEmpty = (index) => toNumber(pick(index));
|
|
29
|
+
const clicks = asNum(map.clicks);
|
|
30
|
+
const impressions = asNum(map.impressions);
|
|
31
|
+
const spend = asNum(map.spend);
|
|
32
|
+
const sales = asNum(map.sales);
|
|
33
|
+
const orders = asNum(map.orders);
|
|
34
|
+
const keywordText = asText(map.keywordText);
|
|
35
|
+
const customerSearchTerm = asText(map.customerSearchTerm);
|
|
36
|
+
// Infer targetingType as "auto" from product targeting expression auto subtypes
|
|
37
|
+
const productTargetingExpr = asText(map.productTargetingExpression);
|
|
38
|
+
const AUTO_SUBTYPES = ["close-match", "loose-match", "substitutes", "complements"];
|
|
39
|
+
let targetingType = asText(map.targetingType);
|
|
40
|
+
if (!targetingType && AUTO_SUBTYPES.includes(productTargetingExpr)) {
|
|
41
|
+
targetingType = "auto";
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
campaignId: asText(map.campaignId),
|
|
45
|
+
campaignName: asText(map.campaignName),
|
|
46
|
+
adGroupId: asText(map.adGroupId),
|
|
47
|
+
adGroupName: asText(map.adGroupName),
|
|
48
|
+
keywordId: asText(map.keywordId),
|
|
49
|
+
keywordText,
|
|
50
|
+
customerSearchTerm,
|
|
51
|
+
productTargetingExpression: productTargetingExpr,
|
|
52
|
+
matchType: normalizeMatchType(asText(map.matchType)),
|
|
53
|
+
targetingType,
|
|
54
|
+
sku: asText(map.sku),
|
|
55
|
+
asin: asText(map.asin),
|
|
56
|
+
portfolioId: asText(map.portfolioId),
|
|
57
|
+
state: normalizeState(asText(map.state)),
|
|
58
|
+
campaignStatus: normalizeState(asText(map.state)),
|
|
59
|
+
dailyBudget: asNumOrEmpty(map.dailyBudget),
|
|
60
|
+
bid: asNumOrEmpty(map.bid),
|
|
61
|
+
adGroupDefaultBid: asNumOrEmpty(map.adGroupDefaultBid),
|
|
62
|
+
clicks,
|
|
63
|
+
impressions,
|
|
64
|
+
spend,
|
|
65
|
+
sales,
|
|
66
|
+
orders,
|
|
67
|
+
ctr: safeDivide(clicks, impressions),
|
|
68
|
+
cvr: safeDivide(orders, clicks),
|
|
69
|
+
acos: safeDivide(spend, sales),
|
|
70
|
+
roas: safeDivide(sales, spend),
|
|
71
|
+
startDate: "",
|
|
72
|
+
endDate: "",
|
|
73
|
+
biddingStrategy: "",
|
|
74
|
+
sourceFile: source.sourceFile,
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
export const runAnalyzePipeline = async (inputPattern, config, options) => {
|
|
78
|
+
const input = await readInputs(inputPattern);
|
|
79
|
+
const dateRange = extractDateRangeFromFiles(input.map((i) => i.sourceFile));
|
|
80
|
+
const records = input
|
|
81
|
+
.flatMap((file) => file.rows.map((row) => normalizeRecord(row, file)))
|
|
82
|
+
.filter((row) => row.campaignId !== "" ||
|
|
83
|
+
row.campaignName !== "" ||
|
|
84
|
+
row.keywordText !== "" ||
|
|
85
|
+
row.customerSearchTerm !== "" ||
|
|
86
|
+
row.productTargetingExpression !== "" ||
|
|
87
|
+
row.clicks > 0 ||
|
|
88
|
+
row.impressions > 0 ||
|
|
89
|
+
row.spend > 0 ||
|
|
90
|
+
row.sales > 0);
|
|
91
|
+
// Build SEO ranking data if ranking DB is available
|
|
92
|
+
let seoRankingData;
|
|
93
|
+
const rankingDbPath = options?.rankingDbPath ?? process.env.RANKING_DB_PATH;
|
|
94
|
+
if (rankingDbPath && config.seo.enabled && existsSync(rankingDbPath)) {
|
|
95
|
+
let rankingDb;
|
|
96
|
+
try {
|
|
97
|
+
rankingDb = new RankingDb(rankingDbPath);
|
|
98
|
+
const adKeywords = [...new Set(records.map((r) => r.keywordText).filter((k) => k !== ""))];
|
|
99
|
+
const asins = [...new Set(records.map((r) => r.asin).filter((a) => a !== ""))];
|
|
100
|
+
seoRankingData = rankingDb.buildSeoRankingData(adKeywords, asins, rankingDbPath);
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
rankingDb?.close();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const campaignMetrics = analyzePerformance(records);
|
|
107
|
+
const structure = buildCampaignStructure(records);
|
|
108
|
+
const skuClassification = classifySkus(records);
|
|
109
|
+
const cpcRecommendations = generateCpcRecommendations(records, skuClassification, {
|
|
110
|
+
minClicks: config.minClicksForCpc,
|
|
111
|
+
targetAcos: config.targetAcos,
|
|
112
|
+
seoRankingData,
|
|
113
|
+
seoConfig: config.seo,
|
|
114
|
+
});
|
|
115
|
+
const { promotionCandidates, negativeCandidates } = analyzeAutoToManual(records, {
|
|
116
|
+
minClicks: config.minClicksForPromotion,
|
|
117
|
+
minCvr: config.minCvrForPromotion,
|
|
118
|
+
negativeAcosThreshold: config.negativeAcosThreshold,
|
|
119
|
+
});
|
|
120
|
+
// Layer classification (optional, skipped if policy not found)
|
|
121
|
+
let layerClassification;
|
|
122
|
+
try {
|
|
123
|
+
const policy = await loadCampaignLayerPolicy(options?.layerPolicyPath);
|
|
124
|
+
if (policy) {
|
|
125
|
+
layerClassification = classifyCampaignLayers(campaignMetrics, policy);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Policy file invalid or unreadable — skip layer classification silently
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
input,
|
|
133
|
+
records,
|
|
134
|
+
dateRange,
|
|
135
|
+
campaignMetrics,
|
|
136
|
+
structure,
|
|
137
|
+
skuClassification,
|
|
138
|
+
cpcRecommendations,
|
|
139
|
+
promotionCandidates,
|
|
140
|
+
negativeCandidates,
|
|
141
|
+
layerClassification,
|
|
142
|
+
seoRankingData,
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
//# sourceMappingURL=analyze-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-pipeline.js","sourceRoot":"","sources":["../../src/pipeline/analyze-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type { CampaignLayerClassification } from "../analysis/campaign-layer-classifier.js";
|
|
2
|
+
import type { SeoRankingData } from "../ranking/types.js";
|
|
3
|
+
export type RowValue = string | number | boolean | Date | null | undefined;
|
|
4
|
+
export type DataRow = Record<string, RowValue>;
|
|
5
|
+
export type OutputFormat = "console" | "json" | "markdown" | "xlsx";
|
|
6
|
+
export interface BulkInputData {
|
|
7
|
+
sourceFile: string;
|
|
8
|
+
headers: string[];
|
|
9
|
+
rows: DataRow[];
|
|
10
|
+
}
|
|
11
|
+
export interface NormalizedRecord {
|
|
12
|
+
campaignId: string;
|
|
13
|
+
campaignName: string;
|
|
14
|
+
adGroupId: string;
|
|
15
|
+
adGroupName: string;
|
|
16
|
+
keywordId: string;
|
|
17
|
+
keywordText: string;
|
|
18
|
+
customerSearchTerm: string;
|
|
19
|
+
productTargetingExpression: string;
|
|
20
|
+
matchType: string;
|
|
21
|
+
targetingType: string;
|
|
22
|
+
sku: string;
|
|
23
|
+
asin: string;
|
|
24
|
+
portfolioId: string;
|
|
25
|
+
state: string;
|
|
26
|
+
campaignStatus: string;
|
|
27
|
+
dailyBudget: number | "";
|
|
28
|
+
bid: number | "";
|
|
29
|
+
adGroupDefaultBid: number | "";
|
|
30
|
+
clicks: number;
|
|
31
|
+
impressions: number;
|
|
32
|
+
spend: number;
|
|
33
|
+
sales: number;
|
|
34
|
+
orders: number;
|
|
35
|
+
ctr: number;
|
|
36
|
+
cvr: number;
|
|
37
|
+
acos: number;
|
|
38
|
+
roas: number;
|
|
39
|
+
startDate: string;
|
|
40
|
+
endDate: string;
|
|
41
|
+
biddingStrategy: string;
|
|
42
|
+
sourceFile: string;
|
|
43
|
+
}
|
|
44
|
+
export interface CampaignMetrics {
|
|
45
|
+
campaignId: string;
|
|
46
|
+
campaignName: string;
|
|
47
|
+
targetingType: string;
|
|
48
|
+
state: string;
|
|
49
|
+
clicks: number;
|
|
50
|
+
impressions: number;
|
|
51
|
+
spend: number;
|
|
52
|
+
sales: number;
|
|
53
|
+
orders: number;
|
|
54
|
+
ctr: number;
|
|
55
|
+
cvr: number;
|
|
56
|
+
acos: number;
|
|
57
|
+
roas: number;
|
|
58
|
+
dailyBudget: number | "";
|
|
59
|
+
}
|
|
60
|
+
export interface CampaignStructureNode {
|
|
61
|
+
campaignId: string;
|
|
62
|
+
campaignName: string;
|
|
63
|
+
adGroups: Array<{
|
|
64
|
+
adGroupId: string;
|
|
65
|
+
adGroupName: string;
|
|
66
|
+
keywordCount: number;
|
|
67
|
+
productTargetCount: number;
|
|
68
|
+
spend: number;
|
|
69
|
+
sales: number;
|
|
70
|
+
acos: number;
|
|
71
|
+
}>;
|
|
72
|
+
}
|
|
73
|
+
export type SkuLabel = "focus" | "nurture" | "improve" | "prune";
|
|
74
|
+
export interface SkuClassification {
|
|
75
|
+
sku: string;
|
|
76
|
+
label: SkuLabel;
|
|
77
|
+
bidAdjust: number;
|
|
78
|
+
budgetAdjust: number;
|
|
79
|
+
reason: string;
|
|
80
|
+
}
|
|
81
|
+
export interface CpcRecommendation {
|
|
82
|
+
campaignId: string;
|
|
83
|
+
campaignName: string;
|
|
84
|
+
adGroupId: string;
|
|
85
|
+
adGroupName: string;
|
|
86
|
+
keywordId: string;
|
|
87
|
+
keywordText: string;
|
|
88
|
+
matchType: string;
|
|
89
|
+
sku: string;
|
|
90
|
+
clicks: number;
|
|
91
|
+
avgCpc: number;
|
|
92
|
+
currentBid: number;
|
|
93
|
+
recommendedBid: number;
|
|
94
|
+
bidAdjust: number;
|
|
95
|
+
reason: string;
|
|
96
|
+
seoFactor?: number;
|
|
97
|
+
organicPosition?: number | null;
|
|
98
|
+
seoReason?: string;
|
|
99
|
+
}
|
|
100
|
+
export interface PromotionCandidate {
|
|
101
|
+
campaignId: string;
|
|
102
|
+
campaignName: string;
|
|
103
|
+
adGroupId: string;
|
|
104
|
+
adGroupName: string;
|
|
105
|
+
keywordText: string;
|
|
106
|
+
matchType: string;
|
|
107
|
+
sku: string;
|
|
108
|
+
clicks: number;
|
|
109
|
+
spend: number;
|
|
110
|
+
orders: number;
|
|
111
|
+
cvr: number;
|
|
112
|
+
avgCpc: number;
|
|
113
|
+
recommendedBid: number;
|
|
114
|
+
recommendedAdGroupName: string;
|
|
115
|
+
}
|
|
116
|
+
export interface NegativeCandidate {
|
|
117
|
+
campaignId: string;
|
|
118
|
+
campaignName: string;
|
|
119
|
+
adGroupId: string;
|
|
120
|
+
adGroupName: string;
|
|
121
|
+
keywordText: string;
|
|
122
|
+
matchType: string;
|
|
123
|
+
reason: string;
|
|
124
|
+
}
|
|
125
|
+
export interface AnalyzePipelineResult {
|
|
126
|
+
input: BulkInputData[];
|
|
127
|
+
records: NormalizedRecord[];
|
|
128
|
+
dateRange: {
|
|
129
|
+
startDate: string;
|
|
130
|
+
endDate: string;
|
|
131
|
+
days: number;
|
|
132
|
+
} | null;
|
|
133
|
+
campaignMetrics: CampaignMetrics[];
|
|
134
|
+
structure: CampaignStructureNode[];
|
|
135
|
+
skuClassification: SkuClassification[];
|
|
136
|
+
cpcRecommendations: CpcRecommendation[];
|
|
137
|
+
promotionCandidates: PromotionCandidate[];
|
|
138
|
+
negativeCandidates: NegativeCandidate[];
|
|
139
|
+
layerClassification?: CampaignLayerClassification[];
|
|
140
|
+
seoRankingData?: SeoRankingData;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pipeline/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { KeywordMapping } from "./types.js";
|
|
2
|
+
export declare const normalizeKeyword: (text: string) => string;
|
|
3
|
+
export interface KeywordMatchResult {
|
|
4
|
+
adKeyword: string;
|
|
5
|
+
rankingKeyword: string;
|
|
6
|
+
normalizedKey: string;
|
|
7
|
+
source: "exact" | "normalized" | "mapping";
|
|
8
|
+
}
|
|
9
|
+
export declare const matchKeywords: (adKeywords: string[], rankingKeywords: string[], mappings?: KeywordMapping[]) => KeywordMatchResult[];
|
|
10
|
+
//# sourceMappingURL=keyword-matcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyword-matcher.d.ts","sourceRoot":"","sources":["../../src/ranking/keyword-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAqBjD,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,KAAG,MAE/C,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAAC;CAC5C;AAED,eAAO,MAAM,aAAa,GACxB,YAAY,MAAM,EAAE,EACpB,iBAAiB,MAAM,EAAE,EACzB,WAAW,cAAc,EAAE,KAC1B,kBAAkB,EA2CpB,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Full-width to half-width conversion table for ASCII range (U+FF01..U+FF5E -> U+0021..U+007E)
|
|
2
|
+
const FULLWIDTH_OFFSET = 0xff01 - 0x0021;
|
|
3
|
+
const toHalfWidth = (text) => {
|
|
4
|
+
let result = "";
|
|
5
|
+
for (const ch of text) {
|
|
6
|
+
const code = ch.codePointAt(0);
|
|
7
|
+
if (code >= 0xff01 && code <= 0xff5e) {
|
|
8
|
+
result += String.fromCodePoint(code - FULLWIDTH_OFFSET);
|
|
9
|
+
}
|
|
10
|
+
else if (code === 0x3000) {
|
|
11
|
+
// Ideographic space -> ASCII space
|
|
12
|
+
result += " ";
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
result += ch;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
export const normalizeKeyword = (text) => {
|
|
21
|
+
return toHalfWidth(text).toLowerCase().replace(/\s+/g, " ").trim();
|
|
22
|
+
};
|
|
23
|
+
export const matchKeywords = (adKeywords, rankingKeywords, mappings) => {
|
|
24
|
+
const results = [];
|
|
25
|
+
const rankingNormMap = new Map();
|
|
26
|
+
for (const rk of rankingKeywords) {
|
|
27
|
+
rankingNormMap.set(normalizeKeyword(rk), rk);
|
|
28
|
+
}
|
|
29
|
+
// Build manual mapping lookup (adKeyword normalized -> rankingKeyword)
|
|
30
|
+
const manualMap = new Map();
|
|
31
|
+
if (mappings) {
|
|
32
|
+
for (const m of mappings) {
|
|
33
|
+
manualMap.set(normalizeKeyword(m.adKeyword), m.rankingKeyword);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
for (const adKw of adKeywords) {
|
|
37
|
+
const normAd = normalizeKeyword(adKw);
|
|
38
|
+
// 1. Manual mapping takes priority
|
|
39
|
+
const mappedRanking = manualMap.get(normAd);
|
|
40
|
+
if (mappedRanking) {
|
|
41
|
+
results.push({
|
|
42
|
+
adKeyword: adKw,
|
|
43
|
+
rankingKeyword: mappedRanking,
|
|
44
|
+
normalizedKey: normalizeKeyword(mappedRanking),
|
|
45
|
+
source: "mapping",
|
|
46
|
+
});
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
// 2. Normalized match
|
|
50
|
+
const exactRanking = rankingNormMap.get(normAd);
|
|
51
|
+
if (exactRanking) {
|
|
52
|
+
results.push({
|
|
53
|
+
adKeyword: adKw,
|
|
54
|
+
rankingKeyword: exactRanking,
|
|
55
|
+
normalizedKey: normAd,
|
|
56
|
+
source: "normalized",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return results;
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=keyword-matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyword-matcher.js","sourceRoot":"","sources":["../../src/ranking/keyword-matcher.ts"],"names":[],"mappings":"AAEA,+FAA+F;AAC/F,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAU,EAAE;IAC3C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC;QAChC,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YACrC,MAAM,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,GAAG,gBAAgB,CAAC,CAAC;QAC1D,CAAC;aAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,mCAAmC;YACnC,MAAM,IAAI,GAAG,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAU,EAAE;IACvD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACrE,CAAC,CAAC;AASF,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,UAAoB,EACpB,eAAyB,EACzB,QAA2B,EACL,EAAE;IACxB,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;IACjD,KAAK,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC;QACjC,cAAc,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,uEAAuE;IACvE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAEtC,mCAAmC;QACnC,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC;gBACX,SAAS,EAAE,IAAI;gBACf,cAAc,EAAE,aAAa;gBAC7B,aAAa,EAAE,gBAAgB,CAAC,aAAa,CAAC;gBAC9C,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,sBAAsB;QACtB,MAAM,YAAY,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC;gBACX,SAAS,EAAE,IAAI;gBACf,cAAc,EAAE,YAAY;gBAC5B,aAAa,EAAE,MAAM;gBACrB,MAAM,EAAE,YAAY;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { KeywordRankingInfo, SeoRankingData } from "./types.js";
|
|
2
|
+
export declare class RankingDb {
|
|
3
|
+
private db;
|
|
4
|
+
constructor(dbPath: string);
|
|
5
|
+
getOrganicPosition(keyword: string, asin: string): number | null;
|
|
6
|
+
getSponsoredPosition(keyword: string, asin: string): number | null;
|
|
7
|
+
getLatestRanking(keyword: string, asin: string): KeywordRankingInfo;
|
|
8
|
+
getTrackedKeywords(): string[];
|
|
9
|
+
getTrackedAsins(): string[];
|
|
10
|
+
getLatestSnapshotDate(): string;
|
|
11
|
+
buildSeoRankingData(adKeywords: string[], asins: string[], dbPath: string): SeoRankingData;
|
|
12
|
+
close(): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=ranking-db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ranking-db.d.ts","sourceRoot":"","sources":["../../src/ranking/ranking-db.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAgBrE,qBAAa,SAAS;IACpB,OAAO,CAAC,EAAE,CAAoB;gBAElB,MAAM,EAAE,MAAM;IAK1B,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAahE,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAalE,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB;IAgCnE,kBAAkB,IAAI,MAAM,EAAE;IAM9B,eAAe,IAAI,MAAM,EAAE;IAM3B,qBAAqB,IAAI,MAAM;IAQ/B,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc;IAiC1F,KAAK,IAAI,IAAI;CAGd"}
|