semantifold 0.1.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.
Files changed (111) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +71 -0
  3. package/build/index.d.ts +54 -0
  4. package/build/index.d.ts.map +1 -0
  5. package/build/index.js +45 -0
  6. package/build/src/backends/identifiers.d.ts +19 -0
  7. package/build/src/backends/identifiers.d.ts.map +1 -0
  8. package/build/src/backends/identifiers.js +93 -0
  9. package/build/src/backends/index.d.ts +35 -0
  10. package/build/src/backends/index.d.ts.map +1 -0
  11. package/build/src/backends/index.js +149 -0
  12. package/build/src/backends/java.d.ts +8 -0
  13. package/build/src/backends/java.d.ts.map +1 -0
  14. package/build/src/backends/java.js +172 -0
  15. package/build/src/backends/javascript.d.ts +8 -0
  16. package/build/src/backends/javascript.d.ts.map +1 -0
  17. package/build/src/backends/javascript.js +173 -0
  18. package/build/src/backends/php.d.ts +8 -0
  19. package/build/src/backends/php.d.ts.map +1 -0
  20. package/build/src/backends/php.js +175 -0
  21. package/build/src/backends/ruby.d.ts +8 -0
  22. package/build/src/backends/ruby.d.ts.map +1 -0
  23. package/build/src/backends/ruby.js +155 -0
  24. package/build/src/backends/scalars.d.ts +15 -0
  25. package/build/src/backends/scalars.d.ts.map +1 -0
  26. package/build/src/backends/scalars.js +138 -0
  27. package/build/src/backends/shared.d.ts +26 -0
  28. package/build/src/backends/shared.d.ts.map +1 -0
  29. package/build/src/backends/shared.js +424 -0
  30. package/build/src/backends/typescript.d.ts +8 -0
  31. package/build/src/backends/typescript.d.ts.map +1 -0
  32. package/build/src/backends/typescript.js +160 -0
  33. package/build/src/backends/writer.d.ts +87 -0
  34. package/build/src/backends/writer.d.ts.map +1 -0
  35. package/build/src/backends/writer.js +207 -0
  36. package/build/src/diagnostic.d.ts +67 -0
  37. package/build/src/diagnostic.d.ts.map +1 -0
  38. package/build/src/diagnostic.js +96 -0
  39. package/build/src/frontends/index.d.ts +14 -0
  40. package/build/src/frontends/index.d.ts.map +1 -0
  41. package/build/src/frontends/index.js +36 -0
  42. package/build/src/frontends/java.d.ts +12 -0
  43. package/build/src/frontends/java.d.ts.map +1 -0
  44. package/build/src/frontends/java.js +630 -0
  45. package/build/src/frontends/javascript-typescript.d.ts +19 -0
  46. package/build/src/frontends/javascript-typescript.d.ts.map +1 -0
  47. package/build/src/frontends/javascript-typescript.js +633 -0
  48. package/build/src/frontends/php.d.ts +12 -0
  49. package/build/src/frontends/php.d.ts.map +1 -0
  50. package/build/src/frontends/php.js +523 -0
  51. package/build/src/frontends/ruby.d.ts +12 -0
  52. package/build/src/frontends/ruby.d.ts.map +1 -0
  53. package/build/src/frontends/ruby.js +515 -0
  54. package/build/src/frontends/scalars.d.ts +19 -0
  55. package/build/src/frontends/scalars.d.ts.map +1 -0
  56. package/build/src/frontends/scalars.js +71 -0
  57. package/build/src/mapping.d.ts +160 -0
  58. package/build/src/mapping.d.ts.map +1 -0
  59. package/build/src/mapping.js +1120 -0
  60. package/build/src/semantic/location.d.ts +61 -0
  61. package/build/src/semantic/location.d.ts.map +1 -0
  62. package/build/src/semantic/location.js +142 -0
  63. package/build/src/semantic/operators.d.ts +16 -0
  64. package/build/src/semantic/operators.d.ts.map +1 -0
  65. package/build/src/semantic/operators.js +24 -0
  66. package/build/src/semantic/provenance.d.ts +74 -0
  67. package/build/src/semantic/provenance.d.ts.map +1 -0
  68. package/build/src/semantic/provenance.js +577 -0
  69. package/build/src/semantic/scalars.d.ts +19 -0
  70. package/build/src/semantic/scalars.d.ts.map +1 -0
  71. package/build/src/semantic/scalars.js +40 -0
  72. package/build/src/semantic/types.d.ts +1003 -0
  73. package/build/src/semantic/types.d.ts.map +1 -0
  74. package/build/src/semantic/types.js +279 -0
  75. package/build/src/semantic/validate.d.ts +60 -0
  76. package/build/src/semantic/validate.d.ts.map +1 -0
  77. package/build/src/semantic/validate.js +472 -0
  78. package/docs/architecture.md +39 -0
  79. package/docs/coding-standards.md +7 -0
  80. package/docs/goals.md +7 -0
  81. package/docs/language-support.md +69 -0
  82. package/docs/plans/2026-09-02-initial-toolchain.md +54 -0
  83. package/docs/source-maps.md +134 -0
  84. package/docs/testing.md +25 -0
  85. package/index.js +63 -0
  86. package/package.json +69 -0
  87. package/src/backends/identifiers.js +101 -0
  88. package/src/backends/index.js +159 -0
  89. package/src/backends/java.js +182 -0
  90. package/src/backends/javascript.js +184 -0
  91. package/src/backends/php.js +184 -0
  92. package/src/backends/ruby.js +163 -0
  93. package/src/backends/scalars.js +120 -0
  94. package/src/backends/shared.js +456 -0
  95. package/src/backends/typescript.js +168 -0
  96. package/src/backends/writer.js +224 -0
  97. package/src/diagnostic.js +103 -0
  98. package/src/frontends/index.js +36 -0
  99. package/src/frontends/java.js +735 -0
  100. package/src/frontends/javascript-typescript.js +718 -0
  101. package/src/frontends/php.js +593 -0
  102. package/src/frontends/ruby.js +622 -0
  103. package/src/frontends/scalars.js +77 -0
  104. package/src/mapping.js +1260 -0
  105. package/src/semantic/location.js +154 -0
  106. package/src/semantic/operators.js +28 -0
  107. package/src/semantic/provenance.js +629 -0
  108. package/src/semantic/scalars.js +44 -0
  109. package/src/semantic/types.js +319 -0
  110. package/src/semantic/validate.js +529 -0
  111. package/tsconfig.json +16 -0
