@mwturnbull/papi-mcp 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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +320 -0
  3. package/dist/config/assembler.d.ts +6 -0
  4. package/dist/config/assembler.d.ts.map +1 -0
  5. package/dist/config/assembler.js +56 -0
  6. package/dist/config/assembler.js.map +1 -0
  7. package/dist/config/parser.d.ts +6 -0
  8. package/dist/config/parser.d.ts.map +1 -0
  9. package/dist/config/parser.js +79 -0
  10. package/dist/config/parser.js.map +1 -0
  11. package/dist/config/snippets.d.ts +12 -0
  12. package/dist/config/snippets.d.ts.map +1 -0
  13. package/dist/config/snippets.js +75 -0
  14. package/dist/config/snippets.js.map +1 -0
  15. package/dist/git/git-ops.d.ts +16 -0
  16. package/dist/git/git-ops.d.ts.map +1 -0
  17. package/dist/git/git-ops.js +64 -0
  18. package/dist/git/git-ops.js.map +1 -0
  19. package/dist/git/github.d.ts +12 -0
  20. package/dist/git/github.d.ts.map +1 -0
  21. package/dist/git/github.js +83 -0
  22. package/dist/git/github.js.map +1 -0
  23. package/dist/git/gitlab.d.ts +11 -0
  24. package/dist/git/gitlab.d.ts.map +1 -0
  25. package/dist/git/gitlab.js +65 -0
  26. package/dist/git/gitlab.js.map +1 -0
  27. package/dist/git/provider.d.ts +33 -0
  28. package/dist/git/provider.d.ts.map +1 -0
  29. package/dist/git/provider.js +49 -0
  30. package/dist/git/provider.js.map +1 -0
  31. package/dist/papi/auth.d.ts +12 -0
  32. package/dist/papi/auth.d.ts.map +1 -0
  33. package/dist/papi/auth.js +74 -0
  34. package/dist/papi/auth.js.map +1 -0
  35. package/dist/papi/client.d.ts +19 -0
  36. package/dist/papi/client.d.ts.map +1 -0
  37. package/dist/papi/client.js +115 -0
  38. package/dist/papi/client.js.map +1 -0
  39. package/dist/papi/types.d.ts +487 -0
  40. package/dist/papi/types.d.ts.map +1 -0
  41. package/dist/papi/types.js +94 -0
  42. package/dist/papi/types.js.map +1 -0
  43. package/dist/redaction/redactor.d.ts +25 -0
  44. package/dist/redaction/redactor.d.ts.map +1 -0
  45. package/dist/redaction/redactor.js +128 -0
  46. package/dist/redaction/redactor.js.map +1 -0
  47. package/dist/server.d.ts +3 -0
  48. package/dist/server.d.ts.map +1 -0
  49. package/dist/server.js +219 -0
  50. package/dist/server.js.map +1 -0
  51. package/dist/tools/activate.d.ts +16 -0
  52. package/dist/tools/activate.d.ts.map +1 -0
  53. package/dist/tools/activate.js +59 -0
  54. package/dist/tools/activate.js.map +1 -0
  55. package/dist/tools/diff-configs.d.ts +3 -0
  56. package/dist/tools/diff-configs.d.ts.map +1 -0
  57. package/dist/tools/diff-configs.js +152 -0
  58. package/dist/tools/diff-configs.js.map +1 -0
  59. package/dist/tools/get-property-config.d.ts +9 -0
  60. package/dist/tools/get-property-config.d.ts.map +1 -0
  61. package/dist/tools/get-property-config.js +53 -0
  62. package/dist/tools/get-property-config.js.map +1 -0
  63. package/dist/tools/pipeline.d.ts +11 -0
  64. package/dist/tools/pipeline.d.ts.map +1 -0
  65. package/dist/tools/pipeline.js +9 -0
  66. package/dist/tools/pipeline.js.map +1 -0
  67. package/dist/tools/sync-property.d.ts +9 -0
  68. package/dist/tools/sync-property.d.ts.map +1 -0
  69. package/dist/tools/sync-property.js +65 -0
  70. package/dist/tools/sync-property.js.map +1 -0
  71. package/dist/tools/write-snippet.d.ts +30 -0
  72. package/dist/tools/write-snippet.d.ts.map +1 -0
  73. package/dist/tools/write-snippet.js +92 -0
  74. package/dist/tools/write-snippet.js.map +1 -0
  75. package/dist/validation/local.d.ts +3 -0
  76. package/dist/validation/local.d.ts.map +1 -0
  77. package/dist/validation/local.js +290 -0
  78. package/dist/validation/local.js.map +1 -0
  79. package/dist/validation/papi.d.ts +6 -0
  80. package/dist/validation/papi.d.ts.map +1 -0
  81. package/dist/validation/papi.js +59 -0
  82. package/dist/validation/papi.js.map +1 -0
  83. package/package.json +55 -0
  84. package/src/skill/system-prompt.md +205 -0
  85. package/templates/.gitkeep +0 -0
  86. package/templates/CLAUDE.md +115 -0
  87. package/templates/copilot-instructions.md +78 -0
