+443
-4
deno.lock
+443
-4
deno.lock
···
10
10
"npm:@atcute/lexicons@^1.2.3": "1.2.3",
11
11
"npm:@atcute/microcosm@1": "1.0.0",
12
12
"npm:@atcute/oauth-browser-client@^2.0.1": "2.0.1_@atcute+identity@1.1.2",
13
+
"npm:@huggingface/transformers@^3.8.0": "3.8.0",
13
14
"npm:@pandacss/dev@^1.5.1": "1.5.1_typescript@5.9.3",
14
15
"npm:@pandacss/preset-base@^1.5.1": "1.5.1",
15
16
"npm:@park-ui/panda-preset@~0.43.1": "0.43.1_@pandacss+dev@1.5.1__typescript@5.9.3_typescript@5.9.3",
···
243
244
"debug",
244
245
"gensync",
245
246
"json5",
246
-
"semver"
247
+
"semver@6.3.1"
247
248
]
248
249
},
249
250
"@babel/generator@7.28.5": {
···
263
264
"@babel/helper-validator-option",
264
265
"browserslist@4.28.0",
265
266
"lru-cache",
266
-
"semver"
267
+
"semver@6.3.1"
267
268
]
268
269
},
269
270
"@babel/helper-globals@7.28.0": {
···
390
391
"postcss-selector-parser"
391
392
]
392
393
},
394
+
"@emnapi/runtime@1.7.1": {
395
+
"integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==",
396
+
"dependencies": [
397
+
"tslib"
398
+
]
399
+
},
393
400
"@esbuild/aix-ppc64@0.25.12": {
394
401
"integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
395
402
"os": ["aix"],
···
543
550
"@floating-ui/utils@0.2.10": {
544
551
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="
545
552
},
553
+
"@huggingface/jinja@0.5.1": {
554
+
"integrity": "sha512-yUZLld4lrM9iFxHCwFQ7D1HW2MWMwSbeB7WzWqFYDWK+rEb+WldkLdAJxUPOmgICMHZLzZGVcVjFh3w/YGubng=="
555
+
},
556
+
"@huggingface/transformers@3.8.0": {
557
+
"integrity": "sha512-bEvx9k/fnhjKtekc1pDYLGDhVwxW5mO3k4UkP/mJQtQI5dC34daCQ28O1B19lkyM0QYFwAj+RGl0qOjE9Upt/w==",
558
+
"dependencies": [
559
+
"@huggingface/jinja",
560
+
"onnxruntime-node",
561
+
"onnxruntime-web",
562
+
"sharp"
563
+
]
564
+
},
565
+
"@img/colour@1.0.0": {
566
+
"integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="
567
+
},
568
+
"@img/sharp-darwin-arm64@0.34.5": {
569
+
"integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
570
+
"optionalDependencies": [
571
+
"@img/sharp-libvips-darwin-arm64"
572
+
],
573
+
"os": ["darwin"],
574
+
"cpu": ["arm64"]
575
+
},
576
+
"@img/sharp-darwin-x64@0.34.5": {
577
+
"integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
578
+
"optionalDependencies": [
579
+
"@img/sharp-libvips-darwin-x64"
580
+
],
581
+
"os": ["darwin"],
582
+
"cpu": ["x64"]
583
+
},
584
+
"@img/sharp-libvips-darwin-arm64@1.2.4": {
585
+
"integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
586
+
"os": ["darwin"],
587
+
"cpu": ["arm64"]
588
+
},
589
+
"@img/sharp-libvips-darwin-x64@1.2.4": {
590
+
"integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
591
+
"os": ["darwin"],
592
+
"cpu": ["x64"]
593
+
},
594
+
"@img/sharp-libvips-linux-arm64@1.2.4": {
595
+
"integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
596
+
"os": ["linux"],
597
+
"cpu": ["arm64"]
598
+
},
599
+
"@img/sharp-libvips-linux-arm@1.2.4": {
600
+
"integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
601
+
"os": ["linux"],
602
+
"cpu": ["arm"]
603
+
},
604
+
"@img/sharp-libvips-linux-ppc64@1.2.4": {
605
+
"integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
606
+
"os": ["linux"],
607
+
"cpu": ["ppc64"]
608
+
},
609
+
"@img/sharp-libvips-linux-riscv64@1.2.4": {
610
+
"integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
611
+
"os": ["linux"],
612
+
"cpu": ["riscv64"]
613
+
},
614
+
"@img/sharp-libvips-linux-s390x@1.2.4": {
615
+
"integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
616
+
"os": ["linux"],
617
+
"cpu": ["s390x"]
618
+
},
619
+
"@img/sharp-libvips-linux-x64@1.2.4": {
620
+
"integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
621
+
"os": ["linux"],
622
+
"cpu": ["x64"]
623
+
},
624
+
"@img/sharp-libvips-linuxmusl-arm64@1.2.4": {
625
+
"integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
626
+
"os": ["linux"],
627
+
"cpu": ["arm64"]
628
+
},
629
+
"@img/sharp-libvips-linuxmusl-x64@1.2.4": {
630
+
"integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
631
+
"os": ["linux"],
632
+
"cpu": ["x64"]
633
+
},
634
+
"@img/sharp-linux-arm64@0.34.5": {
635
+
"integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
636
+
"optionalDependencies": [
637
+
"@img/sharp-libvips-linux-arm64"
638
+
],
639
+
"os": ["linux"],
640
+
"cpu": ["arm64"]
641
+
},
642
+
"@img/sharp-linux-arm@0.34.5": {
643
+
"integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
644
+
"optionalDependencies": [
645
+
"@img/sharp-libvips-linux-arm"
646
+
],
647
+
"os": ["linux"],
648
+
"cpu": ["arm"]
649
+
},
650
+
"@img/sharp-linux-ppc64@0.34.5": {
651
+
"integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
652
+
"optionalDependencies": [
653
+
"@img/sharp-libvips-linux-ppc64"
654
+
],
655
+
"os": ["linux"],
656
+
"cpu": ["ppc64"]
657
+
},
658
+
"@img/sharp-linux-riscv64@0.34.5": {
659
+
"integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
660
+
"optionalDependencies": [
661
+
"@img/sharp-libvips-linux-riscv64"
662
+
],
663
+
"os": ["linux"],
664
+
"cpu": ["riscv64"]
665
+
},
666
+
"@img/sharp-linux-s390x@0.34.5": {
667
+
"integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
668
+
"optionalDependencies": [
669
+
"@img/sharp-libvips-linux-s390x"
670
+
],
671
+
"os": ["linux"],
672
+
"cpu": ["s390x"]
673
+
},
674
+
"@img/sharp-linux-x64@0.34.5": {
675
+
"integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
676
+
"optionalDependencies": [
677
+
"@img/sharp-libvips-linux-x64"
678
+
],
679
+
"os": ["linux"],
680
+
"cpu": ["x64"]
681
+
},
682
+
"@img/sharp-linuxmusl-arm64@0.34.5": {
683
+
"integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
684
+
"optionalDependencies": [
685
+
"@img/sharp-libvips-linuxmusl-arm64"
686
+
],
687
+
"os": ["linux"],
688
+
"cpu": ["arm64"]
689
+
},
690
+
"@img/sharp-linuxmusl-x64@0.34.5": {
691
+
"integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
692
+
"optionalDependencies": [
693
+
"@img/sharp-libvips-linuxmusl-x64"
694
+
],
695
+
"os": ["linux"],
696
+
"cpu": ["x64"]
697
+
},
698
+
"@img/sharp-wasm32@0.34.5": {
699
+
"integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
700
+
"dependencies": [
701
+
"@emnapi/runtime"
702
+
],
703
+
"cpu": ["wasm32"]
704
+
},
705
+
"@img/sharp-win32-arm64@0.34.5": {
706
+
"integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
707
+
"os": ["win32"],
708
+
"cpu": ["arm64"]
709
+
},
710
+
"@img/sharp-win32-ia32@0.34.5": {
711
+
"integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
712
+
"os": ["win32"],
713
+
"cpu": ["ia32"]
714
+
},
715
+
"@img/sharp-win32-x64@0.34.5": {
716
+
"integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
717
+
"os": ["win32"],
718
+
"cpu": ["x64"]
719
+
},
546
720
"@internationalized/date@3.10.0": {
547
721
"integrity": "sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==",
548
722
"dependencies": [
···
574
748
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
575
749
"dependencies": [
576
750
"@isaacs/balanced-match"
751
+
]
752
+
},
753
+
"@isaacs/fs-minipass@4.0.1": {
754
+
"integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
755
+
"dependencies": [
756
+
"minipass"
577
757
]
578
758
},
579
759
"@jridgewell/gen-mapping@0.3.13": {
···
817
997
"effect"
818
998
],
819
999
"scripts": true
1000
+
},
1001
+
"@protobufjs/aspromise@1.1.2": {
1002
+
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
1003
+
},
1004
+
"@protobufjs/base64@1.1.2": {
1005
+
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
1006
+
},
1007
+
"@protobufjs/codegen@2.0.4": {
1008
+
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
1009
+
},
1010
+
"@protobufjs/eventemitter@1.1.0": {
1011
+
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
1012
+
},
1013
+
"@protobufjs/fetch@1.1.0": {
1014
+
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
1015
+
"dependencies": [
1016
+
"@protobufjs/aspromise",
1017
+
"@protobufjs/inquire"
1018
+
]
1019
+
},
1020
+
"@protobufjs/float@1.0.2": {
1021
+
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
1022
+
},
1023
+
"@protobufjs/inquire@1.1.0": {
1024
+
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
1025
+
},
1026
+
"@protobufjs/path@1.1.2": {
1027
+
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
1028
+
},
1029
+
"@protobufjs/pool@1.1.0": {
1030
+
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
1031
+
},
1032
+
"@protobufjs/utf8@1.1.0": {
1033
+
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
820
1034
},
821
1035
"@rollup/rollup-android-arm-eabi@4.52.5": {
822
1036
"integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==",
···
2484
2698
"integrity": "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==",
2485
2699
"bin": true
2486
2700
},
2701
+
"boolean@3.2.0": {
2702
+
"integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
2703
+
"deprecated": true
2704
+
},
2487
2705
"braces@3.0.3": {
2488
2706
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
2489
2707
"dependencies": [
···
2539
2757
"readdirp"
2540
2758
]
2541
2759
},
2760
+
"chownr@3.0.0": {
2761
+
"integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="
2762
+
},
2542
2763
"code-block-writer@13.0.3": {
2543
2764
"integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg=="
2544
2765
},
···
2582
2803
"ms"
2583
2804
]
2584
2805
},
2806
+
"define-data-property@1.1.4": {
2807
+
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
2808
+
"dependencies": [
2809
+
"es-define-property",
2810
+
"es-errors",
2811
+
"gopd"
2812
+
]
2813
+
},
2814
+
"define-properties@1.2.1": {
2815
+
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
2816
+
"dependencies": [
2817
+
"define-data-property",
2818
+
"has-property-descriptors",
2819
+
"object-keys"
2820
+
]
2821
+
},
2585
2822
"detect-libc@1.0.3": {
2586
2823
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
2587
2824
"bin": true
2825
+
},
2826
+
"detect-libc@2.1.2": {
2827
+
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="
2828
+
},
2829
+
"detect-node@2.1.0": {
2830
+
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
2588
2831
},
2589
2832
"effect@3.10.15": {
2590
2833
"integrity": "sha512-LdczPAFbtij3xGr9i+8PyDtuWdlXjSY5UJ8PKrYrr0DClKfR/OW3j8sxtambWYljzJAYD865KFhv7LdbWdG7VQ==",
···
2604
2847
"entities@6.0.1": {
2605
2848
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="
2606
2849
},
2850
+
"es-define-property@1.0.1": {
2851
+
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="
2852
+
},
2853
+
"es-errors@1.3.0": {
2854
+
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
2855
+
},
2856
+
"es6-error@4.1.1": {
2857
+
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="
2858
+
},
2607
2859
"esbuild@0.25.12": {
2608
2860
"integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
2609
2861
"optionalDependencies": [
···
2642
2894
},
2643
2895
"escalade@3.2.0": {
2644
2896
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="
2897
+
},
2898
+
"escape-string-regexp@4.0.0": {
2899
+
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
2645
2900
},
2646
2901
"esm-env@1.2.2": {
2647
2902
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="
···
2698
2953
"to-regex-range"
2699
2954
]
2700
2955
},
2956
+
"flatbuffers@25.9.23": {
2957
+
"integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ=="
2958
+
},
2701
2959
"focus-trap@7.5.4": {
2702
2960
"integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==",
2703
2961
"dependencies": [
···
2730
2988
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
2731
2989
"dependencies": [
2732
2990
"is-glob"
2991
+
]
2992
+
},
2993
+
"global-agent@3.0.0": {
2994
+
"integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
2995
+
"dependencies": [
2996
+
"boolean",
2997
+
"es6-error",
2998
+
"matcher",
2999
+
"roarr",
3000
+
"semver@7.7.3",
3001
+
"serialize-error"
3002
+
]
3003
+
},
3004
+
"globalthis@1.0.4": {
3005
+
"integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
3006
+
"dependencies": [
3007
+
"define-properties",
3008
+
"gopd"
2733
3009
]
2734
3010
},
2735
3011
"globrex@0.1.2": {
2736
3012
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="
2737
3013
},
3014
+
"gopd@1.2.0": {
3015
+
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
3016
+
},
2738
3017
"graceful-fs@4.2.11": {
2739
3018
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
3019
+
},
3020
+
"guid-typescript@1.0.9": {
3021
+
"integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ=="
3022
+
},
3023
+
"has-property-descriptors@1.0.2": {
3024
+
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
3025
+
"dependencies": [
3026
+
"es-define-property"
3027
+
]
2740
3028
},
2741
3029
"hookable@5.5.3": {
2742
3030
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
···
2775
3063
"json-schema-traverse@1.0.0": {
2776
3064
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
2777
3065
},
3066
+
"json-stringify-safe@5.0.1": {
3067
+
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
3068
+
},
2778
3069
"json5@2.2.3": {
2779
3070
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
2780
3071
"bin": true
···
2842
3133
"lightningcss@1.25.1": {
2843
3134
"integrity": "sha512-V0RMVZzK1+rCHpymRv4URK2lNhIRyO8g7U7zOFwVAhJuat74HtkjIQpQRKNCwFEYkRGpafOpmXXLoaoBcyVtBg==",
2844
3135
"dependencies": [
2845
-
"detect-libc"
3136
+
"detect-libc@1.0.3"
2846
3137
],
2847
3138
"optionalDependencies": [
2848
3139
"lightningcss-darwin-arm64",
···
2868
3159
"lodash.uniq@4.5.0": {
2869
3160
"integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="
2870
3161
},
3162
+
"long@5.3.2": {
3163
+
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="
3164
+
},
2871
3165
"look-it-up@2.1.0": {
2872
3166
"integrity": "sha512-nMoGWW2HurtuJf6XAL56FWTDCWLOTSsanrgwOyaR5Y4e3zfG5N/0cU5xWZSEU3tBxhQugRbV1xL9jb+ug7yZww=="
2873
3167
},
2874
3168
"lru-cache@5.1.1": {
2875
3169
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
2876
3170
"dependencies": [
2877
-
"yallist"
3171
+
"yallist@3.1.1"
2878
3172
]
2879
3173
},
2880
3174
"lucide-solid@0.553.0_solid-js@1.9.10__seroval@1.3.2": {
···
2887
3181
"integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==",
2888
3182
"dependencies": [
2889
3183
"@jridgewell/sourcemap-codec"
3184
+
]
3185
+
},
3186
+
"matcher@3.0.0": {
3187
+
"integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
3188
+
"dependencies": [
3189
+
"escape-string-regexp"
2890
3190
]
2891
3191
},
2892
3192
"mediabunny@1.25.0": {
···
2921
3221
"@isaacs/brace-expansion"
2922
3222
]
2923
3223
},
3224
+
"minipass@7.1.2": {
3225
+
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="
3226
+
},
3227
+
"minizlib@3.1.0": {
3228
+
"integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
3229
+
"dependencies": [
3230
+
"minipass"
3231
+
]
3232
+
},
2924
3233
"ms@2.1.3": {
2925
3234
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
2926
3235
},
···
2941
3250
"node-releases@2.0.27": {
2942
3251
"integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="
2943
3252
},
3253
+
"object-keys@1.1.1": {
3254
+
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
3255
+
},
2944
3256
"object-path@0.11.8": {
2945
3257
"integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA=="
2946
3258
},
3259
+
"onnxruntime-common@1.21.0": {
3260
+
"integrity": "sha512-Q632iLLrtCAVOTO65dh2+mNbQir/QNTVBG3h/QdZBpns7mZ0RYbLRBgGABPbpU9351AgYy7SJf1WaeVwMrBFPQ=="
3261
+
},
3262
+
"onnxruntime-common@1.22.0-dev.20250409-89f8206ba4": {
3263
+
"integrity": "sha512-vDJMkfCfb0b1A836rgHj+ORuZf4B4+cc2bASQtpeoJLueuFc5DuYwjIZUBrSvx/fO5IrLjLz+oTrB3pcGlhovQ=="
3264
+
},
3265
+
"onnxruntime-node@1.21.0": {
3266
+
"integrity": "sha512-NeaCX6WW2L8cRCSqy3bInlo5ojjQqu2fD3D+9W5qb5irwxhEyWKXeH2vZ8W9r6VxaMPUan+4/7NDwZMtouZxEw==",
3267
+
"dependencies": [
3268
+
"global-agent",
3269
+
"onnxruntime-common@1.21.0",
3270
+
"tar"
3271
+
],
3272
+
"os": ["win32", "darwin", "linux"],
3273
+
"scripts": true
3274
+
},
3275
+
"onnxruntime-web@1.22.0-dev.20250409-89f8206ba4": {
3276
+
"integrity": "sha512-0uS76OPgH0hWCPrFKlL8kYVV7ckM7t/36HfbgoFw6Nd0CZVVbQC4PkrR8mBX8LtNUFZO25IQBqV2Hx2ho3FlbQ==",
3277
+
"dependencies": [
3278
+
"flatbuffers",
3279
+
"guid-typescript",
3280
+
"long",
3281
+
"onnxruntime-common@1.22.0-dev.20250409-89f8206ba4",
3282
+
"platform",
3283
+
"protobufjs"
3284
+
]
3285
+
},
2947
3286
"outdent@0.8.0": {
2948
3287
"integrity": "sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A=="
2949
3288
},
···
2987
3326
"exsolve",
2988
3327
"pathe"
2989
3328
]
3329
+
},
3330
+
"platform@1.3.6": {
3331
+
"integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="
2990
3332
},
2991
3333
"pluralize@8.0.0": {
2992
3334
"integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA=="
···
3057
3399
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
3058
3400
"bin": true
3059
3401
},
3402
+
"protobufjs@7.5.4": {
3403
+
"integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==",
3404
+
"dependencies": [
3405
+
"@protobufjs/aspromise",
3406
+
"@protobufjs/base64",
3407
+
"@protobufjs/codegen",
3408
+
"@protobufjs/eventemitter",
3409
+
"@protobufjs/fetch",
3410
+
"@protobufjs/float",
3411
+
"@protobufjs/inquire",
3412
+
"@protobufjs/path",
3413
+
"@protobufjs/pool",
3414
+
"@protobufjs/utf8",
3415
+
"@types/node",
3416
+
"long"
3417
+
],
3418
+
"scripts": true
3419
+
},
3060
3420
"proxy-compare@3.0.0": {
3061
3421
"integrity": "sha512-y44MCkgtZUCT9tZGuE278fB7PWVf7fRYy0vbRXAts2o5F0EfC4fIQrvQQGBJo1WJbFcVLXzApOscyJuZqHQc1w=="
3062
3422
},
···
3084
3444
"reusify@1.1.0": {
3085
3445
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="
3086
3446
},
3447
+
"roarr@2.15.4": {
3448
+
"integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
3449
+
"dependencies": [
3450
+
"boolean",
3451
+
"detect-node",
3452
+
"globalthis",
3453
+
"json-stringify-safe",
3454
+
"semver-compare",
3455
+
"sprintf-js"
3456
+
]
3457
+
},
3087
3458
"rollup@4.52.5": {
3088
3459
"integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==",
3089
3460
"dependencies": [
···
3122
3493
"queue-microtask"
3123
3494
]
3124
3495
},
3496
+
"semver-compare@1.0.0": {
3497
+
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="
3498
+
},
3125
3499
"semver@6.3.1": {
3126
3500
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
3127
3501
"bin": true
3502
+
},
3503
+
"semver@7.7.3": {
3504
+
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
3505
+
"bin": true
3506
+
},
3507
+
"serialize-error@7.0.1": {
3508
+
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
3509
+
"dependencies": [
3510
+
"type-fest"
3511
+
]
3128
3512
},
3129
3513
"seroval-plugins@1.3.3_seroval@1.3.2": {
3130
3514
"integrity": "sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==",
···
3135
3519
"seroval@1.3.2": {
3136
3520
"integrity": "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ=="
3137
3521
},
3522
+
"sharp@0.34.5": {
3523
+
"integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
3524
+
"dependencies": [
3525
+
"@img/colour",
3526
+
"detect-libc@2.1.2",
3527
+
"semver@7.7.3"
3528
+
],
3529
+
"optionalDependencies": [
3530
+
"@img/sharp-darwin-arm64",
3531
+
"@img/sharp-darwin-x64",
3532
+
"@img/sharp-libvips-darwin-arm64",
3533
+
"@img/sharp-libvips-darwin-x64",
3534
+
"@img/sharp-libvips-linux-arm",
3535
+
"@img/sharp-libvips-linux-arm64",
3536
+
"@img/sharp-libvips-linux-ppc64",
3537
+
"@img/sharp-libvips-linux-riscv64",
3538
+
"@img/sharp-libvips-linux-s390x",
3539
+
"@img/sharp-libvips-linux-x64",
3540
+
"@img/sharp-libvips-linuxmusl-arm64",
3541
+
"@img/sharp-libvips-linuxmusl-x64",
3542
+
"@img/sharp-linux-arm",
3543
+
"@img/sharp-linux-arm64",
3544
+
"@img/sharp-linux-ppc64",
3545
+
"@img/sharp-linux-riscv64",
3546
+
"@img/sharp-linux-s390x",
3547
+
"@img/sharp-linux-x64",
3548
+
"@img/sharp-linuxmusl-arm64",
3549
+
"@img/sharp-linuxmusl-x64",
3550
+
"@img/sharp-wasm32",
3551
+
"@img/sharp-win32-arm64",
3552
+
"@img/sharp-win32-ia32",
3553
+
"@img/sharp-win32-x64"
3554
+
],
3555
+
"scripts": true
3556
+
},
3138
3557
"sisteransi@1.0.5": {
3139
3558
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="
3140
3559
},
···
3181
3600
"source-map-js@1.2.1": {
3182
3601
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
3183
3602
},
3603
+
"sprintf-js@1.1.3": {
3604
+
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="
3605
+
},
3184
3606
"string-width@4.2.3": {
3185
3607
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
3186
3608
"dependencies": [
···
3208
3630
"strip-ansi"
3209
3631
]
3210
3632
},
3633
+
"tar@7.5.1": {
3634
+
"integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==",
3635
+
"dependencies": [
3636
+
"@isaacs/fs-minipass",
3637
+
"chownr",
3638
+
"minipass",
3639
+
"minizlib",
3640
+
"yallist@5.0.0"
3641
+
]
3642
+
},
3211
3643
"tinyglobby@0.2.15_picomatch@4.0.3": {
3212
3644
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
3213
3645
"dependencies": [
···
3252
3684
},
3253
3685
"tslib@2.8.1": {
3254
3686
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
3687
+
},
3688
+
"type-fest@0.13.1": {
3689
+
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="
3255
3690
},
3256
3691
"typescript@5.9.3": {
3257
3692
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
···
3338
3773
},
3339
3774
"yallist@3.1.1": {
3340
3775
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
3776
+
},
3777
+
"yallist@5.0.0": {
3778
+
"integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="
3341
3779
}
3342
3780
},
3343
3781
"workspace": {
···
3352
3790
"npm:@atcute/lexicons@^1.2.3",
3353
3791
"npm:@atcute/microcosm@1",
3354
3792
"npm:@atcute/oauth-browser-client@^2.0.1",
3793
+
"npm:@huggingface/transformers@^3.8.0",
3355
3794
"npm:@pandacss/dev@^1.5.1",
3356
3795
"npm:@pandacss/preset-base@^1.5.1",
3357
3796
"npm:@park-ui/panda-preset@~0.43.1",
+1
package.json
+1
package.json
+50
-22
src/components/FileTask.tsx
+50
-22
src/components/FileTask.tsx
···
1
1
import {
2
+
CaptionsIcon,
2
3
CircleAlertIcon,
3
4
DownloadIcon,
4
5
EllipsisVerticalIcon,
···
14
15
15
16
import { TaskState } from "~/lib/task";
16
17
import PostDialog from "./PostDialog";
17
-
import { Button } from "./ui/button";
18
+
import { Button, ButtonProps } from "./ui/button";
18
19
import { Menu } from "./ui/menu";
19
20
import { createSignal } from "solid-js";
21
+
import { toaster } from "./Toaster";
20
22
21
23
const downloadFile = (blob: Blob, fileName: string) => {
22
24
const url = URL.createObjectURL(blob);
···
53
55
</Popover.Positioner>
54
56
</Popover.Root>
55
57
);
56
-
const statusSuccess = (result: Blob) => {
58
+
const statusSuccess = (result: Blob, altText?: string) => {
59
+
const [menuOpen, setMenuOpen] = createSignal(false);
60
+
const MenuButton = (props: ButtonProps) => (
61
+
<Button
62
+
color={{ _hover: "colorPalette.emphasized" }}
63
+
variant="ghost"
64
+
display="flex"
65
+
justifyContent="space-between"
66
+
alignItems="center"
67
+
{...props}
68
+
onClick={(e) => {
69
+
if (typeof props.onClick === "function") props.onClick(e);
70
+
setMenuOpen(false);
71
+
}}
72
+
/>
73
+
);
57
74
return (
58
75
<>
59
76
<PostDialog
60
77
openSignal={[dialogOpen, setDialogOpen]}
61
78
account={selectedAccount}
62
79
result={result}
80
+
initialAltText={altText}
63
81
/>
64
82
<Menu.Root
83
+
open={menuOpen()}
84
+
onOpenChange={(e) => setMenuOpen(e.open)}
65
85
positioning={{ placement: "bottom-start", strategy: "fixed" }}
66
86
>
67
87
<Menu.Trigger
···
72
92
)}
73
93
/>
74
94
<Menu.Positioner>
75
-
<Menu.Content>
95
+
<Menu.Content py="0">
76
96
<Menu.ItemGroup>
77
-
<Button
78
-
color={{ _hover: "colorPalette.emphasized" }}
79
-
onClick={() =>
97
+
<MenuButton
98
+
onClick={() => {
80
99
downloadFile(
81
100
result,
82
101
process.file.name
···
84
103
.slice(0, -1)
85
104
.join(".")
86
105
.concat(".mp4"),
87
-
)
88
-
}
89
-
variant="ghost"
90
-
display="flex"
91
-
justifyContent="space-between"
92
-
alignItems="center"
106
+
);
107
+
toaster.create({
108
+
title: "downloaded result file",
109
+
type: "success",
110
+
duration: 1000,
111
+
});
112
+
}}
93
113
>
94
114
download <DownloadIcon />
95
-
</Button>
96
-
<Button
97
-
onClick={() => setDialogOpen(!dialogOpen())}
115
+
</MenuButton>
116
+
<MenuButton
117
+
disabled={altText === undefined}
118
+
onClick={() => {
119
+
navigator.clipboard.writeText(altText!);
120
+
toaster.create({
121
+
title: "copied transcribed text to clipboard",
122
+
type: "success",
123
+
duration: 1000,
124
+
});
125
+
}}
126
+
>
127
+
copy transcription <CaptionsIcon />
128
+
</MenuButton>
129
+
<MenuButton
98
130
disabled={selectedAccount === undefined}
99
-
color={{ _hover: "colorPalette.emphasized" }}
100
-
variant="ghost"
101
-
display="flex"
102
-
justifyContent="space-between"
103
-
alignItems="center"
131
+
onClick={() => setDialogOpen(!dialogOpen())}
104
132
>
105
133
post to bsky <SendIcon />
106
-
</Button>
134
+
</MenuButton>
107
135
</Menu.ItemGroup>
108
136
</Menu.Content>
109
137
</Menu.Positioner>
···
123
151
const status = () => {
124
152
switch (process.status) {
125
153
case "success":
126
-
return statusSuccess(process.result);
154
+
return statusSuccess(process.result, process.altText);
127
155
case "processing":
128
156
return statusProcessing();
129
157
default:
+39
-2
src/components/PostDialog.tsx
+39
-2
src/components/PostDialog.tsx
···
1
1
import { Component, createSignal, Signal } from "solid-js";
2
2
3
-
import { SendIcon, XIcon } from "lucide-solid";
3
+
import { CaptionsIcon, SendIcon, XIcon } from "lucide-solid";
4
4
import { Stack } from "styled-system/jsx";
5
5
import { IconButton } from "~/components/ui/icon-button";
6
6
import { Spinner } from "~/components/ui/spinner";
···
14
14
import { Dialog } from "~/components/ui/dialog";
15
15
import { Textarea } from "~/components/ui/textarea";
16
16
import { Account } from "~/lib/accounts";
17
+
import { Popover } from "./ui/popover";
17
18
18
19
const PostDialog = (props: {
19
20
result: Blob;
20
21
account: Account | undefined;
21
22
openSignal: Signal<boolean>;
23
+
initialAltText?: string;
22
24
}) => {
23
25
const [postContent, setPostContent] = createSignal<string>("");
26
+
const [altText, setAltText] = createSignal<string>(
27
+
props.initialAltText ?? "",
28
+
);
24
29
const [posting, setPosting] = createSignal(false);
25
30
const [open, setOpen] = props.openSignal;
26
31
···
82
87
)}
83
88
/>
84
89
)}
90
+
<Popover.Root>
91
+
<Popover.Trigger
92
+
asChild={(triggerProps) => (
93
+
<IconButton
94
+
{...triggerProps()}
95
+
variant={altText() ? "solid" : "ghost"}
96
+
size="sm"
97
+
>
98
+
<CaptionsIcon />
99
+
</IconButton>
100
+
)}
101
+
/>
102
+
<Popover.Positioner>
103
+
<Popover.Content width="sm">
104
+
<Popover.Arrow />
105
+
<Stack gap="2">
106
+
<Popover.Title>video alt text</Popover.Title>
107
+
<Textarea
108
+
value={altText()}
109
+
onInput={(e) => setAltText(e.currentTarget.value)}
110
+
placeholder="describe the video content..."
111
+
rows={4}
112
+
/>
113
+
</Stack>
114
+
</Popover.Content>
115
+
</Popover.Positioner>
116
+
</Popover.Root>
85
117
<IconButton
86
118
disabled={posting()}
87
119
onClick={() => {
88
120
setPosting(true);
89
-
sendPost(props.account?.did!, props.result, postContent())
121
+
sendPost(
122
+
props.account?.did!,
123
+
props.result,
124
+
postContent(),
125
+
altText(),
126
+
)
90
127
.then((result) => {
91
128
const parsedUri = parseCanonicalResourceUri(result.uri);
92
129
if (!parsedUri.ok) throw "failed to parse atproto uri";
+119
-61
src/components/Settings.tsx
+119
-61
src/components/Settings.tsx
···
1
-
import { createSignal, For, Signal } from "solid-js";
1
+
import { Component, createSignal, For, JSXElement, Signal } from "solid-js";
2
2
3
3
import {
4
4
CheckIcon,
···
34
34
backgroundColor as backgroundColorSetting,
35
35
frameRate as frameRateSetting,
36
36
useDominantColorAsBg as useDominantColorAsBgSetting,
37
+
autoTranscribe as autoTranscribeSetting,
38
+
whisperModel as whisperModelSetting,
37
39
Setting,
40
+
defaultWhisperModel,
38
41
} from "~/lib/settings";
39
42
import { handleResolver } from "~/lib/at";
40
43
import { toaster } from "~/components/Toaster";
···
43
46
import { type Color, type ListCollection, parseColor } from "@ark-ui/solid";
44
47
import { ColorPicker } from "~/components/ui/color-picker";
45
48
import { Input } from "~/components/ui/input";
49
+
import { preloadModel } from "~/lib/transcribe";
46
50
47
51
const SettingCheckbox = (props: {
48
52
setting: Setting<boolean>;
···
191
195
);
192
196
};
193
197
198
+
const Category = ({
199
+
title,
200
+
children,
201
+
}: {
202
+
title: string;
203
+
children: JSXElement;
204
+
}) => (
205
+
<Stack>
206
+
<FormLabel>{title}</FormLabel>
207
+
<Stack
208
+
gap="0"
209
+
border="1px solid var(--colors-border-default)"
210
+
borderBottomWidth="3px"
211
+
rounded="xs"
212
+
>
213
+
{children}
214
+
</Stack>
215
+
</Stack>
216
+
);
217
+
194
218
const Settings = () => {
195
219
const [handle, setHandle] = createSignal("");
196
220
const isHandleValid = () => isHandle(handle());
···
259
283
</For>
260
284
);
261
285
return (
262
-
<Stack>
263
-
<FormLabel>accounts</FormLabel>
286
+
<Category title="accounts">
264
287
<Stack
265
-
border="1px solid var(--colors-border-default)"
266
-
borderBottomWidth="3px"
267
-
rounded="xs"
288
+
borderBottom="1px solid var(--colors-border-default)"
289
+
p="2"
290
+
marginBottom="2"
291
+
direction="row"
292
+
gap="2"
293
+
w="full"
268
294
>
269
-
<Stack
270
-
borderBottom="1px solid var(--colors-border-default)"
271
-
p="2"
272
-
direction="row"
273
-
gap="2"
274
-
w="full"
275
-
>
276
-
<Field.Root w="full">
277
-
<Field.Input
278
-
placeholder="example.bsky.social"
279
-
value={handle()}
280
-
onInput={(e) => setHandle(e.currentTarget.value)}
281
-
/>
282
-
</Field.Root>
283
-
<IconButton onClick={startAccountFlow} disabled={!isHandleValid()}>
284
-
<PlusIcon />
285
-
</IconButton>
286
-
</Stack>
287
-
{items(accounts())}
295
+
<Field.Root w="full">
296
+
<Field.Input
297
+
placeholder="example.bsky.social"
298
+
value={handle()}
299
+
onInput={(e) => setHandle(e.currentTarget.value)}
300
+
/>
301
+
</Field.Root>
302
+
<IconButton onClick={startAccountFlow} disabled={!isHandleValid()}>
303
+
<PlusIcon />
304
+
</IconButton>
288
305
</Stack>
289
-
</Stack>
306
+
{items(accounts())}
307
+
</Category>
290
308
);
291
309
};
292
310
···
322
340
backgroundColorSetting.set(newColor.toString("rgb"));
323
341
};
324
342
343
+
const whisperModelCollection = createListCollection({
344
+
items: [
345
+
{ tag: "tiny", size: "40MB" },
346
+
{ tag: "base", size: "80MB" },
347
+
{ tag: "small", size: "250MB" },
348
+
].map((model) => ({
349
+
label: `${model.tag} (${model.size})`,
350
+
value: `onnx-community/whisper-${model.tag}`,
351
+
})),
352
+
});
353
+
const [whisperModel, _setWhisperModel] = createSignal(
354
+
(whisperModelSetting.get() ?? defaultWhisperModel).toString(),
355
+
);
356
+
const setWhisperModel = (value: string | ((prev: string) => string)) => {
357
+
const newModel = _setWhisperModel(value);
358
+
whisperModelSetting.set(newModel);
359
+
if (autoTranscribe()) setTimeout(() => preloadModel(), 200);
360
+
};
361
+
const [autoTranscribe, setAutoTranscribe] = createSignal(
362
+
autoTranscribeSetting.get() ?? false,
363
+
);
364
+
325
365
return (
326
366
<Drawer.Root>
327
367
<Drawer.Trigger
···
351
391
<Drawer.Body>
352
392
<Stack gap="4">
353
393
<Accounts />
354
-
<Stack>
355
-
<FormLabel>processing</FormLabel>
356
-
<Stack
357
-
gap="0"
358
-
border="1px solid var(--colors-border-default)"
359
-
borderBottomWidth="3px"
360
-
rounded="xs"
361
-
>
362
-
<Box borderBottom="1px solid var(--colors-border-subtle)">
363
-
<SettingCheckbox
364
-
label="show profile picture"
365
-
setting={showProfilePictureSetting}
366
-
signal={[showProfilePicture, setShowProfilePicture]}
367
-
/>
368
-
</Box>
394
+
<Category title="video processing">
395
+
<Box borderBottom="1px solid var(--colors-border-subtle)">
369
396
<SettingCheckbox
370
-
label="show visualizer"
371
-
setting={showVisualizerSetting}
372
-
signal={[showVisualizer, setShowVisualizer]}
397
+
label="show profile picture"
398
+
setting={showProfilePictureSetting}
399
+
signal={[showProfilePicture, setShowProfilePicture]}
373
400
/>
374
-
<Stack gap="0" borderY="1px solid var(--colors-border-muted)">
375
-
<SettingCheckbox
376
-
label="use dominant color as bg"
377
-
setting={useDominantColorAsBgSetting}
378
-
signal={[useDominantColorAsBg, setUseDominantColorAsBg]}
379
-
disabled={!showProfilePicture()}
380
-
/>
381
-
<SettingColorPicker
382
-
label="background color"
383
-
signal={[backgroundColor, setBackgroundColor]}
384
-
/>
385
-
</Stack>
386
-
<SettingSelect
387
-
label="frame rate"
388
-
signal={[frameRate, setFrameRate]}
389
-
collection={frameRateCollection}
401
+
</Box>
402
+
<SettingCheckbox
403
+
label="show visualizer"
404
+
setting={showVisualizerSetting}
405
+
signal={[showVisualizer, setShowVisualizer]}
406
+
/>
407
+
<Stack gap="0" borderY="1px solid var(--colors-border-muted)">
408
+
<SettingCheckbox
409
+
label="use dominant color as bg"
410
+
setting={useDominantColorAsBgSetting}
411
+
signal={[useDominantColorAsBg, setUseDominantColorAsBg]}
412
+
disabled={!showProfilePicture()}
413
+
/>
414
+
<SettingColorPicker
415
+
label="background color"
416
+
signal={[backgroundColor, setBackgroundColor]}
390
417
/>
391
418
</Stack>
392
-
</Stack>
419
+
<SettingSelect
420
+
label="frame rate"
421
+
signal={[frameRate, setFrameRate]}
422
+
collection={frameRateCollection}
423
+
/>
424
+
</Category>
425
+
<Category title="audio transcription">
426
+
<Box borderBottom="1px solid var(--colors-border-subtle)">
427
+
<SettingCheckbox
428
+
label="transcribe audio"
429
+
setting={autoTranscribeSetting}
430
+
signal={[
431
+
autoTranscribe,
432
+
(val) => {
433
+
const newVal = setAutoTranscribe(val);
434
+
if (newVal) preloadModel();
435
+
return val;
436
+
},
437
+
]}
438
+
/>
439
+
</Box>
440
+
<Box borderBottom="1px solid var(--colors-border-subtle)">
441
+
<SettingSelect
442
+
label="whisper model"
443
+
signal={[whisperModel, setWhisperModel]}
444
+
collection={whisperModelCollection}
445
+
/>
446
+
</Box>
447
+
<Text color="fg.subtle" p="2" fontSize="sm" fontWeight="normal">
448
+
note: the model will only be downloaded once.
449
+
</Text>
450
+
</Category>
393
451
</Stack>
394
452
</Drawer.Body>
395
453
<Drawer.Footer p="2" gap="3">
+4
src/index.tsx
+4
src/index.tsx
···
12
12
import { accounts, setAccounts } from "./lib/accounts";
13
13
import { AtprotoDid } from "@atcute/lexicons/syntax";
14
14
import { toaster } from "./components/Toaster";
15
+
import { autoTranscribe } from "./lib/settings";
16
+
import { preloadModel } from "./lib/transcribe";
15
17
16
18
const root = document.getElementById("root");
17
19
···
52
54
type: "error",
53
55
});
54
56
});
57
+
58
+
if (autoTranscribe.get()) preloadModel();
55
59
56
60
render(() => <App />, root!);
+2
src/lib/at.ts
+2
src/lib/at.ts
···
35
35
did: AtprotoDid,
36
36
blob: Blob,
37
37
postContent: string,
38
+
altText?: string,
38
39
) => {
39
40
const login = await getSessionClient(did);
40
41
const upload = await login.client.post("com.atproto.repo.uploadBlob", {
···
47
48
embed: {
48
49
$type: "app.bsky.embed.video",
49
50
video: upload.data.blob,
51
+
alt: altText,
50
52
},
51
53
createdAt: new Date().toISOString(),
52
54
};
+4
src/lib/settings.ts
+4
src/lib/settings.ts
···
17
17
export const useDominantColorAsBg = setting<boolean>("useDominantColorAsBg");
18
18
export const backgroundColor = setting<string>("backgroundColor");
19
19
export const frameRate = setting<number>("frameRate");
20
+
21
+
export const autoTranscribe = setting<boolean>("autoTranscribe");
22
+
export const whisperModel = setting<string>("whisperModel");
23
+
export const defaultWhisperModel = "onnx-community/whisper-tiny";
+16
-8
src/lib/task.ts
+16
-8
src/lib/task.ts
···
6
6
showProfilePicture,
7
7
showVisualizer,
8
8
useDominantColorAsBg,
9
+
autoTranscribe,
9
10
} from "./settings";
10
11
import { getSessionClient } from "./oauth";
11
12
import { is } from "@atcute/lexicons";
···
15
16
import { FastAverageColor } from "fast-average-color";
16
17
import { toaster } from "~/components/Toaster";
17
18
import { parseColor } from "@ark-ui/solid";
19
+
import { transcribe } from "./transcribe";
18
20
19
21
export type TaskState = { file: File } & (
20
22
| { status: "processing" }
21
23
| { status: "error"; error: string }
22
-
| { status: "success"; result: Blob }
24
+
| { status: "success"; result: Blob; altText?: string }
23
25
);
24
26
25
27
let _idCounter = 0;
···
80
82
});
81
83
}
82
84
}
83
-
const result = await render(file, {
84
-
pfpUrl,
85
-
visualizer: showVisualizer.get() ?? true,
86
-
frameRate: frameRate.get() ?? 30,
87
-
bgColor,
88
-
duration,
89
-
});
85
+
const [result, altText] = await Promise.all([
86
+
render(file, {
87
+
pfpUrl,
88
+
visualizer: showVisualizer.get() ?? true,
89
+
frameRate: frameRate.get() ?? 30,
90
+
bgColor,
91
+
duration,
92
+
}),
93
+
(autoTranscribe.get() ?? false)
94
+
? transcribe(file)
95
+
: Promise.resolve(undefined),
96
+
]);
90
97
tasks.set(id, {
91
98
file,
92
99
status: "success",
93
100
result,
101
+
altText,
94
102
});
95
103
} catch (error) {
96
104
console.error(error);
+101
src/lib/transcribe.ts
+101
src/lib/transcribe.ts
···
1
+
import {
2
+
AutomaticSpeechRecognitionPipeline,
3
+
pipeline,
4
+
} from "@huggingface/transformers";
5
+
import { toaster } from "~/components/Toaster";
6
+
import { defaultWhisperModel, whisperModel } from "./settings";
7
+
8
+
let transcriberPromise: Promise<AutomaticSpeechRecognitionPipeline> | null =
9
+
null;
10
+
let model: AutomaticSpeechRecognitionPipeline | null = null;
11
+
12
+
const loadModel = () => {
13
+
if (model) return Promise.resolve(model);
14
+
15
+
if (transcriberPromise) return transcriberPromise;
16
+
17
+
let toastId: string | undefined;
18
+
19
+
const modelName = whisperModel.get() ?? defaultWhisperModel;
20
+
21
+
transcriberPromise = pipeline("automatic-speech-recognition", modelName, {
22
+
progress_callback: (data: any) => {
23
+
// data contains: { status, file, name, loaded, total, progress }
24
+
if (data.status === "initiate") {
25
+
if (!toastId) {
26
+
toastId = toaster.create({
27
+
title: "downloading transcription model",
28
+
description: `fetching ${data.file}...`,
29
+
type: "info",
30
+
duration: 999999,
31
+
});
32
+
}
33
+
} else if (data.status === "progress" && toastId) {
34
+
const percent = data.progress ? Math.round(data.progress) : 0;
35
+
toaster.update(toastId, {
36
+
title: "downloading transcription model",
37
+
description: `fetching ${data.file} (at ${percent}%)...`,
38
+
type: "info",
39
+
duration: 999999,
40
+
});
41
+
}
42
+
},
43
+
})
44
+
.then((transcriber) => {
45
+
if (toastId) {
46
+
toaster.update(toastId, {
47
+
title: "transcription model loaded",
48
+
description: `${modelName.split("/")[1]} is ready`,
49
+
type: "success",
50
+
duration: 3000,
51
+
});
52
+
}
53
+
model = transcriber;
54
+
return transcriber;
55
+
})
56
+
.catch((err) => {
57
+
const toastOpts = {
58
+
title: "transcription model download failed",
59
+
description: `${err}`,
60
+
type: "error",
61
+
duration: 5000,
62
+
};
63
+
if (toastId) toaster.update(toastId, toastOpts);
64
+
else toaster.create(toastOpts);
65
+
66
+
model = null;
67
+
68
+
throw err;
69
+
})
70
+
.finally(() => {
71
+
transcriberPromise = null;
72
+
});
73
+
74
+
return transcriberPromise;
75
+
};
76
+
77
+
export const preloadModel = () => {
78
+
model = null;
79
+
loadModel().catch((e) => console.error("preload failed", e));
80
+
};
81
+
82
+
export const transcribe = async (file: File): Promise<string> => {
83
+
const url = URL.createObjectURL(file);
84
+
try {
85
+
await loadModel();
86
+
if (!model) throw "model not loaded";
87
+
88
+
const output = await model(url);
89
+
return [output].flat()[0].text.trim();
90
+
} catch (err) {
91
+
console.error("transcription failed", err);
92
+
toaster.create({
93
+
title: "transcription failed",
94
+
description: `${err}`,
95
+
type: "error",
96
+
});
97
+
throw err;
98
+
} finally {
99
+
URL.revokeObjectURL(url);
100
+
}
101
+
};