pinokiod 3.9.0 → 3.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/kernel/api/filepicker/index.js +59 -0
- package/kernel/api/fs/index.js +6 -4
- package/kernel/api/index.js +123 -37
- package/kernel/api/input/index.js +2 -0
- package/kernel/api/web/index.js +6 -0
- package/kernel/bin/caddy.js +127 -0
- package/kernel/bin/cloudflared.js +1 -0
- package/kernel/bin/conda.js +10 -2
- package/kernel/bin/cuda.js +0 -16
- package/kernel/bin/ffmpeg.js +4 -6
- package/kernel/bin/git.js +55 -29
- package/kernel/bin/gxx.js +8 -6
- package/kernel/bin/huggingface.js +4 -5
- package/kernel/bin/index.js +347 -88
- package/kernel/bin/node.js +13 -6
- package/kernel/bin/py.js +1 -1
- package/kernel/bin/setup.js +146 -0
- package/kernel/bin/uv.js +4 -5
- package/kernel/bin/zip.js +7 -8
- package/kernel/connect/index.js +25 -0
- package/kernel/connect/providers/github/README.md +11 -0
- package/kernel/connect/providers/x/README.md +96 -0
- package/kernel/connect/providers/x/index.js +152 -0
- package/kernel/environment.js +50 -1
- package/kernel/index.js +152 -32
- package/kernel/info.js +4 -2
- package/kernel/kv.js +38 -0
- package/kernel/loader.js +13 -3
- package/kernel/peer.js +161 -0
- package/kernel/procs.js +116 -0
- package/kernel/prototype.js +62 -0
- package/kernel/router/common.js +42 -0
- package/kernel/router/connector.js +81 -0
- package/kernel/router/index.js +235 -0
- package/kernel/router/localhost_home_router.js +84 -0
- package/kernel/router/localhost_port_router.js +15 -0
- package/kernel/router/localhost_variable_router.js +37 -0
- package/kernel/router/peer_home_router.js +15 -0
- package/kernel/router/peer_peer_router.js +26 -0
- package/kernel/router/peer_port_router.js +45 -0
- package/kernel/router/peer_variable_router.js +46 -0
- package/kernel/router/processor.js +31 -0
- package/kernel/shell.js +141 -60
- package/kernel/shells.js +32 -17
- package/kernel/store.js +58 -0
- package/kernel/sysinfo.js +0 -1
- package/kernel/util.js +143 -36
- package/package.json +4 -1
- package/pipe/index.js +0 -2
- package/script/index.js +12 -0
- package/server/index.js +1473 -553
- package/server/public/Socket.js +5 -1
- package/server/public/SourceCodePro-Regular.ttf +0 -0
- package/server/public/SpaceMono-Bold.ttf +0 -0
- package/server/public/SpaceMono-BoldItalic.ttf +0 -0
- package/server/public/SpaceMono-Italic.ttf +0 -0
- package/server/public/SpaceMono-Regular.ttf +0 -0
- package/server/public/commander.js +40 -0
- package/server/public/common.js +60 -0
- package/server/public/dropzone-min.js +2 -0
- package/server/public/dropzone.css +1 -0
- package/server/public/filepond-plugin-file-validate-type.min.js +9 -0
- package/server/public/filepond-plugin-image-crop.min.js +9 -0
- package/server/public/filepond-plugin-image-edit.min.css +8 -0
- package/server/public/filepond-plugin-image-edit.min.js +9 -0
- package/server/public/filepond-plugin-image-exif-orientation.min.js +9 -0
- package/server/public/filepond-plugin-image-preview.min.css +8 -0
- package/server/public/filepond-plugin-image-preview.min.js +9 -0
- package/server/public/filepond-plugin-image-resize.min.js +9 -0
- package/server/public/filepond-plugin-image-transform.min.js +9 -0
- package/server/public/filepond.min.css +8 -0
- package/server/public/filepond.min.js +9 -0
- package/server/public/fscreator.js +174 -0
- package/server/public/fseditor.js +212 -0
- package/server/public/github.png +0 -0
- package/server/public/highlight-js.js +81 -0
- package/server/public/highlight.css +9 -0
- package/server/public/highlight.js +1244 -0
- package/server/public/install.js +17 -20
- package/server/public/modalinput.js +105 -9
- package/server/public/opener.js +3 -1
- package/server/public/pinokio-black.png +0 -0
- package/server/public/pinokio-black2.png +0 -0
- package/server/public/redoc.standalone.js +1832 -0
- package/server/public/style.css +211 -17
- package/server/public/swagger-ui-bundle.js +2 -0
- package/server/public/swagger-ui.css +3 -0
- package/server/public/x.js +63 -0
- package/server/socket.js +136 -39
- package/server/views/404.ejs +0 -1
- package/server/views/app.ejs +356 -90
- package/server/views/bootstrap.ejs +22 -19
- package/server/views/connect/x.ejs +324 -0
- package/server/views/connect.ejs +197 -0
- package/server/views/download.ejs +7 -1
- package/server/views/editor.ejs +68 -9
- package/server/views/explore.ejs +13 -10
- package/server/views/file_explorer.ejs +10 -37
- package/server/views/github.ejs +218 -0
- package/server/views/help.ejs +4 -3
- package/server/views/index.ejs +268 -118
- package/server/views/install.ejs +56 -29
- package/server/views/keys.ejs +276 -0
- package/server/views/network.ejs +889 -0
- package/server/views/partials/dynamic.ejs +9 -0
- package/server/views/partials/menu.ejs +7 -1
- package/server/views/prototype/index.ejs +311 -0
- package/server/views/prototype/show.ejs +383 -0
- package/server/views/redoc.ejs +18 -0
- package/server/views/required_env_editor.ejs +11 -2
- package/server/views/settings.ejs +38 -10
- package/server/views/setup.ejs +254 -0
- package/server/views/setup_home.ejs +192 -0
- package/server/views/shell.ejs +781 -0
- package/server/views/swaggerui.ejs +19 -0
- package/server/views/terminal.ejs +174 -42
- package/LICENSE +0 -7
- package/server/views/proxy.ejs +0 -405
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<% dynamic.forEach((item, i) => { %>
|
|
2
|
+
<a target="<%=item.target%>" href="<%=item.href%>" class='dynamic-item btn header-item frame-link' data-index="<%=i+4%>" data-key="<%=item.key%>">
|
|
3
|
+
<div class='tab'><%-item.btn%></div>
|
|
4
|
+
<% if (item.running) { %>
|
|
5
|
+
<div class='loader shutdown online'>
|
|
6
|
+
</div>
|
|
7
|
+
<% } %>
|
|
8
|
+
</a>
|
|
9
|
+
<% }) %>
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
<div <%=item.default ? 'data-default' : ''%> data-action="<%=JSON.stringify(item.action)%>" class='btn header-item frame-link'>
|
|
15
15
|
<div class='tab'><%-item.btn%></div>
|
|
16
16
|
</div>
|
|
17
|
+
<% } else if (item.command) { %>
|
|
18
|
+
<div data-command="<%=item.command%>" data-filepath="<%=item.href%>" class='btn header-item frame-link'>
|
|
19
|
+
<div class='tab'><%-item.btn%></div>
|
|
20
|
+
</div>
|
|
17
21
|
<% } else if (item.fs) { %>
|
|
18
22
|
<div data-filepath="<%=item.href%>" class='btn header-item frame-link'>
|
|
19
23
|
<div class='tab'><%-item.btn%></div>
|
|
@@ -29,7 +33,9 @@
|
|
|
29
33
|
<a <%=item.default ? 'data-default' : ''%> data-confirm="<%=item.confirm%>" data-index="<%=index%>" target="<%=item.target%>" data-mode="<%=item.mode%>" href="<%=item.href%>" class='btn header-item frame-link'>
|
|
30
34
|
<div class='tab'><%-item.btn%></div>
|
|
31
35
|
<% if (item.running) { %>
|
|
32
|
-
<div class='loader shutdown'>
|
|
36
|
+
<div class='loader shutdown online'>
|
|
37
|
+
</div>
|
|
38
|
+
<div class='loader shutdown hidden'>
|
|
33
39
|
<!--
|
|
34
40
|
<i class='fa-solid fa-spin fa-circle-notch'></i>
|
|
35
41
|
<i class="fa-solid fa-chevron-right"></i>
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Pinokio</title>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
|
6
|
+
<link href="/xterm.min.css" rel="stylesheet" />
|
|
7
|
+
<link href="/css/fontawesome.min.css" rel="stylesheet">
|
|
8
|
+
<link href="/css/solid.min.css" rel="stylesheet">
|
|
9
|
+
<link href="/css/regular.min.css" rel="stylesheet">
|
|
10
|
+
<link href="/css/brands.min.css" rel="stylesheet">
|
|
11
|
+
<link href="/markdown.css" rel="stylesheet"/>
|
|
12
|
+
<link href="/noty.css" rel="stylesheet"/>
|
|
13
|
+
<link href="/filepond.min.css" rel="stylesheet" />
|
|
14
|
+
<link href="/filepond-plugin-image-preview.min.css" rel="stylesheet" />
|
|
15
|
+
<link href="/filepond-plugin-image-edit.min.css" rel="stylesheet" />
|
|
16
|
+
<link href="/style.css" rel="stylesheet"/>
|
|
17
|
+
<% if (agent === "electron") { %>
|
|
18
|
+
<link href="/electron.css" rel="stylesheet"/>
|
|
19
|
+
<% } %>
|
|
20
|
+
<style>
|
|
21
|
+
.line2 {
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
background: rgba(0,0,100,0.04);
|
|
26
|
+
}
|
|
27
|
+
.line2 a {
|
|
28
|
+
text-decoration: none;
|
|
29
|
+
color: black;
|
|
30
|
+
}
|
|
31
|
+
.status {
|
|
32
|
+
padding: 10px;
|
|
33
|
+
margin: 10px;
|
|
34
|
+
border-radius: 10px;
|
|
35
|
+
}
|
|
36
|
+
.status.offline {
|
|
37
|
+
background: silver;
|
|
38
|
+
}
|
|
39
|
+
.status.online {
|
|
40
|
+
background: yellowgreen;
|
|
41
|
+
}
|
|
42
|
+
.switch {
|
|
43
|
+
padding: 10px;
|
|
44
|
+
margin: 10px 0;
|
|
45
|
+
}
|
|
46
|
+
.switch[data-online=true] {
|
|
47
|
+
color: yellowgreen;
|
|
48
|
+
}
|
|
49
|
+
.button {
|
|
50
|
+
padding: 10px;
|
|
51
|
+
}
|
|
52
|
+
.on, .off {
|
|
53
|
+
display: flex;
|
|
54
|
+
align-items: center;
|
|
55
|
+
}
|
|
56
|
+
header .runner {
|
|
57
|
+
padding: 10px 0 0;
|
|
58
|
+
}
|
|
59
|
+
.proxy {
|
|
60
|
+
padding: 0 10px;
|
|
61
|
+
text-align: right;
|
|
62
|
+
}
|
|
63
|
+
.proxy a {
|
|
64
|
+
text-decoration: none;
|
|
65
|
+
display: inline-block;
|
|
66
|
+
padding: 5px 10px;
|
|
67
|
+
border-radius: 2px;
|
|
68
|
+
background: black;
|
|
69
|
+
color: white;
|
|
70
|
+
}
|
|
71
|
+
.browser-options-btns {
|
|
72
|
+
display: flex;
|
|
73
|
+
padding-top: 5px;
|
|
74
|
+
}
|
|
75
|
+
.browser-options-row {
|
|
76
|
+
/*
|
|
77
|
+
border-top: 1px solid rgba(0,0,0,0.1);
|
|
78
|
+
border-bottom: 1px solid rgba(0,0,0,0.1);
|
|
79
|
+
*/
|
|
80
|
+
display: flex;
|
|
81
|
+
padding: 10px;
|
|
82
|
+
align-items: flex-start;
|
|
83
|
+
}
|
|
84
|
+
.browser-options-row h3 {
|
|
85
|
+
margin: 0;
|
|
86
|
+
font-size: 14px;
|
|
87
|
+
margin-bottom: 3px;
|
|
88
|
+
}
|
|
89
|
+
.browser-options-row .btn.disabled {
|
|
90
|
+
opacity: 0.7;
|
|
91
|
+
}
|
|
92
|
+
.browser-options-row .btn {
|
|
93
|
+
font-weight: bold;
|
|
94
|
+
width: 100px;
|
|
95
|
+
text-align: center;
|
|
96
|
+
display: block;
|
|
97
|
+
margin-right: 10px;
|
|
98
|
+
flex-shrink: 0;
|
|
99
|
+
padding: 5px;
|
|
100
|
+
}
|
|
101
|
+
.badge {
|
|
102
|
+
font-size: 12px;
|
|
103
|
+
padding: 5px 10px;
|
|
104
|
+
background: rgba(0,0,100,0.1);
|
|
105
|
+
border-radius: 5px;
|
|
106
|
+
display: inline-block;
|
|
107
|
+
margin-top: 5px;
|
|
108
|
+
}
|
|
109
|
+
a.badge {
|
|
110
|
+
color: royalblue;
|
|
111
|
+
text-decoration: none;
|
|
112
|
+
cursor: pointer;
|
|
113
|
+
}
|
|
114
|
+
.badge a {
|
|
115
|
+
color: royalblue;
|
|
116
|
+
text-decoration: none;
|
|
117
|
+
}
|
|
118
|
+
body.dark .btn {
|
|
119
|
+
color: white;
|
|
120
|
+
border: 1px solid rgba(255,255,255,0.3);
|
|
121
|
+
}
|
|
122
|
+
body.dark .badge {
|
|
123
|
+
background: rgba(255,255,255,0.1);
|
|
124
|
+
}
|
|
125
|
+
.folder-templates {
|
|
126
|
+
background: rgba(0,0,100, 0.02);
|
|
127
|
+
}
|
|
128
|
+
.folder-templates .folder {
|
|
129
|
+
text-decoration: none;
|
|
130
|
+
color: rgba(0,0,0,0.9);
|
|
131
|
+
font-size: 12px;
|
|
132
|
+
padding: 10px;
|
|
133
|
+
display: flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
}
|
|
136
|
+
.folder-templates .folder .title {
|
|
137
|
+
font-weight: bold;
|
|
138
|
+
font-size: 15px;
|
|
139
|
+
text-transform: capitalize;
|
|
140
|
+
}
|
|
141
|
+
.folder-templates .folder img {
|
|
142
|
+
width: 30px;
|
|
143
|
+
height: 30px;
|
|
144
|
+
margin-right: 10px;
|
|
145
|
+
border-radius: 10px;
|
|
146
|
+
}
|
|
147
|
+
.prototype-header .btn {
|
|
148
|
+
border: 1px solid rgba(255,255,255,0.3);
|
|
149
|
+
}
|
|
150
|
+
.prototype-header {
|
|
151
|
+
align-items: center;
|
|
152
|
+
display: flex;
|
|
153
|
+
padding: 40px;
|
|
154
|
+
background: black;
|
|
155
|
+
color: white;
|
|
156
|
+
}
|
|
157
|
+
.prototype-header h1 {
|
|
158
|
+
letter-spacing: -1px;
|
|
159
|
+
}
|
|
160
|
+
.prototype-header .desc {
|
|
161
|
+
color: silver;
|
|
162
|
+
}
|
|
163
|
+
/*
|
|
164
|
+
body.dark .browser-options-row {
|
|
165
|
+
border-top: 1px solid rgba(255,255,255,0.05);
|
|
166
|
+
border-bottom: 1px solid rgba(255,255,255,0.05);
|
|
167
|
+
}
|
|
168
|
+
*/
|
|
169
|
+
.meta {
|
|
170
|
+
display: flex;
|
|
171
|
+
align-items: flex-start;
|
|
172
|
+
padding: 20px;
|
|
173
|
+
}
|
|
174
|
+
.meta-content {
|
|
175
|
+
padding: 10px;
|
|
176
|
+
}
|
|
177
|
+
.meta-content h2 {
|
|
178
|
+
margin: 0;
|
|
179
|
+
font-size: 30px;
|
|
180
|
+
}
|
|
181
|
+
.meta-path {
|
|
182
|
+
padding: 10px 0;
|
|
183
|
+
opacity: 0.7;
|
|
184
|
+
}
|
|
185
|
+
.meta img {
|
|
186
|
+
width: 100px;
|
|
187
|
+
}
|
|
188
|
+
@media only screen and (max-width: 480px) {
|
|
189
|
+
.btn2 {
|
|
190
|
+
padding: 5px;
|
|
191
|
+
font-size: 11px;
|
|
192
|
+
}
|
|
193
|
+
.nav-btns {
|
|
194
|
+
flex-grow: 1;
|
|
195
|
+
justify-content: center;
|
|
196
|
+
padding: 0;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
</style>
|
|
200
|
+
<script src="/hotkeys.min.js"></script>
|
|
201
|
+
<script src="/sweetalert2.js"></script>
|
|
202
|
+
<script src="/noty.js"></script>
|
|
203
|
+
<script src="/notyq.js"></script>
|
|
204
|
+
<script src="/xterm.js"></script>
|
|
205
|
+
<script src="/xterm-addon-fit.js"></script>
|
|
206
|
+
<script src="/xterm-addon-web-links.js"></script>
|
|
207
|
+
<script src="/xterm-theme.js"></script>
|
|
208
|
+
<script src="/Socket.js"></script>
|
|
209
|
+
<script src="/install.js"></script>
|
|
210
|
+
<script src="/common.js"></script>
|
|
211
|
+
<script src="/opener.js"></script>
|
|
212
|
+
<script src="/nav.js"></script>
|
|
213
|
+
<script src="/fuse.js"></script>
|
|
214
|
+
<script src="/report.js"></script>
|
|
215
|
+
<script src="/filepond-plugin-file-validate-type.min.js"></script>
|
|
216
|
+
<script src="/filepond-plugin-image-exif-orientation.min.js"></script>
|
|
217
|
+
<script src="/filepond-plugin-image-preview.min.js"></script>
|
|
218
|
+
<script src="/filepond-plugin-image-edit.min.js"></script>
|
|
219
|
+
<script src="/filepond-plugin-image-crop.min.js"></script>
|
|
220
|
+
<script src="/filepond-plugin-image-resize.min.js"></script>
|
|
221
|
+
<script src="/filepond-plugin-image-transform.min.js"></script>
|
|
222
|
+
<script src="/filepond.min.js"></script>
|
|
223
|
+
<script src="/commander.js"></script>
|
|
224
|
+
</head>
|
|
225
|
+
<body class='<%=theme%>'>
|
|
226
|
+
<header class='navheader grabbable'>
|
|
227
|
+
<h1>
|
|
228
|
+
<a class='home' href="/"><i class="fa-solid fa-house"></i></a>
|
|
229
|
+
<button class='btn2' id='back'><div><i class="fa-solid fa-chevron-left"></i></div><div>Prev</div></button>
|
|
230
|
+
<button class='btn2' id='forward'><div><i class="fa-solid fa-chevron-right"></i></div><div>Next</div></button>
|
|
231
|
+
<a class='btn2 create-new' id='create-new-folder'><div><i class='fa-solid fa-plus'></i></div><div>New</div></a>
|
|
232
|
+
<a class='btn2' id='explore' href="/?mode=explore"><div><i class="fa-solid fa-globe"></i></div><div>Discover</div></a>
|
|
233
|
+
<a href="/network" class='btn2'><div><i class="fa-solid fa-wifi"></i></div><div>Network</div></a>
|
|
234
|
+
<a href="/connect" class='btn2'><div><i class="fa-solid fa-circle-user"></i></div><div>Connect</div></a>
|
|
235
|
+
<div class='flexible'></div>
|
|
236
|
+
<div class='nav-btns'>
|
|
237
|
+
<a href="/network" class='btn2'><div><i class="fa-solid fa-wifi"></i></div><div>Network</div></a>
|
|
238
|
+
<a class='btn2' href="<%=portal%>" target="_blank"><div><i class="fa-solid fa-question"></i></div><div>Help</div></a>
|
|
239
|
+
<button class='btn2' id='genlog'><div><i class="fa-solid fa-laptop-code"></i></div><div>Logs</div></button>
|
|
240
|
+
<a id='downloadlogs' download class='hidden btn2' href="/pinokio/logs.zip"><div><i class="fa-solid fa-download"></i></div><div>Download logs</div></a>
|
|
241
|
+
<a class='btn2' href="/?mode=settings"><div><i class="fa-solid fa-gear"></i></div><div>Settings</div></a>
|
|
242
|
+
<% if (agent === "electron") { %>
|
|
243
|
+
<a href="/" target="_blank" class='btn2' features="browser"><div><i class="fa-solid fa-square-up-right"></i></div><div>Open</div></a>
|
|
244
|
+
<% } else { %>
|
|
245
|
+
<a href="/" target="_blank" class='btn2'><div><i class="fa-solid fa-square-up-right"></i></div><div>Open</div></a>
|
|
246
|
+
<% } %>
|
|
247
|
+
<button id='new-window' title='open a new window' class='btn2'><div><i class="fa-solid fa-plus"></i></div><div>Window</div></button>
|
|
248
|
+
</div>
|
|
249
|
+
</h1>
|
|
250
|
+
</header>
|
|
251
|
+
<main>
|
|
252
|
+
<div id='terminal' class='hidden'></div>
|
|
253
|
+
<div class='container'>
|
|
254
|
+
<div class='prototype-header'>
|
|
255
|
+
<div>
|
|
256
|
+
<h1>Create a new project</h1>
|
|
257
|
+
<div class='desc'>Select an option to set up a new folder</div>
|
|
258
|
+
</div>
|
|
259
|
+
<div class='flexible'></div>
|
|
260
|
+
<a class='btn' id='download'><i class='fa-solid fa-download'></i> Download a custom prototype script</a>
|
|
261
|
+
</div>
|
|
262
|
+
<div class='folder-templates drawer'>
|
|
263
|
+
<% items.forEach((folder, i) => { %>
|
|
264
|
+
<a class='line folder' href="/prototype/show/<%=folder.id%>">
|
|
265
|
+
<% if (folder.icon) { %>
|
|
266
|
+
<img src="<%=folder.icon%>">
|
|
267
|
+
<% } else { %>
|
|
268
|
+
<% if (theme === 'dark') { %>
|
|
269
|
+
<img src="/pinokio-white.png">
|
|
270
|
+
<% } else { %>
|
|
271
|
+
<img src="/pinokio-black.png">
|
|
272
|
+
<% } %>
|
|
273
|
+
<% } %>
|
|
274
|
+
<div class='col flexible'>
|
|
275
|
+
<div class='title'><%=folder.title%></div>
|
|
276
|
+
<div class='description'><%=folder.description%></div>
|
|
277
|
+
</div>
|
|
278
|
+
</a>
|
|
279
|
+
<% }) %>
|
|
280
|
+
</div>
|
|
281
|
+
</div>
|
|
282
|
+
</main>
|
|
283
|
+
<script>
|
|
284
|
+
let paths = location.pathname.split("/").filter(x=>x)
|
|
285
|
+
var term
|
|
286
|
+
const n = new N()
|
|
287
|
+
let socket = new Socket()
|
|
288
|
+
let list = []
|
|
289
|
+
document.querySelectorAll(".line").forEach((el, index) => {
|
|
290
|
+
list.push({
|
|
291
|
+
index: parseInt(el.getAttribute("data-index")),
|
|
292
|
+
name: el.getAttribute("data-name"),
|
|
293
|
+
description: el.getAttribute("data-description"),
|
|
294
|
+
})
|
|
295
|
+
})
|
|
296
|
+
const search = (items, value) => {
|
|
297
|
+
let filtered = []
|
|
298
|
+
for(let i=0; i<items.length; i++) {
|
|
299
|
+
let item = items[i]
|
|
300
|
+
let re = new RegExp(value, "i")
|
|
301
|
+
if (re.test(item.name)) {
|
|
302
|
+
filtered.push({ item })
|
|
303
|
+
} else if (re.test(item.description)) {
|
|
304
|
+
filtered.push({ item })
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return filtered
|
|
308
|
+
}
|
|
309
|
+
</script>
|
|
310
|
+
</body>
|
|
311
|
+
</html>
|