xray16 1.2.3 → 1.3.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/README.md CHANGED
@@ -69,7 +69,23 @@ Following ones are available:
69
69
  - from_cast_utils - additional utils that should be removed in runtime
70
70
  - global_declarations_transform - transforms xray16 imports and removes them from runtime
71
71
  - inject_filename - adds $filename global variable to access current file name
72
- - strip_lua_logger - removes lua logger from runtime
72
+ - strip_lua_logger - removes lua logger from runtime (if path param is provided or ENV variable is set)
73
+ - inject_tracy_zones - removes lua logger from runtime (if path param is provided or ENV variable is set)
74
+
75
+ Path params:
76
+
77
+ - `--no-lua-logs`
78
+ - `--inject-tracy-zones`
79
+
80
+ Env variables:
81
+
82
+ - `XR_NO_LUA_LOGS `
83
+ - `XR_INJECT_TRACY_ZONES `
84
+
85
+ export const IS_LUA_LOGGER_DISABLED: boolean = process.argv.includes("--no-lua-logs")
86
+ || process.env.NO_LUA_LOGS === "true";
87
+ export const IS_TRACY_ZONES_INJECTION_ENABLED: boolean = process.argv.includes("--inject-tracy-zones")
88
+ || process.env.INJECT_TRACY_ZONES === "true";
73
89
 
74
90
  Plugins can be included in tsconfig file as following:
75
91
 
@@ -82,7 +98,8 @@ Plugins can be included in tsconfig file as following:
82
98
  { "name": "xray16/plugins/built_at_info" },
83
99
  { "name": "xray16/plugins/strip_lua_logger" },
84
100
  { "name": "xray16/plugins/inject_filename" },
85
- { "name": "xray16/plugins/from_cast_utils" }
101
+ { "name": "xray16/plugins/from_cast_utils" },
102
+ { "name": "xray16/plugins/inject_tracy_zones" }
86
103
  ]
87
104
  }
88
105
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xray16",
3
- "version": "1.2.3",
3
+ "version": "1.3.0",
4
4
  "author": "Neloreck",
5
5
  "repository": "https://github.com/stalker-xrts/xray-16-types",
6
6
  "private": false,
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const typescript_1 = require("typescript");
4
+ const environment_1 = require("./utils/environment");
5
+ const tracy_1 = require("./utils/tracy");
6
+ const ast_1 = require("./utils/ast");
7
+ /**
8
+ * Plugin that injects FILE_NAME in compile-time.
9
+ */
10
+ const plugin = {
11
+ visitors: {
12
+ [typescript_1.SyntaxKind.FunctionDeclaration]: (node, context) => {
13
+ return context.superTransformStatements(environment_1.IS_TRACY_ZONES_INJECTION_ENABLED ? (0, tracy_1.transformWithInjectedZones)(node) : node);
14
+ },
15
+ [typescript_1.SyntaxKind.ClassDeclaration]: (node, context) => {
16
+ if (environment_1.IS_TRACY_ZONES_INJECTION_ENABLED) {
17
+ const name = node.name ? node.name.getText() : null;
18
+ return context.superTransformStatements(typescript_1.factory.updateClassDeclaration(node, node.modifiers, node.name, node.typeParameters, node.heritageClauses, node.members.map((it) => {
19
+ if ((0, typescript_1.isMethodDeclaration)(it)) {
20
+ return (0, tracy_1.transformWithInjectedZones)(it, name);
21
+ }
22
+ return it;
23
+ })));
24
+ }
25
+ return context.superTransformStatements(node);
26
+ },
27
+ [typescript_1.SyntaxKind.ExpressionStatement]: (statement, context) => {
28
+ if (environment_1.IS_TRACY_ZONES_INJECTION_ENABLED) {
29
+ const expression = statement.expression;
30
+ if ((0, typescript_1.isCallExpression)(expression) &&
31
+ expression.expression?.kind === typescript_1.SyntaxKind.Identifier &&
32
+ expression.expression.getText() === "extern" &&
33
+ expression.arguments.length === 2) {
34
+ const first = expression.arguments[0];
35
+ const second = expression.arguments[1];
36
+ if (!(0, typescript_1.isStringLiteral)(first)) {
37
+ return context.transformStatements(statement);
38
+ }
39
+ if ((0, typescript_1.isObjectLiteralExpression)(second)) {
40
+ return context.superTransformStatements(typescript_1.factory.updateExpressionStatement(statement, typescript_1.factory.updateCallExpression(expression, expression.expression, expression.typeArguments, [
41
+ first,
42
+ typescript_1.factory.updateObjectLiteralExpression(second, second.properties.map((it) => {
43
+ if ((0, typescript_1.isPropertyAssignment)(it) && (0, typescript_1.isArrowFunction)(it.initializer)) {
44
+ return typescript_1.factory.updatePropertyAssignment(it, it.name, (0, tracy_1.transformArrowFunctionWithInjectedZones)(it.initializer, `${(0, ast_1.getIdentifierText)(first)}.${it.name.getText()}`));
45
+ }
46
+ return it;
47
+ })),
48
+ ])));
49
+ }
50
+ else if ((0, typescript_1.isArrowFunction)(second)) {
51
+ return context.superTransformStatements(typescript_1.factory.updateExpressionStatement(statement, typescript_1.factory.updateCallExpression(expression, expression.expression, expression.typeArguments, [
52
+ first,
53
+ (0, tracy_1.transformArrowFunctionWithInjectedZones)(second, (0, ast_1.getIdentifierText)(first)),
54
+ ])));
55
+ }
56
+ }
57
+ }
58
+ return context.superTransformStatements(statement);
59
+ },
60
+ },
61
+ };
62
+ exports.default = plugin;
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const typescript_1 = require("typescript");
4
+ const environment_1 = require("./utils/environment");
4
5
  const LUA_LOGGER_STRIP_TARGET = "LuaLogger";