@@ -0,0 +1,128 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { resolve } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ export class Redactor {
5
+ config;
6
+ constructor(config) {
7
+ this.config = config?.redact;
8
+ }
9
+ /**
10
+ * Apply redaction rules to an object. Returns a deep clone with sensitive fields replaced.
11
+ * If no redaction config, returns the original object unchanged.
12
+ */
13
+ redact(data) {
14
+ if (!this.config)
15
+ return data;
16
+ if (data === null || data === undefined)
17
+ return data;
18
+ if (typeof data !== 'object')
19
+ return data;
20
+ return this.redactValue(structuredClone(data), []);
21
+ }
22
+ redactValue(value, path) {
23
+ if (value === null || value === undefined)
24
+ return value;
25
+ if (typeof value !== 'object')
26
+ return value;
27
+ if (Array.isArray(value)) {
28
+ return value.map((item, i) => this.redactValue(item, [...path, String(i)]));
29
+ }
30
+ const obj = value;
31
+ for (const key of Object.keys(obj)) {
32
+ const currentPath = [...path, key];
33
+ // Check sensitiveHeaders — context-aware: if this is options.headerName matching a sensitive header,
34
+ // redact the sibling options.headerValue
35
+ if (key === 'headerValue' && this.config?.sensitiveHeaders) {
36
+ const headerName = obj['headerName'];
37
+ if (typeof headerName === 'string') {
38
+ const isSensitive = this.config.sensitiveHeaders.some(h => h.toLowerCase() === headerName.toLowerCase());
39
+ if (isSensitive) {
40
+ obj[key] = '[REDACTED]';
41
+ continue;
42
+ }
43
+ }
44
+ }
45
+ // Check sensitiveVariables — redact value field of sensitive variables
46
+ if (this.config?.sensitiveVariables && key === 'value') {
47
+ const sensitive = obj['sensitive'];
48
+ if (sensitive === true) {
49
+ obj[key] = '[REDACTED]';
50
+ continue;
51
+ }
52
+ }
53
+ // Check field patterns
54
+ if (this.config?.fields && typeof obj[key] !== 'object') {
55
+ const pathStr = currentPath.join('.');
56
+ const shouldRedact = this.config.fields.some(pattern => this.matchPattern(pathStr, pattern));
57
+ if (shouldRedact) {
58
+ obj[key] = '[REDACTED]';
59
+ continue;
60
+ }
61
+ }
62
+ // Recurse into nested objects
63
+ obj[key] = this.redactValue(obj[key], currentPath);
64
+ }
65
+ return obj;
66
+ }
67
+ /**
68
+ * Pattern matching: dot-delimited suffix matching.
69
+ * `*` matches a single path segment.
70
+ * e.g., pattern "options.hostname" matches "rules.children.0.behaviors.0.options.hostname"
71
+ * e.g., pattern "variables.*.value" matches "variables.0.value" or "variables.MY_VAR.value"
72
+ */
73
+ matchPattern(fullPath, pattern) {
74
+ const pathParts = fullPath.split('.');
75
+ const patternParts = pattern.split('.');
76
+ // Suffix matching — try matching pattern against end of path
77
+ if (pathParts.length < patternParts.length)
78
+ return false;
79
+ const startIdx = pathParts.length - patternParts.length;
80
+ for (let i = 0; i < patternParts.length; i++) {
81
+ const pathPart = pathParts[startIdx + i];
82
+ const patternPart = patternParts[i];
83
+ if (patternPart !== '*' && patternPart !== pathPart) {
84
+ return false;
85
+ }
86
+ }
87
+ return true;
88
+ }
89
+ }
90
+ /**
91
+ * Load RedactionConfig from .papi-mcp.json.
92
+ * Search order: env var path > working dir > home dir.
93
+ * Returns undefined if no config found (not an error).
94
+ */
95
+ export async function loadRedactionConfig() {
96
+ const envPath = process.env['PAPI_MCP_CONFIG_PATH'];
97
+ // Check env var overrides first (individual fields)
98
+ const envFields = process.env['PAPI_MCP_REDACT_FIELDS'];
99
+ const envHeaders = process.env['PAPI_MCP_REDACT_SENSITIVE_HEADERS'];
100
+ const envSensitiveVars = process.env['PAPI_MCP_REDACT_SENSITIVE_VARS'];
101
+ if (envFields || envHeaders || envSensitiveVars) {
102
+ return {
103
+ redact: {
104
+ fields: envFields ? envFields.split(',').map(f => f.trim()) : undefined,
105
+ sensitiveHeaders: envHeaders ? envHeaders.split(',').map(h => h.trim()) : undefined,
106
+ sensitiveVariables: envSensitiveVars === 'true',
107
+ },
108
+ };
109
+ }
110
+ // Try config file
111
+ const searchPaths = envPath
112
+ ? [envPath]
113
+ : [
114
+ resolve(process.cwd(), '.papi-mcp.json'),
115
+ resolve(homedir(), '.papi-mcp.json'),
116
+ ];
117
+ for (const configPath of searchPaths) {
118
+ try {
119
+ const content = await readFile(configPath, 'utf-8');
120
+ return JSON.parse(content);
121
+ }
122
+ catch {
123
+ // File not found, try next
124
+ }
125
+ }
126
+ return undefined;
127
+ }
128
+ //# sourceMappingURL=redactor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redactor.js","sourceRoot":"","sources":["../../src/redaction/redactor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
package/dist/server.js ADDED
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env node
2
+ import { z } from 'zod';
3
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
+ import { Redactor, loadRedactionConfig } from './redaction/redactor.js';
6
+ // Import Zod schemas from types (plain z.object schemas only — refined schemas need inline shapes)
7
+ import { GetPropertyConfigSchema, ReadSnippetsSchema, AssembleRuleTreeSchema, SyncPropertySchema, ValidateConfigSchema, DiffConfigsSchema, WriteSnippetSchema, ApplyBehaviorSchema, CreateBranchSchema, CreateMergeRequestSchema, TriggerPipelineSchema, } from './papi/types.js';
8
+ // Import tool implementations
9
+ import { getPropertyConfig } from './tools/get-property-config.js';
10
+ import { listSnippets, readSnippet } from './config/snippets.js';
11
+ import { parseRuleTree } from './config/parser.js';
12
+ import { assembleRuleTree } from './config/assembler.js';
13
+ import { syncProperty } from './tools/sync-property.js';
14
+ import { validateLocal } from './validation/local.js';
15
+ import { validateWithApi } from './validation/papi.js';
16
+ import { diffConfigs } from './tools/diff-configs.js';
17
+ import { writeSnippet, applyBehavior } from './tools/write-snippet.js';
18
+ import { activateStaging, activateProduction } from './tools/activate.js';
19
+ import { triggerPipeline } from './tools/pipeline.js';
20
+ import { createBranch, commitAndPush, buildBranchName, getCurrentBranch } from './git/git-ops.js';
21
+ import { createProvider } from './git/provider.js';
22
+ async function main() {
23
+ const config = await loadRedactionConfig();
24
+ const redactor = new Redactor(config);
25
+ const server = new McpServer({
26
+ name: 'papi-mcp',
27
+ version: '0.1.0',
28
+ });
29
+ // ─── Read & Analyse ──────────────────────────────────────────────
30
+ server.tool('get_property_config', 'Fetch current property rule tree via the PAPI API. Provide either propertyId or repoPath (which auto-detects from envInfo.json).', GetPropertyConfigSchema.shape, async (params) => {
31
+ try {
32
+ const result = await getPropertyConfig(params);
33
+ return { content: [{ type: 'text', text: redactor.redact(result) }] };
34
+ }
35
+ catch (error) {
36
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
37
+ }
38
+ });
39
+ server.tool('read_snippets', 'Read local config snippet files or list all snippet names. Provide snippetName to read one, or omit to list all.', ReadSnippetsSchema.shape, async (params) => {
40
+ try {
41
+ if (params.snippetName) {
42
+ const snippet = await readSnippet(params.repoPath, params.snippetName);
43
+ const text = JSON.stringify(redactor.redact(snippet), null, 2);
44
+ return { content: [{ type: 'text', text }] };
45
+ }
46
+ const snippets = await listSnippets(params.repoPath);
47
+ return { content: [{ type: 'text', text: JSON.stringify(snippets, null, 2) }] };
48
+ }
49
+ catch (error) {
50
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
51
+ }
52
+ });
53
+ // ParseRuleTreeSchema uses .refine() — define inline shape
54
+ server.tool('parse_rule_tree', 'Parse PAPI rule tree JSON into an LLM-optimised flat representation. Provide either repoPath (assembles from disk) or ruleTree (raw JSON string).', {
55
+ repoPath: z.string().optional().describe('Path to the property repo (assembles from disk)'),
56
+ ruleTree: z.string().optional().describe('Raw rule tree JSON string'),
57
+ }, async (params) => {
58
+ try {
59
+ if (!params.repoPath && !params.ruleTree) {
60
+ return { content: [{ type: 'text', text: 'Error: Either repoPath or ruleTree must be provided' }], isError: true };
61
+ }
62
+ const result = await parseRuleTree(params);
63
+ const text = JSON.stringify(redactor.redact(result), null, 2);
64
+ return { content: [{ type: 'text', text }] };
65
+ }
66
+ catch (error) {
67
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
68
+ }
69
+ });
70
+ server.tool('assemble_rule_tree', 'Resolve all #include: directives into a complete, assembled rule tree from disk.', AssembleRuleTreeSchema.shape, async (params) => {
71
+ try {
72
+ const result = await assembleRuleTree(params.repoPath);
73
+ const text = JSON.stringify(redactor.redact(result), null, 2);
74
+ return { content: [{ type: 'text', text }] };
75
+ }
76
+ catch (error) {
77
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
78
+ }
79
+ });
80
+ server.tool('sync_property', 'Compare local config against live PAPI version using version-number comparison.', SyncPropertySchema.shape, async (params) => {
81
+ try {
82
+ const result = await syncProperty(params);
83
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
84
+ }
85
+ catch (error) {
86
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
87
+ }
88
+ });
89
+ // ─── Validate & Diff ─────────────────────────────────────────────
90
+ server.tool('validate_config', 'Check syntax, logic, and PAPI schema compliance. Runs 7 local checks; set apiValidation=true to also validate against the PAPI API.', ValidateConfigSchema.shape, async (params) => {
91
+ try {
92
+ const result = params.apiValidation
93
+ ? await validateWithApi(params.repoPath, { edgercPath: params.edgercPath, edgercSection: params.edgercSection })
94
+ : await validateLocal(params.repoPath);
95
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
96
+ }
97
+ catch (error) {
98
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
99
+ }
100
+ });
101
+ server.tool('diff_configs', 'Compare two rule tree versions with behavior-level, criteria-level, and variable-level granularity.', DiffConfigsSchema.shape, async (params) => {
102
+ try {
103
+ const result = diffConfigs(params.before, params.after);
104
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
105
+ }
106
+ catch (error) {
107
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
108
+ }
109
+ });
110
+ // ─── Write & Ship ────────────────────────────────────────────────
111
+ server.tool('write_snippet', 'Create or update a config snippet file on disk. Validates PapiRule structure. Optionally adds #include: to main.json.', WriteSnippetSchema.shape, async (params) => {
112
+ try {
113
+ const result = await writeSnippet(params);
114
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
115
+ }
116
+ catch (error) {
117
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
118
+ }
119
+ });
120
+ server.tool('apply_behavior', 'Add or modify a single behavior in an existing snippet. Replaces in-place if the behavior name already exists.', ApplyBehaviorSchema.shape, async (params) => {
121
+ try {
122
+ const result = await applyBehavior(params);
123
+ const text = JSON.stringify(redactor.redact(result), null, 2);
124
+ return { content: [{ type: 'text', text }] };
125
+ }
126
+ catch (error) {
127
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
128
+ }
129
+ });
130
+ server.tool('create_branch', 'Create a git branch following the akamai/<type>/<description> naming convention.', CreateBranchSchema.shape, async (params) => {
131
+ try {
132
+ const branchName = buildBranchName(params.type, params.description);
133
+ await createBranch(params.repoPath, branchName);
134
+ return { content: [{ type: 'text', text: JSON.stringify({ branch: branchName, created: true }, null, 2) }] };
135
+ }
136
+ catch (error) {
137
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
138
+ }
139
+ });
140
+ server.tool('create_merge_request', 'Commit changes, push branch, and open a merge request / pull request via the detected git provider.', CreateMergeRequestSchema.shape, async (params) => {
141
+ try {
142
+ const branch = await getCurrentBranch(params.repoPath);
143
+ await commitAndPush(params.repoPath, params.title, params.files);
144
+ const provider = await createProvider(params.repoPath);
145
+ const result = await provider.createMergeRequest({
146
+ title: params.title,
147
+ description: params.description,
148
+ sourceBranch: branch,
149
+ targetBranch: params.targetBranch,
150
+ });
151
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
152
+ }
153
+ catch (error) {
154
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
155
+ }
156
+ });
157
+ // ─── Activate & Pipeline ─────────────────────────────────────────
158
+ // ActivateStagingSchema uses .refine() — define inline shape
159
+ server.tool('activate_staging', 'Activate a property version to the staging network. Provide either propertyId or repoPath.', {
160
+ propertyId: z.string().optional().describe('Akamai property ID'),
161
+ version: z.number().optional().describe('Property version'),
162
+ repoPath: z.string().optional().describe('Path to the property repo'),
163
+ note: z.string().optional().describe('Activation note'),
164
+ edgercPath: z.string().optional().describe('Custom .edgerc file path'),
165
+ edgercSection: z.string().optional().describe('.edgerc section name'),
166
+ }, async (params) => {
167
+ try {
168
+ if (!params.propertyId && !params.repoPath) {
169
+ return { content: [{ type: 'text', text: 'Error: Either propertyId or repoPath must be provided' }], isError: true };
170
+ }
171
+ const result = await activateStaging(params);
172
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
173
+ }
174
+ catch (error) {
175
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
176
+ }
177
+ });
178
+ // ActivateProductionSchema uses .refine() — define inline shape
179
+ server.tool('activate_production', 'Activate a property version to production. Requires explicit risk acknowledgement and contact emails.', {
180
+ propertyId: z.string().optional().describe('Akamai property ID'),
181
+ version: z.number().optional().describe('Property version'),
182
+ repoPath: z.string().optional().describe('Path to the property repo'),
183
+ acknowledgeProductionRisk: z.literal(true, {
184
+ errorMap: () => ({ message: 'You must set acknowledgeProductionRisk to true for production activation' }),
185
+ }),
186
+ contactEmails: z.array(z.string().email()).min(1).describe('Required notification emails'),
187
+ note: z.string().optional().describe('Activation note'),
188
+ edgercPath: z.string().optional().describe('Custom .edgerc file path'),
189
+ edgercSection: z.string().optional().describe('.edgerc section name'),
190
+ }, async (params) => {
191
+ try {
192
+ if (!params.propertyId && !params.repoPath) {
193
+ return { content: [{ type: 'text', text: 'Error: Either propertyId or repoPath must be provided' }], isError: true };
194
+ }
195
+ const result = await activateProduction(params);
196
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
197
+ }
198
+ catch (error) {
199
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
200
+ }
201
+ });
202
+ server.tool('trigger_pipeline', 'Trigger a CI/CD pipeline for the specified branch (defaults to current branch).', TriggerPipelineSchema.shape, async (params) => {
203
+ try {
204
+ const result = await triggerPipeline(params);
205
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
206
+ }
207
+ catch (error) {
208
+ return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
209
+ }
210
+ });
211
+ // Start server
212
+ const transport = new StdioServerTransport();
213
+ await server.connect(transport);
214
+ }
215
+ main().catch((error) => {
216
+ console.error('Fatal error:', error);
217
+ process.exit(1);
218
+ });
219
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAExE,mGAAmG;AACnG,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,8BAA8B;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC3C,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEtC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,oEAAoE;IAEpE,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,kIAAkI,EAClI,uBAAuB,CAAC,KAAK,EAC7B,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC/C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,eAAe,EACf,kHAAkH,EAClH,kBAAkB,CAAC,KAAK,EACxB,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACvB,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;gBACvE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC/D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACxD,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACrD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAC3F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,2DAA2D;IAC3D,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,mJAAmJ,EACnJ;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iDAAiD,CAAC;QAC3F,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;KACtE,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACzC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,qDAAqD,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC9H,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC9D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,kFAAkF,EAClF,sBAAsB,CAAC,KAAK,EAC5B,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC9D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,eAAe,EACf,iFAAiF,EACjF,kBAAkB,CAAC,KAAK,EACxB,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACzF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,oEAAoE;IAEpE,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,qIAAqI,EACrI,oBAAoB,CAAC,KAAK,EAC1B,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa;gBACjC,CAAC,CAAC,MAAM,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC;gBAChH,CAAC,CAAC,MAAM,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACzC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACzF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,cAAc,EACd,qGAAqG,EACrG,iBAAiB,CAAC,KAAK,EACvB,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YACxD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACzF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,oEAAoE;IAEpE,MAAM,CAAC,IAAI,CACT,eAAe,EACf,uHAAuH,EACvH,kBAAkB,CAAC,KAAK,EACxB,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACzF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,gHAAgH,EAChH,mBAAmB,CAAC,KAAK,EACzB,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC9D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,eAAe,EACf,kFAAkF,EAClF,kBAAkB,CAAC,KAAK,EACxB,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;YACpE,MAAM,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAChD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACxH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,qGAAqG,EACrG,wBAAwB,CAAC,KAAK,EAC9B,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvD,MAAM,aAAa,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YACjE,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC;gBAC/C,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,YAAY,EAAE,MAAM;gBACpB,YAAY,EAAE,MAAM,CAAC,YAAY;aAClC,CAAC,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACzF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,oEAAoE;IAEpE,6DAA6D;IAC7D,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,4FAA4F,EAC5F;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QAChE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAC3D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QACrE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QACvD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QACtE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACtE,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC3C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,uDAAuD,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAChI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;YAC7C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACzF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,gEAAgE;IAChE,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,uGAAuG,EACvG;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QAChE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAC3D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QACrE,yBAAyB,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE;YACzC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,0EAA0E,EAAE,CAAC;SAC1G,CAAC;QACF,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAC1F,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QACvD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QACtE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACtE,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC3C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,uDAAuD,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAChI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAChD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACzF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,iFAAiF,EACjF,qBAAqB,CAAC,KAAK,EAC3B,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;YAC7C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACzF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAW,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7G,CAAC;IACH,CAAC,CACF,CAAC;IAEF,eAAe;IACf,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { ActivationResponse } from '../papi/types.js';
2
+ export interface ActivateStagingParams {
3
+ propertyId?: string;
4
+ version?: number;
5
+ repoPath?: string;
6
+ note?: string;
7
+ edgercPath?: string;
8
+ edgercSection?: string;
9
+ }
10
+ export interface ActivateProductionParams extends ActivateStagingParams {
11
+ acknowledgeProductionRisk: boolean;
12
+ contactEmails: string[];
13
+ }
14
+ export declare function activateStaging(params: ActivateStagingParams): Promise<ActivationResponse>;
15
+ export declare function activateProduction(params: ActivateProductionParams): Promise<ActivationResponse>;
16
+ //# sourceMappingURL=activate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activate.d.ts","sourceRoot":"","sources":["../../src/tools/activate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAW,MAAM,kBAAkB,CAAC;AAEpE,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,wBAAyB,SAAQ,qBAAqB;IACrE,yBAAyB,EAAE,OAAO,CAAC;IACnC,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAsB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAchG;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAuBtG"}
@@ -0,0 +1,59 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { resolve } from 'node:path';
3
+ import { PapiClient } from '../papi/client.js';
4
+ import { resolveCredentials } from '../papi/auth.js';
5
+ import { findPmDirectory } from '../config/snippets.js';
6
+ export async function activateStaging(params) {
7
+ const { propertyId, version } = await resolvePropertyInfo(params);
8
+ const credentials = await resolveCredentials({
9
+ edgercPath: params.edgercPath,
10
+ section: params.edgercSection,
11
+ });
12
+ const client = new PapiClient(credentials);
13
+ return client.activateProperty({
14
+ propertyId,
15
+ propertyVersion: version,
16
+ network: 'STAGING',
17
+ note: params.note ?? 'Staging activation via papi-mcp',
18
+ });
19
+ }
20
+ export async function activateProduction(params) {
21
+ // Hard gate: reject without risk acknowledgement
22
+ if (params.acknowledgeProductionRisk !== true) {
23
+ throw new Error('Production activation requires acknowledgeProductionRisk: true. ' +
24
+ 'This confirms you understand the impact of activating to production.');
25
+ }
26
+ const { propertyId, version } = await resolvePropertyInfo(params);
27
+ const credentials = await resolveCredentials({
28
+ edgercPath: params.edgercPath,
29
+ section: params.edgercSection,
30
+ });
31
+ const client = new PapiClient(credentials);
32
+ return client.activateProperty({
33
+ propertyId,
34
+ propertyVersion: version,
35
+ network: 'PRODUCTION',
36
+ note: params.note ?? 'Production activation via papi-mcp',
37
+ notifyEmails: params.contactEmails,
38
+ });
39
+ }
40
+ async function resolvePropertyInfo(params) {
41
+ let propertyId = params.propertyId;
42
+ let version = params.version;
43
+ if (!propertyId && params.repoPath) {
44
+ const pmDir = await findPmDirectory(params.repoPath);
45
+ const envInfoPath = resolve(pmDir, 'envInfo.json');
46
+ const content = await readFile(envInfoPath, 'utf-8');
47
+ const envInfo = JSON.parse(content);
48
+ propertyId = String(envInfo.propertyId);
49
+ version = version ?? envInfo.latestVersionInfo.propertyVersion;
50
+ }
51
+ if (!propertyId) {
52
+ throw new Error('Either propertyId or repoPath must be provided');
53
+ }
54
+ if (!version) {
55
+ throw new Error('Property version must be provided (either explicitly or via envInfo.json)');
56
+ }
57
+ return { propertyId, version };
58
+ }
59
+ //# sourceMappingURL=activate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activate.js","sourceRoot":"","sources":["../../src/tools/activate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAiBxD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAA6B;IACjE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAClE,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC;QAC3C,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,OAAO,EAAE,MAAM,CAAC,aAAa;KAC9B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;IAE3C,OAAO,MAAM,CAAC,gBAAgB,CAAC;QAC7B,UAAU;QACV,eAAe,EAAE,OAAO;QACxB,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,iCAAiC;KACvD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAgC;IACvE,iDAAiD;IACjD,IAAI,MAAM,CAAC,yBAAyB,KAAK,IAAI,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,kEAAkE;YAClE,sEAAsE,CACvE,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAClE,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC;QAC3C,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,OAAO,EAAE,MAAM,CAAC,aAAa;KAC9B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;IAE3C,OAAO,MAAM,CAAC,gBAAgB,CAAC;QAC7B,UAAU;QACV,eAAe,EAAE,OAAO;QACxB,OAAO,EAAE,YAAY;QACrB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,oCAAoC;QACzD,YAAY,EAAE,MAAM,CAAC,aAAa;KACnC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,MAAoE;IACrG,IAAI,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACnC,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAE7B,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACrD,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;QAC/C,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACxC,OAAO,GAAG,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC,eAAe,CAAC;IACjE,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;IAC/F,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { DiffResult } from '../papi/types.js';
2
+ export declare function diffConfigs(beforeJson: string, afterJson: string): DiffResult;
3
+ //# sourceMappingURL=diff-configs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-configs.d.ts","sourceRoot":"","sources":["../../src/tools/diff-configs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,UAAU,EAAsD,MAAM,kBAAkB,CAAC;AAEnH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,CAyC7E"}
@@ -0,0 +1,152 @@
1
+ export function diffConfigs(beforeJson, afterJson) {
2
+ const before = JSON.parse(beforeJson);
3
+ const after = JSON.parse(afterJson);
4
+ const changes = [];
5
+ // Diff rules
6
+ diffRules(before.rules, after.rules, '', changes);
7
+ // Diff variables
8
+ diffVariables(before.rules.variables ?? [], after.rules.variables ?? [], changes);
9
+ const summary = {
10
+ rulesAdded: 0, rulesRemoved: 0, rulesModified: 0,
11
+ behaviorsAdded: 0, behaviorsRemoved: 0, behaviorsModified: 0,
12
+ criteriaAdded: 0, criteriaRemoved: 0, criteriaModified: 0,
13
+ variablesAdded: 0, variablesRemoved: 0, variablesModified: 0,
14
+ };
15
+ for (const c of changes) {
16
+ const prefix = c.path.split('.')[0] ?? '';
17
+ if (prefix === 'rule' || prefix === 'rules') {
18
+ summary[`rules${capitalize(c.type)}`]++;
19
+ }
20
+ else if (prefix === 'behavior') {
21
+ summary[`behaviors${capitalize(c.type)}`]++;
22
+ }
23
+ else if (prefix === 'criteria') {
24
+ summary[`criteria${capitalize(c.type)}`]++;
25
+ }
26
+ else if (prefix === 'variable') {
27
+ summary[`variables${capitalize(c.type)}`]++;
28
+ }
29
+ }
30
+ // Generate unified diff
31
+ const unifiedDiff = generateUnifiedDiff(beforeJson, afterJson);
32
+ return {
33
+ hasChanges: changes.length > 0,
34
+ summary,
35
+ changes,
36
+ unifiedDiff,
37
+ };
38
+ }
39
+ function diffRules(before, after, path, changes) {
40
+ const currentPath = path ? `${path} > ${before.name}` : before.name;
41
+ // Diff behaviors
42
+ diffBehaviors(before.behaviors, after.behaviors, currentPath, changes);
43
+ // Diff criteria
44
+ diffCriteria(before.criteria, after.criteria, currentPath, changes);
45
+ // Diff child rules
46
+ const beforeChildren = (before.children ?? []).filter(c => typeof c === 'object');
47
+ const afterChildren = (after.children ?? []).filter(c => typeof c === 'object');
48
+ const beforeMap = new Map(beforeChildren.map(c => [c.name, c]));
49
+ const afterMap = new Map(afterChildren.map(c => [c.name, c]));
50
+ for (const [name, rule] of afterMap) {
51
+ if (!beforeMap.has(name)) {
52
+ changes.push({ type: 'added', path: `rule.${currentPath}`, name, after: rule });
53
+ }
54
+ else {
55
+ diffRules(beforeMap.get(name), rule, currentPath, changes);
56
+ }
57
+ }
58
+ for (const [name, rule] of beforeMap) {
59
+ if (!afterMap.has(name)) {
60
+ changes.push({ type: 'removed', path: `rule.${currentPath}`, name, before: rule });
61
+ }
62
+ }
63
+ }
64
+ function diffBehaviors(before, after, rulePath, changes) {
65
+ const beforeMap = new Map(before.map(b => [b.name, b]));
66
+ const afterMap = new Map(after.map(b => [b.name, b]));
67
+ for (const [name, behavior] of afterMap) {
68
+ if (!beforeMap.has(name)) {
69
+ changes.push({ type: 'added', path: `behavior.${rulePath}`, name, after: behavior });
70
+ }
71
+ else {
72
+ const beforeBehavior = beforeMap.get(name);
73
+ if (JSON.stringify(beforeBehavior.options) !== JSON.stringify(behavior.options)) {
74
+ changes.push({
75
+ type: 'modified', path: `behavior.${rulePath}`, name,
76
+ before: beforeBehavior, after: behavior,
77
+ });
78
+ }
79
+ }
80
+ }
81
+ for (const name of beforeMap.keys()) {
82
+ if (!afterMap.has(name)) {
83
+ changes.push({ type: 'removed', path: `behavior.${rulePath}`, name, before: beforeMap.get(name) });
84
+ }
85
+ }
86
+ }
87
+ function diffCriteria(before, after, rulePath, changes) {
88
+ const beforeMap = new Map(before.map(c => [c.name, c]));
89
+ const afterMap = new Map(after.map(c => [c.name, c]));
90
+ for (const [name, criteria] of afterMap) {
91
+ if (!beforeMap.has(name)) {
92
+ changes.push({ type: 'added', path: `criteria.${rulePath}`, name, after: criteria });
93
+ }
94
+ else {
95
+ const beforeCriteria = beforeMap.get(name);
96
+ if (JSON.stringify(beforeCriteria.options) !== JSON.stringify(criteria.options)) {
97
+ changes.push({
98
+ type: 'modified', path: `criteria.${rulePath}`, name,
99
+ before: beforeCriteria, after: criteria,
100
+ });
101
+ }
102
+ }
103
+ }
104
+ for (const name of beforeMap.keys()) {
105
+ if (!afterMap.has(name)) {
106
+ changes.push({ type: 'removed', path: `criteria.${rulePath}`, name, before: beforeMap.get(name) });
107
+ }
108
+ }
109
+ }
110
+ function diffVariables(before, after, changes) {
111
+ const beforeMap = new Map(before.map(v => [v.name, v]));
112
+ const afterMap = new Map(after.map(v => [v.name, v]));
113
+ for (const [name, variable] of afterMap) {
114
+ if (!beforeMap.has(name)) {
115
+ changes.push({ type: 'added', path: 'variable', name, after: variable });
116
+ }
117
+ else {
118
+ if (JSON.stringify(beforeMap.get(name)) !== JSON.stringify(variable)) {
119
+ changes.push({ type: 'modified', path: 'variable', name, before: beforeMap.get(name), after: variable });
120
+ }
121
+ }
122
+ }
123
+ for (const name of beforeMap.keys()) {
124
+ if (!afterMap.has(name)) {
125
+ changes.push({ type: 'removed', path: 'variable', name, before: beforeMap.get(name) });
126
+ }
127
+ }
128
+ }
129
+ function capitalize(s) {
130
+ return s.charAt(0).toUpperCase() + s.slice(1);
131
+ }
132
+ function generateUnifiedDiff(beforeJson, afterJson) {
133
+ const beforeLines = JSON.stringify(JSON.parse(beforeJson), null, 2).split('\n');
134
+ const afterLines = JSON.stringify(JSON.parse(afterJson), null, 2).split('\n');
135
+ const diff = ['--- before', '+++ after'];
136
+ const maxLen = Math.max(beforeLines.length, afterLines.length);
137
+ for (let i = 0; i < maxLen; i++) {
138
+ const bLine = beforeLines[i];
139
+ const aLine = afterLines[i];
140
+ if (bLine === aLine) {
141
+ diff.push(` ${bLine}`);
142
+ }
143
+ else {
144
+ if (bLine !== undefined)
145
+ diff.push(`-${bLine}`);
146
+ if (aLine !== undefined)
147
+ diff.push(`+${aLine}`);
148
+ }
149
+ }
150
+ return diff.join('\n');
151
+ }
152
+ //# sourceMappingURL=diff-configs.js.map