@@ -0,0 +1,175 @@
1
+ // @ts-check
2
+ import { emitExpression } from "./shared.js";
3
+ import { emitScalarType } from "./scalars.js";
4
+ /**
5
+ * Emits an independently executable PHP program through the source-aware writer.
6
+ * @param {import("../semantic/types.js").SemanticModule} module - Semantic module.
7
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
8
+ * @returns {void}
9
+ */
10
+ export function generatePhp(module, writer) {
11
+ writer.synthetic("<?php\ndeclare(strict_types=1);\n\n", "PHP program scaffolding", [module]);
12
+ module.functions.forEach((declaration, functionIndex) => {
13
+ if (functionIndex > 0)
14
+ writer.synthetic("\n\n", "declaration separator", [declaration]);
15
+ writer.mapped("function", { mappingKind: "anchor", node: declaration });
16
+ writer.synthetic(" ", "function spacing", [declaration]);
17
+ writer.mapped(declaration.name, { mappingKind: "exact", node: declaration, role: "name" });
18
+ writer.mapped("(", { mappingKind: "anchor", node: declaration });
19
+ declaration.parameters.forEach((parameter, index) => {
20
+ const parameterPath = `/functions/${functionIndex}/parameters/${index}`;
21
+ if (index > 0)
22
+ writer.synthetic(", ", "parameter separator", [declaration]);
23
+ writer.mapped(emitScalarType("php", parameter.type), {
24
+ mappingKind: "exact",
25
+ node: parameter.type,
26
+ path: `${parameterPath}/type`,
27
+ role: "type"
28
+ });
29
+ writer.synthetic(" ", "parameter spacing", [parameter], [parameterPath]);
30
+ writer.mapped(`$${parameter.name}`, { mappingKind: "exact", node: parameter, path: parameterPath, role: "name" });
31
+ });
32
+ writer.mapped(")", { mappingKind: "anchor", node: declaration });
33
+ writer.synthetic(": ", "return type separator", [declaration]);
34
+ writer.mapped(emitScalarType("php", declaration.returnType), {
35
+ mappingKind: "exact",
36
+ node: declaration.returnType,
37
+ path: `/functions/${functionIndex}/returnType`,
38
+ role: "type"
39
+ });
40
+ writer.synthetic("\n", "line break", [declaration]);
41
+ writer.mapped("{", { mappingKind: "anchor", node: declaration });
42
+ writer.synthetic("\n", "line break", [declaration]);
43
+ emitBlock(writer, declaration.body, " ", `/functions/${functionIndex}/body`);
44
+ writer.mapped("}", { mappingKind: "anchor", node: declaration });
45
+ });
46
+ writer.synthetic("\n\n", "entry-point separator", [module.entryPoint]);
47
+ emitBlock(writer, module.entryPoint.body, "", "/entryPoint/body");
48
+ }
49
+ /**
50
+ * Emits one ordered PHP block body.
51
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
52
+ * @param {import("../semantic/types.js").Block} block - Semantic block.
53
+ * @param {string} indent - Indentation.
54
+ * @param {string} path - Exact block path.
55
+ * @returns {void}
56
+ */
57
+ function emitBlock(writer, block, indent, path) {
58
+ block.statements.forEach((statement, index) => emitStatement(writer, statement, indent, `${path}/statements/${index}`));
59
+ }
60
+ /**
61
+ * Emits one PHP statement.
62
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
63
+ * @param {import("../semantic/types.js").Statement} statement - Semantic statement.
64
+ * @param {string} indent - Indentation.
65
+ * @param {string} path - Exact statement path.
66
+ * @returns {void}
67
+ */
68
+ function emitStatement(writer, statement, indent, path) {
69
+ if (statement.kind == "LocalDeclaration" || statement.kind == "AssignmentStatement")
70
+ return emitLocal(writer, statement, indent, path);
71
+ writer.synthetic(indent, "indentation", [statement], [path]);
72
+ if (statement.kind == "ReturnStatement") {
73
+ writer.mapped("return", { mappingKind: "anchor", node: statement, path });
74
+ writer.synthetic(" ", "return spacing", [statement], [path]);
75
+ emitExpression(writer, statement.expression, `${path}/expression`, "php", phpIdentifier);
76
+ writer.mapped(";", { mappingKind: "anchor", node: statement, path });
77
+ writer.synthetic("\n", "line break", [statement], [path]);
78
+ return;
79
+ }
80
+ if (statement.kind == "PrintStatement") {
81
+ writer.mapped("echo", { mappingKind: "anchor", node: statement, path });
82
+ writer.synthetic(" ", "print spacing", [statement], [path]);
83
+ emitExpression(writer, statement.expression, `${path}/expression`, "php", phpIdentifier);
84
+ writer.synthetic(", ", "PHP print separator", [statement], [path]);
85
+ writer.mapped("PHP_EOL", { mappingKind: "anchor", node: statement, path });
86
+ writer.mapped(";", { mappingKind: "anchor", node: statement, path });
87
+ writer.synthetic("\n", "line break", [statement], [path]);
88
+ return;
89
+ }
90
+ writer.mapped("if", { mappingKind: "anchor", node: statement, path });
91
+ writer.synthetic(" ", "conditional spacing", [statement], [path]);
92
+ writer.mapped("(", { mappingKind: "anchor", node: statement, path });
93
+ emitExpression(writer, statement.condition, `${path}/condition`, "php", phpIdentifier);
94
+ writer.mapped(")", { mappingKind: "anchor", node: statement, path });
95
+ writer.synthetic(" ", "conditional spacing", [statement], [path]);
96
+ writer.mapped("{", { mappingKind: "anchor", node: statement.consequent, path: `${path}/consequent` });
97
+ writer.synthetic("\n", "line break", [statement], [path]);
98
+ emitBlock(writer, statement.consequent, `${indent} `, `${path}/consequent`);
99
+ writer.synthetic(indent, "indentation", [statement], [path]);
100
+ writer.mapped("}", { mappingKind: "anchor", node: statement.consequent, path: `${path}/consequent` });
101
+ if (statement.alternate) {
102
+ writer.synthetic(" ", "conditional spacing", [statement], [path]);
103
+ writer.mapped("else", { mappingKind: "anchor", node: statement, path });
104
+ writer.synthetic(" ", "conditional spacing", [statement], [path]);
105
+ writer.mapped("{", { mappingKind: "anchor", node: statement.alternate, path: `${path}/alternate` });
106
+ writer.synthetic("\n", "line break", [statement], [path]);
107
+ emitBlock(writer, statement.alternate, `${indent} `, `${path}/alternate`);
108
+ writer.synthetic(indent, "indentation", [statement], [path]);
109
+ writer.mapped("}", { mappingKind: "anchor", node: statement.alternate, path: `${path}/alternate` });
110
+ }
111
+ writer.synthetic("\n", "line break", [statement], [path]);
112
+ }
113
+ /**
114
+ * Emits one PHP local statement with its exact Semantifold profile metadata.
115
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
116
+ * @param {import("../semantic/types.js").LocalStatement} statement - Local statement.
117
+ * @param {string} indent - Leading indentation.
118
+ * @param {string} statementPath - Exact JSON Pointer for this statement occurrence.
119
+ * @returns {void}
120
+ */
121
+ function emitLocal(writer, statement, indent, statementPath) {
122
+ writer.synthetic(indent, "indentation", [statement], [statementPath]);
123
+ if (statement.kind == "AssignmentStatement") {
124
+ writer.mapped(`$${statement.target.name}`, { mappingKind: "exact", node: statement.target, path: `${statementPath}/target`, role: "name" });
125
+ writer.synthetic(" ", "assignment spacing", [statement], [statementPath]);
126
+ writer.mapped("=", { mappingKind: "exact", node: statement, path: statementPath, role: "operator" });
127
+ writer.synthetic(" ", "assignment spacing", [statement], [statementPath]);
128
+ emitExpression(writer, statement.expression, `${statementPath}/expression`, "php", phpIdentifier);
129
+ writer.mapped(";", { mappingKind: "anchor", node: statement, path: statementPath });
130
+ writer.synthetic("\n", "line break", [statement], [statementPath]);
131
+ return;
132
+ }
133
+ if (statement.mutable) {
134
+ writer.synthetic("/** @var ", "PHP local type scaffolding", [statement], [statementPath]);
135
+ writer.mapped(emitScalarType("php", statement.type), {
136
+ mappingKind: "exact",
137
+ node: statement.type,
138
+ path: `${statementPath}/type`,
139
+ role: "type"
140
+ });
141
+ writer.synthetic(" ", "PHP local type scaffolding", [statement], [statementPath]);
142
+ writer.mapped(`$${statement.name}`, { mappingKind: "exact", node: statement, path: statementPath, role: "name" });
143
+ writer.synthetic(" */\n", "PHP local type scaffolding", [statement], [statementPath]);
144
+ }
145
+ else {
146
+ writer.synthetic("/**\n", "PHP local type scaffolding", [statement], [statementPath]);
147
+ writer.synthetic(`${indent} * @var `, "PHP local type scaffolding", [statement], [statementPath]);
148
+ writer.mapped(emitScalarType("php", statement.type), {
149
+ mappingKind: "exact",
150
+ node: statement.type,
151
+ path: `${statementPath}/type`,
152
+ role: "type"
153
+ });
154
+ writer.synthetic(" ", "PHP local type scaffolding", [statement], [statementPath]);
155
+ writer.mapped(`$${statement.name}`, { mappingKind: "exact", node: statement, path: statementPath, role: "name" });
156
+ writer.synthetic(`\n${indent} * @semantifold-immutable\n${indent} */\n`, "PHP local type scaffolding", [statement], [statementPath]);
157
+ }
158
+ writer.synthetic(indent, "indentation", [statement], [statementPath]);
159
+ writer.mapped(`$${statement.name}`, { mappingKind: "exact", node: statement, path: statementPath, role: "name" });
160
+ writer.synthetic(" ", "assignment spacing", [statement], [statementPath]);
161
+ writer.mapped("=", { mappingKind: "exact", node: statement, path: statementPath, role: "operator" });
162
+ writer.synthetic(" ", "assignment spacing", [statement], [statementPath]);
163
+ emitExpression(writer, statement.initializer, `${statementPath}/initializer`, "php", phpIdentifier);
164
+ writer.mapped(";", { mappingKind: "anchor", node: statement, path: statementPath });
165
+ writer.synthetic("\n", "line break", [statement], [statementPath]);
166
+ }
167
+ /**
168
+ * Formats one PHP variable identifier.
169
+ * @param {string} name - Semantic identifier.
170
+ * @returns {string} PHP identifier.
171
+ */
172
+ function phpIdentifier(name) {
173
+ return `$${name}`;
174
+ }
175
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGhwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2JhY2tlbmRzL3BocC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLGFBQWEsQ0FBQTtBQUMxQyxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sY0FBYyxDQUFBO0FBRTNDOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBQyxNQUFNLEVBQUUsTUFBTTtJQUN4QyxNQUFNLENBQUMsU0FBUyxDQUFDLHFDQUFxQyxFQUFFLHlCQUF5QixFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtJQUU1RixNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsRUFBRTtRQUN0RCxJQUFJLGFBQWEsR0FBRyxDQUFDO1lBQUUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFBO1FBRXZGLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLEVBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFDLENBQUMsQ0FBQTtRQUNyRSxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUE7UUFDeEQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLEVBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUMsQ0FBQyxDQUFBO1FBQ3hGLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLEVBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFDLENBQUMsQ0FBQTtRQUM5RCxXQUFXLENBQUMsVUFBVSxDQUFDLE9B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LENBQUE7SUFDakUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsRUFBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQTtJQUNsRSxjQUFjLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxTQUFTLEVBQUUsR0FBRyxJQUFJLFlBQVksRUFBRSxLQUFLLEVBQUUsYUFBYSxDQUFDLENBQUE7SUFDdEYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsRUFBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQTtJQUNsRSxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxxQkFBcUIsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtJQUNqRSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLEdBQUcsSUFBSSxhQUFhLEVBQUMsQ0FBQyxDQUFBO0lBQ25HLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtJQUN6RCxTQUFTLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxVQUFVLEVBQUUsR0FBRyxNQUFNLE1BQU0sRUFBRSxHQUFHLElBQUksYUFBYSxDQUFDLENBQUE7SUFDOUUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO0lBQzVELE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLEVBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsU0FBUyxDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsR0FB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QUFXLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFDLENBQUMsQ0FBQTtJQUMvRyxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxvQkFBb0IsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQTtJQUN6RSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUMsQ0FBQyxDQUFBO0lBQ2xHLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLG9CQUFvQixFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFBO0lBQ3pFLGNBQWMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLFdBQVcsRUFBRSxHQUFHLGFBQWEsY0FBYyxFQUFFLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQTtJQUNuRyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFDLENBQUMsQ0FBQTtJQUNqRixNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUE7QUFDcEUsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLGFBQWEsQ0FBQyxJQUFJO0lBQ3pCLE9BQU8sSUFBSSxJQUFJLEVBQUUsQ0FBQTtBQUNuQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7ZW1pdEV4cHJlc3Npb259IGZyb20gXCIuL3NoYXJlZC5qc1wiXG5pbXBvcnQge2VtaXRTY2FsYXJUeXBlfSBmcm9tIFwiLi9zY2FsYXJzLmpzXCJcblxuLyoqXG4gKiBFbWl0cyBhbiBpbmRlcGVuZGVudGx5IGV4ZWN1dGFibGUgUEhQIHByb2dyYW0gdGhyb3VnaCB0aGUgc291cmNlLWF3YXJlIHdyaXRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi93cml0ZXIuanNcIikuU291cmNlV3JpdGVyfSB3cml0ZXIgLSBTb3VyY2UtYXdhcmUgd3JpdGVyLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVBocChtb2R1bGUsIHdyaXRlcikge1xuICB3cml0ZXIuc3ludGhldGljKFwiPD9waHBcXG5kZWNsYXJlKHN0cmljdF90eXBlcz0xKTtcXG5cXG5cIiwgXCJQSFAgcHJvZ3JhbSBzY2FmZm9sZGluZ1wiLCBbbW9kdWxlXSlcblxuICBtb2R1bGUuZnVuY3Rpb25zLmZvckVhY2goKGRlY2xhcmF0aW9uLCBmdW5jdGlvbkluZGV4KSA9PiB7XG4gICAgaWYgKGZ1bmN0aW9uSW5kZXggPiAwKSB3cml0ZXIuc3ludGhldGljKFwiXFxuXFxuXCIsIFwiZGVjbGFyYXRpb24gc2VwYXJhdG9yXCIsIFtkZWNsYXJhdGlvbl0pXG5cbiAgICB3cml0ZXIubWFwcGVkKFwiZnVuY3Rpb25cIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBkZWNsYXJhdGlvbn0pXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhcIiBcIiwgXCJmdW5jdGlvbiBzcGFjaW5nXCIsIFtkZWNsYXJhdGlvbl0pXG4gICAgd3JpdGVyLm1hcHBlZChkZWNsYXJhdGlvbi5uYW1lLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZGVjbGFyYXRpb24sIHJvbGU6IFwibmFtZVwifSlcbiAgICB3cml0ZXIubWFwcGVkKFwiKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGRlY2xhcmF0aW9ufSlcbiAgICBkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLmZvckVhY2goKHBhcmFtZXRlciwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtZXRlclBhdGggPSBgL2Z1bmN0aW9ucy8ke2Z1bmN0aW9uSW5kZXh9L3BhcmFtZXRlcnMvJHtpbmRleH1gXG5cbiAgICAgIGlmIChpbmRleCA+IDApIHdyaXRlci5zeW50aGV0aWMoXCIsIFwiLCBcInBhcmFtZXRlciBzZXBhcmF0b3JcIiwgW2RlY2xhcmF0aW9uXSlcbiAgICAgIHdyaXRlci5tYXBwZWQoZW1pdFNjYWxhclR5cGUoXCJwaHBcIiwgcGFyYW1ldGVyLnR5cGUpLCB7XG4gICAgICAgIG1hcHBpbmdLaW5kOiBcImV4YWN0XCIsXG4gICAgICAgIG5vZGU6IHBhcmFtZXRlci50eXBlLFxuICAgICAgICBwYXRoOiBgJHtwYXJhbWV0ZXJQYXRofS90eXBlYCxcbiAgICAgICAgcm9sZTogXCJ0eXBlXCJcbiAgICAgIH0pXG4gICAgICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcInBhcmFtZXRlciBzcGFjaW5nXCIsIFtwYXJhbWV0ZXJdLCBbcGFyYW1ldGVyUGF0aF0pXG4gICAgICB3cml0ZXIubWFwcGVkKGAkJHtwYXJhbWV0ZXIubmFtZX1gLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogcGFyYW1ldGVyLCBwYXRoOiBwYXJhbWV0ZXJQYXRoLCByb2xlOiBcIm5hbWVcIn0pXG4gICAgfSlcbiAgICB3cml0ZXIubWFwcGVkKFwiKVwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGRlY2xhcmF0aW9ufSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiOiBcIiwgXCJyZXR1cm4gdHlwZSBzZXBhcmF0b3JcIiwgW2RlY2xhcmF0aW9uXSlcbiAgICB3cml0ZXIubWFwcGVkKGVtaXRTY2FsYXJUeXBlKFwicGhwXCIsIGRlY2xhcmF0aW9uLnJldHVyblR5cGUpLCB7XG4gICAgICBtYXBwaW5nS2luZDogXCJleGFjdFwiLFxuICAgICAgbm9kZTogZGVjbGFyYXRpb24ucmV0dXJuVHlwZSxcbiAgICAgIHBhdGg6IGAvZnVuY3Rpb25zLyR7ZnVuY3Rpb25JbmRleH0vcmV0dXJuVHlwZWAsXG4gICAgICByb2xlOiBcInR5cGVcIlxuICAgIH0pXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhcIlxcblwiLCBcImxpbmUgYnJlYWtcIiwgW2RlY2xhcmF0aW9uXSlcbiAgICB3cml0ZXIubWFwcGVkKFwie1wiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGRlY2xhcmF0aW9ufSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiXFxuXCIsIFwibGluZSBicmVha1wiLCBbZGVjbGFyYXRpb25dKVxuXG4gICAgZW1pdEJsb2NrKHdyaXRlciwgZGVjbGFyYXRpb24uYm9keSwgXCIgICAgXCIsIGAvZnVuY3Rpb25zLyR7ZnVuY3Rpb25JbmRleH0vYm9keWApXG4gICAgd3JpdGVyLm1hcHBlZChcIn1cIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBkZWNsYXJhdGlvbn0pXG4gIH0pXG5cbiAgd3JpdGVyLnN5bnRoZXRpYyhcIlxcblxcblwiLCBcImVudHJ5LXBvaW50IHNlcGFyYXRvclwiLCBbbW9kdWxlLmVudHJ5UG9pbnRdKVxuICBlbWl0QmxvY2sod3JpdGVyLCBtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBcIlwiLCBcIi9lbnRyeVBvaW50L2JvZHlcIilcbn1cblxuLyoqXG4gKiBFbWl0cyBvbmUgb3JkZXJlZCBQSFAgYmxvY2sgYm9keS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi93cml0ZXIuanNcIikuU291cmNlV3JpdGVyfSB3cml0ZXIgLSBTb3VyY2UtYXdhcmUgd3JpdGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBTZW1hbnRpYyBibG9jay5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbmRlbnQgLSBJbmRlbnRhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gRXhhY3QgYmxvY2sgcGF0aC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBlbWl0QmxvY2sod3JpdGVyLCBibG9jaywgaW5kZW50LCBwYXRoKSB7XG4gIGJsb2NrLnN0YXRlbWVudHMuZm9yRWFjaCgoc3RhdGVtZW50LCBpbmRleCkgPT4gZW1pdFN0YXRlbWVudCh3cml0ZXIsIHN0YXRlbWVudCwgaW5kZW50LCBgJHtwYXRofS9zdGF0ZW1lbnRzLyR7aW5kZXh9YCkpXG59XG5cbi8qKlxuICogRW1pdHMgb25lIFBIUCBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIC0gU291cmNlLWF3YXJlIHdyaXRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU3RhdGVtZW50fSBzdGF0ZW1lbnQgLSBTZW1hbnRpYyBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5kZW50IC0gSW5kZW50YXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIEV4YWN0IHN0YXRlbWVudCBwYXRoLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIGVtaXRTdGF0ZW1lbnQod3JpdGVyLCBzdGF0ZW1lbnQsIGluZGVudCwgcGF0aCkge1xuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJBc3NpZ25tZW50U3RhdGVtZW50XCIpIHJldHVybiBlbWl0TG9jYWwod3JpdGVyLCBzdGF0ZW1lbnQsIGluZGVudCwgcGF0aClcbiAgd3JpdGVyLnN5bnRoZXRpYyhpbmRlbnQsIFwiaW5kZW50YXRpb25cIiwgW3N0YXRlbWVudF0sIFtwYXRoXSlcbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIpIHtcbiAgICB3cml0ZXIubWFwcGVkKFwicmV0dXJuXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogc3RhdGVtZW50LCBwYXRofSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcInJldHVybiBzcGFjaW5nXCIsIFtzdGF0ZW1lbnRdLCBbcGF0aF0pXG4gICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgYCR7cGF0aH0vZXhwcmVzc2lvbmAsIFwicGhwXCIsIHBocElkZW50aWZpZXIpXG4gICAgd3JpdGVyLm1hcHBlZChcIjtcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBzdGF0ZW1lbnQsIHBhdGh9KVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCJcXG5cIiwgXCJsaW5lIGJyZWFrXCIsIFtzdGF0ZW1lbnRdLCBbcGF0aF0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgIHdyaXRlci5tYXBwZWQoXCJlY2hvXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogc3RhdGVtZW50LCBwYXRofSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcInByaW50IHNwYWNpbmdcIiwgW3N0YXRlbWVudF0sIFtwYXRoXSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIHN0YXRlbWVudC5leHByZXNzaW9uLCBgJHtwYXRofS9leHByZXNzaW9uYCwgXCJwaHBcIiwgcGhwSWRlbnRpZmllcilcbiAgICB3cml0ZXIuc3ludGhldGljKFwiLCBcIiwgXCJQSFAgcHJpbnQgc2VwYXJhdG9yXCIsIFtzdGF0ZW1lbnRdLCBbcGF0aF0pXG4gICAgd3JpdGVyLm1hcHBlZChcIlBIUF9FT0xcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBzdGF0ZW1lbnQsIHBhdGh9KVxuICAgIHdyaXRlci5tYXBwZWQoXCI7XCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogc3RhdGVtZW50LCBwYXRofSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiXFxuXCIsIFwibGluZSBicmVha1wiLCBbc3RhdGVtZW50XSwgW3BhdGhdKVxuICAgIHJldHVyblxuICB9XG4gIHdyaXRlci5tYXBwZWQoXCJpZlwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IHN0YXRlbWVudCwgcGF0aH0pXG4gIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwiY29uZGl0aW9uYWwgc3BhY2luZ1wiLCBbc3RhdGVtZW50XSwgW3BhdGhdKVxuICB3cml0ZXIubWFwcGVkKFwiKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IHN0YXRlbWVudCwgcGF0aH0pXG4gIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgc3RhdGVtZW50LmNvbmRpdGlvbiwgYCR7cGF0aH0vY29uZGl0aW9uYCwgXCJwaHBcIiwgcGhwSWRlbnRpZmllcilcbiAgd3JpdGVyLm1hcHBlZChcIilcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBzdGF0ZW1lbnQsIHBhdGh9KVxuICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcImNvbmRpdGlvbmFsIHNwYWNpbmdcIiwgW3N0YXRlbWVudF0sIFtwYXRoXSlcbiAgd3JpdGVyLm1hcHBlZChcIntcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBzdGF0ZW1lbnQuY29uc2VxdWVudCwgcGF0aDogYCR7cGF0aH0vY29uc2VxdWVudGB9KVxuICB3cml0ZXIuc3ludGhldGljKFwiXFxuXCIsIFwibGluZSBicmVha1wiLCBbc3RhdGVtZW50XSwgW3BhdGhdKVxuICBlbWl0QmxvY2sod3JpdGVyLCBzdGF0ZW1lbnQuY29uc2VxdWVudCwgYCR7aW5kZW50fSAgICBgLCBgJHtwYXRofS9jb25zZXF1ZW50YClcbiAgd3JpdGVyLnN5bnRoZXRpYyhpbmRlbnQsIFwiaW5kZW50YXRpb25cIiwgW3N0YXRlbWVudF0sIFtwYXRoXSlcbiAgd3JpdGVyLm1hcHBlZChcIn1cIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBzdGF0ZW1lbnQuY29uc2VxdWVudCwgcGF0aDogYCR7cGF0aH0vY29uc2VxdWVudGB9KVxuICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkge1xuICAgIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwiY29uZGl0aW9uYWwgc3BhY2luZ1wiLCBbc3RhdGVtZW50XSwgW3BhdGhdKVxuICAgIHdyaXRlci5tYXBwZWQoXCJlbHNlXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogc3RhdGVtZW50LCBwYXRofSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcImNvbmRpdGlvbmFsIHNwYWNpbmdcIiwgW3N0YXRlbWVudF0sIFtwYXRoXSlcbiAgICB3cml0ZXIubWFwcGVkKFwie1wiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IHN0YXRlbWVudC5hbHRlcm5hdGUsIHBhdGg6IGAke3BhdGh9L2FsdGVybmF0ZWB9KVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCJcXG5cIiwgXCJsaW5lIGJyZWFrXCIsIFtzdGF0ZW1lbnRdLCBbcGF0aF0pXG4gICAgZW1pdEJsb2NrKHdyaXRlciwgc3RhdGVtZW50LmFsdGVybmF0ZSwgYCR7aW5kZW50fSAgICBgLCBgJHtwYXRofS9hbHRlcm5hdGVgKVxuICAgIHdyaXRlci5zeW50aGV0aWMoaW5kZW50LCBcImluZGVudGF0aW9uXCIsIFtzdGF0ZW1lbnRdLCBbcGF0aF0pXG4gICAgd3JpdGVyLm1hcHBlZChcIn1cIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBzdGF0ZW1lbnQuYWx0ZXJuYXRlLCBwYXRoOiBgJHtwYXRofS9hbHRlcm5hdGVgfSlcbiAgfVxuICB3cml0ZXIuc3ludGhldGljKFwiXFxuXCIsIFwibGluZSBicmVha1wiLCBbc3RhdGVtZW50XSwgW3BhdGhdKVxufVxuXG4vKipcbiAqIEVtaXRzIG9uZSBQSFAgbG9jYWwgc3RhdGVtZW50IHdpdGggaXRzIGV4YWN0IFNlbWFudGlmb2xkIHByb2ZpbGUgbWV0YWRhdGEuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIC0gU291cmNlLWF3YXJlIHdyaXRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTG9jYWxTdGF0ZW1lbnR9IHN0YXRlbWVudCAtIExvY2FsIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbmRlbnQgLSBMZWFkaW5nIGluZGVudGF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHN0YXRlbWVudFBhdGggLSBFeGFjdCBKU09OIFBvaW50ZXIgZm9yIHRoaXMgc3RhdGVtZW50IG9jY3VycmVuY2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gZW1pdExvY2FsKHdyaXRlciwgc3RhdGVtZW50LCBpbmRlbnQsIHN0YXRlbWVudFBhdGgpIHtcbiAgd3JpdGVyLnN5bnRoZXRpYyhpbmRlbnQsIFwiaW5kZW50YXRpb25cIiwgW3N0YXRlbWVudF0sIFtzdGF0ZW1lbnRQYXRoXSlcblxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJBc3NpZ25tZW50U3RhdGVtZW50XCIpIHtcbiAgICB3cml0ZXIubWFwcGVkKGAkJHtzdGF0ZW1lbnQudGFyZ2V0Lm5hbWV9YCwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IHN0YXRlbWVudC50YXJnZXQsIHBhdGg6IGAke3N0YXRlbWVudFBhdGh9L3RhcmdldGAsIHJvbGU6IFwibmFtZVwifSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcImFzc2lnbm1lbnQgc3BhY2luZ1wiLCBbc3RhdGVtZW50XSwgW3N0YXRlbWVudFBhdGhdKVxuICAgIHdyaXRlci5tYXBwZWQoXCI9XCIsIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBzdGF0ZW1lbnQsIHBhdGg6IHN0YXRlbWVudFBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIn0pXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhcIiBcIiwgXCJhc3NpZ25tZW50IHNwYWNpbmdcIiwgW3N0YXRlbWVudF0sIFtzdGF0ZW1lbnRQYXRoXSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIHN0YXRlbWVudC5leHByZXNzaW9uLCBgJHtzdGF0ZW1lbnRQYXRofS9leHByZXNzaW9uYCwgXCJwaHBcIiwgcGhwSWRlbnRpZmllcilcbiAgICB3cml0ZXIubWFwcGVkKFwiO1wiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IHN0YXRlbWVudCwgcGF0aDogc3RhdGVtZW50UGF0aH0pXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhcIlxcblwiLCBcImxpbmUgYnJlYWtcIiwgW3N0YXRlbWVudF0sIFtzdGF0ZW1lbnRQYXRoXSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChzdGF0ZW1lbnQubXV0YWJsZSkge1xuICAgIHdyaXRlci5zeW50aGV0aWMoXCIvKiogQHZhciBcIiwgXCJQSFAgbG9jYWwgdHlwZSBzY2FmZm9sZGluZ1wiLCBbc3RhdGVtZW50XSwgW3N0YXRlbWVudFBhdGhdKVxuICAgIHdyaXRlci5tYXBwZWQoZW1pdFNjYWxhclR5cGUoXCJwaHBcIiwgc3RhdGVtZW50LnR5cGUpLCB7XG4gICAgICBtYXBwaW5nS2luZDogXCJleGFjdFwiLFxuICAgICAgbm9kZTogc3RhdGVtZW50LnR5cGUsXG4gICAgICBwYXRoOiBgJHtzdGF0ZW1lbnRQYXRofS90eXBlYCxcbiAgICAgIHJvbGU6IFwidHlwZVwiXG4gICAgfSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcIlBIUCBsb2NhbCB0eXBlIHNjYWZmb2xkaW5nXCIsIFtzdGF0ZW1lbnRdLCBbc3RhdGVtZW50UGF0aF0pXG4gICAgd3JpdGVyLm1hcHBlZChgJCR7c3RhdGVtZW50Lm5hbWV9YCwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IHN0YXRlbWVudCwgcGF0aDogc3RhdGVtZW50UGF0aCwgcm9sZTogXCJuYW1lXCJ9KVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCIgKi9cXG5cIiwgXCJQSFAgbG9jYWwgdHlwZSBzY2FmZm9sZGluZ1wiLCBbc3RhdGVtZW50XSwgW3N0YXRlbWVudFBhdGhdKVxuICB9IGVsc2Uge1xuICAgIHdyaXRlci5zeW50aGV0aWMoXCIvKipcXG5cIiwgXCJQSFAgbG9jYWwgdHlwZSBzY2FmZm9sZGluZ1wiLCBbc3RhdGVtZW50XSwgW3N0YXRlbWVudFBhdGhdKVxuICAgIHdyaXRlci5zeW50aGV0aWMoYCR7aW5kZW50fSAqIEB2YXIgYCwgXCJQSFAgbG9jYWwgdHlwZSBzY2FmZm9sZGluZ1wiLCBbc3RhdGVtZW50XSwgW3N0YXRlbWVudFBhdGhdKVxuICAgIHdyaXRlci5tYXBwZWQoZW1pdFNjYWxhclR5cGUoXCJwaHBcIiwgc3RhdGVtZW50LnR5cGUpLCB7XG4gICAgICBtYXBwaW5nS2luZDogXCJleGFjdFwiLFxuICAgICAgbm9kZTogc3RhdGVtZW50LnR5cGUsXG4gICAgICBwYXRoOiBgJHtzdGF0ZW1lbnRQYXRofS90eXBlYCxcbiAgICAgIHJvbGU6IFwidHlwZVwiXG4gICAgfSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcIlBIUCBsb2NhbCB0eXBlIHNjYWZmb2xkaW5nXCIsIFtzdGF0ZW1lbnRdLCBbc3RhdGVtZW50UGF0aF0pXG4gICAgd3JpdGVyLm1hcHBlZChgJCR7c3RhdGVtZW50Lm5hbWV9YCwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IHN0YXRlbWVudCwgcGF0aDogc3RhdGVtZW50UGF0aCwgcm9sZTogXCJuYW1lXCJ9KVxuICAgIHdyaXRlci5zeW50aGV0aWMoYFxcbiR7aW5kZW50fSAqIEBzZW1hbnRpZm9sZC1pbW11dGFibGVcXG4ke2luZGVudH0gKi9cXG5gLCBcIlBIUCBsb2NhbCB0eXBlIHNjYWZmb2xkaW5nXCIsIFtzdGF0ZW1lbnRdLCBbc3RhdGVtZW50UGF0aF0pXG4gIH1cblxuICB3cml0ZXIuc3ludGhldGljKGluZGVudCwgXCJpbmRlbnRhdGlvblwiLCBbc3RhdGVtZW50XSwgW3N0YXRlbWVudFBhdGhdKVxuICB3cml0ZXIubWFwcGVkKGAkJHtzdGF0ZW1lbnQubmFtZX1gLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogc3RhdGVtZW50LCBwYXRoOiBzdGF0ZW1lbnRQYXRoLCByb2xlOiBcIm5hbWVcIn0pXG4gIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwiYXNzaWdubWVudCBzcGFjaW5nXCIsIFtzdGF0ZW1lbnRdLCBbc3RhdGVtZW50UGF0aF0pXG4gIHdyaXRlci5tYXBwZWQoXCI9XCIsIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBzdGF0ZW1lbnQsIHBhdGg6IHN0YXRlbWVudFBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIn0pXG4gIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwiYXNzaWdubWVudCBzcGFjaW5nXCIsIFtzdGF0ZW1lbnRdLCBbc3RhdGVtZW50UGF0aF0pXG4gIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgc3RhdGVtZW50LmluaXRpYWxpemVyLCBgJHtzdGF0ZW1lbnRQYXRofS9pbml0aWFsaXplcmAsIFwicGhwXCIsIHBocElkZW50aWZpZXIpXG4gIHdyaXRlci5tYXBwZWQoXCI7XCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogc3RhdGVtZW50LCBwYXRoOiBzdGF0ZW1lbnRQYXRofSlcbiAgd3JpdGVyLnN5bnRoZXRpYyhcIlxcblwiLCBcImxpbmUgYnJlYWtcIiwgW3N0YXRlbWVudF0sIFtzdGF0ZW1lbnRQYXRoXSlcbn1cblxuLyoqXG4gKiBGb3JtYXRzIG9uZSBQSFAgdmFyaWFibGUgaWRlbnRpZmllci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gU2VtYW50aWMgaWRlbnRpZmllci5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFBIUCBpZGVudGlmaWVyLlxuICovXG5mdW5jdGlvbiBwaHBJZGVudGlmaWVyKG5hbWUpIHtcbiAgcmV0dXJuIGAkJHtuYW1lfWBcbn1cbiJdfQ==
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Emits an independently executable Ruby program through the source-aware writer.
3
+ * @param {import("../semantic/types.js").SemanticModule} module - Semantic module.
4
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
5
+ * @returns {void}
6
+ */
7
+ export declare function generateRuby(module: import("../semantic/types.js").SemanticModule, writer: import("./writer.js").SourceWriter): void;
8
+ //# sourceMappingURL=ruby.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ruby.d.ts","sourceRoot":"","sources":["../../../src/backends/ruby.js"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAJxB,OAAO,sBAAsB,EAAE,cAIP,EAAE,MAAM,EAHhC,OAAO,aAAa,EAAE,YAGU,GAF9B,IAAI,CAkDhB"}
@@ -0,0 +1,155 @@
1
+ // @ts-check
2
+ import { emitExpression } from "./shared.js";
3
+ import { emitScalarType } from "./scalars.js";
4
+ /**
5
+ * Emits an independently executable Ruby program through the source-aware writer.
6
+ * @param {import("../semantic/types.js").SemanticModule} module - Semantic module.
7
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
8
+ * @returns {void}
9
+ */
10
+ export function generateRuby(module, writer) {
11
+ module.functions.forEach((declaration, functionIndex) => {
12
+ if (functionIndex > 0)
13
+ writer.synthetic("\n\n", "declaration separator", [declaration]);
14
+ for (const [parameterIndex, parameter] of declaration.parameters.entries()) {
15
+ const parameterPath = `/functions/${functionIndex}/parameters/${parameterIndex}`;
16
+ writer.synthetic("# @param ", "Ruby type scaffolding", [parameter], [parameterPath]);
17
+ writer.mapped(parameter.name, { mappingKind: "exact", node: parameter, path: parameterPath, role: "name" });
18
+ writer.synthetic(" [", "Ruby type scaffolding", [parameter], [parameterPath]);
19
+ writer.mapped(emitScalarType("ruby", parameter.type), {
20
+ mappingKind: "exact",
21
+ node: parameter.type,
22
+ path: `${parameterPath}/type`,
23
+ role: "type"
24
+ });
25
+ writer.synthetic("]\n", "Ruby type scaffolding", [parameter], [parameterPath]);
26
+ }
27
+ writer.synthetic("# @return [", "Ruby type scaffolding", [declaration]);
28
+ writer.mapped(emitScalarType("ruby", declaration.returnType), {
29
+ mappingKind: "exact",
30
+ node: declaration.returnType,
31
+ path: `/functions/${functionIndex}/returnType`,
32
+ role: "type"
33
+ });
34
+ writer.synthetic("]\n", "Ruby type scaffolding", [declaration]);
35
+ writer.mapped("def", { mappingKind: "anchor", node: declaration });
36
+ writer.synthetic(" ", "function spacing", [declaration]);
37
+ writer.mapped(declaration.name, { mappingKind: "exact", node: declaration, role: "name" });
38
+ writer.mapped("(", { mappingKind: "anchor", node: declaration });
39
+ declaration.parameters.forEach((parameter, index) => {
40
+ if (index > 0)
41
+ writer.synthetic(", ", "parameter separator", [declaration]);
42
+ writer.mapped(parameter.name, {
43
+ mappingKind: "exact",
44
+ node: parameter,
45
+ path: `/functions/${functionIndex}/parameters/${index}`,
46
+ role: "name"
47
+ });
48
+ });
49
+ writer.mapped(")", { mappingKind: "anchor", node: declaration });
50
+ writer.synthetic("\n", "line break", [declaration]);
51
+ emitBlock(writer, declaration.body, " ", `/functions/${functionIndex}/body`);
52
+ writer.mapped("end", { mappingKind: "anchor", node: declaration });
53
+ });
54
+ writer.synthetic("\n\n", "entry-point separator", [module.entryPoint]);
55
+ emitBlock(writer, module.entryPoint.body, "", "/entryPoint/body");
56
+ }
57
+ /**
58
+ * Emits one ordered Ruby block body.
59
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
60
+ * @param {import("../semantic/types.js").Block} block - Semantic block.
61
+ * @param {string} indent - Indentation.
62
+ * @param {string} path - Exact block path.
63
+ * @returns {void}
64
+ */
65
+ function emitBlock(writer, block, indent, path) {
66
+ block.statements.forEach((statement, index) => emitStatement(writer, statement, indent, `${path}/statements/${index}`));
67
+ }
68
+ /**
69
+ * Emits one Ruby statement.
70
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
71
+ * @param {import("../semantic/types.js").Statement} statement - Semantic statement.
72
+ * @param {string} indent - Indentation.
73
+ * @param {string} path - Exact statement path.
74
+ * @returns {void}
75
+ */
76
+ function emitStatement(writer, statement, indent, path) {
77
+ if (statement.kind == "LocalDeclaration" || statement.kind == "AssignmentStatement")
78
+ return emitLocal(writer, statement, indent, path);
79
+ writer.synthetic(indent, "indentation", [statement], [path]);
80
+ if (statement.kind == "ReturnStatement") {
81
+ writer.mapped("return", { mappingKind: "anchor", node: statement, path });
82
+ writer.synthetic(" ", "return spacing", [statement], [path]);
83
+ emitExpression(writer, statement.expression, `${path}/expression`, "ruby", identity);
84
+ writer.synthetic("\n", "line break", [statement], [path]);
85
+ return;
86
+ }
87
+ if (statement.kind == "PrintStatement") {
88
+ writer.mapped("puts", { mappingKind: "anchor", node: statement, path });
89
+ writer.synthetic(" ", "print spacing", [statement], [path]);
90
+ emitExpression(writer, statement.expression, `${path}/expression`, "ruby", identity);
91
+ writer.synthetic("\n", "line break", [statement], [path]);
92
+ return;
93
+ }
94
+ writer.mapped("if", { mappingKind: "anchor", node: statement, path });
95
+ writer.synthetic(" ", "conditional spacing", [statement], [path]);
96
+ emitExpression(writer, statement.condition, `${path}/condition`, "ruby", identity);
97
+ writer.synthetic("\n", "line break", [statement], [path]);
98
+ emitBlock(writer, statement.consequent, `${indent} `, `${path}/consequent`);
99
+ if (statement.alternate) {
100
+ writer.synthetic(indent, "indentation", [statement], [path]);
101
+ writer.mapped("else", { mappingKind: "anchor", node: statement, path });
102
+ writer.synthetic("\n", "line break", [statement], [path]);
103
+ emitBlock(writer, statement.alternate, `${indent} `, `${path}/alternate`);
104
+ }
105
+ writer.synthetic(indent, "indentation", [statement], [path]);
106
+ writer.mapped("end", { mappingKind: "anchor", node: statement, path });
107
+ writer.synthetic("\n", "line break", [statement], [path]);
108
+ }
109
+ /**
110
+ * Emits one Ruby local statement with exact Semantifold profile metadata.
111
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
112
+ * @param {import("../semantic/types.js").LocalStatement} statement - Local statement.
113
+ * @param {string} indent - Leading indentation.
114
+ * @param {string} statementPath - Exact JSON Pointer for this statement occurrence.
115
+ * @returns {void}
116
+ */
117
+ function emitLocal(writer, statement, indent, statementPath) {
118
+ writer.synthetic(indent, "indentation", [statement], [statementPath]);
119
+ if (statement.kind == "AssignmentStatement") {
120
+ writer.mapped(statement.target.name, { mappingKind: "exact", node: statement.target, path: `${statementPath}/target`, role: "name" });
121
+ writer.synthetic(" ", "assignment spacing", [statement], [statementPath]);
122
+ writer.mapped("=", { mappingKind: "exact", node: statement, path: statementPath, role: "operator" });
123
+ writer.synthetic(" ", "assignment spacing", [statement], [statementPath]);
124
+ emitExpression(writer, statement.expression, `${statementPath}/expression`, "ruby", identity);
125
+ writer.synthetic("\n", "line break", [statement], [statementPath]);
126
+ return;
127
+ }
128
+ writer.synthetic("# @type [", "Ruby local type scaffolding", [statement], [statementPath]);
129
+ writer.mapped(emitScalarType("ruby", statement.type), {
130
+ mappingKind: "exact",
131
+ node: statement.type,
132
+ path: `${statementPath}/type`,
133
+ role: "type"
134
+ });
135
+ writer.synthetic("]\n", "Ruby local type scaffolding", [statement], [statementPath]);
136
+ if (!statement.mutable) {
137
+ writer.synthetic(`${indent}# @semantifold-immutable\n`, "Ruby immutability scaffolding", [statement], [statementPath]);
138
+ }
139
+ writer.synthetic(indent, "indentation", [statement], [statementPath]);
140
+ writer.mapped(statement.name, { mappingKind: "exact", node: statement, path: statementPath, role: "name" });
141
+ writer.synthetic(" ", "assignment spacing", [statement], [statementPath]);
142
+ writer.mapped("=", { mappingKind: "exact", node: statement, path: statementPath, role: "operator" });
143
+ writer.synthetic(" ", "assignment spacing", [statement], [statementPath]);
144
+ emitExpression(writer, statement.initializer, `${statementPath}/initializer`, "ruby", identity);
145
+ writer.synthetic("\n", "line break", [statement], [statementPath]);
146
+ }
147
+ /**
148
+ * Returns an unchanged Ruby identifier.
149
+ * @param {string} name - Identifier.
150
+ * @returns {string} Identifier.
151
+ */
152
+ function identity(name) {
153
+ return name;
154
+ }
155
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVieS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZW5kcy9ydWJ5LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sYUFBYSxDQUFBO0FBQzFDLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFFM0M7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsWUFBWSxDQUFDLE1BQU0sRUFBRSxNQUFNO0lBQ3pDLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLGFBQWEsRUFBRSxFQUFFO1FBQ3RELElBQUksYUFBYSxHQUFHLENBQUM7WUFBRSxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSx1QkFBdUIsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUE7UUFFdkYsS0FBSyxNQUFNLENBQUMsY0FBYyxFQUFFLFNBQVMsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztZQUMzRSxNQUFNLGFBQWEsR0FBRyxjQUFjLGFBQWEsZUFBZSxjQUFjLEVBQUUsQ0FBQTtZQUVoRixNQUFNLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSx1QkFBdUIsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQTtZQUNwRixNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsRUFBQyxXQUFXLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFDLENBQUMsQ0FBQTtZQUN6RyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSx1QkFBdUIsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQTtZQUM3RSxNQUFNLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUNwRCxXQUFXLEVBQUUsT0FBTztnQkFDcEIsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO2dCQUNwQixJQUFJLEVBQUUsR0FBRyxhQUFhLE9BQU87Z0JBQzdCLElBQUksRUFBRSxNQUFNO2FBQ2IsQ0FBQyxDQUFBO1lBQ0YsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUE7UUFDaEYsQ0FBQztRQUNELE1BQU0sQ0FBQyxTQUFTLENBQUMsYUFBYSxFQUFFLHVCQUF1QixFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQTtRQUN2RSxNQUFNLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1lBQzVELFdBQVcsRUFBRSxPQUFPO1lBQ3BCLElBQUksRUFBRSxXQUFXLENBQUMsVUFBVTtZQUM1QixJQUFJLEVBQUUsY0FBYyxhQUFhLGFBQWE7WUFDOUMsSUFBSSxFQUFFLE1BQU07U0FDYixDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUE7UUFDL0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsRUFBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFBO1FBQ2hFLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLGtCQUFrQixFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQTtRQUN4RCxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBQyxXQUFXLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBQyxDQUFDLENBQUE7UUFDeEYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsRUFBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFBO1FBQzlELFdBQVcsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ2xELElBQUksS0FBSyxHQUFHLENBQUM7Z0JBQUUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUscUJBQXFCLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFBO1lBQzNFLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRTtnQkFDNUIsV0FBVyxFQUFFLE9BQU87Z0JBQ3BCLElBQUksRUFBRSxTQUFTO2dCQUNmLElBQUksRUFBRSxjQUFjLGFBQWEsZUFBZSxLQUFLLEVBQUU7Z0JBQ3ZELElBQUksRUFBRSxNQUFNO2FBQ2IsQ0FBQyxDQUFBO1FBQ0osQ0FBQyxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBQyxDQUFDLENBQUE7UUFDOUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQTtRQUVuRCxTQUFTLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLGNBQWMsYUFBYSxPQUFPLENBQUMsQ0FBQTtRQUM3RSxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxFQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBQyxDQUFDLENBQUE7SUFDbEUsQ0FBQyxDQUFDLENBQUE7SUFFRixNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSx1QkFBdUIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFBO0lBQ3RFLFNBQVMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLGtCQUFrQixDQUFDLENBQUE7QUFDbkUsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFTLFNBQVMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJO0lBQzVDLEtBQUssQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxlQUFlLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQTtBQUN6SCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMsYUFBYSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLElBQUk7SUFDcEQsSUFBSSxTQUFTLENBQUMsSUFBSSxJQUFJLGtCQUFrQixJQUFJLFNBQVMsQ0FBQyxJQUFJLElBQUkscUJBQXFCO1FBQUUsT0FBTyxTQUFTLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUE7SUFDdEksTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO0lBQzVELElBQUksU0FBUyxDQUFDLElBQUksSUFBSSxpQkFBaUIsRUFBRSxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBQyxDQUFDLENBQUE7UUFDdkUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7UUFDNUQsY0FBYyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsVUFBVSxFQUFFLEdBQUcsSUFBSSxhQUFhLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBQ3BGLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtRQUN6RCxPQUFNO0lBQ1IsQ0FBQztJQUNELElBQUksU0FBUyxDQUFDLElBQUksSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBQyxDQUFDLENBQUE7UUFDckUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsZUFBZSxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO1FBQzNELGNBQWMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLFVBQVUsRUFBRSxHQUFHLElBQUksYUFBYSxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQTtRQUNwRixNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7UUFDekQsT0FBTTtJQUNSLENBQUM7SUFDRCxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxFQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBO0lBQ25FLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLHFCQUFxQixFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO0lBQ2pFLGNBQWMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLFNBQVMsRUFBRSxHQUFHLElBQUksWUFBWSxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUNsRixNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7SUFDekQsU0FBUyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsVUFBVSxFQUFFLEdBQUcsTUFBTSxJQUFJLEVBQUUsR0FBRyxJQUFJLGFBQWEsQ0FBQyxDQUFBO0lBQzVFLElBQUksU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ3hCLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtRQUM1RCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBO1FBQ3JFLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtRQUN6RCxTQUFTLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxTQUFTLEVBQUUsR0FBRyxNQUFNLElBQUksRUFBRSxHQUFHLElBQUksWUFBWSxDQUFDLENBQUE7SUFDNUUsQ0FBQztJQUNELE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtJQUM1RCxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxFQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBO0lBQ3BFLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtBQUMzRCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMs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LFNBQVMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUMsQ0FBQyxDQUFBO0lBQ2xHLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLG9CQUFvQixFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFBO0lBQ3pFLGNBQWMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLFdBQVcsRUFBRSxHQUFHLGFBQWEsY0FBYyxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUMvRixNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUE7QUFDcEUsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLFFBQVEsQ0FBQyxJQUFJO0lBQ3BCLE9BQU8sSUFBSSxDQUFBO0FBQ2IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge2VtaXRFeHByZXNzaW9ufSBmcm9tIFwiLi9zaGFyZWQuanNcIlxuaW1wb3J0IHtlbWl0U2NhbGFyVHlwZX0gZnJvbSBcIi4vc2NhbGFycy5qc1wiXG5cbi8qKlxuICogRW1pdHMgYW4gaW5kZXBlbmRlbnRseSBleGVjdXRhYmxlIFJ1YnkgcHJvZ3JhbSB0aHJvdWdoIHRoZSBzb3VyY2UtYXdhcmUgd3JpdGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3dyaXRlci5qc1wiKS5Tb3VyY2VXcml0ZXJ9IHdyaXRlciAtIFNvdXJjZS1hd2FyZSB3cml0ZXIuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlUnVieShtb2R1bGUsIHdyaXRlcikge1xuICBtb2R1bGUuZnVuY3Rpb25zLmZvckVhY2goKGRlY2xhcmF0aW9uLCBmdW5jdGlvbkluZGV4KSA9PiB7XG4gICAgaWYgKGZ1bmN0aW9uSW5kZXggPiAwKSB3cml0ZXIuc3ludGhldGljKFwiXFxuXFxuXCIsIFwiZGVjbGFyYXRpb24gc2VwYXJhdG9yXCIsIFtkZWNsYXJhdGlvbl0pXG5cbiAgICBmb3IgKGNvbnN0IFtwYXJhbWV0ZXJJbmRleCwgcGFyYW1ldGVyXSBvZiBkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLmVudHJpZXMoKSkge1xuICAgICAgY29uc3QgcGFyYW1ldGVyUGF0aCA9IGAvZnVuY3Rpb25zLyR7ZnVuY3Rpb25JbmRleH0vcGFyYW1ldGVycy8ke3BhcmFtZXRlckluZGV4fWBcblxuICAgICAgd3JpdGVyLnN5bnRoZXRpYyhcIiMgQHBhcmFtIFwiLCBcIlJ1YnkgdHlwZSBzY2FmZm9sZGluZ1wiLCBbcGFyYW1ldGVyXSwgW3BhcmFtZXRlclBhdGhdKVxuICAgICAgd3JpdGVyLm1hcHBlZChwYXJhbWV0ZXIubmFtZSwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IHBhcmFtZXRlciwgcGF0aDogcGFyYW1ldGVyUGF0aCwgcm9sZTogXCJuYW1lXCJ9KVxuICAgICAgd3JpdGVyLnN5bnRoZXRpYyhcIiBbXCIsIFwiUnVieSB0eXBlIHNjYWZmb2xkaW5nXCIsIFtwYXJhbWV0ZXJdLCBbcGFyYW1ldGVyUGF0aF0pXG4gICAgICB3cml0ZXIubWFwcGVkKGVtaXRTY2FsYXJUeXBlKFwicnVieVwiLCBwYXJhbWV0ZXIudHlwZSksIHtcbiAgICAgICAgbWFwcGluZ0tpbmQ6IFwiZXhhY3RcIixcbiAgICAgICAgbm9kZTogcGFyYW1ldGVyLnR5cGUsXG4gICAgICAgIHBhdGg6IGAke3BhcmFtZXRlclBhdGh9L3R5cGVgLFxuICAgICAgICByb2xlOiBcInR5cGVcIlxuICAgICAgfSlcbiAgICAgIHdyaXRlci5zeW50aGV0aWMoXCJdXFxuXCIsIFwiUnVieSB0eXBlIHNjYWZmb2xkaW5nXCIsIFtwYXJhbWV0ZXJdLCBbcGFyYW1ldGVyUGF0aF0pXG4gICAgfVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCIjIEByZXR1cm4gW1wiLCBcIlJ1YnkgdHlwZSBzY2FmZm9sZGluZ1wiLCBbZGVjbGFyYXRpb25dKVxuICAgIHdyaXRlci5tYXBwZWQoZW1pdFNjYWxhclR5cGUoXCJydWJ5XCIsIGRlY2xhcmF0aW9uLnJldHVyblR5cGUpLCB7XG4gICAgICBtYXBwaW5nS2luZDogXCJleGFjdFwiLFxuICAgICAgbm9kZTogZGVjbGFyYXRpb24ucmV0dXJuVHlwZSxcbiAgICAgIHBhdGg6IGAvZnVuY3Rpb25zLyR7ZnVuY3Rpb25JbmRleH0vcmV0dXJuVHlwZWAsXG4gICAgICByb2xlOiBcInR5cGVcIlxuICAgIH0pXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhcIl1cXG5cIiwgXCJSdWJ5IHR5cGUgc2NhZmZvbGRpbmdcIiwgW2RlY2xhcmF0aW9uXSlcbiAgICB3cml0ZXIubWFwcGVkKFwiZGVmXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZGVjbGFyYXRpb259KVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwiZnVuY3Rpb24gc3BhY2luZ1wiLCBbZGVjbGFyYXRpb25dKVxuICAgIHdyaXRlci5tYXBwZWQoZGVjbGFyYXRpb24ubmFtZSwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGRlY2xhcmF0aW9uLCByb2xlOiBcIm5hbWVcIn0pXG4gICAgd3JpdGVyLm1hcHBlZChcIihcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBkZWNsYXJhdGlvbn0pXG4gICAgZGVjbGFyYXRpb24ucGFyYW1ldGVycy5mb3JFYWNoKChwYXJhbWV0ZXIsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoaW5kZXggPiAwKSB3cml0ZXIuc3ludGhldGljKFwiLCBcIiwgXCJwYXJhbWV0ZXIgc2VwYXJhdG9yXCIsIFtkZWNsYXJhdGlvbl0pXG4gICAgICB3cml0ZXIubWFwcGVkKHBhcmFtZXRlci5uYW1lLCB7XG4gICAgICAgIG1hcHBpbmdLaW5kOiBcImV4YWN0XCIsXG4gICAgICAgIG5vZGU6IHBhcmFtZXRlcixcbiAgICAgICAgcGF0aDogYC9mdW5jdGlvbnMvJHtmdW5jdGlvbkluZGV4fS9wYXJhbWV0ZXJzLyR7aW5kZXh9YCxcbiAgICAgICAgcm9sZTogXCJuYW1lXCJcbiAgICAgIH0pXG4gICAgfSlcbiAgICB3cml0ZXIubWFwcGVkKFwiKVwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGRlY2xhcmF0aW9ufSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiXFxuXCIsIFwibGluZSBicmVha1wiLCBbZGVjbGFyYXRpb25dKVxuXG4gICAgZW1pdEJsb2NrKHdyaXRlciwgZGVjbGFyYXRpb24uYm9keSwgXCIgIFwiLCBgL2Z1bmN0aW9ucy8ke2Z1bmN0aW9uSW5kZXh9L2JvZHlgKVxuICAgIHdyaXRlci5tYXBwZWQoXCJlbmRcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBkZWNsYXJhdGlvbn0pXG4gIH0pXG5cbiAgd3JpdGVyLnN5bnRoZXRpYyhcIlxcblxcblwiLCBcImVudHJ5LXBvaW50IHNlcGFyYXRvclwiLCBbbW9kdWxlLmVudHJ5UG9pbnRdKVxuICBlbWl0QmxvY2sod3JpdGVyLCBtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBcIlwiLCBcIi9lbnRyeVBvaW50L2JvZHlcIilcbn1cblxuLyoqXG4gKiBFbWl0cyBvbmUgb3JkZXJlZCBSdWJ5IGJsb2NrIGJvZHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIC0gU291cmNlLWF3YXJlIHdyaXRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gU2VtYW50aWMgYmxvY2suXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5kZW50IC0gSW5kZW50YXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIEV4YWN0IGJsb2NrIHBhdGguXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gZW1pdEJsb2NrKHdyaXRlciwgYmxvY2ssIGluZGVudCwgcGF0aCkge1xuICBibG9jay5zdGF0ZW1lbnRzLmZvckVhY2goKHN0YXRlbWVudCwgaW5kZXgpID0+IGVtaXRTdGF0ZW1lbnQod3JpdGVyLCBzdGF0ZW1lbnQsIGluZGVudCwgYCR7cGF0aH0vc3RhdGVtZW50cy8ke2luZGV4fWApKVxufVxuXG4vKipcbiAqIEVtaXRzIG9uZSBSdWJ5IHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi93cml0ZXIuanNcIikuU291cmNlV3JpdGVyfSB3cml0ZXIgLSBTb3VyY2UtYXdhcmUgd3JpdGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdGF0ZW1lbnR9IHN0YXRlbWVudCAtIFNlbWFudGljIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbmRlbnQgLSBJbmRlbnRhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gRXhhY3Qgc3RhdGVtZW50IHBhdGguXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gZW1pdFN0YXRlbWVudCh3cml0ZXIsIHN0YXRlbWVudCwgaW5kZW50LCBwYXRoKSB7XG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIikgcmV0dXJuIGVtaXRMb2NhbCh3cml0ZXIsIHN0YXRlbWVudCwgaW5kZW50LCBwYXRoKVxuICB3cml0ZXIuc3ludGhldGljKGluZGVudCwgXCJpbmRlbnRhdGlvblwiLCBbc3RhdGVtZW50XSwgW3BhdGhdKVxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIikge1xuICAgIHdyaXRlci5tYXBwZWQoXCJyZXR1cm5cIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBzdGF0ZW1lbnQsIHBhdGh9KVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwicmV0dXJuIHNwYWNpbmdcIiwgW3N0YXRlbWVudF0sIFtwYXRoXSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIHN0YXRlbWVudC5leHByZXNzaW9uLCBgJHtwYXRofS9leHByZXNzaW9uYCwgXCJydWJ5XCIsIGlkZW50aXR5KVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCJcXG5cIiwgXCJsaW5lIGJyZWFrXCIsIFtzdGF0ZW1lbnRdLCBbcGF0aF0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgIHdyaXRlci5tYXBwZWQoXCJwdXRzXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogc3RhdGVtZW50LCBwYXRofSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcInByaW50IHNwYWNpbmdcIiwgW3N0YXRlbWVudF0sIFtwYXRoXSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIHN0YXRlbWVudC5leHByZXNzaW9uLCBgJHtwYXRofS9leHByZXNzaW9uYCwgXCJydWJ5XCIsIGlkZW50aXR5KVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCJcXG5cIiwgXCJsaW5lIGJyZWFrXCIsIFtzdGF0ZW1lbnRdLCBbcGF0aF0pXG4gICAgcmV0dXJuXG4gIH1cbiAgd3JpdGVyLm1hcHBlZChcImlmXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogc3RhdGVtZW50LCBwYXRofSlcbiAgd3JpdGVyLnN5bnRoZXRpYyhcIiBcIiwgXCJjb25kaXRpb25hbCBzcGFjaW5nXCIsIFtzdGF0ZW1lbnRdLCBbcGF0aF0pXG4gIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgc3RhdGVtZW50LmNvbmRpdGlvbiwgYCR7cGF0aH0vY29uZGl0aW9uYCwgXCJydWJ5XCIsIGlkZW50aXR5KVxuICB3cml0ZXIuc3ludGhldGljKFwiXFxuXCIsIFwibGluZSBicmVha1wiLCBbc3RhdGVtZW50XSwgW3BhdGhdKVxuICBlbWl0QmxvY2sod3JpdGVyLCBzdGF0ZW1lbnQuY29uc2VxdWVudCwgYCR7aW5kZW50fSAgYCwgYCR7cGF0aH0vY29uc2VxdWVudGApXG4gIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSB7XG4gICAgd3JpdGVyLnN5bnRoZXRpYyhpbmRlbnQsIFwiaW5kZW50YXRpb25cIiwgW3N0YXRlbWVudF0sIFtwYXRoXSlcbiAgICB3cml0ZXIubWFwcGVkKFwiZWxzZVwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IHN0YXRlbWVudCwgcGF0aH0pXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhcIlxcblwiLCBcImxpbmUgYnJlYWtcIiwgW3N0YXRlbWVudF0sIFtwYXRoXSlcbiAgICBlbWl0QmxvY2sod3JpdGVyLCBzdGF0ZW1lbnQuYWx0ZXJuYXRlLCBgJHtpbmRlbnR9ICBgLCBgJHtwYXRofS9hbHRlcm5hdGVgKVxuICB9XG4gIHdyaXRlci5zeW50aGV0aWMoaW5kZW50LCBcImluZGVudGF0aW9uXCIsIFtzdGF0ZW1lbnRdLCBbcGF0aF0pXG4gIHdyaXRlci5tYXBwZWQoXCJlbmRcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBzdGF0ZW1lbnQsIHBhdGh9KVxuICB3cml0ZXIuc3ludGhldGljKFwiXFxuXCIsIFwibGluZSBicmVha1wiLCBbc3RhdGVtZW50XSwgW3BhdGhdKVxufVxuXG4vKipcbiAqIEVtaXRzIG9uZSBSdWJ5IGxvY2FsIHN0YXRlbWVudCB3aXRoIGV4YWN0IFNlbWFudGlmb2xkIHByb2ZpbGUgbWV0YWRhdGEuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIC0gU291cmNlLWF3YXJlIHdyaXRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTG9jYWxTdGF0ZW1lbnR9IHN0YXRlbWVudCAtIExvY2FsIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbmRlbnQgLSBMZWFkaW5nIGluZGVudGF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHN0YXRlbWVudFBhdGggLSBFeGFjdCBKU09OIFBvaW50ZXIgZm9yIHRoaXMgc3RhdGVtZW50IG9jY3VycmVuY2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gZW1pdExvY2FsKHdyaXRlciwgc3RhdGVtZW50LCBpbmRlbnQsIHN0YXRlbWVudFBhdGgpIHtcbiAgd3JpdGVyLnN5bnRoZXRpYyhpbmRlbnQsIFwiaW5kZW50YXRpb25cIiwgW3N0YXRlbWVudF0sIFtzdGF0ZW1lbnRQYXRoXSlcblxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJBc3NpZ25tZW50U3RhdGVtZW50XCIpIHtcbiAgICB3cml0ZXIubWFwcGVkKHN0YXRlbWVudC50YXJnZXQubmFtZSwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IHN0YXRlbWVudC50YXJnZXQsIHBhdGg6IGAke3N0YXRlbWVudFBhdGh9L3RhcmdldGAsIHJvbGU6IFwibmFtZVwifSlcbiAgICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcImFzc2lnbm1lbnQgc3BhY2luZ1wiLCBbc3RhdGVtZW50XSwgW3N0YXRlbWVudFBhdGhdKVxuICAgIHdyaXRlci5tYXBwZWQoXCI9XCIsIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBzdGF0ZW1lbnQsIHBhdGg6IHN0YXRlbWVudFBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIn0pXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhcIiBcIiwgXCJhc3NpZ25tZW50IHNwYWNpbmdcIiwgW3N0YXRlbWVudF0sIFtzdGF0ZW1lbnRQYXRoXSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIHN0YXRlbWVudC5leHByZXNzaW9uLCBgJHtzdGF0ZW1lbnRQYXRofS9leHByZXNzaW9uYCwgXCJydWJ5XCIsIGlkZW50aXR5KVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCJcXG5cIiwgXCJsaW5lIGJyZWFrXCIsIFtzdGF0ZW1lbnRdLCBbc3RhdGVtZW50UGF0aF0pXG4gICAgcmV0dXJuXG4gIH1cblxuICB3cml0ZXIuc3ludGhldGljKFwiIyBAdHlwZSBbXCIsIFwiUnVieSBsb2NhbCB0eXBlIHNjYWZmb2xkaW5nXCIsIFtzdGF0ZW1lbnRdLCBbc3RhdGVtZW50UGF0aF0pXG4gIHdyaXRlci5tYXBwZWQoZW1pdFNjYWxhclR5cGUoXCJydWJ5XCIsIHN0YXRlbWVudC50eXBlKSwge1xuICAgIG1hcHBpbmdLaW5kOiBcImV4YWN0XCIsXG4gICAgbm9kZTogc3RhdGVtZW50LnR5cGUsXG4gICAgcGF0aDogYCR7c3RhdGVtZW50UGF0aH0vdHlwZWAsXG4gICAgcm9sZTogXCJ0eXBlXCJcbiAgfSlcbiAgd3JpdGVyLnN5bnRoZXRpYyhcIl1cXG5cIiwgXCJSdWJ5IGxvY2FsIHR5cGUgc2NhZmZvbGRpbmdcIiwgW3N0YXRlbWVudF0sIFtzdGF0ZW1lbnRQYXRoXSlcbiAgaWYgKCFzdGF0ZW1lbnQubXV0YWJsZSkge1xuICAgIHdyaXRlci5zeW50aGV0aWMoYCR7aW5kZW50fSMgQHNlbWFudGlmb2xkLWltbXV0YWJsZVxcbmAsIFwiUnVieSBpbW11dGFiaWxpdHkgc2NhZmZvbGRpbmdcIiwgW3N0YXRlbWVudF0sIFtzdGF0ZW1lbnRQYXRoXSlcbiAgfVxuICB3cml0ZXIuc3ludGhldGljKGluZGVudCwgXCJpbmRlbnRhdGlvblwiLCBbc3RhdGVtZW50XSwgW3N0YXRlbWVudFBhdGhdKVxuICB3cml0ZXIubWFwcGVkKHN0YXRlbWVudC5uYW1lLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogc3RhdGVtZW50LCBwYXRoOiBzdGF0ZW1lbnRQYXRoLCByb2xlOiBcIm5hbWVcIn0pXG4gIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwiYXNzaWdubWVudCBzcGFjaW5nXCIsIFtzdGF0ZW1lbnRdLCBbc3RhdGVtZW50UGF0aF0pXG4gIHdyaXRlci5tYXBwZWQoXCI9XCIsIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBzdGF0ZW1lbnQsIHBhdGg6IHN0YXRlbWVudFBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIn0pXG4gIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwiYXNzaWdubWVudCBzcGFjaW5nXCIsIFtzdGF0ZW1lbnRdLCBbc3RhdGVtZW50UGF0aF0pXG4gIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgc3RhdGVtZW50LmluaXRpYWxpemVyLCBgJHtzdGF0ZW1lbnRQYXRofS9pbml0aWFsaXplcmAsIFwicnVieVwiLCBpZGVudGl0eSlcbiAgd3JpdGVyLnN5bnRoZXRpYyhcIlxcblwiLCBcImxpbmUgYnJlYWtcIiwgW3N0YXRlbWVudF0sIFtzdGF0ZW1lbnRQYXRoXSlcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIHVuY2hhbmdlZCBSdWJ5IGlkZW50aWZpZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIElkZW50aWZpZXIuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBJZGVudGlmaWVyLlxuICovXG5mdW5jdGlvbiBpZGVudGl0eShuYW1lKSB7XG4gIHJldHVybiBuYW1lXG59XG4iXX0=
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Emits one target-language scalar type spelling.
3
+ * @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
4
+ * @param {import("../semantic/types.js").TypeReference} type - Semantic scalar type.
5
+ * @returns {string} Target type spelling.
6
+ */
7
+ export declare function emitScalarType(language: import("../semantic/types.js").SemanticLanguage, type: import("../semantic/types.js").TypeReference): string;
8
+ /**
9
+ * Emits a safely escaped target-language string literal.
10
+ * @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
11
+ * @param {string} value - Valid Unicode scalar string.
12
+ * @returns {string} Target string literal.
13
+ */
14
+ export declare function emitStringLiteral(language: import("../semantic/types.js").SemanticLanguage, value: string): string;
15
+ //# sourceMappingURL=scalars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scalars.d.ts","sourceRoot":"","sources":["../../../src/backends/scalars.js"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAJ5B,OAAO,sBAAsB,EAAE,gBAIH,EAAE,IAAI,EAHlC,OAAO,sBAAsB,EAAE,aAGG,GAFhC,MAAM,CAIlB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAJ/B,OAAO,sBAAsB,EAAE,gBAIA,EAAE,KAAK,EAHtC,MAGsC,GAFpC,MAAM,CAYlB"}
@@ -0,0 +1,138 @@
1
+ // @ts-check
2
+ /** @type {Readonly<Record<import("../semantic/types.js").SemanticLanguage, Readonly<Record<import("../semantic/types.js").SemanticTypeName, string>>>>} */
3
+ const targetScalarTypes = Object.freeze({
4
+ java: Object.freeze({ boolean: "boolean", integer: "int", string: "String" }),
5
+ javascript: Object.freeze({ boolean: "boolean", integer: "number", string: "string" }),
6
+ php: Object.freeze({ boolean: "bool", integer: "int", string: "string" }),
7
+ ruby: Object.freeze({ boolean: "bool", integer: "Integer", string: "String" }),
8
+ typescript: Object.freeze({ boolean: "boolean", integer: "number", string: "string" })
9
+ });
10
+ /**
11
+ * Emits one target-language scalar type spelling.
12
+ * @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
13
+ * @param {import("../semantic/types.js").TypeReference} type - Semantic scalar type.
14
+ * @returns {string} Target type spelling.
15
+ */
16
+ export function emitScalarType(language, type) {
17
+ return targetScalarTypes[language][type.name];
18
+ }
19
+ /**
20
+ * Emits a safely escaped target-language string literal.
21
+ * @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
22
+ * @param {string} value - Valid Unicode scalar string.
23
+ * @returns {string} Target string literal.
24
+ */
25
+ export function emitStringLiteral(language, value) {
26
+ if (language == "php")
27
+ return emitPhpString(value);
28
+ if (language == "ruby")
29
+ return emitRubyString(value);
30
+ if (language == "java")
31
+ return emitJavaString(value);
32
+ const literal = JSON.stringify(value);
33
+ if (typeof literal != "string")
34
+ throw new TypeError("A validated semantic string did not serialize.");
35
+ return literal.replaceAll("\u2028", "\\u2028").replaceAll("\u2029", "\\u2029");
36
+ }
37
+ /**
38
+ * Emits a PHP double-quoted string while preventing interpolation.
39
+ * @param {string} value - Valid Unicode scalar string.
40
+ * @returns {string} PHP string literal.
41
+ */
42
+ function emitPhpString(value) {
43
+ let emitted = "\"";
44
+ for (const character of value) {
45
+ const codePoint = character.codePointAt(0);
46
+ if (character == "\"")
47
+ emitted += "\\\"";
48
+ else if (character == "\\")
49
+ emitted += "\\\\";
50
+ else if (character == "$")
51
+ emitted += "\\$";
52
+ else if (character == "\n")
53
+ emitted += "\\n";
54
+ else if (character == "\r")
55
+ emitted += "\\r";
56
+ else if (character == "\t")
57
+ emitted += "\\t";
58
+ else if (character == "\f")
59
+ emitted += "\\f";
60
+ else if (character == "\v")
61
+ emitted += "\\v";
62
+ else if (codePoint == 27)
63
+ emitted += "\\e";
64
+ else if (codePoint !== undefined && (codePoint < 32 || codePoint == 127)) {
65
+ emitted += `\\x${codePoint.toString(16).padStart(2, "0")}`;
66
+ }
67
+ else
68
+ emitted += character;
69
+ }
70
+ return `${emitted}"`;
71
+ }
72
+ /**
73
+ * Emits a Ruby double-quoted string while preventing interpolation.
74
+ * @param {string} value - Valid Unicode scalar string.
75
+ * @returns {string} Ruby string literal.
76
+ */
77
+ function emitRubyString(value) {
78
+ let emitted = "\"";
79
+ for (const character of value) {
80
+ const codePoint = character.codePointAt(0);
81
+ if (character == "\"")
82
+ emitted += "\\\"";
83
+ else if (character == "\\")
84
+ emitted += "\\\\";
85
+ else if (character == "#")
86
+ emitted += "\\#";
87
+ else if (character == "\n")
88
+ emitted += "\\n";
89
+ else if (character == "\r")
90
+ emitted += "\\r";
91
+ else if (character == "\t")
92
+ emitted += "\\t";
93
+ else if (character == "\f")
94
+ emitted += "\\f";
95
+ else if (character == "\v")
96
+ emitted += "\\v";
97
+ else if (codePoint == 27)
98
+ emitted += "\\e";
99
+ else if (codePoint !== undefined && (codePoint < 32 || codePoint == 127)) {
100
+ emitted += `\\u{${codePoint.toString(16)}}`;
101
+ }
102
+ else
103
+ emitted += character;
104
+ }
105
+ return `${emitted}"`;
106
+ }
107
+ /**
108
+ * Emits a Java string using standard or fixed-width octal control escapes.
109
+ * @param {string} value - Valid Unicode scalar string.
110
+ * @returns {string} Java string literal.
111
+ */
112
+ function emitJavaString(value) {
113
+ let emitted = "\"";
114
+ for (const character of value) {
115
+ const codePoint = character.codePointAt(0);
116
+ if (character == "\"")
117
+ emitted += "\\\"";
118
+ else if (character == "\\")
119
+ emitted += "\\\\";
120
+ else if (character == "\b")
121
+ emitted += "\\b";
122
+ else if (character == "\t")
123
+ emitted += "\\t";
124
+ else if (character == "\n")
125
+ emitted += "\\n";
126
+ else if (character == "\f")
127
+ emitted += "\\f";
128
+ else if (character == "\r")
129
+ emitted += "\\r";
130
+ else if (codePoint !== undefined && (codePoint < 32 || codePoint == 127)) {
131
+ emitted += `\\${codePoint.toString(8).padStart(3, "0")}`;
132
+ }
133
+ else
134
+ emitted += character;
135
+ }
136
+ return `${emitted}"`;
137
+ }
138
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhbGFycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZW5kcy9zY2FsYXJzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWiwySkFBMko7QUFDM0osTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3RDLElBQUksRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUMsQ0FBQztJQUMzRSxVQUFVLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFDLENBQUM7SUFDcEYsR0FBRyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBQyxDQUFDO0lBQ3ZFLElBQUksRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUMsQ0FBQztJQUM1RSxVQUFVLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFDLENBQUM7Q0FDckYsQ0FBQyxDQUFBO0FBRUY7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLFFBQVEsRUFBRSxJQUFJO0lBQzNDLE9BQU8saUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO0FBQy9DLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxR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QUssQ0FBQTthQUN2QyxJQUFJLFNBQVMsS0FBSyxTQUFTLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxJQUFJLFNBQVMsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3pFLE9BQU8sSUFBSSxLQUFLLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFBO1FBQzFELENBQUM7O1lBQU0sT0FBTyxJQUFJLFNBQVMsQ0FBQTtJQUM3QixDQUFDO0lBRUQsT0FBTyxHQUFHLE9BQU8sR0FBRyxDQUFBO0FBQ3RCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuLyoqIEB0eXBlIHtSZWFkb25seTxSZWNvcmQ8aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZSwgUmVhZG9ubHk8UmVjb3JkPGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVHlwZU5hbWUsIHN0cmluZz4+Pj59ICovXG5jb25zdCB0YXJnZXRTY2FsYXJUeXBlcyA9IE9iamVjdC5mcmVlemUoe1xuICBqYXZhOiBPYmplY3QuZnJlZXplKHtib29sZWFuOiBcImJvb2xlYW5cIiwgaW50ZWdlcjogXCJpbnRcIiwgc3RyaW5nOiBcIlN0cmluZ1wifSksXG4gIGphdmFzY3JpcHQ6IE9iamVjdC5mcmVlemUoe2Jvb2xlYW46IFwiYm9vbGVhblwiLCBpbnRlZ2VyOiBcIm51bWJlclwiLCBzdHJpbmc6IFwic3RyaW5nXCJ9KSxcbiAgcGhwOiBPYmplY3QuZnJlZXplKHtib29sZWFuOiBcImJvb2xcIiwgaW50ZWdlcjogXCJpbnRcIiwgc3RyaW5nOiBcInN0cmluZ1wifSksXG4gIHJ1Ynk6IE9iamVjdC5mcmVlemUoe2Jvb2xlYW46IFwiYm9vbFwiLCBpbnRlZ2VyOiBcIkludGVnZXJcIiwgc3RyaW5nOiBcIlN0cmluZ1wifSksXG4gIHR5cGVzY3JpcHQ6IE9iamVjdC5mcmVlemUoe2Jvb2xlYW46IFwiYm9vbGVhblwiLCBpbnRlZ2VyOiBcIm51bWJlclwiLCBzdHJpbmc6IFwic3RyaW5nXCJ9KVxufSlcblxuLyoqXG4gKiBFbWl0cyBvbmUgdGFyZ2V0LWxhbmd1YWdlIHNjYWxhciB0eXBlIHNwZWxsaW5nLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gdHlwZSAtIFNlbWFudGljIHNjYWxhciB0eXBlLlxuICogQHJldHVybnMge3N0cmluZ30gVGFyZ2V0IHR5cGUgc3BlbGxpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWl0U2NhbGFyVHlwZShsYW5ndWFnZSwgdHlwZSkge1xuICByZXR1cm4gdGFyZ2V0U2NhbGFyVHlwZXNbbGFuZ3VhZ2VdW3R5cGUubmFtZV1cbn1cblxuLyoqXG4gKiBFbWl0cyBhIHNhZmVseSBlc2NhcGVkIHRhcmdldC1sYW5ndWFnZSBzdHJpbmcgbGl0ZXJhbC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBWYWxpZCBVbmljb2RlIHNjYWxhciBzdHJpbmcuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUYXJnZXQgc3RyaW5nIGxpdGVyYWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWl0U3RyaW5nTGl0ZXJhbChsYW5ndWFnZSwgdmFsdWUpIHtcbiAgaWYgKGxhbmd1YWdlID09IFwicGhwXCIpIHJldHVybiBlbWl0UGhwU3RyaW5nKHZhbHVlKVxuICBpZiAobGFuZ3VhZ2UgPT0gXCJydWJ5XCIpIHJldHVybiBlbWl0UnVieVN0cmluZyh2YWx1ZSlcbiAgaWYgKGxhbmd1YWdlID09IFwiamF2YVwiKSByZXR1cm4gZW1pdEphdmFTdHJpbmcodmFsdWUpXG5cbiAgY29uc3QgbGl0ZXJhbCA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKVxuXG4gIGlmICh0eXBlb2YgbGl0ZXJhbCAhPSBcInN0cmluZ1wiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQSB2YWxpZGF0ZWQgc2VtYW50aWMgc3RyaW5nIGRpZCBub3Qgc2VyaWFsaXplLlwiKVxuXG4gIHJldHVybiBsaXRlcmFsLnJlcGxhY2VBbGwoXCJcXHUyMDI4XCIsIFwiXFxcXHUyMDI4XCIpLnJlcGxhY2VBbGwoXCJcXHUyMDI5XCIsIFwiXFxcXHUyMDI5XCIpXG59XG5cbi8qKlxuICogRW1pdHMgYSBQSFAgZG91YmxlLXF1b3RlZCBzdHJpbmcgd2hpbGUgcHJldmVudGluZyBpbnRlcnBvbGF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVmFsaWQgVW5pY29kZSBzY2FsYXIgc3RyaW5nLlxuICogQHJldHVybnMge3N0cmluZ30gUEhQIHN0cmluZyBsaXRlcmFsLlxuICovXG5mdW5jdGlvbiBlbWl0UGhwU3RyaW5nKHZhbHVlKSB7XG4gIGxldCBlbWl0dGVkID0gXCJcXFwiXCJcblxuICBmb3IgKGNvbnN0IGNoYXJhY3RlciBvZiB2YWx1ZSkge1xuICAgIGNvbnN0IGNvZGVQb2ludCA9IGNoYXJhY3Rlci5jb2RlUG9pbnRBdCgwKVxuXG4gICAgaWYgKGNoYXJhY3RlciA9PSBcIlxcXCJcIikgZW1pdHRlZCArPSBcIlxcXFxcXFwiXCJcbiAgICBlbHNlIGlmIChjaGFyYWN0ZXIgPT0gXCJcXFxcXCIpIGVtaXR0ZWQgKz0gXCJcXFxcXFxcXFwiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiJFwiKSBlbWl0dGVkICs9IFwiXFxcXCRcIlxuICAgIGVsc2UgaWYgKGNoYXJhY3RlciA9PSBcIlxcblwiKSBlbWl0dGVkICs9IFwiXFxcXG5cIlxuICAgIGVsc2UgaWYgKGNoYXJhY3RlciA9PSBcIlxcclwiKSBlbWl0dGVkICs9IFwiXFxcXHJcIlxuICAgIGVsc2UgaWYgKGNoYXJhY3RlciA9PSBcIlxcdFwiKSBlbWl0dGVkICs9IFwiXFxcXHRcIlxuICAgIGVsc2UgaWYgKGNoYXJhY3RlciA9PSBcIlxcZlwiKSBlbWl0dGVkICs9IFwiXFxcXGZcIlxuICAgIGVsc2UgaWYgKGNoYXJhY3RlciA9PSBcIlxcdlwiKSBlbWl0dGVkICs9IFwiXFxcXHZcIlxuICAgIGVsc2UgaWYgKGNvZGVQb2ludCA9PSAyNykgZW1pdHRlZCArPSBcIlxcXFxlXCJcbiAgICBlbHNlIGlmIChjb2RlUG9pbnQgIT09IHVuZGVmaW5lZCAmJiAoY29kZVBvaW50IDwgMzIgfHwgY29kZVBvaW50ID09IDEyNykpIHtcbiAgICAgIGVtaXR0ZWQgKz0gYFxcXFx4JHtjb2RlUG9pbnQudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIFwiMFwiKX1gXG4gICAgfSBlbHNlIGVtaXR0ZWQgKz0gY2hhcmFjdGVyXG4gIH1cblxuICByZXR1cm4gYCR7ZW1pdHRlZH1cImBcbn1cblxuLyoqXG4gKiBFbWl0cyBhIFJ1YnkgZG91YmxlLXF1b3RlZCBzdHJpbmcgd2hpbGUgcHJldmVudGluZyBpbnRlcnBvbGF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVmFsaWQgVW5pY29kZSBzY2FsYXIgc3RyaW5nLlxuICogQHJldHVybnMge3N0cmluZ30gUnVieSBzdHJpbmcgbGl0ZXJhbC5cbiAqL1xuZnVuY3Rpb24gZW1pdFJ1YnlTdHJpbmcodmFsdWUpIHtcbiAgbGV0IGVtaXR0ZWQgPSBcIlxcXCJcIlxuXG4gIGZvciAoY29uc3QgY2hhcmFjdGVyIG9mIHZhbHVlKSB7XG4gICAgY29uc3QgY29kZVBvaW50ID0gY2hhcmFjdGVyLmNvZGVQb2ludEF0KDApXG5cbiAgICBpZiAoY2hhcmFjdGVyID09IFwiXFxcIlwiKSBlbWl0dGVkICs9IFwiXFxcXFxcXCJcIlxuICAgIGVsc2UgaWYgKGNoYXJhY3RlciA9PSBcIlxcXFxcIikgZW1pdHRlZCArPSBcIlxcXFxcXFxcXCJcbiAgICBlbHNlIGlmIChjaGFyYWN0ZXIgPT0gXCIjXCIpIGVtaXR0ZWQgKz0gXCJcXFxcI1wiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiXFxuXCIpIGVtaXR0ZWQgKz0gXCJcXFxcblwiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiXFxyXCIpIGVtaXR0ZWQgKz0gXCJcXFxcclwiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiXFx0XCIpIGVtaXR0ZWQgKz0gXCJcXFxcdFwiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiXFxmXCIpIGVtaXR0ZWQgKz0gXCJcXFxcZlwiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiXFx2XCIpIGVtaXR0ZWQgKz0gXCJcXFxcdlwiXG4gICAgZWxzZSBpZiAoY29kZVBvaW50ID09IDI3KSBlbWl0dGVkICs9IFwiXFxcXGVcIlxuICAgIGVsc2UgaWYgKGNvZGVQb2ludCAhPT0gdW5kZWZpbmVkICYmIChjb2RlUG9pbnQgPCAzMiB8fCBjb2RlUG9pbnQgPT0gMTI3KSkge1xuICAgICAgZW1pdHRlZCArPSBgXFxcXHV7JHtjb2RlUG9pbnQudG9TdHJpbmcoMTYpfX1gXG4gICAgfSBlbHNlIGVtaXR0ZWQgKz0gY2hhcmFjdGVyXG4gIH1cblxuICByZXR1cm4gYCR7ZW1pdHRlZH1cImBcbn1cblxuLyoqXG4gKiBFbWl0cyBhIEphdmEgc3RyaW5nIHVzaW5nIHN0YW5kYXJkIG9yIGZpeGVkLXdpZHRoIG9jdGFsIGNvbnRyb2wgZXNjYXBlcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSAtIFZhbGlkIFVuaWNvZGUgc2NhbGFyIHN0cmluZy5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IEphdmEgc3RyaW5nIGxpdGVyYWwuXG4gKi9cbmZ1bmN0aW9uIGVtaXRKYXZhU3RyaW5nKHZhbHVlKSB7XG4gIGxldCBlbWl0dGVkID0gXCJcXFwiXCJcblxuICBmb3IgKGNvbnN0IGNoYXJhY3RlciBvZiB2YWx1ZSkge1xuICAgIGNvbnN0IGNvZGVQb2ludCA9IGNoYXJhY3Rlci5jb2RlUG9pbnRBdCgwKVxuXG4gICAgaWYgKGNoYXJhY3RlciA9PSBcIlxcXCJcIikgZW1pdHRlZCArPSBcIlxcXFxcXFwiXCJcbiAgICBlbHNlIGlmIChjaGFyYWN0ZXIgPT0gXCJcXFxcXCIpIGVtaXR0ZWQgKz0gXCJcXFxcXFxcXFwiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiXFxiXCIpIGVtaXR0ZWQgKz0gXCJcXFxcYlwiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiXFx0XCIpIGVtaXR0ZWQgKz0gXCJcXFxcdFwiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiXFxuXCIpIGVtaXR0ZWQgKz0gXCJcXFxcblwiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiXFxmXCIpIGVtaXR0ZWQgKz0gXCJcXFxcZlwiXG4gICAgZWxzZSBpZiAoY2hhcmFjdGVyID09IFwiXFxyXCIpIGVtaXR0ZWQgKz0gXCJcXFxcclwiXG4gICAgZWxzZSBpZiAoY29kZVBvaW50ICE9PSB1bmRlZmluZWQgJiYgKGNvZGVQb2ludCA8IDMyIHx8IGNvZGVQb2ludCA9PSAxMjcpKSB7XG4gICAgICBlbWl0dGVkICs9IGBcXFxcJHtjb2RlUG9pbnQudG9TdHJpbmcoOCkucGFkU3RhcnQoMywgXCIwXCIpfWBcbiAgICB9IGVsc2UgZW1pdHRlZCArPSBjaGFyYWN0ZXJcbiAgfVxuXG4gIHJldHVybiBgJHtlbWl0dGVkfVwiYFxufVxuIl19