@hanzo/runtime 0.0.0-dev

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.
@@ -0,0 +1,366 @@
1
+ /*
2
+ * Copyright 2025 Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import { SandboxCodeToolbox } from '../Sandbox'
7
+ import { CodeRunParams } from '../Process'
8
+
9
+ export class SandboxPythonCodeToolbox implements SandboxCodeToolbox {
10
+ public getRunCommand(code: string, params?: CodeRunParams): string {
11
+ // Encode the provided code in base64
12
+ let base64Code = Buffer.from(code).toString('base64')
13
+
14
+ // Override plt.show() method if matplotlib is imported
15
+ if (SandboxPythonCodeToolbox.isMatplotlibImported(code)) {
16
+ let code_wrapper = Buffer.from(PYTHON_CODE_WRAPPER, 'base64').toString('utf-8')
17
+ code_wrapper = code_wrapper.replace('{encoded_code}', base64Code)
18
+ base64Code = Buffer.from(code_wrapper).toString('base64')
19
+ }
20
+
21
+ // Build command-line arguments string
22
+ const argv = params?.argv ? params.argv.join(' ') : ''
23
+
24
+ // Execute the bootstrapper code directly
25
+ // Use -u flag to ensure unbuffered output for real-time error reporting
26
+ // eslint-disable-next-line no-useless-escape
27
+ return `sh -c 'python3 -u -c "exec(__import__(\\\"base64\\\").b64decode(\\\"${base64Code}\\\").decode())" ${argv}'`
28
+ }
29
+
30
+ /**
31
+ * Checks if matplotlib is imported in the given Python code string.
32
+ * @param codeString Python code as a string
33
+ * @returns True if matplotlib is imported, false otherwise
34
+ */
35
+ private static isMatplotlibImported(codeString: string): boolean {
36
+ // Regex patterns for different import styles
37
+ const patterns: RegExp[] = [
38
+ // Standard imports
39
+ /^[^#]*import\s+matplotlib/m,
40
+ /^[^#]*from\s+matplotlib/m,
41
+
42
+ // Dynamic imports
43
+ /^[^#]*__import__\s*\(\s*['"]matplotlib['"]/m,
44
+ /^[^#]*importlib\.import_module\s*\(\s*['"]matplotlib['"]/m,
45
+
46
+ // Other dynamic loading patterns
47
+ /^[^#]*loader\.load_module\s*\(\s*['"]matplotlib['"]/m,
48
+ /^[^#]*sys\.modules\[['"]matplotlib['"]\]/m,
49
+ ]
50
+
51
+ // Check each pattern
52
+ for (const pattern of patterns) {
53
+ if (pattern.test(codeString)) {
54
+ return true
55
+ }
56
+ }
57
+
58
+ return false
59
+ }
60
+ }
61
+
62
+ const PYTHON_CODE_WRAPPER = `
63
+ aW1wb3J0IGJhc2U2NAppbXBvcnQgZGF0ZXRpbWUKaW1wb3J0IGhhc2hsaWIKaW1wb3J0IGlvCmlt
64
+ cG9ydCBqc29uCmltcG9ydCBsaW5lY2FjaGUKaW1wb3J0IHN5cwppbXBvcnQgdHJhY2ViYWNrCmlt
65
+ cG9ydCB0eXBlcwpmcm9tIGltcG9ydGxpYi5hYmMgaW1wb3J0IExvYWRlciwgTWV0YVBhdGhGaW5k
66
+ ZXIKZnJvbSBpbXBvcnRsaWIudXRpbCBpbXBvcnQgZmluZF9zcGVjLCBzcGVjX2Zyb21fbG9hZGVy
67
+ CgojIEdsb2JhbCB2YXJpYWJsZXMgdG8gaG9sZCBpbXBvcnRlZCBsaWJyYXJpZXMgaWYgbmVlZGVk
68
+ Cm5wID0gTm9uZQptcGwgPSBOb25lCnBpbF9pbWcgPSBOb25lCgoKcGx0X3BhdGNoZWQgPSBGYWxz
69
+ ZQpwcm9jZXNzZWRfZmlndXJlcyA9IHNldCgpCgoKZGVmIF9wYXJzZV9wb2ludChwb2ludCk6CiAg
70
+ ICBpZiBpc2luc3RhbmNlKHBvaW50LCBkYXRldGltZS5kYXRlKToKICAgICAgICByZXR1cm4gcG9p
71
+ bnQuaXNvZm9ybWF0KCkKICAgIGlmIGlzaW5zdGFuY2UocG9pbnQsIG5wLmRhdGV0aW1lNjQpOgog
72
+ ICAgICAgIHJldHVybiBwb2ludC5hc3R5cGUoImRhdGV0aW1lNjRbc10iKS5hc3R5cGUoc3RyKQog
73
+ ICAgcmV0dXJuIHBvaW50CgoKZGVmIF9pc19ncmlkX2xpbmUobGluZTogYW55KSAtPiBib29sOgog
74
+ ICAgeF9kYXRhID0gbGluZS5nZXRfeGRhdGEoKQogICAgaWYgbGVuKHhfZGF0YSkgIT0gMjoKICAg
75
+ ICAgICByZXR1cm4gRmFsc2UKCiAgICB5X2RhdGEgPSBsaW5lLmdldF95ZGF0YSgpCiAgICBpZiBs
76
+ ZW4oeV9kYXRhKSAhPSAyOgogICAgICAgIHJldHVybiBGYWxzZQoKICAgIGlmIHhfZGF0YVswXSA9
77
+ PSB4X2RhdGFbMV0gb3IgeV9kYXRhWzBdID09IHlfZGF0YVsxXToKICAgICAgICByZXR1cm4gVHJ1
78
+ ZQoKICAgIHJldHVybiBGYWxzZQoKCmRlZiBfZXh0cmFjdF9saW5lX2NoYXJ0X2VsZW1lbnRzKGF4
79
+ KToKICAgIGVsZW1lbnRzID0gW10KCiAgICBmb3IgbGluZSBpbiBheC5nZXRfbGluZXMoKToKICAg
80
+ ICAgICBpZiBfaXNfZ3JpZF9saW5lKGxpbmUpOgogICAgICAgICAgICBjb250aW51ZQogICAgICAg
81
+ IGxhYmVsID0gbGluZS5nZXRfbGFiZWwoKQogICAgICAgIHBvaW50cyA9IFtfcGFyc2VfcG9pbnQo
82
+ KHgsIHkpKSBmb3IgeCwgeSBpbiB6aXAobGluZS5nZXRfeGRhdGEoKSwgbGluZS5nZXRfeWRhdGEo
83
+ KSldCgogICAgICAgIGVsZW1lbnQgPSB7ImxhYmVsIjogbGFiZWwsICJwb2ludHMiOiBwb2ludHN9
84
+ CiAgICAgICAgZWxlbWVudHMuYXBwZW5kKGVsZW1lbnQpCgogICAgcmV0dXJuIGVsZW1lbnRzCgoK
85
+ ZGVmIF9leHRyYWN0X3NjYXR0ZXJfY2hhcnRfZWxlbWVudHMoYXgpOgogICAgZWxlbWVudHMgPSBb
86
+ XQoKICAgIGZvciBjb2xsZWN0aW9uIGluIGF4LmNvbGxlY3Rpb25zOgogICAgICAgIHBvaW50cyA9
87
+ IFtfcGFyc2VfcG9pbnQoKHgsIHkpKSBmb3IgeCwgeSBpbiBjb2xsZWN0aW9uLmdldF9vZmZzZXRz
88
+ KCldCiAgICAgICAgZWxlbWVudCA9IHsibGFiZWwiOiBjb2xsZWN0aW9uLmdldF9sYWJlbCgpLCAi
89
+ cG9pbnRzIjogcG9pbnRzfQogICAgICAgIGVsZW1lbnRzLmFwcGVuZChlbGVtZW50KQoKICAgIHJl
90
+ dHVybiBlbGVtZW50cwoKCmRlZiBfZXh0cmFjdF9iYXJfY2hhcnRfZWxlbWVudHMoYXgpOgogICAg
91
+ ZWxlbWVudHMgPSBbXQogICAgY2hhbmdlX29yaWVudGF0aW9uID0gRmFsc2UKCiAgICBmb3IgY29u
92
+ dGFpbmVyIGluIGF4LmNvbnRhaW5lcnM6CiAgICAgICAgaGVpZ2h0cyA9IFtyZWN0LmdldF9oZWln
93
+ aHQoKSBmb3IgcmVjdCBpbiBjb250YWluZXJdCiAgICAgICAgaWYgYWxsKGhlaWdodCA9PSBoZWln
94
+ aHRzWzBdIGZvciBoZWlnaHQgaW4gaGVpZ2h0cyk6CiAgICAgICAgICAgICMgdmVydGljYWwgYmFy
95
+ cwogICAgICAgICAgICBjaGFuZ2Vfb3JpZW50YXRpb24gPSBUcnVlCiAgICAgICAgICAgIGxhYmVs
96
+ cyA9IFtsYWJlbC5nZXRfdGV4dCgpIGZvciBsYWJlbCBpbiBheC5nZXRfeXRpY2tsYWJlbHMoKV0K
97
+ ICAgICAgICAgICAgdmFsdWVzID0gW3JlY3QuZ2V0X3dpZHRoKCkgZm9yIHJlY3QgaW4gY29udGFp
98
+ bmVyXQogICAgICAgIGVsc2U6CiAgICAgICAgICAgICMgaG9yaXpvbnRhbCBiYXJzCiAgICAgICAg
99
+ ICAgIGxhYmVscyA9IFtsYWJlbC5nZXRfdGV4dCgpIGZvciBsYWJlbCBpbiBheC5nZXRfeHRpY2ts
100
+ YWJlbHMoKV0KICAgICAgICAgICAgdmFsdWVzID0gaGVpZ2h0cwogICAgICAgIGZvciBsYWJlbCwg
101
+ dmFsdWUgaW4gemlwKGxhYmVscywgdmFsdWVzKToKICAgICAgICAgICAgZWxlbWVudCA9IHsibGFi
102
+ ZWwiOiBsYWJlbCwgImdyb3VwIjogY29udGFpbmVyLmdldF9sYWJlbCgpLCAidmFsdWUiOiB2YWx1
103
+ ZX0KICAgICAgICAgICAgZWxlbWVudHMuYXBwZW5kKGVsZW1lbnQpCgogICAgcmV0dXJuIGVsZW1l
104
+ bnRzLCBjaGFuZ2Vfb3JpZW50YXRpb24KCgpkZWYgX2V4dHJhY3RfcGllX2NoYXJ0X2VsZW1lbnRz
105
+ KGF4KToKICAgIGVsZW1lbnRzID0gW10KCiAgICB3ZWRnZXMgPSBbcGF0Y2ggZm9yIHBhdGNoIGlu
106
+ IGF4LnBhdGNoZXMgaWYgaXNpbnN0YW5jZShwYXRjaCwgbXBsLnBhdGNoZXMuV2VkZ2UpXQogICAg
107
+ aWYgbGVuKHdlZGdlcykgPT0gMDoKICAgICAgICByZXR1cm4gZWxlbWVudHMKCiAgICB0ZXh0cyA9
108
+ IFt0ZXh0X29iai5nZXRfdGV4dCgpIGZvciB0ZXh0X29iaiBpbiBheC50ZXh0c10KCiAgICBsYWJl
109
+ bHMgPSBbXQogICAgYXV0b3BjdHMgPSBbXQoKICAgIGlmIGxlbih0ZXh0cykgPT0gMiAqIGxlbih3
110
+ ZWRnZXMpOgogICAgICAgIGxhYmVscyA9IFt0ZXh0c1tpXSBmb3IgaSBpbiByYW5nZSgwLCAyICog
111
+ bGVuKHdlZGdlcyksIDIpXQogICAgICAgIGF1dG9wY3RzID0gW3RleHRzW2ldIGZvciBpIGluIHJh
112
+ bmdlKDEsIDIgKiBsZW4od2VkZ2VzKSwgMildCiAgICBlbHNlOgogICAgICAgIGxhYmVscyA9IHRl
113
+ eHRzWzogbGVuKHdlZGdlcyldCgogICAgZm9yIGlkeCwgd2VkZ2UgaW4gZW51bWVyYXRlKHdlZGdl
114
+ cyk6CiAgICAgICAgZWxlbWVudCA9IHsKICAgICAgICAgICAgImxhYmVsIjogbGFiZWxzW2lkeF0s
115
+ CiAgICAgICAgICAgICJhbmdsZSI6IGFicyh3ZWRnZS50aGV0YTIgLSB3ZWRnZS50aGV0YTEpLAog
116
+ ICAgICAgICAgICAicmFkaXVzIjogd2VkZ2UuciwKICAgICAgICAgICAgImF1dG9wY3QiOiBhdXRv
117
+ cGN0c1tpZHhdIGlmIGF1dG9wY3RzIGFuZCBsZW4oYXV0b3BjdHMpID4gaWR4IGVsc2UgTm9uZSwK
118
+ ICAgICAgICB9CiAgICAgICAgZWxlbWVudHMuYXBwZW5kKGVsZW1lbnQpCgogICAgcmV0dXJuIGVs
119
+ ZW1lbnRzCgoKIyBweWxpbnQ6IGRpc2FibGU9dG9vLW1hbnktYnJhbmNoZXMKZGVmIF9leHRyYWN0
120
+ X2JveF9jaGFydF9lbGVtZW50cyhheCk6CiAgICBjaGFuZ2Vfb3JpZW50YXRpb24gPSBGYWxzZQoK
121
+ ICAgIHh0aWNrbGFiZWxzID0gW2xhYmVsLmdldF90ZXh0KCkgZm9yIGxhYmVsIGluIGF4LmdldF94
122
+ dGlja2xhYmVscygpXQogICAgYm94ZXMgPSBbXQogICAgZm9yIGxhYmVsLCBib3ggaW4gemlwKHh0
123
+ aWNrbGFiZWxzLCBheC5wYXRjaGVzKToKICAgICAgICB2ZXJ0aWNlcyA9IGJveC5nZXRfcGF0aCgp
124
+ LnZlcnRpY2VzCiAgICAgICAgeF92ZXJ0aWNlcyA9IGxpc3QodmVydGljZXNbOiwgMF0pCiAgICAg
125
+ ICAgeV92ZXJ0aWNlcyA9IGxpc3QodmVydGljZXNbOiwgMV0pCiAgICAgICAgeCA9IG1pbih4X3Zl
126
+ cnRpY2VzKQogICAgICAgIHkgPSBtaW4oeV92ZXJ0aWNlcykKCiAgICAgICAgYm94ZXMuYXBwZW5k
127
+ KAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAieCI6IHgsCiAgICAgICAgICAgICAgICAi
128
+ eSI6IHksCiAgICAgICAgICAgICAgICAibGFiZWwiOiBsYWJlbCwKICAgICAgICAgICAgICAgICJ3
129
+ aWR0aCI6IG1heCh4X3ZlcnRpY2VzKSAtIHgsCiAgICAgICAgICAgICAgICAiaGVpZ2h0IjogbWF4
130
+ KHlfdmVydGljZXMpIC0geSwKICAgICAgICAgICAgICAgICJvdXRsaWVycyI6IFtdLAogICAgICAg
131
+ ICAgICB9CiAgICAgICAgKQoKICAgIG9yaWVudGF0aW9uID0gImhvcml6b250YWwiCiAgICBpZiBh
132
+ bGwoYm94WyJoZWlnaHQiXSA9PSBib3hlc1swXVsiaGVpZ2h0Il0gZm9yIGJveCBpbiBib3hlcyk6
133
+ CiAgICAgICAgb3JpZW50YXRpb24gPSAidmVydGljYWwiCgogICAgaWYgb3JpZW50YXRpb24gPT0g
134
+ InZlcnRpY2FsIjoKICAgICAgICBjaGFuZ2Vfb3JpZW50YXRpb24gPSBUcnVlCiAgICAgICAgZm9y
135
+ IGJveCBpbiBib3hlczoKICAgICAgICAgICAgYm94WyJ4Il0sIGJveFsieSJdID0gYm94WyJ5Il0s
136
+ IGJveFsieCJdCiAgICAgICAgICAgIGJveFsid2lkdGgiXSwgYm94WyJoZWlnaHQiXSA9IGJveFsi
137
+ aGVpZ2h0Il0sIGJveFsid2lkdGgiXQoKICAgIGZvciBsaW5lIGluIGF4LmxpbmVzOgogICAgICAg
138
+ IHhkYXRhID0gbGluZS5nZXRfeGRhdGEoKQogICAgICAgIHlkYXRhID0gbGluZS5nZXRfeWRhdGEo
139
+ KQoKICAgICAgICBpZiBvcmllbnRhdGlvbiA9PSAidmVydGljYWwiOgogICAgICAgICAgICB4ZGF0
140
+ YSwgeWRhdGEgPSB5ZGF0YSwgeGRhdGEKCiAgICAgICAgaWYgbGVuKHhkYXRhKSA8PSAxIG9yIGxl
141
+ bih5ZGF0YSkgIT0gMjoKICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgZm9yIGJveCBpbiBi
142
+ b3hlczoKICAgICAgICAgICAgaWYgYm94WyJ4Il0gPD0geGRhdGFbMF0gPD0geGRhdGFbMV0gPD0g
143
+ Ym94WyJ4Il0gKyBib3hbIndpZHRoIl06CiAgICAgICAgICAgICAgICAjIEhvcml6b250YWwgbGlu
144
+ ZSAobWVkaWFuIG9yIGNhcCkKICAgICAgICAgICAgICAgIGlmIGFicyh5ZGF0YVswXSAtIHlkYXRh
145
+ WzFdKSA8IDAuMDAxIGFuZCBib3hbInkiXSA8PSB5ZGF0YVswXSA8PSBib3hbInkiXSArIGJveFsi
146
+ aGVpZ2h0Il06CiAgICAgICAgICAgICAgICAgICAgYm94WyJtZWRpYW4iXSA9IHlkYXRhWzBdCiAg
147
+ ICAgICAgICAgICAgICAjIFZlcnRpY2FsIGxpbmUgKHdoaXNrZXJzKQogICAgICAgICAgICAgICAg
148
+ ZWxpZiBhYnMoeGRhdGFbMF0gLSB4ZGF0YVsxXSkgPCAwLjAwMToKICAgICAgICAgICAgICAgICAg
149
+ ICB5X21pbiA9IG1pbih5ZGF0YSkKICAgICAgICAgICAgICAgICAgICB5X21heCA9IG1heCh5ZGF0
150
+ YSkKCiAgICAgICAgICAgICAgICAgICAgIyBJZiBhdHRhY2hlZCB0byBib3R0b20gb2YgYm94CiAg
151
+ ICAgICAgICAgICAgICAgICAgaWYgYWJzKHlfbWF4IC0gYm94WyJ5Il0pIDwgMC4wMDE6CiAgICAg
152
+ ICAgICAgICAgICAgICAgICAgIGJveFsid2hpc2tlcl9sb3dlciJdID0geV9taW4KCiAgICAgICAg
153
+ ICAgICAgICAgICAgIyBJZiBhdHRhY2hlZCB0byB0b3Agb2YgYm94CiAgICAgICAgICAgICAgICAg
154
+ ICAgZWxpZiBhYnMoeV9taW4gLSAoYm94WyJ5Il0gKyBib3hbImhlaWdodCJdKSkgPCAwLjAwMToK
155
+ ICAgICAgICAgICAgICAgICAgICAgICAgYm94WyJ3aGlza2VyX3VwcGVyIl0gPSB5X21heAogICAg
156
+ ICAgICAgICAgICAgYnJlYWsKCiAgICBvdXRsaWVyX2NhbmRpZGF0ZXMgPSBbXQoKICAgICMgQ2hl
157
+ Y2sgZm9yIGFueSBtYXJrZXJzIGluIGFsbCBhcnRpc3RzCiAgICBmb3IgYXJ0aXN0IGluIGF4Lmdl
158
+ dF9jaGlsZHJlbigpOgogICAgICAgIGlmIGhhc2F0dHIoYXJ0aXN0LCAiZ2V0X3hkYXRhIikgYW5k
159
+ IGhhc2F0dHIoYXJ0aXN0LCAiZ2V0X3lkYXRhIik6CiAgICAgICAgICAgIHRyeToKICAgICAgICAg
160
+ ICAgICAgIHhkYXRhID0gYXJ0aXN0LmdldF94ZGF0YSgpCiAgICAgICAgICAgICAgICB5ZGF0YSA9
161
+ IGFydGlzdC5nZXRfeWRhdGEoKQoKICAgICAgICAgICAgICAgIGlmIG9yaWVudGF0aW9uID09ICJ2
162
+ ZXJ0aWNhbCI6CiAgICAgICAgICAgICAgICAgICAgeGRhdGEsIHlkYXRhID0geWRhdGEsIHhkYXRh
163
+ CgogICAgICAgICAgICAgICAgaWYgaXNpbnN0YW5jZSh4ZGF0YSwgKGxpc3QsIG5wLm5kYXJyYXkp
164
+ KSBhbmQgaXNpbnN0YW5jZSh5ZGF0YSwgKGxpc3QsIG5wLm5kYXJyYXkpKToKICAgICAgICAgICAg
165
+ ICAgICAgICBmb3IgaSBpbiByYW5nZShtaW4obGVuKHhkYXRhKSwgbGVuKHlkYXRhKSkpOgogICAg
166
+ ICAgICAgICAgICAgICAgICAgICBvdXRsaWVyX2NhbmRpZGF0ZXMuYXBwZW5kKChmbG9hdCh4ZGF0
167
+ YVtpXSksIGZsb2F0KHlkYXRhW2ldKSkpCiAgICAgICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAg
168
+ ICAgIHBhc3MKCiAgICAjIEFzc2lnbiBwb2ludHMgdG8gYm94ZXMgYW5kIGRldGVybWluZSBpZiB0
169
+ aGV5J3JlIG91dGxpZXJzCiAgICBmb3IgeCwgeSBpbiBvdXRsaWVyX2NhbmRpZGF0ZXM6CiAgICAg
170
+ ICAgZm9yIGJveCBpbiBib3hlczoKICAgICAgICAgICAgaWYgYm94WyJ4Il0gPD0geCA8PSBib3hb
171
+ IngiXSArIGJveFsid2lkdGgiXToKICAgICAgICAgICAgICAgIGJveF9jZW50ZXIgPSBib3hbIngi
172
+ XSArIGJveFsid2lkdGgiXSAvIDIKICAgICAgICAgICAgICAgIGlmIGFicyh4IC0gYm94X2NlbnRl
173
+ cikgPCAwLjAwMToKICAgICAgICAgICAgICAgICAgICB5X21pbiA9IGJveFsieSJdCiAgICAgICAg
174
+ ICAgICAgICAgICAgeV9tYXggPSBib3hbInkiXSArIGJveFsiaGVpZ2h0Il0KICAgICAgICAgICAg
175
+ ICAgICAgICBpZiBib3guZ2V0KCJ3aGlza2VyX2xvd2VyIiwgTm9uZSk6CiAgICAgICAgICAgICAg
176
+ ICAgICAgICAgIHlfbWluID0gYm94WyJ3aGlza2VyX2xvd2VyIl0KICAgICAgICAgICAgICAgICAg
177
+ ICBpZiBib3guZ2V0KCJ3aGlza2VyX3VwcGVyIiwgTm9uZSk6CiAgICAgICAgICAgICAgICAgICAg
178
+ ICAgIHlfbWF4ID0gYm94WyJ3aGlza2VyX3VwcGVyIl0KICAgICAgICAgICAgICAgICAgICBpZiB5
179
+ IDwgeV9taW4gb3IgeSA+IHlfbWF4OgogICAgICAgICAgICAgICAgICAgICAgICBib3hbIm91dGxp
180
+ ZXJzIl0uYXBwZW5kKHkpCiAgICAgICAgICAgICAgICBicmVhawoKICAgIHJldHVybiBbCiAgICAg
181
+ ICAgewogICAgICAgICAgICAibGFiZWwiOiBib3hbImxhYmVsIl0sCiAgICAgICAgICAgICJtaW4i
182
+ OiBib3guZ2V0KCJ3aGlza2VyX2xvd2VyIiwgTm9uZSksCiAgICAgICAgICAgICJmaXJzdF9xdWFy
183
+ dGlsZSI6IGJveFsieSJdLAogICAgICAgICAgICAibWVkaWFuIjogYm94LmdldCgibWVkaWFuIiwg
184
+ Tm9uZSksCiAgICAgICAgICAgICJ0aGlyZF9xdWFydGlsZSI6IGJveFsieSJdICsgYm94WyJoZWln
185
+ aHQiXSwKICAgICAgICAgICAgIm1heCI6IGJveC5nZXQoIndoaXNrZXJfdXBwZXIiLCBOb25lKSwK
186
+ ICAgICAgICAgICAgIm91dGxpZXJzIjogYm94WyJvdXRsaWVycyJdLAogICAgICAgIH0KICAgICAg
187
+ ICBmb3IgYm94IGluIGJveGVzCiAgICBdLCBjaGFuZ2Vfb3JpZW50YXRpb24KCgpkZWYgX3NhdmVf
188
+ ZmlndXJlX2FzX2Jhc2U2NChmaWcsIGJib3hfaW5jaGVzPSJ0aWdodCIsIGRwaT0xMDApOgogICAg
189
+ IyBGaXJzdCBzYXZlIHdpdGggbWF0cGxvdGxpYgogICAgcG5nX2J1ZmZlciA9IGlvLkJ5dGVzSU8o
190
+ KQogICAgZmlnLnNhdmVmaWcocG5nX2J1ZmZlciwgZm9ybWF0PSJwbmciLCBiYm94X2luY2hlcz1i
191
+ Ym94X2luY2hlcywgZHBpPWRwaSkKICAgIHBuZ19idWZmZXIuc2VlaygwKQoKICAgICMgT3BlbiB3
192
+ aXRoIFBJTCBhbmQgYXBwbHkgbWF4aW11bSBjb21wcmVzc2lvbgogICAgd2l0aCBwaWxfaW1nLm9w
193
+ ZW4ocG5nX2J1ZmZlcikgYXMgaW1nOgogICAgICAgIG9wdGltaXplZF9idWZmZXIgPSBpby5CeXRl
194
+ c0lPKCkKICAgICAgICBpbWcuc2F2ZShvcHRpbWl6ZWRfYnVmZmVyLCBmb3JtYXQ9InBuZyIsIG9w
195
+ dGltaXplPVRydWUsIHF1YWxpdHk9MTAwLCBjb21wcmVzc19sZXZlbD05KQogICAgICAgIG9wdGlt
196
+ aXplZF9idWZmZXIuc2VlaygwKQogICAgICAgIHJldHVybiBiYXNlNjQuYjY0ZW5jb2RlKG9wdGlt
197
+ aXplZF9idWZmZXIuZ2V0dmFsdWUoKSkuZGVjb2RlKCJ1dGYtOCIpCgoKZGVmIF9nZXRfZmlndXJl
198
+ X2hhc2goZmlnKToKICAgIHBuZ19idWZmZXIgPSBpby5CeXRlc0lPKCkKICAgIGZpZy5zYXZlZmln
199
+ KHBuZ19idWZmZXIsIGZvcm1hdD0icG5nIiwgZHBpPTUwKQogICAgcmV0dXJuIGhhc2hsaWIubWQ1
200
+ KHBuZ19idWZmZXIuZ2V0dmFsdWUoKSkuaGV4ZGlnZXN0KCkKCgpkZWYgX2dldF9jaGFydF90eXBl
201
+ KGF4KToKICAgIG9iamVjdHMgPSBsaXN0KAogICAgICAgIGZpbHRlcigKICAgICAgICAgICAgbGFt
202
+ YmRhIG9iajogbm90IGlzaW5zdGFuY2Uob2JqLCBtcGwudGV4dC5UZXh0KSBhbmQgbm90IGlzaW5z
203
+ dGFuY2Uob2JqLCBtcGwucGF0Y2hlcy5TaGFkb3cpLAogICAgICAgICAgICBheC5fY2hpbGRyZW4s
204
+ ICAjIHB5bGludDogZGlzYWJsZT1wcm90ZWN0ZWQtYWNjZXNzCiAgICAgICAgKQogICAgKQoKICAg
205
+ ICMgQ2hlY2sgZm9yIExpbmUgcGxvdHMKICAgIGlmIGFsbChpc2luc3RhbmNlKGxpbmUsIG1wbC5s
206
+ aW5lcy5MaW5lMkQpIGZvciBsaW5lIGluIG9iamVjdHMpOgogICAgICAgIHJldHVybiAibGluZSIK
207
+ CiAgICBpZiBhbGwoaXNpbnN0YW5jZShib3hfb3JfcGF0aCwgKG1wbC5wYXRjaGVzLlBhdGhQYXRj
208
+ aCwgbXBsLmxpbmVzLkxpbmUyRCkpIGZvciBib3hfb3JfcGF0aCBpbiBvYmplY3RzKToKICAgICAg
209
+ ICByZXR1cm4gImJveF9hbmRfd2hpc2tlciIKCiAgICBmaWx0ZXJlZCA9IFtdCiAgICBmb3Igb2Jq
210
+ IGluIG9iamVjdHM6CiAgICAgICAgaWYgaXNpbnN0YW5jZShvYmosIG1wbC5saW5lcy5MaW5lMkQp
211
+ IGFuZCBfaXNfZ3JpZF9saW5lKG9iaik6CiAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgZmls
212
+ dGVyZWQuYXBwZW5kKG9iaikKCiAgICBvYmplY3RzID0gZmlsdGVyZWQKCiAgICAjIENoZWNrIGZv
213
+ ciBTY2F0dGVyIHBsb3RzCiAgICBpZiBhbGwoaXNpbnN0YW5jZShwYXRoLCBtcGwuY29sbGVjdGlv
214
+ bnMuUGF0aENvbGxlY3Rpb24pIGZvciBwYXRoIGluIG9iamVjdHMpOgogICAgICAgIHJldHVybiAi
215
+ c2NhdHRlciIKCiAgICAjIENoZWNrIGZvciBCYXIgcGxvdHMKICAgIGlmIGFsbChpc2luc3RhbmNl
216
+ KHJlY3QsIG1wbC5wYXRjaGVzLlJlY3RhbmdsZSkgZm9yIHJlY3QgaW4gb2JqZWN0cyk6CiAgICAg
217
+ ICAgcmV0dXJuICJiYXIiCgogICAgIyBDaGVjayBmb3IgUGllIHBsb3RzCiAgICBpZiBhbGwoaXNp
218
+ bnN0YW5jZShhcnRpc3QsIG1wbC5wYXRjaGVzLldlZGdlKSBmb3IgYXJ0aXN0IGluIG9iamVjdHMp
219
+ OgogICAgICAgIHJldHVybiAicGllIgoKICAgIHJldHVybiAidW5rbm93biIKCgpkZWYgX2lzX2F1
220
+ dG9fZW1wdHlfYXhpcyhheCk6CiAgICByZXR1cm4gYXguZ2V0X3N1YnBsb3RzcGVjKCkgaXMgbm90
221
+ IE5vbmUgYW5kIG5vdCBheC5oYXNfZGF0YSgpCgoKZGVmIF9pc19jb2xvcmJhcl9heGlzKGF4KToK
222
+ ICAgIHJldHVybiBhbnkoCiAgICAgICAgIyBweWxpbnQ6IGRpc2FibGU9cHJvdGVjdGVkLWFjY2Vz
223
+ cwogICAgICAgIGlzaW5zdGFuY2UoY2hpbGQsIG1wbC5jb2xvcmJhci5fQ29sb3JiYXJTcGluZSkK
224
+ ICAgICAgICBmb3IgY2hpbGQgaW4gYXguZ2V0X2NoaWxkcmVuKCkKICAgICkKCgpkZWYgX2ZpbHRl
225
+ cl9vdXRfdW53YW50ZWRfYXhlcyhheGVzKToKICAgIHJldHVybiBbYXggZm9yIGF4IGluIGF4ZXMg
226
+ aWYgbm90IF9pc19hdXRvX2VtcHR5X2F4aXMoYXgpIGFuZCBub3QgX2lzX2NvbG9yYmFyX2F4aXMo
227
+ YXgpXQoKCmRlZiBfZXh0cmFjdF90aWNrc19kYXRhKGNvbnZlcnRlcjogYW55LCB0aWNrczogYW55
228
+ KSAtPiBsaXN0OgogICAgaWYgaXNpbnN0YW5jZShjb252ZXJ0ZXIsIG1wbC5kYXRlcy5fU3dpdGNo
229
+ YWJsZURhdGVDb252ZXJ0ZXIpOiAgIyBweWxpbnQ6IGRpc2FibGU9cHJvdGVjdGVkLWFjY2Vzcwog
230
+ ICAgICAgIHJldHVybiBbbXBsLmRhdGVzLm51bTJkYXRlKHRpY2spLmlzb2Zvcm1hdCgpIGZvciB0
231
+ aWNrIGluIHRpY2tzXQogICAgdHJ5OgogICAgICAgIHJldHVybiBbZmxvYXQodGljaykgZm9yIHRp
232
+ Y2sgaW4gdGlja3NdCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgIHJldHVybiBsaXN0KHRp
233
+ Y2tzKQoKCmRlZiBfZXh0cmFjdF9zY2FsZShjb252ZXJ0ZXIsIHNjYWxlOiBzdHIsIHRpY2tzLCBs
234
+ YWJlbHMpIC0+IHN0cjoKICAgIGlmIGlzaW5zdGFuY2UoY29udmVydGVyLCBtcGwuZGF0ZXMuX1N3
235
+ aXRjaGFibGVEYXRlQ29udmVydGVyKTogICMgcHlsaW50OiBkaXNhYmxlPXByb3RlY3RlZC1hY2Nl
236
+ c3MKICAgICAgICByZXR1cm4gImRhdGV0aW1lIgoKICAgICMgSWYgdGhlIHNjYWxlIGlzIG5vdCBs
237
+ aW5lYXIsIGl0IGNhbid0IGJlIGNhdGVnb3JpY2FsCiAgICBpZiBzY2FsZSAhPSAibGluZWFyIjoK
238
+ ICAgICAgICByZXR1cm4gc2NhbGUKCiAgICAjIElmIGFsbCB0aGUgdGlja3MgYXJlIGludGVnZXJz
239
+ IGFuZCBhcmUgaW4gb3JkZXIgZnJvbSAwIHRvIG4tMQogICAgIyBhbmQgdGhlIGxhYmVscyBhcmVu
240
+ J3QgY29ycmVzcG9uZGluZyB0byB0aGUgdGlja3MsIGl0J3MgY2F0ZWdvcmljYWwKICAgIGZvciBp
241
+ LCB0aWNrX2FuZF9sYWJlbCBpbiBlbnVtZXJhdGUoemlwKHRpY2tzLCBsYWJlbHMpKToKICAgICAg
242
+ ICB0aWNrLCBsYWJlbCA9IHRpY2tfYW5kX2xhYmVsCiAgICAgICAgaWYgaXNpbnN0YW5jZSh0aWNr
243
+ LCAoaW50LCBmbG9hdCkpIGFuZCB0aWNrID09IGkgYW5kIHN0cihpKSAhPSBsYWJlbDoKICAgICAg
244
+ ICAgICAgY29udGludWUKICAgICAgICAjIEZvdW5kIGEgdGljaywgd2hpY2ggd291bGRuJ3QgYmUg
245
+ aW4gYSBjYXRlZ29yaWNhbCBzY2FsZQogICAgICAgIHJldHVybiAibGluZWFyIgoKICAgIHJldHVy
246
+ biAiY2F0ZWdvcmljYWwiCgoKZGVmIF9leHRyYWN0X2NoYXJ0X2RhdGEoYXgpOgogICAgZGF0YSA9
247
+ IHt9CgogICAgZGF0YVsidGl0bGUiXSA9IGF4LmdldF90aXRsZSgpCgogICAgZGF0YVsieF9sYWJl
248
+ bCJdID0gYXguZ2V0X3hsYWJlbCgpCiAgICBkYXRhWyJ5X2xhYmVsIl0gPSBheC5nZXRfeWxhYmVs
249
+ KCkKCiAgICB4X3RpY2tfbGFiZWxzID0gW2xhYmVsLmdldF90ZXh0KCkgZm9yIGxhYmVsIGluIGF4
250
+ LmdldF94dGlja2xhYmVscygpXQogICAgZGF0YVsieF90aWNrcyJdID0gX2V4dHJhY3RfdGlja3Nf
251
+ ZGF0YShheC54YXhpcy5nZXRfY29udmVydGVyKCksIGF4LmdldF94dGlja3MoKSkKICAgIGRhdGFb
252
+ InhfdGlja19sYWJlbHMiXSA9IHhfdGlja19sYWJlbHMKICAgIGRhdGFbInhfc2NhbGUiXSA9IF9l
253
+ eHRyYWN0X3NjYWxlKGF4LnhheGlzLmdldF9jb252ZXJ0ZXIoKSwgYXguZ2V0X3hzY2FsZSgpLCBh
254
+ eC5nZXRfeHRpY2tzKCksIHhfdGlja19sYWJlbHMpCgogICAgeV90aWNrX2xhYmVscyA9IFtsYWJl
255
+ bC5nZXRfdGV4dCgpIGZvciBsYWJlbCBpbiBheC5nZXRfeXRpY2tsYWJlbHMoKV0KICAgIGRhdGFb
256
+ InlfdGlja3MiXSA9IF9leHRyYWN0X3RpY2tzX2RhdGEoYXgueWF4aXMuZ2V0X2NvbnZlcnRlcigp
257
+ LCBheC5nZXRfeXRpY2tzKCkpCiAgICBkYXRhWyJ5X3RpY2tfbGFiZWxzIl0gPSB5X3RpY2tfbGFi
258
+ ZWxzCiAgICBkYXRhWyJ5X3NjYWxlIl0gPSBfZXh0cmFjdF9zY2FsZShheC55YXhpcy5nZXRfY29u
259
+ dmVydGVyKCksIGF4LmdldF95c2NhbGUoKSwgYXguZ2V0X3l0aWNrcygpLCB5X3RpY2tfbGFiZWxz
260
+ KQoKICAgIGNoYXJ0X3R5cGUgPSBfZ2V0X2NoYXJ0X3R5cGUoYXgpCiAgICBlbGVtZW50cyA9IFtd
261
+ CiAgICBjaGFuZ2Vfb3JpZW50YXRpb24gPSBGYWxzZQoKICAgIGlmIGNoYXJ0X3R5cGUgPT0gImxp
262
+ bmUiOgogICAgICAgIGVsZW1lbnRzID0gX2V4dHJhY3RfbGluZV9jaGFydF9lbGVtZW50cyhheCkK
263
+ ICAgIGVsaWYgY2hhcnRfdHlwZSA9PSAic2NhdHRlciI6CiAgICAgICAgZWxlbWVudHMgPSBfZXh0
264
+ cmFjdF9zY2F0dGVyX2NoYXJ0X2VsZW1lbnRzKGF4KQogICAgZWxpZiBjaGFydF90eXBlID09ICJi
265
+ YXIiOgogICAgICAgIGVsZW1lbnRzLCBjaGFuZ2Vfb3JpZW50YXRpb24gPSBfZXh0cmFjdF9iYXJf
266
+ Y2hhcnRfZWxlbWVudHMoYXgpCiAgICBlbGlmIGNoYXJ0X3R5cGUgPT0gImJveF9hbmRfd2hpc2tl
267
+ ciI6CiAgICAgICAgZWxlbWVudHMsIGNoYW5nZV9vcmllbnRhdGlvbiA9IF9leHRyYWN0X2JveF9j
268
+ aGFydF9lbGVtZW50cyhheCkKICAgIGVsaWYgY2hhcnRfdHlwZSA9PSAicGllIjoKICAgICAgICBl
269
+ bGVtZW50cyA9IF9leHRyYWN0X3BpZV9jaGFydF9lbGVtZW50cyhheCkKCiAgICBpZiBjaGFuZ2Vf
270
+ b3JpZW50YXRpb246CiAgICAgICAgZGF0YVsieF9sYWJlbCJdLCBkYXRhWyJ5X2xhYmVsIl0gPSBk
271
+ YXRhWyJ5X2xhYmVsIl0sIGRhdGFbInhfbGFiZWwiXQoKICAgIGRhdGFbInR5cGUiXSA9IGNoYXJ0
272
+ X3R5cGUKICAgIGRhdGFbImVsZW1lbnRzIl0gPSBlbGVtZW50cwoKICAgIHJldHVybiBkYXRhCgoK
273
+ ZGVmIF9jdXN0b21fanNvbl9zZXJpYWxpemVyKG9iaik6CiAgICBpZiBpc2luc3RhbmNlKG9iaiwg
274
+ bnAuaW50ZWdlcik6CiAgICAgICAgcmV0dXJuIGludChvYmopCiAgICBpZiBpc2luc3RhbmNlKG9i
275
+ aiwgbnAuZmxvYXRpbmcpOgogICAgICAgIHJldHVybiBmbG9hdChvYmopCiAgICBpZiBpc2luc3Rh
276
+ bmNlKG9iaiwgbnAubmRhcnJheSk6CiAgICAgICAgcmV0dXJuIG9iai50b2xpc3QoKQogICAgaWYg
277
+ aXNpbnN0YW5jZShvYmosIHNldCk6CiAgICAgICAgcmV0dXJuIGxpc3Qob2JqKQogICAgcmFpc2Ug
278
+ VHlwZUVycm9yKGYiVHlwZSB7dHlwZShvYmopfSBub3Qgc2VyaWFsaXphYmxlIikKCgpkZWYgZXh0
279
+ cmFjdF9hbmRfcHJpbnRfZmlndXJlX21ldGFkYXRhKGZpZyk6CiAgICAiIiJFeHRyYWN0IG1ldGFk
280
+ YXRhIGZyb20gYSBtYXRwbG90bGliIGZpZ3VyZSBhbmQgcHJpbnQgYXMgSlNPTiIiIgogICAgbWV0
281
+ YWRhdGEgPSB7fQogICAgc3VicGxvdHMgPSBbXQoKICAgIGF4ZXMgPSBfZmlsdGVyX291dF91bndh
282
+ bnRlZF9heGVzKGZpZy5heGVzKQoKICAgIGZvciBheCBpbiBheGVzOgogICAgICAgIGRhdGEgPSBf
283
+ ZXh0cmFjdF9jaGFydF9kYXRhKGF4KQogICAgICAgIHN1YnBsb3RzLmFwcGVuZChkYXRhKQoKICAg
284
+ IGlmIGxlbihzdWJwbG90cykgPiAxOgogICAgICAgIG1ldGFkYXRhID0gewogICAgICAgICAgICAi
285
+ dGl0bGUiOiBmaWcudGV4dHNbMF0uZ2V0X3RleHQoKSBpZiBmaWcudGV4dHMgYW5kIGxlbihmaWcu
286
+ dGV4dHMpID4gMCBlbHNlIE5vbmUsCiAgICAgICAgICAgICJ0eXBlIjogImNvbXBvc2l0ZV9jaGFy
287
+ dCIsCiAgICAgICAgICAgICJlbGVtZW50cyI6IHN1YnBsb3RzLAogICAgICAgIH0KICAgIGVsc2U6
288
+ CiAgICAgICAgbWV0YWRhdGEgPSBzdWJwbG90c1swXSBpZiBzdWJwbG90cyBhbmQgbGVuKHN1YnBs
289
+ b3RzKSA+IDAgZWxzZSB7InR5cGUiOiAidW5rbm93biJ9CgogICAgbWV0YWRhdGFbInBuZyJdID0g
290
+ X3NhdmVfZmlndXJlX2FzX2Jhc2U2NChmaWcpCiAgICBqc29uX291dHB1dCA9IHsidHlwZSI6ICJj
291
+ aGFydCIsICJ2YWx1ZSI6IG1ldGFkYXRhfQoKICAgIHByaW50KGYiZHRuX2FydGlmYWN0X2szOWZk
292
+ Mjp7anNvbi5kdW1wcyhqc29uX291dHB1dCwgZGVmYXVsdD1fY3VzdG9tX2pzb25fc2VyaWFsaXpl
293
+ cil9IikKCgpjbGFzcyBNYXRwbG90bGliRmluZGVyKE1ldGFQYXRoRmluZGVyKToKICAgICIiIkN1
294
+ c3RvbSBmaW5kZXIgdG8gaW50ZXJjZXB0IG1hdHBsb3RsaWIucHlwbG90IGltcG9ydHMiIiIKCiAg
295
+ ICBkZWYgZmluZF9zcGVjKHNlbGYsIGZ1bGxuYW1lLCBwYXRoLCB0YXJnZXQ9Tm9uZSk6ICAjIHB5
296
+ bGludDogZGlzYWJsZT11bnVzZWQtYXJndW1lbnQKICAgICAgICBnbG9iYWwgcGx0X3BhdGNoZWQs
297
+ IG5wLCBtcGwsIHBpbF9pbWcgICMgcHlsaW50OiBkaXNhYmxlPWdsb2JhbC1zdGF0ZW1lbnQKICAg
298
+ ICAgICBpZiBmdWxsbmFtZSA9PSAibWF0cGxvdGxpYi5weXBsb3QiIGFuZCBub3QgcGx0X3BhdGNo
299
+ ZWQ6CiAgICAgICAgICAgIHBsdF9wYXRjaGVkID0gVHJ1ZQoKICAgICAgICAgICAgIyBJbXBvcnQg
300
+ bnVtcHkgYW5kIG1hdHBsb3RsaWIgb25jZSB3ZSBhcmUgc3VyZSB3ZSBuZWVkIHRoZW0KICAgICAg
301
+ ICAgICAgIyBweWxpbnQ6IGRpc2FibGU9aW1wb3J0LW91dHNpZGUtdG9wbGV2ZWwKICAgICAgICAg
302
+ ICAgaW1wb3J0IG1hdHBsb3RsaWIKICAgICAgICAgICAgaW1wb3J0IG51bXB5CiAgICAgICAgICAg
303
+ IGZyb20gUElMIGltcG9ydCBJbWFnZQoKICAgICAgICAgICAgIyBTdG9yZSB0aGVtIGluIGdsb2Jh
304
+ bCB2YXJpYWJsZXMgZm9yIHVzZSB0aHJvdWdob3V0IHRoZSBtb2R1bGUKICAgICAgICAgICAgbnAg
305
+ PSBudW1weQogICAgICAgICAgICBtcGwgPSBtYXRwbG90bGliCiAgICAgICAgICAgIHBpbF9pbWcg
306
+ PSBJbWFnZQoKICAgICAgICAgICAgb3JpZ2luYWxfc3BlYyA9IGZpbmRfc3BlYyhmdWxsbmFtZSkK
307
+ ICAgICAgICAgICAgaWYgb3JpZ2luYWxfc3BlYyBpcyBOb25lOgogICAgICAgICAgICAgICAgcmV0
308
+ dXJuIE5vbmUKICAgICAgICAgICAgcmV0dXJuIHNwZWNfZnJvbV9sb2FkZXIoCiAgICAgICAgICAg
309
+ ICAgICBmdWxsbmFtZSwKICAgICAgICAgICAgICAgIE1hdHBsb3RsaWJMb2FkZXIob3JpZ2luYWxf
310
+ c3BlYy5sb2FkZXIpLAogICAgICAgICAgICAgICAgb3JpZ2luPW9yaWdpbmFsX3NwZWMub3JpZ2lu
311
+ LAogICAgICAgICAgICAgICAgaXNfcGFja2FnZT1vcmlnaW5hbF9zcGVjLnN1Ym1vZHVsZV9zZWFy
312
+ Y2hfbG9jYXRpb25zIGlzIG5vdCBOb25lLAogICAgICAgICAgICApCiAgICAgICAgcmV0dXJuIE5v
313
+ bmUKCgpjbGFzcyBNYXRwbG90bGliTG9hZGVyKExvYWRlcik6CiAgICAiIiJDdXN0b20gbG9hZGVy
314
+ IHRvIHBhdGNoIHRoZSBtYXRwbG90bGliLnB5cGxvdCBtb2R1bGUiIiIKCiAgICBkZWYgX19pbml0
315
+ X18oc2VsZiwgb3JpZ2luYWxfbG9hZGVyKToKICAgICAgICBzZWxmLm9yaWdpbmFsX2xvYWRlciA9
316
+ IG9yaWdpbmFsX2xvYWRlcgoKICAgIGRlZiBjcmVhdGVfbW9kdWxlKHNlbGYsIHNwZWMpOgogICAg
317
+ ICAgIHJldHVybiBzZWxmLm9yaWdpbmFsX2xvYWRlci5jcmVhdGVfbW9kdWxlKHNwZWMpCgogICAg
318
+ ZGVmIGV4ZWNfbW9kdWxlKHNlbGYsIG1vZHVsZSk6CiAgICAgICAgc2VsZi5vcmlnaW5hbF9sb2Fk
319
+ ZXIuZXhlY19tb2R1bGUobW9kdWxlKQogICAgICAgIGlmIGhhc2F0dHIobW9kdWxlLCAic2hvdyIp
320
+ OgogICAgICAgICAgICBvcmlnaW5hbF9zaG93ID0gbW9kdWxlLnNob3cKCiAgICAgICAgICAgIGRl
321
+ ZiBjdXN0b21fc2hvdygqYXJncywgKiprd2FyZ3MpOgogICAgICAgICAgICAgICAgZ2xvYmFsIHBy
322
+ b2Nlc3NlZF9maWd1cmVzICAjIHB5bGludDogZGlzYWJsZT1nbG9iYWwtdmFyaWFibGUtbm90LWFz
323
+ c2lnbmVkCiAgICAgICAgICAgICAgICBmaWdfbnVtcyA9IG1vZHVsZS5nZXRfZmlnbnVtcygpCiAg
324
+ ICAgICAgICAgICAgICBmb3IgZmlnX251bSBpbiBmaWdfbnVtczoKICAgICAgICAgICAgICAgICAg
325
+ ICBmaWcgPSBtb2R1bGUuZmlndXJlKGZpZ19udW0pCiAgICAgICAgICAgICAgICAgICAgZmlnX2hh
326
+ c2ggPSBfZ2V0X2ZpZ3VyZV9oYXNoKGZpZykKICAgICAgICAgICAgICAgICAgICBpZiBmaWdfaGFz
327
+ aCBub3QgaW4gcHJvY2Vzc2VkX2ZpZ3VyZXM6CiAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJh
328
+ Y3RfYW5kX3ByaW50X2ZpZ3VyZV9tZXRhZGF0YShmaWcpCiAgICAgICAgICAgICAgICAgICAgICAg
329
+ IHByb2Nlc3NlZF9maWd1cmVzLmFkZChmaWdfaGFzaCkKICAgICAgICAgICAgICAgIHJlc3VsdCA9
330
+ IG9yaWdpbmFsX3Nob3coKmFyZ3MsICoqa3dhcmdzKQogICAgICAgICAgICAgICAgbW9kdWxlLmNs
331
+ b3NlKCJhbGwiKQogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgICAgICAgICAgbW9k
332
+ dWxlLnNob3cgPSBjdXN0b21fc2hvdwoKCmRlZiBzZXR1cF91c2VyX2NvZGVfZW52aXJvbm1lbnQo
333
+ Y29kZSk6CiAgICAiIiJTZXQgdXAgdGhlIG1vZHVsZSB0byBydW4gdXNlciBjb2RlIGluIiIiCiAg
334
+ ICBtb2R1bGUgPSB0eXBlcy5Nb2R1bGVUeXBlKCJfX21haW5fXyIpCiAgICBtb2R1bGUuX19maWxl
335
+ X18gPSAiPHRhcmdldF9jb2RlPiIKICAgIHN5cy5tb2R1bGVzWyJfX21haW5fXyJdID0gbW9kdWxl
336
+ CiAgICBjb2RlX2xpbmVzID0gY29kZS5zcGxpdGxpbmVzKCkKICAgIGxpbmVjYWNoZS5jYWNoZVsi
337
+ PHRhcmdldF9jb2RlPiJdID0gKGxlbihjb2RlKSwgTm9uZSwgY29kZV9saW5lcywgIjx0YXJnZXRf
338
+ Y29kZT4iKQogICAgcmV0dXJuIG1vZHVsZQoKCmRlZiBydW5fdXNlcl9jb2RlKGNvZGUpOgogICAg
339
+ IiIiUnVuIHRoZSB1c2VyIGNvZGUgd2l0aCB0aGUgbWF0cGxvdGxpYiBpbnRlcmNlcHRvciBpbnN0
340
+ YWxsZWQiIiIKICAgICMgSW5zdGFsbCBtYXRwbG90bGliIGludGVyY2VwdG9yCiAgICBzeXMubWV0
341
+ YV9wYXRoLmluc2VydCgwLCBNYXRwbG90bGliRmluZGVyKCkpCgogICAgIyBTZXQgdXAgY2xlYW4g
342
+ ZW52aXJvbm1lbnQgZm9yIHVzZXIgY29kZQogICAgbW9kdWxlID0gc2V0dXBfdXNlcl9jb2RlX2Vu
343
+ dmlyb25tZW50KGNvZGUpCgogICAgIyBDb21waWxlIGFuZCBydW4gdGhlIGNvZGUKICAgIGNvbXBp
344
+ bGVkID0gY29tcGlsZShjb2RlLCAiPHRhcmdldF9jb2RlPiIsICJleGVjIikKCiAgICAjIEV4ZWN1
345
+ dGUgaW4gdGhlIG1vZHVsZSdzIG5hbWVzcGFjZQogICAgZXhlYyhjb21waWxlZCwgbW9kdWxlLl9f
346
+ ZGljdF9fKSAgIyBweWxpbnQ6IGRpc2FibGU9ZXhlYy11c2VkCgoKaWYgX19uYW1lX18gPT0gIl9f
347
+ bWFpbl9fIjoKICAgIHRyeToKICAgICAgICAjIEdldCB0aGUgZW5jb2RlZCB1c2VyIGNvZGUKICAg
348
+ ICAgICB1c2VyX2NvZGUgPSBiYXNlNjQuYjY0ZGVjb2RlKCJ7ZW5jb2RlZF9jb2RlfSIpLmRlY29k
349
+ ZSgpCgogICAgICAgICMgUnVuIHRoZSBjb2RlCiAgICAgICAgcnVuX3VzZXJfY29kZSh1c2VyX2Nv
350
+ ZGUpCiAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICMgUHJpbnQgb25seSB0aGUgcmVsZXZh
351
+ bnQgcGFydHMgb2YgdGhlIHRyYWNlYmFjawogICAgICAgIGV4Y190eXBlLCBleGNfdmFsdWUsIGV4
352
+ Y190YiA9IHN5cy5leGNfaW5mbygpCgogICAgICAgICMgRmlsdGVyIHRyYWNlYmFjayB0byBvbmx5
353
+ IHNob3cgdXNlciBjb2RlIGZyYW1lcwogICAgICAgIGZpbHRlcmVkX3RiID0gW10KICAgICAgICB0
354
+ YiA9IGV4Y190YgogICAgICAgIHdoaWxlIHRiIGlzIG5vdCBOb25lOgogICAgICAgICAgICBpZiB0
355
+ Yi50Yl9mcmFtZS5mX2NvZGUuY29fZmlsZW5hbWUgPT0gIjx0YXJnZXRfY29kZT4iOgogICAgICAg
356
+ ICAgICAgICAgZmlsdGVyZWRfdGIuYXBwZW5kKHRiKQogICAgICAgICAgICB0YiA9IHRiLnRiX25l
357
+ eHQKCiAgICAgICAgaWYgZmlsdGVyZWRfdGI6CiAgICAgICAgICAgICMgQ3JlYXRlIGEgbmV3IHRy
358
+ YWNlYmFjayBmcm9tIHRoZSBmaWx0ZXJlZCBmcmFtZXMKICAgICAgICAgICAgZXhjX3ZhbHVlLl9f
359
+ dHJhY2ViYWNrX18gPSBmaWx0ZXJlZF90YlstMV0KICAgICAgICAgICAgdHJhY2ViYWNrLnByaW50
360
+ X2V4Y2VwdGlvbihleGNfdHlwZSwgZXhjX3ZhbHVlLCBleGNfdmFsdWUuX190cmFjZWJhY2tfXykK
361
+ ICAgICAgICBlbHNlOgogICAgICAgICAgICAjIEZhbGxiYWNrIGlmIG5vIHVzZXIgY29kZSBmcmFt
362
+ ZXMgZm91bmQgLSByYWlzZSB0aGUgb3JpZ2luYWwgZXhjZXB0aW9uIHR5cGUKICAgICAgICAgICAg
363
+ IyB3aXRoIHRoZSBvcmlnaW5hbCBtZXNzYWdlIGJ1dCBjcmVhdGUgYSBmcmVzaCB0cmFjZWJhY2sK
364
+ ICAgICAgICAgICAgcmFpc2UgZXhjX3R5cGUoc3RyKGV4Y192YWx1ZSkpIGZyb20gTm9uZQoKICAg
365
+ ICAgICBzeXMuZXhpdCgxKQo=
366
+ `
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright 2025 Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import { SandboxCodeToolbox } from '../Sandbox'
7
+ import { CodeRunParams } from '../Process'
8
+
9
+ export class SandboxTsCodeToolbox implements SandboxCodeToolbox {
10
+ public getRunCommand(code: string, params?: CodeRunParams): string {
11
+ const base64Code = Buffer.from(code).toString('base64')
12
+ const argv = params?.argv ? params.argv.join(' ') : ''
13
+
14
+ // eslint-disable-next-line no-useless-escape
15
+ return `sh -c 'echo ${base64Code} | base64 --decode | npx ts-node -O "{\\\"module\\\":\\\"CommonJS\\\"}" -e "$(cat)" x ${argv} 2>&1 | grep -vE "npm notice"'`
16
+ }
17
+ }
@@ -0,0 +1,15 @@
1
+ /*
2
+ * Copyright 2025 Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ /**
7
+ * @module Errors
8
+ */
9
+
10
+ /**
11
+ * Base error for Daytona SDK.
12
+ */
13
+ export class DaytonaError extends Error {}
14
+
15
+ export class DaytonaNotFoundError extends DaytonaError {}
package/src/index.ts ADDED
@@ -0,0 +1,50 @@
1
+ /*
2
+ * Copyright 2025 Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ export { CodeLanguage, Daytona } from './Daytona'
7
+ export type {
8
+ CreateSandboxBaseParams,
9
+ CreateSandboxFromImageParams,
10
+ CreateSandboxFromSnapshotParams,
11
+ DaytonaConfig,
12
+ Resources,
13
+ VolumeMount,
14
+ } from './Daytona'
15
+ export { FileSystem } from './FileSystem'
16
+ export { Git } from './Git'
17
+ export { LspLanguageId } from './LspServer'
18
+ export { Process } from './Process'
19
+ // export { LspServer } from './LspServer'
20
+ // export type { LspLanguageId, Position } from './LspServer'
21
+ export { DaytonaError } from './errors/DaytonaError'
22
+ export { Image } from './Image'
23
+ export { Sandbox } from './Sandbox'
24
+ export type { SandboxCodeToolbox } from './Sandbox'
25
+ export { CreateSnapshotParams } from './Snapshot'
26
+ export { ComputerUse, Mouse, Keyboard, Screenshot, Display } from './ComputerUse'
27
+
28
+ // Chart and artifact types
29
+ export { ChartType } from './types/Charts'
30
+ export type {
31
+ BarChart,
32
+ BoxAndWhiskerChart,
33
+ Chart,
34
+ CompositeChart,
35
+ LineChart,
36
+ PieChart,
37
+ ScatterChart,
38
+ } from './types/Charts'
39
+
40
+ export { SandboxState } from '@daytonaio/api-client'
41
+ export type {
42
+ FileInfo,
43
+ GitStatus,
44
+ ListBranchResponse,
45
+ Match,
46
+ ReplaceResult,
47
+ SearchFilesResponse,
48
+ } from '@daytonaio/api-client'
49
+
50
+ export type { ScreenshotRegion, ScreenshotOptions } from './ComputerUse'
@@ -0,0 +1,193 @@
1
+ /*
2
+ * Copyright 2025 Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ /**
7
+ * Chart types
8
+ */
9
+ export enum ChartType {
10
+ LINE = 'line',
11
+ SCATTER = 'scatter',
12
+ BAR = 'bar',
13
+ PIE = 'pie',
14
+ BOX_AND_WHISKER = 'box_and_whisker',
15
+ COMPOSITE_CHART = 'composite_chart',
16
+ UNKNOWN = 'unknown',
17
+ }
18
+
19
+ /**
20
+ * Represents a chart with metadata from matplotlib.
21
+ */
22
+ export type Chart = {
23
+ /** The type of chart */
24
+ type: ChartType
25
+ /** The title of the chart */
26
+ title: string
27
+ /** The elements of the chart */
28
+ elements: any[]
29
+ /** The PNG representation of the chart encoded in base64 */
30
+ png?: string
31
+ }
32
+
33
+ /**
34
+ * Represents a 2D chart with metadata.
35
+ */
36
+ export type Chart2D = Chart & {
37
+ /** The label of the x-axis */
38
+ x_label?: string
39
+ /** The label of the y-axis */
40
+ y_label?: string
41
+ }
42
+
43
+ /**
44
+ * Represents a point in a 2D chart.
45
+ */
46
+ export type PointData = {
47
+ /** The label of the point */
48
+ label: string
49
+ /** The points of the chart */
50
+ points: [number | string, number | string][]
51
+ }
52
+
53
+ /**
54
+ * Represents a point chart with metadata.
55
+ */
56
+ export type PointChart = Chart2D & {
57
+ /** The ticks of the x-axis */
58
+ x_ticks: (number | string)[]
59
+ /** The scale of the x-axis */
60
+ x_scale: string
61
+ /** The labels of the x-axis */
62
+ x_tick_labels: string[]
63
+ /** The ticks of the y-axis */
64
+ y_ticks: (number | string)[]
65
+ /** The scale of the y-axis */
66
+ y_scale: string
67
+ /** The labels of the y-axis */
68
+ y_tick_labels: string[]
69
+ /** The points of the chart */
70
+ elements: PointData[]
71
+ }
72
+
73
+ /**
74
+ * Represents a line chart with metadata.
75
+ */
76
+ export type LineChart = PointChart & {
77
+ /** The type of chart */
78
+ type: ChartType.LINE
79
+ }
80
+
81
+ /**
82
+ * Represents a scatter chart with metadata.
83
+ */
84
+ export type ScatterChart = PointChart & {
85
+ /** The type of chart */
86
+ type: ChartType.SCATTER
87
+ }
88
+
89
+ /**
90
+ * Represents a bar in a bar chart.
91
+ */
92
+ export type BarData = {
93
+ /** The label of the bar */
94
+ label: string
95
+ /** The value of the bar */
96
+ value: string
97
+ /** The group of the bar */
98
+ group: string
99
+ }
100
+
101
+ /**
102
+ * Represents a bar chart with metadata.
103
+ */
104
+ export type BarChart = Chart2D & {
105
+ /** The type of chart */
106
+ type: ChartType.BAR
107
+ /** The bars of the chart */
108
+ elements: BarData[]
109
+ }
110
+
111
+ /**
112
+ * Represents a pie slice in a pie chart.
113
+ */
114
+ export type PieData = {
115
+ /** The label of the pie slice */
116
+ label: string
117
+ /** The angle of the pie slice */
118
+ angle: number
119
+ /** The radius of the pie slice */
120
+ radius: number
121
+ }
122
+
123
+ /**
124
+ * Represents a pie chart with metadata.
125
+ */
126
+ export type PieChart = Chart & {
127
+ /** The type of chart */
128
+ type: ChartType.PIE
129
+ /** The pie slices of the chart */
130
+ elements: PieData[]
131
+ }
132
+
133
+ /**
134
+ * Represents a box and whisker in a box and whisker chart.
135
+ */
136
+ export type BoxAndWhiskerData = {
137
+ /** The label of the box and whisker */
138
+ label: string
139
+ /** The minimum value of the box and whisker */
140
+ min: number
141
+ /** The first quartile of the box and whisker */
142
+ first_quartile: number
143
+ /** The median of the box and whisker */
144
+ median: number
145
+ /** The third quartile of the box and whisker */
146
+ max: number
147
+ outliers: number[]
148
+ }
149
+
150
+ /**
151
+ * Represents a box and whisker chart with metadata.
152
+ */
153
+ export type BoxAndWhiskerChart = Chart2D & {
154
+ /** The type of chart */
155
+ type: ChartType.BOX_AND_WHISKER
156
+ /** The box and whiskers of the chart */
157
+ elements: BoxAndWhiskerData[]
158
+ }
159
+
160
+ /**
161
+ * Represents a composite chart with metadata.
162
+ */
163
+ export type CompositeChart = Chart & {
164
+ /** The type of chart */
165
+ type: ChartType.COMPOSITE_CHART
166
+ /** The charts of the composite chart */
167
+ elements: Chart[]
168
+ }
169
+
170
+ export function parseChart(data: any): Chart {
171
+ switch (data.type) {
172
+ case ChartType.LINE:
173
+ return { ...data } as LineChart
174
+ case ChartType.SCATTER:
175
+ return { ...data } as ScatterChart
176
+ case ChartType.BAR:
177
+ return { ...data } as BarChart
178
+ case ChartType.PIE:
179
+ return { ...data } as PieChart
180
+ case ChartType.BOX_AND_WHISKER:
181
+ return { ...data } as BoxAndWhiskerChart
182
+ case ChartType.COMPOSITE_CHART:
183
+ // eslint-disable-next-line no-case-declarations
184
+ const charts = data.elements.map((g: any) => parseChart(g))
185
+ delete data.data
186
+ return {
187
+ ...data,
188
+ data: charts,
189
+ } as CompositeChart
190
+ default:
191
+ return { ...data, type: ChartType.UNKNOWN } as Chart
192
+ }
193
+ }
@@ -0,0 +1,33 @@
1
+ /*
2
+ * Copyright 2025 Daytona Platforms Inc.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import { ExecuteResponse as ClientExecuteResponse } from '@daytonaio/api-client'
7
+ import { Chart } from './Charts'
8
+
9
+ /**
10
+ * Artifacts from the command execution.
11
+ *
12
+ * @interface
13
+ * @property stdout - Standard output from the command, same as `result` in `ExecuteResponse`
14
+ * @property charts - List of chart metadata from matplotlib
15
+ */
16
+ export interface ExecutionArtifacts {
17
+ stdout: string
18
+ charts?: Chart[]
19
+ }
20
+
21
+ /**
22
+ * Response from the command execution.
23
+ *
24
+ * @interface
25
+ * @property exitCode - The exit code from the command execution
26
+ * @property result - The output from the command execution
27
+ * @property artifacts - Artifacts from the command execution
28
+ */
29
+ export interface ExecuteResponse extends ClientExecuteResponse {
30
+ exitCode: number
31
+ result: string
32
+ artifacts?: ExecutionArtifacts
33
+ }