5
- const IS_LUA_LOGGER_DISABLED = process.argv.includes("--no-lua-logs") || process.env.NO_LUA_LOGS === "true";
6
6
  /**
7
7
  * Plugin that removes all LuaLogger instance creations and calls when possible.
8
8
  */
9
9
  const plugin = {
10
10
  visitors: {
11
11
  [typescript_1.SyntaxKind.VariableStatement]: (statement, context) => {
12
- if (IS_LUA_LOGGER_DISABLED) {
12
+ if (environment_1.IS_LUA_LOGGER_DISABLED) {
13
13
  let elementsCount = 0;
14
14
  const list = statement.declarationList;
15
15
  const nodes = [];
@@ -34,7 +34,7 @@ const plugin = {
34
34
  return context.superTransformStatements(statement);
35
35
  },
36
36
  [typescript_1.SyntaxKind.ExpressionStatement]: (statement, context) => {
37
- if (IS_LUA_LOGGER_DISABLED && statement.expression?.kind === typescript_1.SyntaxKind.CallExpression) {
37
+ if (environment_1.IS_LUA_LOGGER_DISABLED && statement.expression?.kind === typescript_1.SyntaxKind.CallExpression) {
38
38
  const expression = statement.expression;
39
39
  const propertyAccess = expression.expression;
40
40
  if (propertyAccess.expression?.kind === typescript_1.SyntaxKind.Identifier) {
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getIdentifierText = getIdentifierText;
4
+ function getIdentifierText(node) {
5
+ const text = node.getText();
6
+ if (text.length > 2 && (text.startsWith('"') || text.startsWith("'"))) {
7
+ return text.substring(1, text.length - 1);
8
+ }
9
+ return text;
10
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IS_TRACY_ZONES_INJECTION_ENABLED = exports.IS_LUA_LOGGER_DISABLED = void 0;
4
+ exports.IS_LUA_LOGGER_DISABLED = process.argv.includes("--no-lua-logs") || process.env.XR_NO_LUA_LOGS === "true";
5
+ exports.IS_TRACY_ZONES_INJECTION_ENABLED = process.argv.includes("--inject-tracy-zones") || process.env.XR_INJECT_TRACY_ZONES === "true";
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTraceBeginExpression = isTraceBeginExpression;
4
+ exports.isTraceEndExpression = isTraceEndExpression;
5
+ exports.createTraceZoneBeginExpression = createTraceZoneBeginExpression;
6
+ exports.createTraceZoneBeginNExpression = createTraceZoneBeginNExpression;
7
+ exports.createTraceZoneBeginSExpression = createTraceZoneBeginSExpression;
8
+ exports.createTraceZoneEndExpression = createTraceZoneEndExpression;
9
+ exports.remapStatementsWithZoneEnd = remapStatementsWithZoneEnd;
10
+ exports.transformNestedStatementsToInjectEndZones = transformNestedStatementsToInjectEndZones;
11
+ exports.transformWithInjectedZones = transformWithInjectedZones;
12
+ exports.transformArrowFunctionWithInjectedZones = transformArrowFunctionWithInjectedZones;
13
+ const typescript_1 = require("typescript");
14
+ function isTraceBeginExpression(node) {
15
+ return ((0, typescript_1.isExpressionStatement)(node) &&
16
+ (0, typescript_1.isCallExpression)(node.expression) &&
17
+ (0, typescript_1.isPropertyAccessExpression)(node.expression.expression) &&
18
+ (node.expression.expression.name.escapedText === "ZoneBegin" ||
19
+ node.expression.expression.name.escapedText === "ZoneBeginS" ||
20
+ node.expression.expression.name.escapedText === "ZoneBeginN" ||
21
+ node.expression.expression.name.escapedText === "ZoneBeginNS"));
22
+ }
23
+ function isTraceEndExpression(node) {
24
+ return ((0, typescript_1.isExpressionStatement)(node) &&
25
+ (0, typescript_1.isCallExpression)(node.expression) &&
26
+ (0, typescript_1.isPropertyAccessExpression)(node.expression.expression) &&
27
+ node.expression.expression.name.escapedText === "ZoneEnd");
28
+ }
29
+ function createTraceZoneBeginExpression() {
30
+ return typescript_1.factory.createExpressionStatement(typescript_1.factory.createCallExpression(typescript_1.factory.createPropertyAccessExpression(typescript_1.factory.createIdentifier("tracy"), "ZoneBegin"), undefined, []));
31
+ }
32
+ function createTraceZoneBeginNExpression(name) {
33
+ return typescript_1.factory.createExpressionStatement(typescript_1.factory.createCallExpression(typescript_1.factory.createPropertyAccessExpression(typescript_1.factory.createIdentifier("tracy"), "ZoneBeginN"), undefined, [typescript_1.factory.createStringLiteral(name)]));
34
+ }
35
+ function createTraceZoneBeginSExpression(name) {
36
+ return typescript_1.factory.createExpressionStatement(typescript_1.factory.createCallExpression(typescript_1.factory.createPropertyAccessExpression(typescript_1.factory.createIdentifier("tracy"), "ZoneBeginS"), undefined, [typescript_1.factory.createStringLiteral(name)]));
37
+ }
38
+ function createTraceZoneEndExpression() {
39
+ return typescript_1.factory.createExpressionStatement(typescript_1.factory.createCallExpression(typescript_1.factory.createPropertyAccessExpression(typescript_1.factory.createIdentifier("tracy"), "ZoneEnd"), undefined, []));
40
+ }
41
+ function remapStatementsWithZoneEnd(target) {
42
+ const statements = [...target.statements];
43
+ let index = 0;
44
+ while (statements[index]) {
45
+ if ((0, typescript_1.isReturnStatement)(statements[index])) {
46
+ statements.splice(index, 0, createTraceZoneEndExpression());
47
+ index += 1;
48
+ }
49
+ index++;
50
+ }
51
+ return statements;
52
+ }
53
+ function transformNestedStatementsToInjectEndZones(statement) {
54
+ if (!statement || isTraceBeginExpression(statement) || isTraceEndExpression(statement)) {
55
+ return statement;
56
+ }
57
+ if ((0, typescript_1.isBlock)(statement)) {
58
+ const statements = [...statement.statements];
59
+ let index = 0;
60
+ while (statements[index]) {
61
+ if ((0, typescript_1.isReturnStatement)(statements[index])) {
62
+ statements.splice(index, 0, createTraceZoneEndExpression());
63
+ index += 1;
64
+ }
65
+ index++;
66
+ }
67
+ return typescript_1.factory.updateBlock(statement, remapStatementsWithZoneEnd(statement).map((it) => transformNestedStatementsToInjectEndZones(it)));
68
+ }
69
+ else if ((0, typescript_1.isForStatement)(statement)) {
70
+ if ((0, typescript_1.isBlock)(statement.statement)) {
71
+ return typescript_1.factory.updateForStatement(statement, statement.initializer, statement.condition, statement.incrementor, transformNestedStatementsToInjectEndZones(statement.statement));
72
+ }
73
+ else {
74
+ throw new Error(`Unexpected nested for statement: ${statement.statement.kind} (${typescript_1.SyntaxKind[statement.statement.kind]}).`);
75
+ }
76
+ }
77
+ else if ((0, typescript_1.isForInStatement)(statement)) {
78
+ if ((0, typescript_1.isBlock)(statement.statement)) {
79
+ return typescript_1.factory.updateForInStatement(statement, statement.initializer, statement.expression, transformNestedStatementsToInjectEndZones(statement.statement));
80
+ }
81
+ else {
82
+ throw new Error(`Unexpected nested for-in statement: ${statement.statement.kind} (${typescript_1.SyntaxKind[statement.statement.kind]}).`);
83
+ }
84
+ }
85
+ else if ((0, typescript_1.isForOfStatement)(statement)) {
86
+ if ((0, typescript_1.isBlock)(statement.statement)) {
87
+ return typescript_1.factory.updateForOfStatement(statement, statement.awaitModifier, statement.initializer, statement.expression, transformNestedStatementsToInjectEndZones(statement.statement));
88
+ }
89
+ else {
90
+ throw new Error(`Unexpected nested for-of statement: ${statement.statement.kind} (${typescript_1.SyntaxKind[statement.statement.kind]}).`);
91
+ }
92
+ }
93
+ else if ((0, typescript_1.isIfStatement)(statement)) {
94
+ return typescript_1.factory.updateIfStatement(statement, statement.expression, transformNestedStatementsToInjectEndZones(statement.thenStatement), transformNestedStatementsToInjectEndZones(statement.elseStatement));
95
+ }
96
+ else if ((0, typescript_1.isSwitchStatement)(statement)) {
97
+ return typescript_1.factory.updateSwitchStatement(statement, statement.expression, typescript_1.factory.updateCaseBlock(statement.caseBlock, statement.caseBlock.clauses.map((it) => {
98
+ if ((0, typescript_1.isCaseClause)(it)) {
99
+ return typescript_1.factory.updateCaseClause(it, it.expression, remapStatementsWithZoneEnd(it).map((it) => transformNestedStatementsToInjectEndZones(it)));
100
+ }
101
+ else if ((0, typescript_1.isDefaultClause)(it)) {
102
+ return typescript_1.factory.updateDefaultClause(it, remapStatementsWithZoneEnd(it).map((it) => transformNestedStatementsToInjectEndZones(it)));
103
+ }
104
+ else {
105
+ return it;
106
+ }
107
+ })));
108
+ }
109
+ return statement;
110
+ }
111
+ function transformWithInjectedZones(node, parentName) {
112
+ const name = node.name ? node.name.getText() : null;
113
+ if (!name || !node.body?.statements.length) {
114
+ return node;
115
+ }
116
+ const hasReturnStatement = (0, typescript_1.isReturnStatement)(node.body.statements[node.body.statements.length - 1]);
117
+ // Single line function declaration with return, nothing to profile here without complex assign transformations.
118
+ if (hasReturnStatement && node.body.statements.length === 1) {
119
+ return node;
120
+ }
121
+ const statements = remapStatementsWithZoneEnd(node.body).map(transformNestedStatementsToInjectEndZones);
122
+ // Zone start declaration.
123
+ statements.unshift(createTraceZoneBeginNExpression(`${parentName ? `${parentName}.` : ""}${name}@lua`));
124
+ // Zone end declaration without explicit return.
125
+ if (!hasReturnStatement) {
126
+ statements.push(createTraceZoneEndExpression());
127
+ }
128
+ if ((0, typescript_1.isMethodDeclaration)(node)) {
129
+ return typescript_1.factory.updateMethodDeclaration(node, node.modifiers, node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters, node.type, typescript_1.factory.updateBlock(node.body, statements));
130
+ }
131
+ else if ((0, typescript_1.isConstructorDeclaration)(node)) {
132
+ return typescript_1.factory.updateConstructorDeclaration(node, node.modifiers, node.parameters, typescript_1.factory.updateBlock(node.body, statements));
133
+ }
134
+ else {
135
+ return typescript_1.factory.updateFunctionDeclaration(node, node.modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, typescript_1.factory.updateBlock(node.body, statements));
136
+ }
137
+ }
138
+ function transformArrowFunctionWithInjectedZones(node, name) {
139
+ if (!node || !name || (0, typescript_1.isExpression)(node.body) || !node.body.statements.length) {
140
+ return node;
141
+ }
142
+ const hasReturnStatement = (0, typescript_1.isReturnStatement)(node.body.statements[node.body.statements.length - 1]);
143
+ // Single line function declaration with return, nothing to profile here without complex assign transformations.
144
+ if (hasReturnStatement && node.body.statements.length === 1) {
145
+ return node;
146
+ }
147
+ const statements = remapStatementsWithZoneEnd(node.body).map(transformNestedStatementsToInjectEndZones);
148
+ // Zone start declaration.
149
+ statements.unshift(createTraceZoneBeginNExpression(`${name}@lua`));
150
+ // Zone end declaration without explicit return.
151
+ if (!hasReturnStatement) {
152
+ statements.push(createTraceZoneEndExpression());
153
+ }
154
+ return typescript_1.factory.updateArrowFunction(node, node.modifiers, node.typeParameters, node.parameters, node.type, node.equalsGreaterThanToken, typescript_1.factory.updateBlock(node.body, statements));
155
+ }
package/types/index.d.ts CHANGED
@@ -20,6 +20,7 @@ import "./xr_lib/xr_luabind";
20
20
  import "./xr_lib/xr_map";
21
21
  import "./xr_lib/xr_math";
22
22
  import "./xr_lib/xr_multiplayer";
23
+ import "./xr_lib/xr_profile";
23
24
  import "./xr_lib/xr_properties";
24
25
  import "./xr_lib/xr_relation";
25
26
  import "./xr_lib/xr_render";
@@ -1,27 +1,4 @@
1
1
  declare module "xray16" {
2
- /**
3
- * @source C++ class profile_timer
4
- * @customConstructor profile_timer
5
- * @group xr_debug
6
- */
7
- export class profile_timer extends EngineBinding {
8
- public constructor();
9
- public constructor(timer: profile_timer);
10
-
11
- public stop(): void;
12
-
13
- public start(): void;
14
-
15
- public time(): f32;
16
-
17
- /**
18
- * Overridden string cast is implemented for profiling timer.
19
- *
20
- * @returns serialized profile time.
21
- */
22
- public toString(): string;
23
- }
24
-
25
2
  /**
26
3
  * @source C++ class CConsole
27
4
  * @customConstructor CConsole
@@ -0,0 +1,160 @@
1
+ declare module "xray16" {
2
+ export const PROFILER_TYPE_NONE: 0;
3
+ export const PROFILER_TYPE_HOOK: 1;
4
+ export const PROFILER_TYPE_SAMPLING: 2;
5
+
6
+ export type TXR_ProfilerType = typeof PROFILER_TYPE_NONE | typeof PROFILER_TYPE_HOOK | typeof PROFILER_TYPE_SAMPLING;
7
+
8
+ /**
9
+ * @source C++ class profile_timer
10
+ * @customConstructor profile_timer
11
+ * @group xr_profile
12
+ */
13
+ export class profile_timer extends EngineBinding {
14
+ public constructor();
15
+ public constructor(timer: profile_timer);
16
+
17
+ public stop(): void;
18
+
19
+ public start(): void;
20
+
21
+ public time(): f32;
22
+
23
+ /**
24
+ * Overridden string cast is implemented for profiling timer.
25
+ *
26
+ * @returns serialized profile time.
27
+ */
28
+ public toString(): string;
29
+ }
30
+
31
+ /**
32
+ * @source namespace profiler
33
+ * @group xr_profile
34
+ */
35
+ export interface IXR_profiler {
36
+ /**
37
+ * @returns whether lua scripts profiler is active
38
+ */
39
+ is_active(this: void): boolean;
40
+
41
+ /**
42
+ * @returns currently active profiler type
43
+ */
44
+ get_type(this: void): typeof PROFILER_TYPE_NONE | typeof PROFILER_TYPE_HOOK | typeof PROFILER_TYPE_SAMPLING;
45
+
46
+ /**
47
+ * Start lua scripts profiler in default mode.
48
+ */
49
+ start(this: void): void;
50
+
51
+ /**
52
+ * Start lua scripts profiler of provided type.
53
+ *
54
+ * @param profiler_type - type of profiler to start (note: see global exports of type constants)
55
+ */
56
+ start(this: void, profiler_type: TXR_ProfilerType): void;
57
+
58
+ /**
59
+ * Start profiler in hook mode.
60
+ * Profiling performance based on lua call start/end events.
61
+ */
62
+ start_hook_mode(this: void): void;
63
+
64
+ /**
65
+ * Start profiler in sampling mode with default sampling interval.
66
+ */
67
+ start_sampling_mode(this: void): void;
68
+
69
+ /**
70
+ * Start profiler in sampling mode with provided sampling interval value.
71
+ *
72
+ * @param sampling_interval - interval to collect samples with luaJIT sampling profiler
73
+ */
74
+ start_sampling_mode(this: void, sampling_interval: u32): void;
75
+
76
+ /**
77
+ * Stop currently active profiler.
78
+ */
79
+ stop(this: void): void;
80
+
81
+ /**
82
+ * Reset measurements data of profiler.
83
+ */
84
+ reset(this: void): void;
85
+
86
+ /**
87
+ * Log report of profiler measurements in game console/log file.
88
+ * Use default engine limit to print top N entries.
89
+ */
90
+ log_report(this: void): void;
91
+
92
+ /**
93
+ * Log report of profiler measurements in game console/log file.
94
+ *
95
+ * @param entries_limit - limit of top profiling entries to print
96
+ */
97
+ log_report(this: void, entries_limit: u32): void;
98
+
99
+ /**
100
+ * Save report of profiler measurements in corresponding log/perf file.
101
+ */
102
+ save_report(this: void): void;
103
+ }
104
+
105
+ /**
106
+ * @group xr_profile
107
+ */
108
+ export const profiler: IXR_profiler;
109
+
110
+ /**
111
+ * @source namespace profiler
112
+ * @group xr_profile
113
+ */
114
+ export interface IXR_tracy {
115
+ /**
116
+ * Begin tracy profiling zone.
117
+ */
118
+ ZoneBegin(this: void): void;
119
+
120
+ /**
121
+ * Begin tracy profiling zone with defined name.
122
+ *
123
+ * @param name - name to display in tracy logs for current zone
124
+ */
125
+ ZoneBeginN(this: void, name: string): void;
126
+
127
+ ZoneBeginS(this: void): void;
128
+
129
+ ZoneBeginNS(this: void): void;
130
+
131
+ /**
132
+ * End tracy profiling zone.
133
+ */
134
+ ZoneEnd(this: void): void;
135
+
136
+ /**
137
+ * Set zone text.
138
+ *
139
+ * @param text - text description of the zone
140
+ */
141
+ ZoneText(this: void, text: string): void;
142
+
143
+ /**
144
+ * Set zone name on per-call basis.
145
+ *
146
+ * @param name - name of zone
147
+ */
148
+ ZoneName(this: void, name: string): void;
149
+
150
+ /**
151
+ * Send message to tracy profiler.
152
+ */
153
+ Message(this: void): void;
154
+ }
155
+
156
+ /**
157
+ * @group xr_profile
158
+ */
159
+ export const tracy: IXR_tracy;
160
+ }