pinokiod 1.3.4 → 1.3.6

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 (38) hide show
  1. package/kernel/api/index.js +15 -1
  2. package/kernel/index.js +29 -0
  3. package/kernel/shell.js +28 -0
  4. package/package.json +3 -2
  5. package/script/index.js +3 -2
  6. package/server/index.js +41 -3
  7. package/server/public/css/all.css +93 -9
  8. package/server/public/css/all.min.css +6 -3
  9. package/server/public/css/brands.css +80 -2
  10. package/server/public/css/brands.min.css +3 -3
  11. package/server/public/css/fontawesome.css +15 -9
  12. package/server/public/css/fontawesome.min.css +6 -3
  13. package/server/public/css/regular.css +2 -2
  14. package/server/public/css/regular.min.css +2 -2
  15. package/server/public/css/solid.css +2 -2
  16. package/server/public/css/solid.min.css +2 -2
  17. package/server/public/css/svg-with-js.css +11 -6
  18. package/server/public/css/svg-with-js.min.css +3 -3
  19. package/server/public/css/v4-font-face.css +2 -2
  20. package/server/public/css/v4-font-face.min.css +2 -2
  21. package/server/public/css/v4-shims.css +2 -2
  22. package/server/public/css/v4-shims.min.css +2 -2
  23. package/server/public/css/v5-font-face.css +2 -2
  24. package/server/public/css/v5-font-face.min.css +2 -2
  25. package/server/public/style.css +4 -2
  26. package/server/public/webfonts/fa-brands-400.ttf +0 -0
  27. package/server/public/webfonts/fa-brands-400.woff2 +0 -0
  28. package/server/public/webfonts/fa-regular-400.ttf +0 -0
  29. package/server/public/webfonts/fa-regular-400.woff2 +0 -0
  30. package/server/public/webfonts/fa-solid-900.ttf +0 -0
  31. package/server/public/webfonts/fa-solid-900.woff2 +0 -0
  32. package/server/public/webfonts/fa-v4compatibility.ttf +0 -0
  33. package/server/public/webfonts/fa-v4compatibility.woff2 +0 -0
  34. package/server/views/browser-experimental.ejs +1250 -0
  35. package/server/views/browser.ejs +20 -2
  36. package/server/views/help.ejs +330 -0
  37. package/server/views/index.ejs +7 -1
  38. package/server/views/settings.ejs +40 -2
