@codefresh-io/cf-telemetry 2.0.0-alpha.21 → 2.0.0-alpha.23
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/init.d.mts +1 -0
- package/dist/init.js +79 -2
- package/dist/init.js.map +1 -1
- package/dist/init.mjs +2 -0
- package/dist/init.mjs.map +1 -0
- package/dist/profiles/index.d.ts +1 -0
- package/dist/profiles/index.js +26 -9
- package/dist/profiles/index.js.map +1 -1
- package/package.json +4 -5
- package/dist/index.d.mts +0 -1
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -76
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -2
- package/dist/index.mjs.map +0 -1
package/dist/init.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './init.js';
|
package/dist/init.js
CHANGED
|
@@ -1,5 +1,82 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
36
|
+
// ↓ Should be imported first
|
|
37
|
+
const otel = __importStar(require("./otel"));
|
|
38
|
+
// ↑ Should be imported first
|
|
39
|
+
const global_config_1 = require("./global-config");
|
|
40
|
+
const logs = __importStar(require("./logs"));
|
|
41
|
+
const prometheus = __importStar(require("./metrics/prometheus"));
|
|
42
|
+
const profiles = __importStar(require("./profiles"));
|
|
43
|
+
let isInitialized = false;
|
|
44
|
+
/**
|
|
45
|
+
* Initializes telemetry services.
|
|
46
|
+
* Should be called once as early as possible in the application lifecycle.
|
|
47
|
+
*/
|
|
48
|
+
const init = () => {
|
|
49
|
+
if (isInitialized)
|
|
50
|
+
return;
|
|
51
|
+
try {
|
|
52
|
+
const logger = new logs.Logger('telemetry');
|
|
53
|
+
logger.info('Initializing telemetry services');
|
|
54
|
+
logger.debug('Telemetry configuration', global_config_1.globalConfig);
|
|
55
|
+
otel.init(logger);
|
|
56
|
+
profiles.init(logger);
|
|
57
|
+
prometheus.init(logger).catch(logger.error);
|
|
58
|
+
isInitialized = true;
|
|
59
|
+
logger.info('Telemetry services initialized');
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.error('Failed to initialize telemetry services', error);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const terminate = async () => {
|
|
66
|
+
const logger = new logs.Logger('telemetry');
|
|
67
|
+
try {
|
|
68
|
+
logger.info('Terminating telemetry services');
|
|
69
|
+
await otel.terminate(logger).catch(logger.error);
|
|
70
|
+
await profiles.terminate(logger).catch(logger.error);
|
|
71
|
+
isInitialized = false;
|
|
72
|
+
logger.info('Telemetry services terminated');
|
|
73
|
+
}
|
|
74
|
+
catch (exception) {
|
|
75
|
+
logger.error('Failed to terminate telemetry services', exception);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
init();
|
|
79
|
+
process.on('SIGINT', terminate);
|
|
80
|
+
process.on('SIGTERM', terminate);
|
|
81
|
+
process.once('beforeExit', terminate);
|
|
5
82
|
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6BAA6B;AAC7B,6CAA+B;AAC/B,6BAA6B;AAE7B,mDAA+C;AAC/C,6CAA+B;AAC/B,iEAAmD;AACnD,qDAAuC;AAEvC,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B;;;GAGG;AACH,MAAM,IAAI,GAAG,GAAS,EAAE;IACtB,IAAI,aAAa;QAAE,OAAO;IAE1B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,4BAAY,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtB,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5C,aAAa,GAAG,IAAI,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,KAAK,IAAmB,EAAE;IAC1C,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC9C,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrD,aAAa,GAAG,KAAK,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,SAAS,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,SAAS,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC;AAEF,IAAI,EAAE,CAAC;AAEP,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAChC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AACjC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC"}
|
package/dist/init.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.mjs","sourceRoot":"","sources":["../src/init.mts"],"names":[],"mappings":"AAAA,OAAO,WAAW,CAAC"}
|
package/dist/profiles/index.d.ts
CHANGED
package/dist/profiles/index.js
CHANGED
|
@@ -3,20 +3,37 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.init = void 0;
|
|
6
|
+
exports.terminate = exports.init = void 0;
|
|
7
7
|
const nodejs_1 = __importDefault(require("@pyroscope/nodejs"));
|
|
8
8
|
const config_1 = require("./config");
|
|
9
9
|
const init = (logger) => {
|
|
10
10
|
logger = logger.child('pyroscope');
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
try {
|
|
12
|
+
if (!config_1.config.enabled) {
|
|
13
|
+
logger.info('Pyroscope is disabled. Set CF_TELEMETRY_PYROSCOPE_ENABLE=true to enable it');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
logger.info('Initializing Pyroscope');
|
|
17
|
+
logger.debug('Pyroscope configuration', config_1.config);
|
|
18
|
+
nodejs_1.default.init(config_1.config.config);
|
|
19
|
+
nodejs_1.default.start();
|
|
20
|
+
logger.info('Pyroscope initialized');
|
|
21
|
+
}
|
|
22
|
+
catch (exception) {
|
|
23
|
+
logger.error('Failed to initialize Pyroscope', exception);
|
|
14
24
|
}
|
|
15
|
-
logger.info('Initializing Pyroscope');
|
|
16
|
-
logger.debug('Pyroscope configuration', config_1.config);
|
|
17
|
-
nodejs_1.default.init(config_1.config.config);
|
|
18
|
-
nodejs_1.default.start();
|
|
19
|
-
logger.info('Pyroscope initialized');
|
|
20
25
|
};
|
|
21
26
|
exports.init = init;
|
|
27
|
+
const terminate = async (logger) => {
|
|
28
|
+
logger = logger.child('pyroscope');
|
|
29
|
+
try {
|
|
30
|
+
logger.info('Terminating Pyroscope');
|
|
31
|
+
await nodejs_1.default.stop();
|
|
32
|
+
logger.info('Pyroscope terminated');
|
|
33
|
+
}
|
|
34
|
+
catch (exception) {
|
|
35
|
+
logger.error('Failed to terminate Pyroscope', exception);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
exports.terminate = terminate;
|
|
22
39
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/profiles/index.ts"],"names":[],"mappings":";;;;;;AAAA,+DAA0C;AAE1C,qCAAkC;AAE3B,MAAM,IAAI,GAAG,CAAC,MAAc,EAAQ,EAAE;IAC3C,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACnC,IAAI,CAAC,eAAM,CAAC,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/profiles/index.ts"],"names":[],"mappings":";;;;;;AAAA,+DAA0C;AAE1C,qCAAkC;AAE3B,MAAM,IAAI,GAAG,CAAC,MAAc,EAAQ,EAAE;IAC3C,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACnC,IAAI,CAAC;QACH,IAAI,CAAC,eAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;YAC1F,OAAO;QACT,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,eAAM,CAAC,CAAC;QAChD,gBAAS,CAAC,IAAI,CAAC,eAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,gBAAS,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,SAAS,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,SAAS,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC,CAAC;AAhBW,QAAA,IAAI,QAgBf;AAEK,MAAM,SAAS,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;IAC/D,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACrC,MAAM,gBAAS,CAAC,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,SAAS,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,SAAS,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC,CAAC;AATW,QAAA,SAAS,aASpB"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codefresh-io/cf-telemetry",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.23",
|
|
4
4
|
"exports": {
|
|
5
|
-
"./init":
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
"require": "./dist/index.js"
|
|
5
|
+
"./init": {
|
|
6
|
+
"import": "./dist/init.mjs",
|
|
7
|
+
"require": "./dist/init.js"
|
|
9
8
|
},
|
|
10
9
|
"./logs": {
|
|
11
10
|
"import": "./dist/logs/public.mjs",
|
package/dist/index.d.mts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './index.js';
|
package/dist/index.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Initializes telemetry services. Should be called once as early as possible in the application lifecycle.
|
|
3
|
-
* Preferred method of initialization is to add `--import=@codefresh-io/cf-telemetry/init` Node.js flag,
|
|
4
|
-
* instead of calling this function directly.
|
|
5
|
-
*/
|
|
6
|
-
export declare const init: () => Promise<void>;
|
|
7
|
-
export declare const terminate: () => Promise<void>;
|
package/dist/index.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
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.terminate = exports.init = void 0;
|
|
37
|
-
// ↓ Should be imported first
|
|
38
|
-
const otel = __importStar(require("./otel"));
|
|
39
|
-
// ↑ Should be imported first
|
|
40
|
-
const logs = __importStar(require("./logs"));
|
|
41
|
-
const prometheus = __importStar(require("./metrics/prometheus"));
|
|
42
|
-
const profiles = __importStar(require("./profiles"));
|
|
43
|
-
let isInitialized = false;
|
|
44
|
-
/**
|
|
45
|
-
* Initializes telemetry services. Should be called once as early as possible in the application lifecycle.
|
|
46
|
-
* Preferred method of initialization is to add `--import=@codefresh-io/cf-telemetry/init` Node.js flag,
|
|
47
|
-
* instead of calling this function directly.
|
|
48
|
-
*/
|
|
49
|
-
const init = async () => {
|
|
50
|
-
if (isInitialized)
|
|
51
|
-
return;
|
|
52
|
-
const logger = new logs.Logger('telemetry');
|
|
53
|
-
logger.info('Initializing telemetry services');
|
|
54
|
-
otel.init(logger);
|
|
55
|
-
profiles.init(logger);
|
|
56
|
-
await Promise.all([
|
|
57
|
-
prometheus.init(logger),
|
|
58
|
-
]);
|
|
59
|
-
isInitialized = true;
|
|
60
|
-
logger.info('Telemetry services initialized');
|
|
61
|
-
};
|
|
62
|
-
exports.init = init;
|
|
63
|
-
const terminate = async () => {
|
|
64
|
-
const logger = new logs.Logger('telemetry');
|
|
65
|
-
try {
|
|
66
|
-
logger.info('Terminating telemetry services');
|
|
67
|
-
await otel.terminate(logger).catch(logger.error);
|
|
68
|
-
isInitialized = false;
|
|
69
|
-
logger.info('Telemetry services terminated');
|
|
70
|
-
}
|
|
71
|
-
catch (exception) {
|
|
72
|
-
logger.error('Failed to terminate telemetry services', exception);
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
exports.terminate = terminate;
|
|
76
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6BAA6B;AAC7B,6CAA+B;AAC/B,6BAA6B;AAE7B,6CAA+B;AAC/B,iEAAmD;AACnD,qDAAuC;AAEvC,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B;;;;GAIG;AACI,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;IAC5C,IAAI,aAAa;QAAE,OAAO;IAE1B,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAC/C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtB,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;KACxB,CAAC,CAAC;IACH,aAAa,GAAG,IAAI,CAAC;IACrB,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;AAChD,CAAC,CAAC;AAZW,QAAA,IAAI,QAYf;AAEK,MAAM,SAAS,GAAG,KAAK,IAAmB,EAAE;IACjD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC9C,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACjD,aAAa,GAAG,KAAK,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,SAAS,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,SAAS,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,CAAC;AAVW,QAAA,SAAS,aAUpB"}
|
package/dist/index.mjs
DELETED
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
|