pinokiod 3.9.26 → 3.9.28
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/index.js +0 -4
- package/kernel/bin/git.js +0 -2
- package/kernel/bin/index.js +0 -1
- package/kernel/index.js +41 -28
- package/kernel/plugin.js +25 -21
- package/kernel/prototype.js +34 -32
- package/package.json +1 -1
- package/server/index.js +45 -9
- package/server/public/style.css +29 -8
- package/server/views/download.ejs +0 -1
- package/server/views/install.ejs +6 -5
- package/server/views/settings.ejs +1 -1
package/kernel/api/index.js
CHANGED
|
@@ -496,15 +496,12 @@ class Api {
|
|
|
496
496
|
let method
|
|
497
497
|
let dirname
|
|
498
498
|
let mod
|
|
499
|
-
console.log(">> resolveMethod", { req, cwd })
|
|
500
499
|
if (req.method && typeof req.method === "function") {
|
|
501
|
-
console.log(">> 1")
|
|
502
500
|
modpath = null
|
|
503
501
|
method = req.method
|
|
504
502
|
dirname = __dirname
|
|
505
503
|
mod = null
|
|
506
504
|
} else if (req.uri) {
|
|
507
|
-
console.log(">> 2")
|
|
508
505
|
modpath = this.resolvePath(cwd, req.uri)
|
|
509
506
|
let m = (await this.loader.load(modpath))
|
|
510
507
|
const stats = await fs.promises.stat(modpath)
|
|
@@ -551,7 +548,6 @@ class Api {
|
|
|
551
548
|
}
|
|
552
549
|
method = mod[methodName].bind(mod)
|
|
553
550
|
} else {
|
|
554
|
-
console.log(">> 3")
|
|
555
551
|
if (chunks.length === 1) {
|
|
556
552
|
let methodName = chunks[0]
|
|
557
553
|
modpath = path.resolve(__dirname, methodName)
|
package/kernel/bin/git.js
CHANGED
|
@@ -42,11 +42,9 @@ class Git {
|
|
|
42
42
|
async installed() {
|
|
43
43
|
if (this.kernel.platform === "darwin") {
|
|
44
44
|
let gh_config_exists = await this.kernel.exists("config/gh")
|
|
45
|
-
console.log("conda installed", this.kernel.bin.installed.conda)
|
|
46
45
|
return this.kernel.bin.installed.conda && this.kernel.bin.installed.conda.has("git") && this.kernel.bin.installed.brew.has("gh") && gh_config_exists
|
|
47
46
|
} else {
|
|
48
47
|
let gh_config_exists = await this.kernel.exists("config/gh")
|
|
49
|
-
console.log("conda installed", this.kernel.bin.installed.conda)
|
|
50
48
|
return this.kernel.bin.installed.conda && this.kernel.bin.installed.conda.has("git") && this.kernel.bin.installed.conda.has("gh") && gh_config_exists
|
|
51
49
|
}
|
|
52
50
|
}
|
package/kernel/bin/index.js
CHANGED
|
@@ -183,7 +183,6 @@ class Bin {
|
|
|
183
183
|
// return a single merged env object, constructed from all the modules
|
|
184
184
|
|
|
185
185
|
// 1. get the module envs
|
|
186
|
-
console.log("this.mods", this.mods)
|
|
187
186
|
let envs = this.mods.map((mod) => {
|
|
188
187
|
if (mod.name === "vs") {
|
|
189
188
|
// don't include vs now
|
package/kernel/index.js
CHANGED
|
@@ -637,7 +637,6 @@ class Kernel {
|
|
|
637
637
|
this.shell.init().then(async () => {
|
|
638
638
|
// this.bin.check()
|
|
639
639
|
if (this.envs) {
|
|
640
|
-
console.log("template.update")
|
|
641
640
|
this.template.update({
|
|
642
641
|
env: this.envs,
|
|
643
642
|
envs: this.envs,
|
|
@@ -652,7 +651,6 @@ class Kernel {
|
|
|
652
651
|
return null
|
|
653
652
|
}
|
|
654
653
|
} catch (e) {
|
|
655
|
-
console.log(`>> which ${name}`, e)
|
|
656
654
|
return null
|
|
657
655
|
}
|
|
658
656
|
} else {
|
|
@@ -660,6 +658,23 @@ class Kernel {
|
|
|
660
658
|
}
|
|
661
659
|
}
|
|
662
660
|
})
|
|
661
|
+
if (this.bin.installed.conda.has("git")) {
|
|
662
|
+
await this.proto.init()
|
|
663
|
+
await this.plugin.init()
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
this.sys = new Sysinfo()
|
|
667
|
+
await this.sys.init(this)
|
|
668
|
+
let info = this.sys.info
|
|
669
|
+
|
|
670
|
+
this.sysinfo = info
|
|
671
|
+
|
|
672
|
+
await this.getInfo()
|
|
673
|
+
|
|
674
|
+
await fs.promises.mkdir(this.path("logs"), { recursive: true }).catch((e) => { })
|
|
675
|
+
await fs.promises.writeFile(this.path("logs/system.json"), JSON.stringify(this.i, null, 2))
|
|
676
|
+
let pwpath = this.bin.path("playwright/node_modules/playwright")
|
|
677
|
+
this.playwright = (await this.loader.load(pwpath)).resolved
|
|
663
678
|
|
|
664
679
|
// get env
|
|
665
680
|
if (!this.launch_complete) {
|
|
@@ -703,9 +718,7 @@ class Kernel {
|
|
|
703
718
|
|
|
704
719
|
//await this.shell.init()
|
|
705
720
|
|
|
706
|
-
console.log("********************************************", { homedir: this.homedir })
|
|
707
721
|
if (this.homedir) {
|
|
708
|
-
console.log("> 1")
|
|
709
722
|
await this.template.init({
|
|
710
723
|
kernel: this,
|
|
711
724
|
system,
|
|
@@ -715,30 +728,30 @@ class Kernel {
|
|
|
715
728
|
return this.api.get_proxy_url("/proxy", port)
|
|
716
729
|
},
|
|
717
730
|
})
|
|
718
|
-
console.log("> 2")
|
|
719
|
-
this.sys = new Sysinfo()
|
|
720
|
-
await this.sys.init(this)
|
|
721
|
-
console.log("> 3")
|
|
722
|
-
let info = this.sys.info
|
|
723
|
-
|
|
724
|
-
this.sysinfo = info
|
|
725
|
-
|
|
726
|
-
await this.getInfo()
|
|
727
|
-
console.log("> 4")
|
|
728
|
-
|
|
729
|
-
await fs.promises.mkdir(this.path("logs"), { recursive: true }).catch((e) => { })
|
|
730
|
-
console.log("> 5")
|
|
731
|
-
await fs.promises.writeFile(this.path("logs/system.json"), JSON.stringify(this.i, null, 2))
|
|
732
|
-
console.log("> 6")
|
|
733
|
-
let pwpath = this.bin.path("playwright/node_modules/playwright")
|
|
734
|
-
this.playwright = (await this.loader.load(pwpath)).resolved
|
|
735
|
-
|
|
736
|
-
console.log("> 7")
|
|
737
|
-
|
|
738
|
-
await this.proto.init()
|
|
739
|
-
console.log("> 8")
|
|
740
|
-
await this.plugin.init()
|
|
741
|
-
console.log("> 9")
|
|
731
|
+
// console.log("> 2")
|
|
732
|
+
// this.sys = new Sysinfo()
|
|
733
|
+
// await this.sys.init(this)
|
|
734
|
+
// console.log("> 3")
|
|
735
|
+
// let info = this.sys.info
|
|
736
|
+
//
|
|
737
|
+
// this.sysinfo = info
|
|
738
|
+
//
|
|
739
|
+
// await this.getInfo()
|
|
740
|
+
// console.log("> 4")
|
|
741
|
+
|
|
742
|
+
// await fs.promises.mkdir(this.path("logs"), { recursive: true }).catch((e) => { })
|
|
743
|
+
// console.log("> 5")
|
|
744
|
+
// await fs.promises.writeFile(this.path("logs/system.json"), JSON.stringify(this.i, null, 2))
|
|
745
|
+
// console.log("> 6")
|
|
746
|
+
// let pwpath = this.bin.path("playwright/node_modules/playwright")
|
|
747
|
+
// this.playwright = (await this.loader.load(pwpath)).resolved
|
|
748
|
+
//
|
|
749
|
+
// console.log("> 7")
|
|
750
|
+
|
|
751
|
+
// await this.proto.init()
|
|
752
|
+
// console.log("> 8")
|
|
753
|
+
// await this.plugin.init()
|
|
754
|
+
// console.log("> 9")
|
|
742
755
|
|
|
743
756
|
// refresh every 5 second
|
|
744
757
|
if (this.refresh_interval) {
|
package/kernel/plugin.js
CHANGED
|
@@ -4,30 +4,34 @@ class Plugin {
|
|
|
4
4
|
this.kernel = kernel
|
|
5
5
|
}
|
|
6
6
|
async init() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
if (this.kernel.bin.installed.conda.has("git")) {
|
|
8
|
+
// if ~/pinokio/prototype doesn't exist, clone
|
|
9
|
+
let exists = await this.kernel.exists("plugin")
|
|
10
|
+
if (!exists) {
|
|
11
|
+
await this.kernel.exec({
|
|
12
|
+
message: "git clone https://github.com/peanutcocktail/plugin",
|
|
13
|
+
path: this.kernel.homedir
|
|
14
|
+
}, (e) => {
|
|
15
|
+
process.stdout.write(e.raw)
|
|
16
|
+
})
|
|
17
|
+
}
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
let plugin_dir = path.resolve(this.kernel.homedir, "plugin")
|
|
20
|
+
let pinokiojs = path.resolve(plugin_dir, "pinokio.js")
|
|
21
|
+
this.config = await this.kernel.require(pinokiojs)
|
|
22
|
+
}
|
|
21
23
|
}
|
|
22
24
|
async update() {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
if (this.kernel.bin.installed.conda.has("git")) {
|
|
26
|
+
let exists = await this.kernel.exists("plugin")
|
|
27
|
+
if (!exists) {
|
|
28
|
+
await this.kernel.exec({
|
|
29
|
+
message: "git pull",
|
|
30
|
+
path: this.kernel.path("plugin")
|
|
31
|
+
}, (e) => {
|
|
32
|
+
process.stdout.write(e.raw)
|
|
33
|
+
})
|
|
34
|
+
}
|
|
31
35
|
}
|
|
32
36
|
}
|
|
33
37
|
}
|
package/kernel/prototype.js
CHANGED
|
@@ -7,42 +7,44 @@ class Proto {
|
|
|
7
7
|
this.kernel = kernel
|
|
8
8
|
}
|
|
9
9
|
async init() {
|
|
10
|
+
this.items = []
|
|
11
|
+
this.kv = {}
|
|
12
|
+
if (this.kernel.bin.installed.conda.has("git")) {
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
// if ~/pinokio/prototype doesn't exist, clone
|
|
15
|
+
let exists = await this.kernel.exists("prototype")
|
|
16
|
+
if (!exists) {
|
|
17
|
+
console.log("prototype doesn't exist. cloning...")
|
|
18
|
+
await fs.promises.mkdir(this.kernel.path("prototype"), { recursive: true }).catch((e) => { })
|
|
19
|
+
await this.kernel.exec({
|
|
20
|
+
message: "git clone https://github.com/peanutcocktail/prototype system",
|
|
21
|
+
path: this.kernel.path("prototype")
|
|
22
|
+
}, (e) => {
|
|
23
|
+
process.stdout.write(e.raw)
|
|
24
|
+
})
|
|
25
|
+
}
|
|
23
26
|
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
let cwd = path.resolve(this.kernel.homedir, "prototype")
|
|
29
|
+
let prototype_paths = (await glob('**/pinokio.js', { cwd }))
|
|
30
|
+
let prototype_dir = path.resolve(this.kernel.homedir, "prototype")
|
|
31
|
+
for(let prototype_path of prototype_paths) {
|
|
32
|
+
let proto = path.dirname(prototype_path)
|
|
33
|
+
let pinokiojs = path.resolve(prototype_dir, prototype_path)
|
|
34
|
+
let config = await this.kernel.require(pinokiojs)
|
|
35
|
+
if (config && config.run) {
|
|
36
|
+
if (config.icon) {
|
|
37
|
+
config.icon = "/prototype/" + proto + "/" + config.icon
|
|
38
|
+
} else {
|
|
39
|
+
config.icon === "/pinokio-black.png"
|
|
40
|
+
}
|
|
41
|
+
let c = {
|
|
42
|
+
id: proto,
|
|
43
|
+
...config
|
|
44
|
+
}
|
|
45
|
+
this.items.push(c)
|
|
46
|
+
this.kv[proto] = c
|
|
43
47
|
}
|
|
44
|
-
this.items.push(c)
|
|
45
|
-
this.kv[proto] = c
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
}
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -1186,6 +1186,8 @@ class Server {
|
|
|
1186
1186
|
pinokioPath = `pinokio://?uri=${gitRemote}/${pathComponents.slice(1).join("/")}`
|
|
1187
1187
|
}
|
|
1188
1188
|
|
|
1189
|
+
console.log("API.RUNNING", this.kernel.api.running)
|
|
1190
|
+
|
|
1189
1191
|
let running = []
|
|
1190
1192
|
let notRunning = []
|
|
1191
1193
|
if (pathComponents.length === 0) {
|
|
@@ -1255,6 +1257,7 @@ class Server {
|
|
|
1255
1257
|
for(let key in this.kernel.api.running) {
|
|
1256
1258
|
//let p = this.kernel.path("api", items[i].name) + path.sep
|
|
1257
1259
|
let p = this.kernel.path("api", items[i].name)
|
|
1260
|
+
console.log({ key, p })
|
|
1258
1261
|
|
|
1259
1262
|
//let re = new RegExp(items[i].name)
|
|
1260
1263
|
//if (re.test(key)) {
|
|
@@ -1262,7 +1265,27 @@ class Server {
|
|
|
1262
1265
|
|
|
1263
1266
|
|
|
1264
1267
|
// not only should include the pattern, but also end with it (otherwise can include similar patterns such as /api/qqqa, /api/qqqaaa, etc.
|
|
1265
|
-
|
|
1268
|
+
|
|
1269
|
+
let is_running
|
|
1270
|
+
let api_path = this.kernel.path("api")
|
|
1271
|
+
if (key.startsWith(api_path)) {
|
|
1272
|
+
// api script
|
|
1273
|
+
if (key.startsWith(p)) {
|
|
1274
|
+
is_running = true
|
|
1275
|
+
}
|
|
1276
|
+
} else {
|
|
1277
|
+
if (key.endsWith(p)) {
|
|
1278
|
+
is_running = true
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
// 1. if the script path starts with api path => api script
|
|
1282
|
+
// => check includes and startsWith
|
|
1283
|
+
|
|
1284
|
+
// 2. if the script path starts with anything else => other scripts (prototype, plugin ,etc.)
|
|
1285
|
+
// => check inlcludes and endsWith
|
|
1286
|
+
|
|
1287
|
+
//if (key.includes(p) && key.endsWith(p)) {
|
|
1288
|
+
if (is_running) {
|
|
1266
1289
|
items[i].running = true
|
|
1267
1290
|
items[i].index = index
|
|
1268
1291
|
if (!items[i].running_scripts) {
|
|
@@ -2256,15 +2279,28 @@ class Server {
|
|
|
2256
2279
|
}
|
|
2257
2280
|
}
|
|
2258
2281
|
async getPlugin(name) {
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2282
|
+
if (this.kernel.plugin.config) {
|
|
2283
|
+
try {
|
|
2284
|
+
let info = new Info(this.kernel)
|
|
2285
|
+
info.caller = () => {
|
|
2286
|
+
return this.kernel.path("api", name, "pinokio.js")
|
|
2287
|
+
}
|
|
2288
|
+
let menu = await this.kernel.plugin.config.menu(this.kernel, info)
|
|
2289
|
+
let plugin = { menu }
|
|
2290
|
+
let uri = this.kernel.path("api")
|
|
2291
|
+
await this.renderMenu(uri, name, plugin, [])
|
|
2292
|
+
return plugin
|
|
2293
|
+
} catch (e) {
|
|
2294
|
+
return {
|
|
2295
|
+
menu: []
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
} else {
|
|
2299
|
+
return {
|
|
2300
|
+
menu: []
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2262
2303
|
}
|
|
2263
|
-
let menu = await this.kernel.plugin.config.menu(this.kernel, info)
|
|
2264
|
-
let plugin = { menu }
|
|
2265
|
-
let uri = this.kernel.path("api")
|
|
2266
|
-
await this.renderMenu(uri, name, plugin, [])
|
|
2267
|
-
return plugin
|
|
2268
2304
|
}
|
|
2269
2305
|
|
|
2270
2306
|
async start(options) {
|
package/server/public/style.css
CHANGED
|
@@ -292,10 +292,12 @@ footer b {
|
|
|
292
292
|
*/
|
|
293
293
|
}
|
|
294
294
|
.requirements {
|
|
295
|
-
padding: 20px;
|
|
295
|
+
padding: 50px 20px;
|
|
296
296
|
font-size: 14px;
|
|
297
|
+
/*
|
|
297
298
|
background: var(--dark-nav-bg);
|
|
298
299
|
color: white;
|
|
300
|
+
*/
|
|
299
301
|
flex-grow: 1;
|
|
300
302
|
display: flex;
|
|
301
303
|
align-items: center;
|
|
@@ -316,10 +318,10 @@ footer b {
|
|
|
316
318
|
font-size: 12px;
|
|
317
319
|
}
|
|
318
320
|
.requirements .requirement-item .label.highlighted {
|
|
319
|
-
color:
|
|
321
|
+
color: royalblue;
|
|
320
322
|
}
|
|
321
323
|
.requirements .requirement-item .name.highlighted {
|
|
322
|
-
color:
|
|
324
|
+
color: royalblue;
|
|
323
325
|
}
|
|
324
326
|
.requirements .requirement-item .name {
|
|
325
327
|
font-weight: bold;
|
|
@@ -338,13 +340,27 @@ footer b {
|
|
|
338
340
|
.requirements form .btn {
|
|
339
341
|
width: 100%;
|
|
340
342
|
}
|
|
341
|
-
|
|
343
|
+
/*
|
|
344
|
+
body.dark .requirement-item:first-child {
|
|
342
345
|
border-top: 1px solid rgba(255,255,255,0.04);
|
|
343
346
|
}
|
|
347
|
+
.requirement-item:first-child {
|
|
348
|
+
border-top: 1px solid rgba(0,0,0,0.08);
|
|
349
|
+
}
|
|
350
|
+
*/
|
|
351
|
+
body.dark .requirement-item {
|
|
352
|
+
/*
|
|
353
|
+
border-bottom: 1px solid rgba(255,255,255,0.04);
|
|
354
|
+
*/
|
|
355
|
+
background: rgba(0,0,0,0.08);
|
|
356
|
+
}
|
|
344
357
|
.requirement-item {
|
|
345
358
|
text-align: left;
|
|
346
|
-
padding: 15px
|
|
347
|
-
|
|
359
|
+
padding: 15px 20px;
|
|
360
|
+
background: rgba(0,0,100,0.03);
|
|
361
|
+
/*
|
|
362
|
+
border-bottom: 1px solid rgba(0,0,0,0.08);
|
|
363
|
+
*/
|
|
348
364
|
}
|
|
349
365
|
.requirement-item .btn {
|
|
350
366
|
margin-right: 5px;
|
|
@@ -372,6 +388,10 @@ footer b {
|
|
|
372
388
|
margin: 10px 0;
|
|
373
389
|
background: rgba(0,0,0,0.05);
|
|
374
390
|
}
|
|
391
|
+
#del-bin {
|
|
392
|
+
cursor: pointer;
|
|
393
|
+
color: royalblue;
|
|
394
|
+
}
|
|
375
395
|
|
|
376
396
|
html.columns {
|
|
377
397
|
height: 100%;
|
|
@@ -589,9 +609,11 @@ body.dark {
|
|
|
589
609
|
color: var(--dark-color);
|
|
590
610
|
background: var(--dark-bg);
|
|
591
611
|
}
|
|
612
|
+
/*
|
|
592
613
|
body.frozen {
|
|
593
614
|
background: #F5F4FA;
|
|
594
615
|
}
|
|
616
|
+
*/
|
|
595
617
|
body.fullscreen {
|
|
596
618
|
/*
|
|
597
619
|
background: white;
|
|
@@ -1470,7 +1492,7 @@ body.dark .swal2-styled.swal2-confirm{
|
|
|
1470
1492
|
color: black;
|
|
1471
1493
|
*/
|
|
1472
1494
|
color: rgba(255,255,255,0.8) !important;
|
|
1473
|
-
border: 1px solid rgba(255,255,255,0.
|
|
1495
|
+
border: 1px solid rgba(255,255,255,0.2) !important;
|
|
1474
1496
|
/*
|
|
1475
1497
|
background: var(--dark-btn-bg);
|
|
1476
1498
|
color: var(--dark-btn-color);
|
|
@@ -1479,7 +1501,6 @@ body.dark .swal2-styled.swal2-confirm{
|
|
|
1479
1501
|
.swal2-styled.swal2-confirm{
|
|
1480
1502
|
background: black !important;
|
|
1481
1503
|
margin: 0;
|
|
1482
|
-
font-weight: bold;
|
|
1483
1504
|
border: none;
|
|
1484
1505
|
}
|
|
1485
1506
|
.swal2-input:focus, .swal2-file:focus, .swal2-textarea:focus {
|
package/server/views/install.ejs
CHANGED
|
@@ -69,7 +69,6 @@ body {
|
|
|
69
69
|
display: flex;
|
|
70
70
|
align-items: flex-start;
|
|
71
71
|
margin: 10px;
|
|
72
|
-
background: rgba(0,0,0,0.04);
|
|
73
72
|
}
|
|
74
73
|
.item img {
|
|
75
74
|
width: 100px;
|
|
@@ -95,19 +94,21 @@ body {
|
|
|
95
94
|
color: rgba(0,0,0,0.5);
|
|
96
95
|
}
|
|
97
96
|
#status-screen {
|
|
98
|
-
padding:
|
|
97
|
+
padding: 15px;
|
|
99
98
|
box-sizing: border-box;
|
|
100
99
|
width: 100%;
|
|
101
100
|
margin: 0;
|
|
102
|
-
|
|
101
|
+
margin-bottom: 10px;
|
|
103
102
|
overflow: auto;
|
|
104
|
-
|
|
103
|
+
border-left: 5px solid royalblue;
|
|
105
104
|
/*
|
|
106
105
|
color: rgb(27, 28, 29);
|
|
107
106
|
*/
|
|
108
107
|
}
|
|
109
108
|
#status-screen b {
|
|
110
|
-
|
|
109
|
+
font-weight: normal;
|
|
110
|
+
color: royalblue;
|
|
111
|
+
font-size: 16px;
|
|
111
112
|
}
|
|
112
113
|
</style>
|
|
113
114
|
<script src="/hotkeys.min.js"></script>
|
|
@@ -257,7 +257,7 @@ hr {
|
|
|
257
257
|
<button class='btn2' id='back'><div><i class="fa-solid fa-chevron-left"></i></div><div>Prev</div></button>
|
|
258
258
|
<button class='btn2' id='forward'><div><i class="fa-solid fa-chevron-right"></i></div><div>Next</div></button>
|
|
259
259
|
<a class='btn2 create-new' id='create-new-folder'><div><i class='fa-solid fa-plus'></i></div><div>New</div></a>
|
|
260
|
-
<a class='btn2' id='explore' href="/?mode=explore"><div><i class="fa-solid fa-
|
|
260
|
+
<a class='btn2' id='explore' href="/?mode=explore"><div><i class="fa-solid fa-magnifying-glass"></i></div><div>Discover</div></a>
|
|
261
261
|
<a href="/network" class='btn2'><div><i class="fa-solid fa-wifi"></i></div><div>Network</div></a>
|
|
262
262
|
<a href="/connect" class='btn2'><div><i class="fa-solid fa-circle-user"></i></div><div>Connect</div></a>
|
|
263
263
|
<% paths.forEach((path) => { %>
|