@boristype/bt-cli 0.1.0-alpha.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.md +66 -0
- package/build/builder/config.js +88 -0
- package/build/cli/commands/artifact.js +14 -0
- package/build/cli/commands/build.js +25 -0
- package/build/cli/commands/dev.js +190 -0
- package/build/cli/commands/index.js +18 -0
- package/build/cli/commands/init.js +15 -0
- package/build/cli/commands/link.js +18 -0
- package/build/cli/commands/push.js +28 -0
- package/build/cli/index.js +14 -0
- package/build/cli/types.js +2 -0
- package/build/core/artifacting/context.js +54 -0
- package/build/core/artifacting/index.js +37 -0
- package/build/core/artifacting/stages/index.js +10 -0
- package/build/core/artifacting/stages/main-archive.js +72 -0
- package/build/core/artifacting/stages/validate.js +70 -0
- package/build/core/artifacting/types.js +6 -0
- package/build/core/artifacting/utils/index.js +10 -0
- package/build/core/artifacting/utils/zip.js +94 -0
- package/build/core/babel.js +96 -0
- package/build/core/btconfig.types.js +6 -0
- package/build/core/build.js +280 -0
- package/build/core/building/compile-mode.js +146 -0
- package/build/core/building/compiler.js +281 -0
- package/build/core/building/coordinator.js +71 -0
- package/build/core/building/files.js +290 -0
- package/build/core/building/index.js +102 -0
- package/build/core/building/output.js +92 -0
- package/build/core/building/transformers.js +110 -0
- package/build/core/building/types.js +19 -0
- package/build/core/config.js +157 -0
- package/build/core/dependencies.js +223 -0
- package/build/core/linking/cache.js +260 -0
- package/build/core/linking/context.js +149 -0
- package/build/core/linking/dependencies.js +240 -0
- package/build/core/linking/executables.js +61 -0
- package/build/core/linking/generators/api-ext.js +57 -0
- package/build/core/linking/generators/component.js +83 -0
- package/build/core/linking/generators/filemap.js +53 -0
- package/build/core/linking/generators/index.js +21 -0
- package/build/core/linking/generators/init-xml.js +37 -0
- package/build/core/linking/generators/package-json.js +50 -0
- package/build/core/linking/index.js +213 -0
- package/build/core/linking/linkers/component.js +175 -0
- package/build/core/linking/linkers/index.js +69 -0
- package/build/core/linking/linkers/standalone.js +144 -0
- package/build/core/linking/linkers/system.js +86 -0
- package/build/core/linking/parsers.js +278 -0
- package/build/core/linking/types.js +6 -0
- package/build/core/linking/utils/copy.js +101 -0
- package/build/core/linking/utils/index.js +26 -0
- package/build/core/linking/utils/node-modules.js +226 -0
- package/build/core/linking/utils/package-type.js +101 -0
- package/build/core/linking/utils/url.js +73 -0
- package/build/core/linking/utils/write.js +91 -0
- package/build/core/logger.js +10 -0
- package/build/core/pushing/config.js +90 -0
- package/build/core/pushing/index.js +96 -0
- package/build/core/pushing/init-scripts.js +173 -0
- package/build/core/pushing/queue.js +95 -0
- package/build/core/pushing/reinit.js +61 -0
- package/build/core/pushing/session.js +167 -0
- package/build/core/pushing/types.js +6 -0
- package/build/core/pushing/upload.js +35 -0
- package/build/core/tsconfig.js +78 -0
- package/build/core/utils/index.js +17 -0
- package/build/core/utils/logger.js +46 -0
- package/build/core/utils/properties.js +81 -0
- package/build/core/utils/xml.js +44 -0
- package/build/core/utils.js +59 -0
- package/build/index.js +76 -0
- package/build/plugins/destructuring.js +83 -0
- package/build/plugins/forOfToForIn.js +14 -0
- package/build/plugins/loopHoistVariables.js +160 -0
- package/build/plugins/precedence.js +172 -0
- package/build/plugins/removeImportExport.js +42 -0
- package/build/plugins/replaceDollar.js +16 -0
- package/build/plugins/spreadArray.js +42 -0
- package/build/plugins/spreadObject.js +91 -0
- package/build/transformers/arrayFunctional.js +467 -0
- package/build/transformers/arrayGeneral.js +222 -0
- package/build/transformers/blockScoping.js +212 -0
- package/build/transformers/destructuring.js +133 -0
- package/build/transformers/dirname.js +79 -0
- package/build/transformers/enumsToObjects.js +25 -0
- package/build/transformers/execObj.js +220 -0
- package/build/transformers/forOfToForIn.js +45 -0
- package/build/transformers/funcSemantic.js +113 -0
- package/build/transformers/functions.js +270 -0
- package/build/transformers/globalCache.js +34 -0
- package/build/transformers/loopHoistVariables.js +352 -0
- package/build/transformers/math.js +39 -0
- package/build/transformers/namespaces.js +22 -0
- package/build/transformers/numericSeparator.js +46 -0
- package/build/transformers/objectProperties.js +54 -0
- package/build/transformers/precedence.js +192 -0
- package/build/transformers/propSemantic.js +467 -0
- package/build/transformers/remodule.js +620 -0
- package/build/transformers/removeImportExport.js +135 -0
- package/build/transformers/replaceDollar.js +46 -0
- package/build/transformers/shorthandProperties.js +34 -0
- package/build/transformers/spreadArray.js +68 -0
- package/build/transformers/spreadObject.js +134 -0
- package/build/transformers/string.js +138 -0
- package/build/transformers/templateLiterals.js +104 -0
- package/build/transformers/tocodelibrary.js +178 -0
- package/build/transformers/utils.js +202 -0
- package/build/wshcm/client.js +193 -0
- package/build/wshcm/evaluator.js +111 -0
- package/build/wshcm/exceptions.js +25 -0
- package/build/wshcm/index.js +20 -0
- package/build/wshcm/soap-utils.js +228 -0
- package/build/wshcm/types.js +2 -0
- package/build/wshcm/uploader.js +320 -0
- package/package.json +51 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.stageMainArchive = stageMainArchive;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const logger_1 = require("../../logger");
|
|
40
|
+
const zip_1 = require("../utils/zip");
|
|
41
|
+
/**
|
|
42
|
+
* Stage 2: Создание полного архива дистрибуции
|
|
43
|
+
*
|
|
44
|
+
* Создаёт main.zip со всем содержимым dist
|
|
45
|
+
*
|
|
46
|
+
* @param ctx - Контекст artifact pipeline
|
|
47
|
+
* @returns Обновлённый контекст с путём к архиву
|
|
48
|
+
*/
|
|
49
|
+
async function stageMainArchive(ctx) {
|
|
50
|
+
logger_1.logger.info('📦 Stage: Create Archive');
|
|
51
|
+
const archiveName = 'main.zip';
|
|
52
|
+
const archivePath = path.join(ctx.artifactPath, archiveName);
|
|
53
|
+
logger_1.logger.info(` → Создание архива: ${archiveName}`);
|
|
54
|
+
await (0, zip_1.createZipArchive)(archivePath, (archive) => {
|
|
55
|
+
const items = fs.readdirSync(ctx.distPath);
|
|
56
|
+
for (const item of items) {
|
|
57
|
+
const itemPath = path.join(ctx.distPath, item);
|
|
58
|
+
const stat = fs.statSync(itemPath);
|
|
59
|
+
if (stat.isDirectory()) {
|
|
60
|
+
(0, zip_1.addDirectoryToArchive)(archive, itemPath, item);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
(0, zip_1.addFileToArchive)(archive, itemPath, item);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
logger_1.logger.info(` ✓ Создан: ${archiveName}`);
|
|
68
|
+
return {
|
|
69
|
+
...ctx,
|
|
70
|
+
archivePath,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.stageValidate = stageValidate;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const logger_1 = require("../../logger");
|
|
39
|
+
/**
|
|
40
|
+
* Stage 1: Валидация и подготовка
|
|
41
|
+
*
|
|
42
|
+
* - Проверяет существование директории dist
|
|
43
|
+
* - Очищает или создаёт директорию artifact
|
|
44
|
+
*
|
|
45
|
+
* @param ctx - Контекст artifact pipeline
|
|
46
|
+
* @returns Контекст (без изменений)
|
|
47
|
+
* @throws Error если dist не существует
|
|
48
|
+
*/
|
|
49
|
+
function stageValidate(ctx) {
|
|
50
|
+
logger_1.logger.info('📋 Stage: Validate');
|
|
51
|
+
// Проверяем существование директории dist
|
|
52
|
+
if (!fs.existsSync(ctx.distPath)) {
|
|
53
|
+
logger_1.logger.error(`Директория dist не найдена: ${ctx.distPath}`);
|
|
54
|
+
throw new Error('Directory dist does not exist');
|
|
55
|
+
}
|
|
56
|
+
logger_1.logger.info(` ✓ Директория dist найдена`);
|
|
57
|
+
// Очищаем или создаём директорию artifact
|
|
58
|
+
if (ctx.options.clean && fs.existsSync(ctx.artifactPath)) {
|
|
59
|
+
fs.rmSync(ctx.artifactPath, { recursive: true, force: true });
|
|
60
|
+
logger_1.logger.info(` ✓ Директория artifact очищена`);
|
|
61
|
+
}
|
|
62
|
+
if (!fs.existsSync(ctx.artifactPath)) {
|
|
63
|
+
fs.mkdirSync(ctx.artifactPath, { recursive: true });
|
|
64
|
+
logger_1.logger.info(` ✓ Создана директория artifact`);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
logger_1.logger.info(` ✓ Директория artifact существует`);
|
|
68
|
+
}
|
|
69
|
+
return ctx;
|
|
70
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addFileToArchive = exports.addDirectoryToArchive = exports.createZipArchive = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Реэкспорт утилит для artifact
|
|
6
|
+
*/
|
|
7
|
+
var zip_1 = require("./zip");
|
|
8
|
+
Object.defineProperty(exports, "createZipArchive", { enumerable: true, get: function () { return zip_1.createZipArchive; } });
|
|
9
|
+
Object.defineProperty(exports, "addDirectoryToArchive", { enumerable: true, get: function () { return zip_1.addDirectoryToArchive; } });
|
|
10
|
+
Object.defineProperty(exports, "addFileToArchive", { enumerable: true, get: function () { return zip_1.addFileToArchive; } });
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.createZipArchive = createZipArchive;
|
|
40
|
+
exports.addDirectoryToArchive = addDirectoryToArchive;
|
|
41
|
+
exports.addFileToArchive = addFileToArchive;
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const archiver_1 = __importDefault(require("archiver"));
|
|
44
|
+
const logger_1 = require("../../logger");
|
|
45
|
+
/**
|
|
46
|
+
* Создает ZIP архив с использованием библиотеки archiver
|
|
47
|
+
*
|
|
48
|
+
* @param archivePath - Путь для сохранения архива
|
|
49
|
+
* @param populateArchive - Функция для добавления содержимого в архив
|
|
50
|
+
* @param options - Опции архивирования
|
|
51
|
+
*/
|
|
52
|
+
async function createZipArchive(archivePath, populateArchive, options = {}) {
|
|
53
|
+
const { compressionLevel = 9 } = options;
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
const output = fs.createWriteStream(archivePath);
|
|
56
|
+
const archive = (0, archiver_1.default)('zip', {
|
|
57
|
+
zlib: { level: compressionLevel }
|
|
58
|
+
});
|
|
59
|
+
output.on('close', () => {
|
|
60
|
+
resolve();
|
|
61
|
+
});
|
|
62
|
+
archive.on('error', (err) => {
|
|
63
|
+
reject(err);
|
|
64
|
+
});
|
|
65
|
+
archive.on('warning', (err) => {
|
|
66
|
+
if (err.code !== 'ENOENT') {
|
|
67
|
+
logger_1.logger.warning(`Предупреждение при архивировании: ${err.message}`);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
archive.pipe(output);
|
|
71
|
+
populateArchive(archive);
|
|
72
|
+
archive.finalize();
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Добавляет директорию в архив
|
|
77
|
+
*
|
|
78
|
+
* @param archive - Архив
|
|
79
|
+
* @param dirPath - Путь к директории
|
|
80
|
+
* @param archiveDirName - Имя директории внутри архива
|
|
81
|
+
*/
|
|
82
|
+
function addDirectoryToArchive(archive, dirPath, archiveDirName) {
|
|
83
|
+
archive.directory(dirPath, archiveDirName);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Добавляет файл в архив
|
|
87
|
+
*
|
|
88
|
+
* @param archive - Архив
|
|
89
|
+
* @param filePath - Путь к файлу
|
|
90
|
+
* @param archiveFileName - Имя файла внутри архива
|
|
91
|
+
*/
|
|
92
|
+
function addFileToArchive(archive, filePath, archiveFileName) {
|
|
93
|
+
archive.file(filePath, { name: archiveFileName });
|
|
94
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createConfig = createConfig;
|
|
4
|
+
function createConfig(options) {
|
|
5
|
+
return {
|
|
6
|
+
presets: [
|
|
7
|
+
[
|
|
8
|
+
require.resolve("@babel/preset-env"),
|
|
9
|
+
{
|
|
10
|
+
targets: "defaults",
|
|
11
|
+
modules: false
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
],
|
|
15
|
+
plugins: [
|
|
16
|
+
// ============================================================
|
|
17
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: numericSeparatorTransformer
|
|
18
|
+
// Трансформирует числовые литералы с разделителями (например, 1_000_000 -> 1000000)
|
|
19
|
+
// require.resolve("@babel/plugin-transform-numeric-separator"),
|
|
20
|
+
// ============================================================
|
|
21
|
+
// TODO: что это такое вообще
|
|
22
|
+
// require.resolve("@babel/plugin-transform-logical-assignment-operators"),
|
|
23
|
+
// Реализует оператор нулевого слияния (??)
|
|
24
|
+
require.resolve("@babel/plugin-transform-nullish-coalescing-operator"),
|
|
25
|
+
// // TODO: реализовать по другому
|
|
26
|
+
// require.resolve("@babel/plugin-transform-optional-chaining"),
|
|
27
|
+
// // TODO: у нас нет Math.pow, надо проверить
|
|
28
|
+
// require.resolve("@babel/plugin-transform-exponentiation-operator"),
|
|
29
|
+
// ============================================================
|
|
30
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: templateLiteralsTransformer
|
|
31
|
+
// Преобразует шаблонные строки в конкатенацию строк
|
|
32
|
+
// [require.resolve("@babel/plugin-transform-template-literals"), { "loose": true }],
|
|
33
|
+
// ============================================================
|
|
34
|
+
// TODO: что это такое вообще
|
|
35
|
+
// require.resolve("@babel/plugin-transform-literals"),
|
|
36
|
+
// // TODO: в BS нельзя анонимные функции
|
|
37
|
+
// require.resolve("@babel/plugin-transform-function-name"),
|
|
38
|
+
// // TODO: в BS нельзя анонимные функции
|
|
39
|
+
// require.resolve("@babel/plugin-transform-arrow-functions"),
|
|
40
|
+
// ============================================================
|
|
41
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: shorthandPropertiesTransformer
|
|
42
|
+
// Преобразует сокращенные свойства объектов в полные
|
|
43
|
+
// require.resolve("@babel/plugin-transform-shorthand-properties"),
|
|
44
|
+
// ============================================================
|
|
45
|
+
// ============================================================
|
|
46
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: forOfToForInTransformer
|
|
47
|
+
// Преобразует циклы for-of в циклы for-in
|
|
48
|
+
// path.resolve(__dirname, "../plugins/forOfToForIn.js"),
|
|
49
|
+
// ============================================================
|
|
50
|
+
// // TODO: не уверен как ведет себя BS и нотацией \u и когда литерал вставлен напрямую
|
|
51
|
+
// require.resolve("@babel/plugin-transform-unicode-escapes"),
|
|
52
|
+
// ============================================================
|
|
53
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: spreadArrayTransformer
|
|
54
|
+
// Реализует оператор расширения для массивов
|
|
55
|
+
// path.resolve(__dirname, "../plugins/spreadArray.js"),
|
|
56
|
+
// ============================================================
|
|
57
|
+
// ============================================================
|
|
58
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: spreadObjectTransformer
|
|
59
|
+
// Реализует оператор расширения для объектов
|
|
60
|
+
// path.resolve(__dirname, "../plugins/spreadObject.js"),
|
|
61
|
+
// ============================================================
|
|
62
|
+
// ============================================================
|
|
63
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: destructuringTransformer
|
|
64
|
+
// Реализует деструктуризацию объектов и массивов
|
|
65
|
+
// path.resolve(__dirname, "../plugins/destructuring.js"),
|
|
66
|
+
// ============================================================
|
|
67
|
+
// ============================================================
|
|
68
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: blockScopingTransformer
|
|
69
|
+
// Заменяет let/const на var с учетом области видимости
|
|
70
|
+
// require.resolve("@babel/plugin-transform-block-scoping"),
|
|
71
|
+
// ============================================================
|
|
72
|
+
// ============================================================
|
|
73
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: replaceDollarTransformer
|
|
74
|
+
// Заменяет знак доллара в идентификаторах на разрешнные символы (например, $ -> _24_)
|
|
75
|
+
// path.resolve(__dirname, "../plugins/replaceDollar.js"),
|
|
76
|
+
// ============================================================
|
|
77
|
+
// ============================================================
|
|
78
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: loopHoistVariablesTransformer
|
|
79
|
+
// Поднимает переменные из циклов перед ними
|
|
80
|
+
// path.resolve(__dirname, "../plugins/loopHoistVariables.js"),
|
|
81
|
+
// ============================================================
|
|
82
|
+
// ============================================================
|
|
83
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: removeImportExportTransformer
|
|
84
|
+
// Удаляет импорты, экспорты по умолчанию и модификаторы экспортов
|
|
85
|
+
// path.resolve(__dirname, "../plugins/removeImportExport.js"),
|
|
86
|
+
// ============================================================
|
|
87
|
+
// ============================================================
|
|
88
|
+
// ЗАМЕНЕНО НА TS ТРАНСФОРМЕР: precedenceTransformer
|
|
89
|
+
// Обрабатывает приоритеты операторов (добавляет скобки там, где нужно)
|
|
90
|
+
// path.resolve(__dirname, "../plugins/precedence.js"),
|
|
91
|
+
// ============================================================
|
|
92
|
+
],
|
|
93
|
+
sourceMaps: options.sourceMaps,
|
|
94
|
+
cwd: options.cwd,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.transformOutput = void 0;
|
|
40
|
+
exports.buildTypescriptFiles = buildTypescriptFiles;
|
|
41
|
+
exports.buildNonTypescriptFiles = buildNonTypescriptFiles;
|
|
42
|
+
exports.collectNonTypescriptFiles = collectNonTypescriptFiles;
|
|
43
|
+
exports.transformWithBabel = transformWithBabel;
|
|
44
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
45
|
+
const node_path_1 = __importStar(require("node:path"));
|
|
46
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
47
|
+
const logger_js_1 = require("./logger.js");
|
|
48
|
+
const output_js_1 = require("./building/output.js");
|
|
49
|
+
const babel = __importStar(require("@babel/core"));
|
|
50
|
+
const namespaces_js_1 = require("../transformers/namespaces.js");
|
|
51
|
+
const enumsToObjects_js_1 = require("../transformers/enumsToObjects.js");
|
|
52
|
+
const arrayFunctional_js_1 = __importDefault(require("../transformers/arrayFunctional.js"));
|
|
53
|
+
const arrayGeneral_js_1 = __importDefault(require("../transformers/arrayGeneral.js"));
|
|
54
|
+
const remodule_js_1 = require("../transformers/remodule.js");
|
|
55
|
+
const functions_js_1 = require("../transformers/functions.js");
|
|
56
|
+
const string_js_1 = __importDefault(require("../transformers/string.js"));
|
|
57
|
+
const math_js_1 = require("../transformers/math.js");
|
|
58
|
+
const babel_js_1 = require("./babel.js");
|
|
59
|
+
const propSemantic_js_1 = __importDefault(require("../transformers/propSemantic.js"));
|
|
60
|
+
const tocodelibrary_js_1 = require("../transformers/tocodelibrary.js");
|
|
61
|
+
const funcSemantic_js_1 = require("../transformers/funcSemantic.js");
|
|
62
|
+
const execObj_js_1 = require("../transformers/execObj.js");
|
|
63
|
+
const dirname_js_1 = require("../transformers/dirname.js");
|
|
64
|
+
const objectProperties_js_1 = require("../transformers/objectProperties.js");
|
|
65
|
+
const globalCache_js_1 = require("../transformers/globalCache.js");
|
|
66
|
+
// After-трансформеры (замена Babel плагинов)
|
|
67
|
+
const numericSeparator_js_1 = require("../transformers/numericSeparator.js");
|
|
68
|
+
const templateLiterals_js_1 = require("../transformers/templateLiterals.js");
|
|
69
|
+
const shorthandProperties_js_1 = require("../transformers/shorthandProperties.js");
|
|
70
|
+
const forOfToForIn_js_1 = require("../transformers/forOfToForIn.js");
|
|
71
|
+
const spreadArray_js_1 = require("../transformers/spreadArray.js");
|
|
72
|
+
const spreadObject_js_1 = require("../transformers/spreadObject.js");
|
|
73
|
+
const destructuring_js_1 = require("../transformers/destructuring.js");
|
|
74
|
+
const replaceDollar_js_1 = require("../transformers/replaceDollar.js");
|
|
75
|
+
const blockScoping_js_1 = require("../transformers/blockScoping.js");
|
|
76
|
+
const loopHoistVariables_js_1 = require("../transformers/loopHoistVariables.js");
|
|
77
|
+
const precedence_js_1 = require("../transformers/precedence.js");
|
|
78
|
+
const removeImportExport_js_1 = require("../transformers/removeImportExport.js");
|
|
79
|
+
function selectFiles(rawFileNames, files) {
|
|
80
|
+
if (files.length === 0) {
|
|
81
|
+
return rawFileNames;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return rawFileNames.filter(x => files.includes(x));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function buildTypescriptFiles(btcConfiguration) {
|
|
88
|
+
const fileNames = selectFiles(btcConfiguration.tsConfig.fileNames, btcConfiguration.files);
|
|
89
|
+
const program = typescript_1.default.createProgram(fileNames, btcConfiguration.tsConfig.options);
|
|
90
|
+
const host = typescript_1.default.createCompilerHost(program.getCompilerOptions());
|
|
91
|
+
const babelConfig = (0, babel_js_1.createConfig)({ sourceMaps: btcConfiguration.tsConfig.options.sourceMap, cwd: process.cwd() });
|
|
92
|
+
decorateHostWriteFile(host, btcConfiguration.btOptions, btcConfiguration.tsConfig, babelConfig);
|
|
93
|
+
const emitResult = decorateProgramEmit(host, program, btcConfiguration.btOptions);
|
|
94
|
+
const diagnostics = [
|
|
95
|
+
...typescript_1.default.getPreEmitDiagnostics(program),
|
|
96
|
+
...(emitResult?.diagnostics || []),
|
|
97
|
+
];
|
|
98
|
+
diagnostics.forEach(diagnostic => {
|
|
99
|
+
if (diagnostic.file) {
|
|
100
|
+
const { line, character } = typescript_1.default.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
|
101
|
+
const message = typescript_1.default.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
|
102
|
+
logger_js_1.logger.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
logger_js_1.logger.error(typescript_1.default.flattenDiagnosticMessageText(diagnostic.messageText, '\n'));
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
return emitResult;
|
|
109
|
+
}
|
|
110
|
+
function buildNonTypescriptFiles(btcConfiguration) {
|
|
111
|
+
if (btcConfiguration.btOptions.includeNonTsFiles === false) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const { rootDir, outDir } = btcConfiguration.tsConfig.options;
|
|
115
|
+
const entries = collectNonTypescriptFiles(btcConfiguration.tsConfig);
|
|
116
|
+
selectFiles(entries, btcConfiguration.files).forEach(x => {
|
|
117
|
+
const filePath = rootDir ? (0, node_path_1.relative)(rootDir, x) : x;
|
|
118
|
+
const outputFilePath = (0, node_path_1.resolve)(outDir, filePath);
|
|
119
|
+
node_fs_1.default.mkdirSync((0, node_path_1.dirname)(outputFilePath), { recursive: true });
|
|
120
|
+
node_fs_1.default.writeFileSync(outputFilePath, node_fs_1.default.readFileSync((0, node_path_1.resolve)(x), 'utf-8'));
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function collectNonTypescriptFiles(configuration) {
|
|
124
|
+
const { outDir } = configuration.options;
|
|
125
|
+
if (outDir === undefined) {
|
|
126
|
+
throw new Error('The outDir option is not set in the tsconfig.json file.');
|
|
127
|
+
}
|
|
128
|
+
if (process.versions.node.split('.')[0] < '22') {
|
|
129
|
+
throw new Error('The watch mode for non TypeScript files is available only since Node.js v22');
|
|
130
|
+
}
|
|
131
|
+
const { exclude, files, include } = configuration.raw;
|
|
132
|
+
const fileNames = configuration.fileNames.map(node_path_1.normalize);
|
|
133
|
+
const normalizedExclude = (exclude ?? []).map(node_path_1.normalize);
|
|
134
|
+
return node_fs_1.default.globSync([...(include ?? []), ...(files ?? [])])
|
|
135
|
+
.filter(x => !fileNames.includes(x))
|
|
136
|
+
.filter(x => !normalizedExclude?.includes(x))
|
|
137
|
+
.filter(x => node_fs_1.default.statSync(x).isFile());
|
|
138
|
+
}
|
|
139
|
+
function reportDiagnostic(diagnostic) {
|
|
140
|
+
if (diagnostic.file) {
|
|
141
|
+
const { line, character } = typescript_1.default.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
|
142
|
+
const message = typescript_1.default.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
|
143
|
+
logger_js_1.logger.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
logger_js_1.logger.error(typescript_1.default.flattenDiagnosticMessageText(diagnostic.messageText, '\n'));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function decorateHostWriteFile(host, options, configuration, babelConfig) {
|
|
150
|
+
const originalWriteFile = host.writeFile;
|
|
151
|
+
host.writeFile = (fileName, text, writeByteOrderMark, onError, sourceFiles, data) => {
|
|
152
|
+
if (fileName.endsWith('.js')) {
|
|
153
|
+
// Babel теперь отключен по умолчанию, вся функциональность перенесена в TS трансформеры
|
|
154
|
+
// Для включения Babel установите options.useBabel = true
|
|
155
|
+
const result = options.useBabel === true ? transformWithBabel(text, fileName, babelConfig) : { code: text, map: undefined };
|
|
156
|
+
const transformedContent = result?.code;
|
|
157
|
+
const sourceMap = result?.map;
|
|
158
|
+
if (transformedContent != null && transformedContent !== undefined) {
|
|
159
|
+
const { fileName: newFileName, content: newFileContent } = (0, output_js_1.transformOutput)(fileName, transformedContent, options);
|
|
160
|
+
originalWriteFile.call(host, newFileName, newFileContent, writeByteOrderMark, onError, sourceFiles);
|
|
161
|
+
if (sourceMap && configuration.options.sourceMap) {
|
|
162
|
+
originalWriteFile.call(host, `${fileName}.map`, JSON.stringify(sourceMap), writeByteOrderMark, onError, sourceFiles);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
logger_js_1.logger.warning(`Babel transformation skipped for ${fileName}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
originalWriteFile.call(host, fileName, text, writeByteOrderMark, onError, sourceFiles);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function transformWithBabel(code, fileName, babelConfig) {
|
|
175
|
+
try {
|
|
176
|
+
const babelResult = babel.transformSync(code, {
|
|
177
|
+
filename: fileName,
|
|
178
|
+
...babelConfig,
|
|
179
|
+
});
|
|
180
|
+
return babelResult;
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
184
|
+
logger_js_1.logger.error(`Babel transformation error for ${fileName}: ${errorMessage}`);
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* @deprecated Используйте {@link transformOutputImpl} из './building/output.js'.
|
|
190
|
+
* Оставлено как re-export для обратной совместимости legacy кода.
|
|
191
|
+
*/
|
|
192
|
+
exports.transformOutput = output_js_1.transformOutput;
|
|
193
|
+
function decorateProgramEmit(host, program, options) {
|
|
194
|
+
const beforeTransformers = [];
|
|
195
|
+
// numericSeparator должен быть в before, т.к. printer сохраняет исходный текст литералов
|
|
196
|
+
beforeTransformers.push((0, numericSeparator_js_1.numericSeparatorTransformer)()); // 1_000_000 -> 1000000
|
|
197
|
+
beforeTransformers.push((0, enumsToObjects_js_1.enumsToObjectsTransformer)());
|
|
198
|
+
beforeTransformers.push((0, namespaces_js_1.namespacesTransformer)());
|
|
199
|
+
if (options.usePolyfill) {
|
|
200
|
+
beforeTransformers.push((0, arrayFunctional_js_1.default)(program), (0, arrayGeneral_js_1.default)(program), (0, string_js_1.default)(program), (0, math_js_1.mathTransformer)(), (0, globalCache_js_1.globalCacheTransformer)(program));
|
|
201
|
+
}
|
|
202
|
+
beforeTransformers.push((0, functions_js_1.functionsTransformer)());
|
|
203
|
+
beforeTransformers.push((0, objectProperties_js_1.objectPropertiesTransformer)());
|
|
204
|
+
const executables = [];
|
|
205
|
+
beforeTransformers.push((0, execObj_js_1.execObjTransformer)(program, executables));
|
|
206
|
+
if (options.useRemodule) {
|
|
207
|
+
beforeTransformers.push((0, dirname_js_1.dirnameTransformer)(), (0, funcSemantic_js_1.funcSemanticTransformer)(), (0, remodule_js_1.remoduleTransformer)(program), (0, tocodelibrary_js_1.tocodelibraryTransformer)(), (0, propSemantic_js_1.default)(program));
|
|
208
|
+
}
|
|
209
|
+
// After-трансформеры выполняются после генерации JS кода
|
|
210
|
+
// Заменяют функциональность Babel плагинов
|
|
211
|
+
const afterTransformers = [
|
|
212
|
+
// numericSeparator перенесён в before - printer сохраняет исходный текст
|
|
213
|
+
(0, templateLiterals_js_1.templateLiteralsTransformer)(), // `hello ${x}` -> "hello " + x
|
|
214
|
+
(0, shorthandProperties_js_1.shorthandPropertiesTransformer)(), // { x } -> { x: x }
|
|
215
|
+
(0, forOfToForIn_js_1.forOfToForInTransformer)(), // for-of -> for-in
|
|
216
|
+
(0, spreadArray_js_1.spreadArrayTransformer)(), // [...arr] -> ArrayUnion(arr)
|
|
217
|
+
(0, spreadObject_js_1.spreadObjectTransformer)(), // {...obj} -> ObjectUnion({}, obj)
|
|
218
|
+
(0, destructuring_js_1.destructuringTransformer)(), // const { a } = obj -> const a = obj.a
|
|
219
|
+
(0, blockScoping_js_1.blockScopingTransformer)(), // let/const -> var (с shadowing)
|
|
220
|
+
(0, loopHoistVariables_js_1.loopHoistVariablesTransformer)(), // hoist loop vars before loop
|
|
221
|
+
(0, precedence_js_1.precedenceTransformer)(), // добавляет скобки для приоритета операций
|
|
222
|
+
(0, replaceDollar_js_1.replaceDollarTransformer)(), // $name -> _24_name
|
|
223
|
+
(0, removeImportExport_js_1.removeImportExportTransformer)(), // удаляет import/export
|
|
224
|
+
];
|
|
225
|
+
const result = program.emit(undefined, host.writeFile, undefined, undefined, {
|
|
226
|
+
before: beforeTransformers,
|
|
227
|
+
after: afterTransformers,
|
|
228
|
+
});
|
|
229
|
+
// console.log('Executable Objects:', executables);
|
|
230
|
+
const outputDir = getOutputDirectory(program);
|
|
231
|
+
node_fs_1.default.writeFileSync(node_path_1.default.join(outputDir, '.executables.json'), JSON.stringify(executables, null, 2), 'utf-8');
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
234
|
+
function getOutputDirectory(program) {
|
|
235
|
+
const options = program.getCompilerOptions();
|
|
236
|
+
return node_path_1.default.normalize(node_path_1.default.join(program.getCurrentDirectory(), options.outDir || ''));
|
|
237
|
+
}
|
|
238
|
+
// function reportWatchStatusChanged(diagnostic: ts.Diagnostic) {
|
|
239
|
+
// console.info(ts.formatDiagnostic(diagnostic, {
|
|
240
|
+
// getCanonicalFileName: path => path,
|
|
241
|
+
// getCurrentDirectory: ts.sys.getCurrentDirectory,
|
|
242
|
+
// getNewLine: () => ts.sys.newLine,
|
|
243
|
+
// }));
|
|
244
|
+
// }
|
|
245
|
+
// export function watchTypescriptFiles(configuration: ts.ParsedCommandLine) {
|
|
246
|
+
// const host = ts.createWatchCompilerHost(
|
|
247
|
+
// configuration.fileNames,
|
|
248
|
+
// configuration.options,
|
|
249
|
+
// ts.sys,
|
|
250
|
+
// ts.createEmitAndSemanticDiagnosticsBuilderProgram,
|
|
251
|
+
// reportDiagnostic,
|
|
252
|
+
// reportWatchStatusChanged
|
|
253
|
+
// );
|
|
254
|
+
// const origCreateProgram = host.createProgram;
|
|
255
|
+
// host.createProgram = (rootNames: ReadonlyArray<string> = [], options, host, oldProgram) => {
|
|
256
|
+
// decorateHostWriteFile(host!);
|
|
257
|
+
// const program = origCreateProgram(rootNames, options, host, oldProgram);
|
|
258
|
+
// decorateProgramEmit(host!, program);
|
|
259
|
+
// return program;
|
|
260
|
+
// };
|
|
261
|
+
// ts.createWatchProgram(host);
|
|
262
|
+
// }
|
|
263
|
+
// export function watchNonTypescriptFiles(configuration: ts.ParsedCommandLine) {
|
|
264
|
+
// if (!args.has(ArgsFlags.INCLUDE_NON_TS_FILES)) {
|
|
265
|
+
// return;
|
|
266
|
+
// }
|
|
267
|
+
// const { rootDir, outDir } = configuration.options;
|
|
268
|
+
// const entries = collectNonTypescriptFiles(configuration);
|
|
269
|
+
// entries.forEach(x => {
|
|
270
|
+
// const filePath = rootDir ? relative(rootDir, x) : x;
|
|
271
|
+
// const outputFilePath = resolve(outDir!, filePath);
|
|
272
|
+
// fs.watch(resolve(x), (event: fs.WatchEventType) => {
|
|
273
|
+
// if (event == 'change') {
|
|
274
|
+
// fs.mkdirSync(dirname(outputFilePath), { recursive: true });
|
|
275
|
+
// fs.writeFileSync(outputFilePath, fs.readFileSync(resolve(x), 'utf-8'));
|
|
276
|
+
// logger.success(`🔨 ${new Date().toLocaleTimeString()} File ${x} has been changed`);
|
|
277
|
+
// }
|
|
278
|
+
// });
|
|
279
|
+
// });
|
|
280
|
+
// }
|