@@ -539,6 +539,7 @@ class Api {
539
539
  // 1. render once
540
540
  let rpc = rawrpc
541
541
  let pass = 0;
542
+ console.log("Render", { rpc, memory })
542
543
  while(true) {
543
544
  rpc = this.kernel.template.render(rpc, memory)
544
545
  if (this.kernel.template.istemplate(rpc)) {
@@ -607,7 +608,20 @@ class Api {
607
608
 
608
609
  if (rpc.hasOwnProperty("when")) {
609
610
  // if rpc.when is false, don't run this and go to the next step
610
- if (!rpc.when) {
611
+ let should_run
612
+ if (rpc.when) {
613
+ // when { allow_undefined: true}, undefined is treated as falsy
614
+ let h = this.kernel.template.render(rpc.when, memory, { allow_undefined: true })
615
+ if (h) {
616
+ should_run = true
617
+ } else {
618
+ should_run = false
619
+ }
620
+ } else {
621
+ should_run = false
622
+ }
623
+ if (!should_run) {
624
+ //if (!rpc.when) {
611
625
  if (typeof rpc.next === "undefined" || rpc.next === null) {
612
626
  // last call
613
627
  if (script.daemon) {
package/kernel/index.js CHANGED
@@ -7,6 +7,7 @@ const fastq = require('fastq')
7
7
  const fetch = require('cross-fetch');
8
8
  const waitOn = require('wait-on');
9
9
  const system = require('systeminformation');
10
+ //const hostile = require('hostile');
10
11
  const Sysinfo = require('./sysinfo')
11
12
  const portfinder = require('portfinder');
12
13
  const Loader = require("./loader")
@@ -225,6 +226,9 @@ class Kernel {
225
226
  }
226
227
  this.procs = {}
227
228
  this.template = new Template()
229
+
230
+
231
+
228
232
  try {
229
233
  if (this.homedir) {
230
234
  await fs.promises.mkdir(this.homedir, { recursive: true }).catch((e) => {})
@@ -286,6 +290,31 @@ class Kernel {
286
290
  // userDataDir: this.bin.path("puppet")
287
291
  // });
288
292
 
293
+
294
+ // set hosts
295
+ //hostile.get(false, async (err, lines) => {
296
+ // if (err) {
297
+ // console.error(err.message)
298
+ // }
299
+ // let hostSet
300
+ // for(let line of lines) {
301
+ // if (line.includes("pinokio.network")) {
302
+ // hostSet = true
303
+ // }
304
+ // }
305
+ // console.log({ hostSet })
306
+ // if (!hostSet) {
307
+ // console.log("setting hosts")
308
+ // await this.exec({
309
+ // sudo: true,
310
+ // message: "npx hostile set 127.0.0.1 pinokio.network"
311
+ // }, (e) => {
312
+ // console.log(e)
313
+ // })
314
+ // console.log("success")
315
+ // }
316
+ //})
317
+
289
318
  } catch (e) {
290
319
  console.log("### ERROR", e)
291
320
  }
package/kernel/shell.js CHANGED
@@ -147,6 +147,33 @@ class Shell {
147
147
  }
148
148
  // custom env was passed in
149
149
 
150
+ console.log("params", params)
151
+
152
+ // override cache folders if cache is specified
153
+ if (params.cache) {
154
+ // cache data files
155
+ let cache_path = path.resolve(params.path, params.cache)
156
+ let types = [
157
+ "HF_HOME", // huggingface models
158
+ "TORCH_HOME", // torch hub models
159
+ "GRADIO_TEMP_DIR" // gradio data
160
+ // "XDG_CACHE_HOME",
161
+ // "PIP_CACHE_DIR",
162
+ // "TMPDIR",
163
+ // "TEMP",
164
+ // "TMP",
165
+ // "XDG_DATA_HOME",
166
+ // "XDG_CONFIG_HOME",
167
+ // "XDG_STATE_HOME",
168
+ ]
169
+ for(let type of types) {
170
+ let p = path.resolve(cache_path, type)
171
+ console.log("setting", p)
172
+ this.env[type] = p
173
+ await fs.promises.mkdir(p, { recursive: true }).catch((e) => { })
174
+ }
175
+ }
176
+
150
177
 
151
178
  if (params.env) {
152
179
  for(let key in params.env) {
@@ -205,6 +232,7 @@ class Shell {
205
232
  // automatically add self to the shells registry
206
233
  this.kernel.shell.add(this)
207
234
 
235
+ console.log("params", params)
208
236
  if (params.sudo) {
209
237
  let options = {
210
238
  name: "Pinokio",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,6 +21,7 @@
21
21
  "decompress": "^4.2.1",
22
22
  "ejs": "^3.1.9",
23
23
  "express": "^4.18.2",
24
+ "express-http-proxy-cp": "^2.0.3",
24
25
  "express-session": "^1.17.3",
25
26
  "fake-useragent": "^1.0.1",
26
27
  "fastq": "^1.15.0",
@@ -32,7 +33,7 @@
32
33
  "http-proxy": "^1.18.1",
33
34
  "http-terminator": "^3.2.0",
34
35
  "isomorphic-git": "^1.23.0",
35
- "jimini": "^0.0.4",
36
+ "jimini": "^0.0.5",
36
37
  "jsdom": "^24.0.0",
37
38
  "jsonpath-plus": "^7.2.0",
38
39
  "key-store": "^1.2.0",
package/script/index.js CHANGED
@@ -35,9 +35,10 @@ class Store {
35
35
  }
36
36
  }
37
37
  const server = new Server({
38
- port: 42000,
38
+ //port: 42000,
39
+ port: 80,
39
40
  agent: "web",
40
41
  store: new Store()
41
42
  })
42
- server.start(true)
43
+ server.start({ debug: true })
43
44
  //server.start()
package/server/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const express = require('express');
2
+ const proxy = require('express-http-proxy-cp');
2
3
  const sudo = require("sudo-prompt-programfiles-x86");
3
4
  const compressing = require('compressing');
4
5
  const { rimraf } = require('rimraf')
@@ -1651,8 +1652,12 @@ class Server {
1651
1652
  }
1652
1653
  }
1653
1654
  }
1654
- async start(debug) {
1655
- this.debug = debug
1655
+ async start(options) {
1656
+ this.debug = false
1657
+ if (options) {
1658
+ this.debug = options.debug
1659
+ this.browser = options.browser
1660
+ }
1656
1661
 
1657
1662
  if (this.listening) {
1658
1663
  // stop proxies
@@ -1714,14 +1719,42 @@ class Server {
1714
1719
  res.redirect("/?mode=settings")
1715
1720
  return
1716
1721
  }
1722
+ if (req.query.mode === "help") {
1723
+ let folders = {}
1724
+ if (this.kernel.homedir) {
1725
+ folders = {
1726
+ bin: path.resolve(this.kernel.homedir, "bin"),
1727
+ cache: path.resolve(this.kernel.homedir, "cache"),
1728
+ drive: path.resolve(this.kernel.homedir, "drive"),
1729
+ }
1730
+ }
1731
+ res.render("help", {
1732
+ version: this.version,
1733
+ logo: this.logo,
1734
+ theme: this.theme,
1735
+ agent: this.agent,
1736
+ ...folders
1737
+ })
1738
+ return
1739
+ }
1740
+
1741
+
1717
1742
  if (req.query.mode === 'settings') {
1743
+
1744
+ let platform = os.platform()
1745
+ let _home
1746
+ if (platform === "win32") {
1747
+ _home = path.resolve(path.parse(os.homedir()).root, "pinokio");
1748
+ } else {
1749
+ _home = path.resolve(os.homedir(), "pinokio")
1750
+ }
1718
1751
  let configArray = [{
1719
1752
  key: "home",
1720
1753
  description: [
1721
1754
  "* NO white spaces (' ')",
1722
1755
  "* NO exFAT drives",
1723
1756
  ],
1724
- val: this.kernel.homedir ? this.kernel.homedir : path.resolve(os.homedir(), "pinokio"),
1757
+ val: this.kernel.homedir ? this.kernel.homedir : _home,
1725
1758
  placeholder: "Enter the absolute path to use as your Pinokio home folder (D:\\pinokio, /Users/alice/pinokiofs, etc.)"
1726
1759
  }, {
1727
1760
  key: "theme",
@@ -2026,6 +2059,11 @@ class Server {
2026
2059
  let folderPath = this.kernel.path("cache")
2027
2060
  await fse.remove(folderPath)
2028
2061
  res.json({ success: true })
2062
+ } else if (req.body.type === 'browser-cache') {
2063
+ if (this.browser) {
2064
+ await this.browser.clearCache()
2065
+ }
2066
+ res.json({ success: true })
2029
2067
  } else if (req.body.name) {
2030
2068
  let folderPath = this.kernel.path("api", req.body.name)
2031
2069
  await fse.remove(folderPath)
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * Font Awesome Free 6.2.1 by @fontawesome - https://fontawesome.com
2
+ * Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com
3
3
  * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4
- * Copyright 2022 Fonticons, Inc.
4
+ * Copyright 2024 Fonticons, Inc.
5
5
  */
6
6
  .fa {
7
7
  font-family: var(--fa-style-family, "Font Awesome 6 Free");
@@ -258,8 +258,10 @@
258
258
  animation-duration: 1ms;
259
259
  -webkit-animation-iteration-count: 1;
260
260
  animation-iteration-count: 1;
261
- transition-delay: 0s;
262
- transition-duration: 0s; } }
261
+ -webkit-transition-delay: 0s;
262
+ transition-delay: 0s;
263
+ -webkit-transition-duration: 0s;
264
+ transition-duration: 0s; } }
263
265
 
264
266
  @-webkit-keyframes fa-beat {
265
267
  0%, 90% {
@@ -461,8 +463,8 @@
461
463
  transform: scale(-1, -1); }
462
464
 
463
465
  .fa-rotate-by {
464
- -webkit-transform: rotate(var(--fa-rotate-angle, none));
465
- transform: rotate(var(--fa-rotate-angle, none)); }
466
+ -webkit-transform: rotate(var(--fa-rotate-angle, 0));
467
+ transform: rotate(var(--fa-rotate-angle, 0)); }
466
468
 
467
469
  .fa-stack {
468
470
  display: inline-block;
@@ -491,6 +493,7 @@
491
493
 
492
494
  /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
493
495
  readers do not read off random characters that represent icons */
496
+
494
497
  .fa-0::before {
495
498
  content: "\30"; }
496
499
 
@@ -2765,6 +2768,9 @@ readers do not read off random characters that represent icons */
2765
2768
  .fa-italic::before {
2766
2769
  content: "\f033"; }
2767
2770
 
2771
+ .fa-table-cells-column-lock::before {
2772
+ content: "\e678"; }
2773
+
2768
2774
  .fa-church::before {
2769
2775
  content: "\f51d"; }
2770
2776
 
@@ -4937,6 +4943,9 @@ readers do not read off random characters that represent icons */
4937
4943
  .fa-font::before {
4938
4944
  content: "\f031"; }
4939
4945
 
4946
+ .fa-table-cells-row-lock::before {
4947
+ content: "\e67a"; }
4948
+
4940
4949
  .fa-rupiah-sign::before {
4941
4950
  content: "\e23d"; }
4942
4951
 
@@ -5966,9 +5975,6 @@ readers do not read off random characters that represent icons */
5966
5975
  .fa-share::before {
5967
5976
  content: "\f064"; }
5968
5977
 
5969
- .fa-arrow-turn-right::before {
5970
- content: "\f064"; }
5971
-
5972
5978
  .fa-mail-forward::before {
5973
5979
  content: "\f064"; }
5974
5980
 
@@ -6418,6 +6424,9 @@ readers do not read off random characters that represent icons */
6418
6424
  .fa-ups:before {
6419
6425
  content: "\f7e0"; }
6420
6426
 
6427
+ .fa-pixiv:before {
6428
+ content: "\e640"; }
6429
+
6421
6430
  .fa-wpexplorer:before {
6422
6431
  content: "\f2de"; }
6423
6432
 
@@ -6478,6 +6487,9 @@ readers do not read off random characters that represent icons */
6478
6487
  .fa-drupal:before {
6479
6488
  content: "\f1a9"; }
6480
6489
 
6490
+ .fa-jxl:before {
6491
+ content: "\e67b"; }
6492
+
6481
6493
  .fa-hire-a-helper:before {
6482
6494
  content: "\f3b0"; }
6483
6495
 
@@ -6523,6 +6535,9 @@ readers do not read off random characters that represent icons */
6523
6535
  .fa-deskpro:before {
6524
6536
  content: "\f38f"; }
6525
6537
 
6538
+ .fa-brave:before {
6539
+ content: "\e63c"; }
6540
+
6526
6541
  .fa-sistrix:before {
6527
6542
  content: "\f3ee"; }
6528
6543
 
@@ -6547,6 +6562,9 @@ readers do not read off random characters that represent icons */
6547
6562
  .fa-edge:before {
6548
6563
  content: "\f282"; }
6549
6564
 
6565
+ .fa-threads:before {
6566
+ content: "\e618"; }
6567
+
6550
6568
  .fa-napster:before {
6551
6569
  content: "\f3d2"; }
6552
6570
 
@@ -6688,6 +6706,9 @@ readers do not read off random characters that represent icons */
6688
6706
  .fa-cloudsmith:before {
6689
6707
  content: "\f384"; }
6690
6708
 
6709
+ .fa-opensuse:before {
6710
+ content: "\e62b"; }
6711
+
6691
6712
  .fa-pied-piper-alt:before {
6692
6713
  content: "\f1a8"; }
6693
6714
 
@@ -6715,6 +6736,9 @@ readers do not read off random characters that represent icons */
6715
6736
  .fa-scribd:before {
6716
6737
  content: "\f28a"; }
6717
6738
 
6739
+ .fa-debian:before {
6740
+ content: "\e60b"; }
6741
+
6718
6742
  .fa-openid:before {
6719
6743
  content: "\f19b"; }
6720
6744
 
@@ -6769,6 +6793,9 @@ readers do not read off random characters that represent icons */
6769
6793
  .fa-kickstarter:before {
6770
6794
  content: "\f3bb"; }
6771
6795
 
6796
+ .fa-square-kickstarter:before {
6797
+ content: "\f3bb"; }
6798
+
6772
6799
  .fa-grav:before {
6773
6800
  content: "\f2d6"; }
6774
6801
 
@@ -6829,6 +6856,9 @@ readers do not read off random characters that represent icons */
6829
6856
  .fa-bluetooth-b:before {
6830
6857
  content: "\f294"; }
6831
6858
 
6859
+ .fa-square-letterboxd:before {
6860
+ content: "\e62e"; }
6861
+
6832
6862
  .fa-sticker-mule:before {
6833
6863
  content: "\f3f7"; }
6834
6864
 
@@ -6862,6 +6892,9 @@ readers do not read off random characters that represent icons */
6862
6892
  .fa-confluence:before {
6863
6893
  content: "\f78d"; }
6864
6894
 
6895
+ .fa-shoelace:before {
6896
+ content: "\e60c"; }
6897
+
6865
6898
  .fa-mdb:before {
6866
6899
  content: "\f8ca"; }
6867
6900
 
@@ -6955,6 +6988,9 @@ readers do not read off random characters that represent icons */
6955
6988
  .fa-neos:before {
6956
6989
  content: "\f612"; }
6957
6990
 
6991
+ .fa-square-threads:before {
6992
+ content: "\e619"; }
6993
+
6958
6994
  .fa-hackerrank:before {
6959
6995
  content: "\f5f7"; }
6960
6996
 
@@ -6982,6 +7018,9 @@ readers do not read off random characters that represent icons */
6982
7018
  .fa-envira:before {
6983
7019
  content: "\f299"; }
6984
7020
 
7021
+ .fa-google-scholar:before {
7022
+ content: "\e63b"; }
7023
+
6985
7024
  .fa-square-gitlab:before {
6986
7025
  content: "\e5ae"; }
6987
7026
 
@@ -7114,6 +7153,9 @@ readers do not read off random characters that represent icons */
7114
7153
  .fa-vine:before {
7115
7154
  content: "\f1ca"; }
7116
7155
 
7156
+ .fa-signal-messenger:before {
7157
+ content: "\e663"; }
7158
+
7117
7159
  .fa-paypal:before {
7118
7160
  content: "\f1ed"; }
7119
7161
 
@@ -7147,6 +7189,9 @@ readers do not read off random characters that represent icons */
7147
7189
  .fa-nfc-symbol:before {
7148
7190
  content: "\e531"; }
7149
7191
 
7192
+ .fa-mintbit:before {
7193
+ content: "\e62f"; }
7194
+
7150
7195
  .fa-ethereum:before {
7151
7196
  content: "\f42e"; }
7152
7197
 
@@ -7171,6 +7216,9 @@ readers do not read off random characters that represent icons */
7171
7216
  .fa-bimobject:before {
7172
7217
  content: "\f378"; }
7173
7218
 
7219
+ .fa-brave-reverse:before {
7220
+ content: "\e63d"; }
7221
+
7174
7222
  .fa-facebook-f:before {
7175
7223
  content: "\f39e"; }
7176
7224
 
@@ -7180,6 +7228,9 @@ readers do not read off random characters that represent icons */
7180
7228
  .fa-google-plus-square:before {
7181
7229
  content: "\f0d4"; }
7182
7230
 
7231
+ .fa-web-awesome:before {
7232
+ content: "\e682"; }
7233
+
7183
7234
  .fa-mandalorian:before {
7184
7235
  content: "\f50f"; }
7185
7236
 
@@ -7273,6 +7324,9 @@ readers do not read off random characters that represent icons */
7273
7324
  .fa-tencent-weibo:before {
7274
7325
  content: "\f1d5"; }
7275
7326
 
7327
+ .fa-letterboxd:before {
7328
+ content: "\e62d"; }
7329
+
7276
7330
  .fa-symfony:before {
7277
7331
  content: "\f83d"; }
7278
7332
 
@@ -7297,6 +7351,9 @@ readers do not read off random characters that represent icons */
7297
7351
  .fa-erlang:before {
7298
7352
  content: "\f39d"; }
7299
7353
 
7354
+ .fa-x-twitter:before {
7355
+ content: "\e61b"; }
7356
+
7300
7357
  .fa-cotton-bureau:before {
7301
7358
  content: "\f89e"; }
7302
7359
 
@@ -7336,6 +7393,9 @@ readers do not read off random characters that represent icons */
7336
7393
  .fa-xbox:before {
7337
7394
  content: "\f412"; }
7338
7395
 
7396
+ .fa-square-web-awesome-stroke:before {
7397
+ content: "\e684"; }
7398
+
7339
7399
  .fa-searchengin:before {
7340
7400
  content: "\f3eb"; }
7341
7401
 
@@ -7408,6 +7468,9 @@ readers do not read off random characters that represent icons */
7408
7468
  .fa-cmplid:before {
7409
7469
  content: "\e360"; }
7410
7470
 
7471
+ .fa-upwork:before {
7472
+ content: "\e641"; }
7473
+
7411
7474
  .fa-facebook:before {
7412
7475
  content: "\f09a"; }
7413
7476
 
@@ -7441,6 +7504,9 @@ readers do not read off random characters that represent icons */
7441
7504
  .fa-whatsapp:before {
7442
7505
  content: "\f232"; }
7443
7506
 
7507
+ .fa-square-upwork:before {
7508
+ content: "\e67c"; }
7509
+
7444
7510
  .fa-slideshare:before {
7445
7511
  content: "\f1e7"; }
7446
7512
 
@@ -7519,6 +7585,9 @@ readers do not read off random characters that represent icons */
7519
7585
  .fa-sellsy:before {
7520
7586
  content: "\f213"; }
7521
7587
 
7588
+ .fa-square-web-awesome:before {
7589
+ content: "\e683"; }
7590
+
7522
7591
  .fa-sass:before {
7523
7592
  content: "\f41e"; }
7524
7593
 
@@ -7555,6 +7624,9 @@ readers do not read off random characters that represent icons */
7555
7624
  .fa-waze:before {
7556
7625
  content: "\f83f"; }
7557
7626
 
7627
+ .fa-bluesky:before {
7628
+ content: "\e671"; }
7629
+
7558
7630
  .fa-cc-jcb:before {
7559
7631
  content: "\f24b"; }
7560
7632
 
@@ -7582,6 +7654,9 @@ readers do not read off random characters that represent icons */
7582
7654
  .fa-supple:before {
7583
7655
  content: "\f3f9"; }
7584
7656
 
7657
+ .fa-webflow:before {
7658
+ content: "\e65c"; }
7659
+
7585
7660
  .fa-rebel:before {
7586
7661
  content: "\f1d0"; }
7587
7662
 
@@ -7744,6 +7819,9 @@ readers do not read off random characters that represent icons */
7744
7819
  .fa-internet-explorer:before {
7745
7820
  content: "\f26b"; }
7746
7821
 
7822
+ .fa-stubber:before {
7823
+ content: "\e5c7"; }
7824
+
7747
7825
  .fa-telegram:before {
7748
7826
  content: "\f2c6"; }
7749
7827
 
@@ -7753,6 +7831,9 @@ readers do not read off random characters that represent icons */
7753
7831
  .fa-old-republic:before {
7754
7832
  content: "\f510"; }
7755
7833
 
7834
+ .fa-odysee:before {
7835
+ content: "\e5c6"; }
7836
+
7756
7837
  .fa-square-whatsapp:before {
7757
7838
  content: "\f40c"; }
7758
7839
 
@@ -7786,6 +7867,9 @@ readers do not read off random characters that represent icons */
7786
7867
  .fa-quora:before {
7787
7868
  content: "\f2c4"; }
7788
7869
 
7870
+ .fa-square-x-twitter:before {
7871
+ content: "\e61a"; }
7872
+
7789
7873
  .fa-reacteurope:before {
7790
7874
  content: "\f75d"; }
7791
7875